Skip to content

Commit 84e7bef

Browse files
mkustermanncommit-bot@chromium.org
authored andcommitted
Reland "[VM] Allow the inlining code to inline implicit getters even if a StaticCallInstr is used"
This also changes the implementation of Function::LookupImplicitGetterSetterField to **not** use token positions for finding the right field, but rather the name. Issue #31798 Change-Id: I418c89a1426c33b2bfa8adc00534511657af51f1 Reviewed-on: https://dart-review.googlesource.com/34141 Commit-Queue: Martin Kustermann <[email protected]> Reviewed-by: Vyacheslav Egorov <[email protected]>
1 parent d380e88 commit 84e7bef

File tree

6 files changed

+53
-19
lines changed

6 files changed

+53
-19
lines changed

runtime/vm/compiler/aot/aot_call_specializer.cc

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,20 @@ bool AotCallSpecializer::TryInlineFieldAccess(InstanceCallInstr* call) {
251251
return false;
252252
}
253253

254+
bool AotCallSpecializer::TryInlineFieldAccess(StaticCallInstr* call) {
255+
if (call->function().IsImplicitGetterFunction()) {
256+
Field& field =
257+
Field::ZoneHandle(call->function().LookupImplicitGetterSetterField());
258+
if (should_clone_fields_) {
259+
field = field.CloneFromOriginal();
260+
}
261+
InlineImplicitInstanceGetter(call, field);
262+
return true;
263+
}
264+
265+
return false;
266+
}
267+
254268
Value* AotCallSpecializer::PrepareStaticOpInput(Value* input,
255269
intptr_t cid,
256270
Instruction* call) {
@@ -825,6 +839,13 @@ void AotCallSpecializer::VisitInstanceCall(InstanceCallInstr* instr) {
825839
}
826840
}
827841

