| Index: runtime/vm/flow_graph_optimizer.cc
|
| ===================================================================
|
| --- runtime/vm/flow_graph_optimizer.cc (revision 39244)
|
| +++ runtime/vm/flow_graph_optimizer.cc (working copy)
|
| @@ -2267,7 +2267,9 @@
|
| // receiver is the same as the caller's receiver and there are no overriden
|
| // callee functions, then no class check is needed.
|
| bool FlowGraphOptimizer::InstanceCallNeedsClassCheck(
|
| - InstanceCallInstr* call) const {
|
| + InstanceCallInstr* call, RawFunction::Kind kind) const {
|
| + ASSERT(kind == RawFunction::kRegularFunction ||
|
| + kind == RawFunction::kMethodExtractor);
|
| if (!FLAG_use_cha) return true;
|
| Definition* callee_receiver = call->ArgumentAt(0);
|
| ASSERT(callee_receiver != NULL);
|
| @@ -2275,31 +2277,16 @@
|
| if (function.IsDynamicFunction() &&
|
| callee_receiver->IsParameter() &&
|
| (callee_receiver->AsParameter()->index() == 0)) {
|
| + const String& name = (kind == RawFunction::kMethodExtractor)
|
| + ? String::Handle(I, Field::NameFromGetter(call->function_name()))
|
| + : call->function_name();
|
| return isolate()->cha()->HasOverride(Class::Handle(I, function.Owner()),
|
| - call->function_name());
|
| + name);
|
| }
|
| return true;
|
| }
|
|
|
|
|
| -bool FlowGraphOptimizer::MethodExtractorNeedsClassCheck(
|
| - InstanceCallInstr* call) const {
|
| - if (!FLAG_use_cha) return true;
|
| - Definition* callee_receiver = call->ArgumentAt(0);
|
| - ASSERT(callee_receiver != NULL);
|
| - const Function& function = flow_graph_->parsed_function().function();
|
| - if (function.IsDynamicFunction() &&
|
| - callee_receiver->IsParameter() &&
|
| - (callee_receiver->AsParameter()->index() == 0)) {
|
| - const String& field_name =
|
| - String::Handle(I, Field::NameFromGetter(call->function_name()));
|
| - return isolate()->cha()->HasOverride(
|
| - Class::Handle(I, function.Owner()), field_name);
|
| - }
|
| - return true;
|
| -}
|
| -
|
| -
|
| void FlowGraphOptimizer::InlineImplicitInstanceGetter(InstanceCallInstr* call) {
|
| ASSERT(call->HasICData());
|
| const ICData& ic_data = *call->ic_data();
|
| @@ -2315,7 +2302,7 @@
|
| Field::ZoneHandle(I, GetField(class_ids[0], field_name));
|
| ASSERT(!field.IsNull());
|
|
|
| - if (InstanceCallNeedsClassCheck(call)) {
|
| + if (InstanceCallNeedsClassCheck(call, RawFunction::kRegularFunction)) {
|
| AddReceiverCheck(call);
|
| }
|
| LoadFieldInstr* load = new(I) LoadFieldInstr(
|
| @@ -4153,7 +4140,7 @@
|
| ? FLAG_max_equality_polymorphic_checks
|
| : FLAG_max_polymorphic_checks;
|
| if ((unary_checks.NumberOfChecks() > max_checks) &&
|
| - InstanceCallNeedsClassCheck(instr)) {
|
| + InstanceCallNeedsClassCheck(instr, RawFunction::kRegularFunction)) {
|
| // Too many checks, it will be megamorphic which needs unary checks.
|
| instr->set_ic_data(&unary_checks);
|
| return;
|
| @@ -4206,11 +4193,9 @@
|
| }
|
|
|
| if (has_one_target) {
|
| - const bool is_method_extraction =
|
| - Function::Handle(I, unary_checks.GetTargetAt(0)).IsMethodExtractor();
|
| -
|
| - if ((is_method_extraction && !MethodExtractorNeedsClassCheck(instr)) ||
|
| - (!is_method_extraction && !InstanceCallNeedsClassCheck(instr))) {
|
| + RawFunction::Kind function_kind =
|
| + Function::Handle(I, unary_checks.GetTargetAt(0)).kind();
|
| + if (!InstanceCallNeedsClassCheck(instr, function_kind)) {
|
| const bool call_with_checks = false;
|
| PolymorphicInstanceCallInstr* call =
|
| new(I) PolymorphicInstanceCallInstr(instr, unary_checks,
|
| @@ -4472,7 +4457,7 @@
|
| Field::ZoneHandle(I, GetField(class_id, field_name));
|
| ASSERT(!field.IsNull());
|
|
|
| - if (InstanceCallNeedsClassCheck(instr)) {
|
| + if (InstanceCallNeedsClassCheck(instr, RawFunction::kRegularFunction)) {
|
| AddReceiverCheck(instr);
|
| }
|
| StoreBarrierType needs_store_barrier = kEmitStoreBarrier;
|
|
|