Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit a69cb6d

Browse files
sstricklcommit-bot@chromium.org
authored andcommitted
[vm] Walk Functions as well as Code objects in DedupInstructions.
Previously, we used the owner field to find the function whose entry points to fix up after deduplicating instructions/code objects. However, this means retrieving and checking the owning Function for each Code object that has one, even if that Code object isn't the current code object for the owning function. Instead, now we extend the instruction deduplication visitors to Functions, where visiting a Function means visiting its active Code object before fixing up the entry point cache. Since the ProgramWalker also visits Code objects, this means visiting some Code objects twice (once in the ProgramWalker and once when visiting the Function for which it is the current code). However, since the deduplication process is idempotent, the additional visits will not cause the entry points for the Code object to change further (which would otherwise invalidate the caches of already visited Functions). Thus, the order of the visits does not affect the results. Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-product-x64-try Change-Id: Idd12fc94c5fb98f1fc9eb669d09b47822b0eac1e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/144700 Reviewed-by: Daco Harkes <[email protected]> Commit-Queue: Tess Strickland <[email protected]>
1 parent 6406155 commit a69cb6d

File tree

1 file changed

+23
-22
lines changed

1 file changed

+23
-22
lines changed

runtime/vm/program_visitor.cc

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,7 +1164,7 @@ void ProgramVisitor::DedupInstructions(Zone* zone, Isolate* isolate) {
11641164
public:
11651165
explicit DedupInstructionsVisitor(Zone* zone)
11661166
: Dedupper(zone),
1167-
function_(Function::Handle(zone)),
1167+
code_(Code::Handle(zone)),
11681168
instructions_(Instructions::Handle(zone)) {
11691169
if (Snapshot::IncludesCode(Dart::vm_snapshot_kind())) {
11701170
// Prefer existing objects in the VM isolate.
@@ -1178,6 +1178,16 @@ void ProgramVisitor::DedupInstructions(Zone* zone, Isolate* isolate) {
11781178
AddCanonical(instructions_);
11791179
}
11801180

1181+
void VisitFunction(const Function& function) {
1182+
if (!function.HasCode()) return;
1183+
code_ = function.CurrentCode();
1184+
// This causes the code to be visited once here and once directly in the
1185+
// ProgramWalker, but as long as the deduplication process is idempotent,
1186+
// the cached entry points won't change during the second visit.
1187+
VisitCode(code_);
1188+
function.SetInstructions(code_); // Update cached entry point.
1189+
}
1190+
11811191
void VisitCode(const Code& code) {
11821192
instructions_ = code.instructions();
11831193
instructions_ = Dedup(instructions_);
@@ -1188,37 +1198,32 @@ void ProgramVisitor::DedupInstructions(Zone* zone, Isolate* isolate) {
11881198
}
11891199
code.SetActiveInstructions(instructions_,
11901200
code.UncheckedEntryPointOffset());
1191-
if (!code.IsFunctionCode()) return;
1192-
function_ = code.function();
1193-
if (function_.IsNull()) return;
1194-
// Make sure that this is the code object currently installed for the
1195-
// function before we update the entry points.
1196-
if (!function_.HasCode()) return;
1197-
if (function_.CurrentCode() != code.raw()) return;
1198-
function_.SetInstructions(code); // Update cached entry point.
11991201
}
12001202

12011203
private:
1202-
Function& function_;
1204+
Code& code_;
12031205
Instructions& instructions_;
12041206
};
12051207

12061208
#if defined(DART_PRECOMPILER)
12071209
class DedupInstructionsWithSameMetadataVisitor
12081210
: public CodeVisitor,
1209-
public Dedupper<Code, CodeKeyValueTrait>,
1210-
public ObjectVisitor {
1211+
public Dedupper<Code, CodeKeyValueTrait> {
12111212
public:
12121213
explicit DedupInstructionsWithSameMetadataVisitor(Zone* zone)
12131214
: Dedupper(zone),
12141215
canonical_(Code::Handle(zone)),
1215-
function_(Function::Handle(zone)),
1216+
code_(Code::Handle(zone)),
12161217
instructions_(Instructions::Handle(zone)) {}
12171218

1218-
void VisitObject(RawObject* obj) {
1219-
if (!obj->IsCode()) return;
1220-
canonical_ = Code::RawCast(obj);
1221-
AddCanonical(canonical_);
1219+
void VisitFunction(const Function& function) {
1220+
if (!function.HasCode()) return;
1221+
code_ = function.CurrentCode();
1222+
// This causes the code to be visited once here and once directly in the
1223+
// ProgramWalker, but as long as the deduplication process is idempotent,
1224+
// the cached entry points won't change during the second visit.
1225+
VisitCode(code_);
1226+
function.SetInstructions(code_); // Update cached entry point.
12221227
}
12231228

12241229
void VisitCode(const Code& code) {
@@ -1228,17 +1233,13 @@ void ProgramVisitor::DedupInstructions(Zone* zone, Isolate* isolate) {
12281233
code.SetActiveInstructions(instructions_,
12291234
code.UncheckedEntryPointOffset());
12301235
code.set_instructions(instructions_);
1231-
if (!code.IsFunctionCode()) return;
1232-
function_ = code.function();
1233-
if (function_.IsNull()) return;
1234-
function_.SetInstructions(code); // Update cached entry point.
12351236
}
12361237

12371238
private:
12381239
bool CanCanonicalize(const Code& code) const { return !code.IsDisabled(); }
12391240

12401241
Code& canonical_;
1241-
Function& function_;
1242+
Code& code_;
12421243
Instructions& instructions_;
12431244
};
12441245

0 commit comments

Comments
 (0)