842+
void AotCallSpecializer::VisitStaticCall(StaticCallInstr* instr) {
843+
if (TryInlineFieldAccess(instr)) {
844+
return;
845+
}
846+
CallSpecializer::VisitStaticCall(instr);
847+
}
848+
828849
bool AotCallSpecializer::TryExpandCallThroughGetter(const Class& receiver_class,
829850
InstanceCallInstr* call) {
830851
// If it's an accessor call it can't be a call through getter.

runtime/vm/compiler/aot/aot_call_specializer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class AotCallSpecializer : public CallSpecializer {
2626
void ReplaceArrayBoundChecks();
2727

2828
virtual void VisitInstanceCall(InstanceCallInstr* instr);
29+
virtual void VisitStaticCall(StaticCallInstr* instr);
2930
virtual void VisitPolymorphicInstanceCall(
3031
PolymorphicInstanceCallInstr* instr);
3132

@@ -44,6 +45,7 @@ class AotCallSpecializer : public CallSpecializer {
4445
bool TryReplaceWithHaveSameRuntimeType(InstanceCallInstr* call);
4546

4647
bool TryInlineFieldAccess(InstanceCallInstr* call);
48+
bool TryInlineFieldAccess(StaticCallInstr* call);
4749

4850
Value* PrepareStaticOpInput(Value* input, intptr_t cid, Instruction* call);
4951

runtime/vm/compiler/backend/inliner.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1069,6 +1069,8 @@ class CallSiteInliner : public ValueObject {
10691069
// before 'SelectRepresentations' which inserts conversion nodes.
10701070
callee_graph->TryOptimizePatterns();
10711071
DEBUG_ASSERT(callee_graph->VerifyUseLists());
1072+
1073+
callee_graph->Canonicalize();
10721074
#else
10731075
UNREACHABLE();
10741076
#endif // DART_PRECOMPILER

runtime/vm/compiler/call_specializer.cc

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -878,6 +878,12 @@ bool CallSpecializer::TryInlineImplicitInstanceGetter(InstanceCallInstr* call) {
878878

879879
AddReceiverCheck(call);
880880
}
881+
InlineImplicitInstanceGetter(call, field);
882+
return true;
883+
}
884+
885+
void CallSpecializer::InlineImplicitInstanceGetter(Definition* call,
886+
const Field& field) {
881887
LoadFieldInstr* load = new (Z) LoadFieldInstr(
882888
new (Z) Value(call->ArgumentAt(0)), &field,
883889
AbstractType::ZoneHandle(Z, field.type()), call->token_pos(),
@@ -895,7 +901,6 @@ bool CallSpecializer::TryInlineImplicitInstanceGetter(InstanceCallInstr* call) {
895901
it.Current()->SetReachingType(NULL);
896902
}
897903
}
898-
return true;
899904
}
900905

901906
bool CallSpecializer::TryInlineInstanceSetter(InstanceCallInstr* instr,

runtime/vm/compiler/call_specializer.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ class CallSpecializer : public FlowGraphVisitor {
3434
bool should_clone_fields)
3535
: FlowGraphVisitor(flow_graph->reverse_postorder()),
3636
speculative_policy_(speculative_policy),
37-
flow_graph_(flow_graph),
38-
should_clone_fields_(should_clone_fields) {}
37+
should_clone_fields_(should_clone_fields),
38+
flow_graph_(flow_graph) {}
3939

4040
virtual ~CallSpecializer() {}
4141

@@ -111,7 +111,10 @@ class CallSpecializer : public FlowGraphVisitor {
111111
virtual bool TryOptimizeStaticCallUsingStaticTypes(StaticCallInstr* call) = 0;
112112

113113
protected:
114+
void InlineImplicitInstanceGetter(Definition* call, const Field& field);
115+
114116
SpeculativeInliningPolicy* speculative_policy_;
117+
const bool should_clone_fields_;
115118

116119
private:
117120
bool TypeCheckAsClassEquality(const AbstractType& type);
@@ -169,7 +172,6 @@ class CallSpecializer : public FlowGraphVisitor {
169172
const AbstractType& type);
170173

171174
FlowGraph* flow_graph_;
172-
const bool should_clone_fields_;
173175
};
174176

175177
} // namespace dart

runtime/vm/object.cc

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5585,22 +5585,24 @@ void Function::set_saved_args_desc(const Array& value) const {
55855585
}
55865586

55875587
RawField* Function::LookupImplicitGetterSetterField() const {
5588-
ASSERT((kind() == RawFunction::kImplicitGetter) ||
5589-
(kind() == RawFunction::kImplicitSetter) ||
5590-
(kind() == RawFunction::kImplicitStaticFinalGetter));
5591-
const Class& owner = Class::Handle(Owner());
5592-
ASSERT(!owner.IsNull());
5593-
const Array& fields = Array::Handle(owner.fields());
5594-
ASSERT(!fields.IsNull());
5595-
Field& field = Field::Handle();
5596-
for (intptr_t i = 0; i < fields.Length(); i++) {
5597-
field ^= fields.At(i);
5598-
ASSERT(!field.IsNull());
5599-
if (field.token_pos() == token_pos()) {
5600-
return field.raw();
5601-
}
5588+
// TODO(27590) Store Field object inside RawFunction::data_ if possible.
5589+
Zone* Z = Thread::Current()->zone();
5590+
String& field_name = String::Handle(Z, name());
5591+
switch (kind()) {
5592+
case RawFunction::kImplicitGetter:
5593+
case RawFunction::kImplicitStaticFinalGetter:
5594+
field_name = Field::NameFromGetter(field_name);
5595+
break;
5596+
case RawFunction::kImplicitSetter:
5597+
field_name = Field::NameFromSetter(field_name);
5598+
break;
5599+
default:
5600+
UNREACHABLE();
56025601
}
5603-
return Field::null();
5602+
ASSERT(field_name.IsSymbol());
5603+
const Class& owner = Class::Handle(Z, Owner());
5604+
ASSERT(!owner.IsNull());
5605+
return owner.LookupField(field_name);
56045606
}
56055607

56065608
RawFunction* Function::parent_function() const {

0 commit comments

Comments
 (0)