Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(83)

Side by Side Diff: runtime/vm/aot_optimizer.cc

Issue 1841073003: VM: Fix receiver type propagation in presence of try-catch. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: addressed comments, added test Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | runtime/vm/flow_graph.h » ('j') | runtime/vm/flow_graph.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/aot_optimizer.h" 5 #include "vm/aot_optimizer.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/branch_optimizer.h" 8 #include "vm/branch_optimizer.h"
9 #include "vm/cha.h" 9 #include "vm/cha.h"
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
(...skipping 1293 matching lines...) Expand 10 before | Expand all | Expand 10 after
1304 field = cls.LookupInstanceField(field_name); 1304 field = cls.LookupInstanceField(field_name);
1305 if (!field.IsNull()) { 1305 if (!field.IsNull()) {
1306 return field.raw(); 1306 return field.raw();
1307 } 1307 }
1308 cls = cls.SuperClass(); 1308 cls = cls.SuperClass();
1309 } 1309 }
1310 return Field::null(); 1310 return Field::null();
1311 } 1311 }
1312 1312
1313 1313
1314 // Use CHA to determine if the call needs a class check: if the callee's
1315 // receiver is the same as the caller's receiver and there are no overriden
1316 // callee functions, then no class check is needed.
1317 bool AotOptimizer::InstanceCallNeedsClassCheck(
1318 InstanceCallInstr* call, RawFunction::Kind kind) const {
1319 if (!FLAG_use_cha_deopt && !isolate()->all_classes_finalized()) {
1320 // Even if class or function are private, lazy class finalization
1321 // may later add overriding methods.
1322 return true;
1323 }
1324 Definition* callee_receiver = call->ArgumentAt(0);
1325 ASSERT(callee_receiver != NULL);
1326 const Function& function = flow_graph_->function();
1327 if (function.IsDynamicFunction() &&
1328 callee_receiver->IsParameter() &&
1329 (callee_receiver->AsParameter()->index() == 0)) {
1330 const String& name = (kind == RawFunction::kMethodExtractor)
1331 ? String::Handle(Z, Field::NameFromGetter(call->function_name()))
1332 : call->function_name();
1333 const Class& cls = Class::Handle(Z, function.Owner());
1334 if (!thread()->cha()->HasOverride(cls, name)) {
1335 if (FLAG_trace_cha) {
1336 THR_Print(" **(CHA) Instance call needs no check, "
1337 "no overrides of '%s' '%s'\n",
1338 name.ToCString(), cls.ToCString());
1339 }
1340 thread()->cha()->AddToLeafClasses(cls);
1341 return false;
1342 }
1343 }
1344 return true;
1345 }
1346
1347
1348 bool AotOptimizer::InlineImplicitInstanceGetter(InstanceCallInstr* call) { 1314 bool AotOptimizer::InlineImplicitInstanceGetter(InstanceCallInstr* call) {
1349 ASSERT(call->HasICData()); 1315 ASSERT(call->HasICData());
1350 const ICData& ic_data = *call->ic_data(); 1316 const ICData& ic_data = *call->ic_data();
1351 ASSERT(ic_data.HasOneTarget()); 1317 ASSERT(ic_data.HasOneTarget());
1352 GrowableArray<intptr_t> class_ids; 1318 GrowableArray<intptr_t> class_ids;
1353 ic_data.GetClassIdsAt(0, &class_ids); 1319 ic_data.GetClassIdsAt(0, &class_ids);
1354 ASSERT(class_ids.length() == 1); 1320 ASSERT(class_ids.length() == 1);
1355 // Inline implicit instance getter. 1321 // Inline implicit instance getter.
1356 const String& field_name = 1322 const String& field_name =
1357 String::Handle(Z, Field::NameFromGetter(call->function_name())); 1323 String::Handle(Z, Field::NameFromGetter(call->function_name()));
1358 const Field& field = 1324 const Field& field =
1359 Field::ZoneHandle(Z, GetField(class_ids[0], field_name)); 1325 Field::ZoneHandle(Z, GetField(class_ids[0], field_name));
1360 ASSERT(!field.IsNull()); 1326 ASSERT(!field.IsNull());
1361 1327
1362 if (InstanceCallNeedsClassCheck(call, RawFunction::kImplicitGetter)) { 1328 if (flow_graph()->InstanceCallNeedsClassCheck(
1329 call, RawFunction::kImplicitGetter)) {
1363 return false; 1330 return false;
1364 } 1331 }
1365 LoadFieldInstr* load = new(Z) LoadFieldInstr( 1332 LoadFieldInstr* load = new(Z) LoadFieldInstr(
1366 new(Z) Value(call->ArgumentAt(0)), 1333 new(Z) Value(call->ArgumentAt(0)),
1367 &field, 1334 &field,
1368 AbstractType::ZoneHandle(Z, field.type()), 1335 AbstractType::ZoneHandle(Z, field.type()),
1369 call->token_pos()); 1336 call->token_pos());
1370 load->set_is_immutable(field.is_final()); 1337 load->set_is_immutable(field.is_final());
1371 1338
1372 // Discard the environment from the original instruction because the load 1339 // Discard the environment from the original instruction because the load
(...skipping 1090 matching lines...) Expand 10 before | Expand all | Expand 10 after
2463 // we don't have one target. 2430 // we don't have one target.
2464 const Function& target = 2431 const Function& target =
2465 Function::Handle(Z, unary_checks.GetTargetAt(0)); 2432 Function::Handle(Z, unary_checks.GetTargetAt(0));
2466 const bool polymorphic_target = MethodRecognizer::PolymorphicTarget(target); 2433 const bool polymorphic_target = MethodRecognizer::PolymorphicTarget(target);
2467 has_one_target = !polymorphic_target; 2434 has_one_target = !polymorphic_target;
2468 } 2435 }
2469 2436
2470 if (has_one_target) { 2437 if (has_one_target) {
2471 RawFunction::Kind function_kind = 2438 RawFunction::Kind function_kind =
2472 Function::Handle(Z, unary_checks.GetTargetAt(0)).kind(); 2439 Function::Handle(Z, unary_checks.GetTargetAt(0)).kind();
2473 if (!InstanceCallNeedsClassCheck(instr, function_kind)) { 2440 if (!flow_graph()->InstanceCallNeedsClassCheck(
2441 instr, function_kind)) {
2474 PolymorphicInstanceCallInstr* call = 2442 PolymorphicInstanceCallInstr* call =
2475 new(Z) PolymorphicInstanceCallInstr(instr, unary_checks, 2443 new(Z) PolymorphicInstanceCallInstr(instr, unary_checks,
2476 /* with_checks = */ false); 2444 /* with_checks = */ false);
2477 instr->ReplaceWith(call, current_iterator()); 2445 instr->ReplaceWith(call, current_iterator());
2478 return; 2446 return;
2479 } 2447 }
2480 } 2448 }
2481 switch (instr->token_kind()) { 2449 switch (instr->token_kind()) {
2482 case Token::kEQ: 2450 case Token::kEQ:
2483 case Token::kLT: 2451 case Token::kLT:
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after
2764 // Non-implicit setter are inlined like normal method calls. 2732 // Non-implicit setter are inlined like normal method calls.
2765 return false; 2733 return false;
2766 } 2734 }
2767 // Inline implicit instance setter. 2735 // Inline implicit instance setter.
2768 const String& field_name = 2736 const String& field_name =
2769 String::Handle(Z, Field::NameFromSetter(instr->function_name())); 2737 String::Handle(Z, Field::NameFromSetter(instr->function_name()));
2770 const Field& field = 2738 const Field& field =
2771 Field::ZoneHandle(Z, GetField(class_id, field_name)); 2739 Field::ZoneHandle(Z, GetField(class_id, field_name));
2772 ASSERT(!field.IsNull()); 2740 ASSERT(!field.IsNull());
2773 2741
2774 if (InstanceCallNeedsClassCheck(instr, RawFunction::kImplicitSetter)) { 2742 if (flow_graph()->InstanceCallNeedsClassCheck(
2743 instr, RawFunction::kImplicitSetter)) {
2775 return false; 2744 return false;
2776 } 2745 }
2777 2746
2778 // Field guard was detached. 2747 // Field guard was detached.
2779 StoreInstanceFieldInstr* store = new(Z) StoreInstanceFieldInstr( 2748 StoreInstanceFieldInstr* store = new(Z) StoreInstanceFieldInstr(
2780 field, 2749 field,
2781 new(Z) Value(instr->ArgumentAt(0)), 2750 new(Z) Value(instr->ArgumentAt(0)),
2782 new(Z) Value(instr->ArgumentAt(1)), 2751 new(Z) Value(instr->ArgumentAt(1)),
2783 kEmitStoreBarrier, 2752 kEmitStoreBarrier,
2784 instr->token_pos()); 2753 instr->token_pos());
2785 2754
2786 // No unboxed stores in precompiled code. 2755 // No unboxed stores in precompiled code.
2787 ASSERT(!store->IsUnboxedStore()); 2756 ASSERT(!store->IsUnboxedStore());
2788 2757
2789 // Discard the environment from the original instruction because the store 2758 // Discard the environment from the original instruction because the store
2790 // can't deoptimize. 2759 // can't deoptimize.
2791 instr->RemoveEnvironment(); 2760 instr->RemoveEnvironment();
2792 ReplaceCall(instr, store); 2761 ReplaceCall(instr, store);
2793 return true; 2762 return true;
2794 } 2763 }
2795 2764
2796 2765
2797 } // namespace dart 2766 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/flow_graph.h » ('j') | runtime/vm/flow_graph.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698