| OLD | NEW |
| 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 2386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2397 | 2397 |
| 2398 ReplaceCall(instr, smi_op); | 2398 ReplaceCall(instr, smi_op); |
| 2399 return; | 2399 return; |
| 2400 } | 2400 } |
| 2401 break; | 2401 break; |
| 2402 } | 2402 } |
| 2403 default: | 2403 default: |
| 2404 break; | 2404 break; |
| 2405 } | 2405 } |
| 2406 | 2406 |
| 2407 // No IC data checks. Try resolve target using the propagated type. | 2407 // No IC data checks. Try resolve target using the propagated cid. |
| 2408 // If the propagated type has a method with the target name and there are | |
| 2409 // no overrides with that name according to CHA, call the method directly. | |
| 2410 const intptr_t receiver_cid = | 2408 const intptr_t receiver_cid = |
| 2411 instr->PushArgumentAt(0)->value()->Type()->ToCid(); | 2409 instr->PushArgumentAt(0)->value()->Type()->ToCid(); |
| 2412 if (receiver_cid != kDynamicCid) { | 2410 if (receiver_cid != kDynamicCid) { |
| 2413 const Class& receiver_class = Class::Handle(Z, | 2411 const Class& receiver_class = Class::Handle(Z, |
| 2414 isolate()->class_table()->At(receiver_cid)); | 2412 isolate()->class_table()->At(receiver_cid)); |
| 2415 | 2413 |
| 2416 const Array& args_desc_array = Array::Handle(Z, | 2414 const Array& args_desc_array = Array::Handle(Z, |
| 2417 ArgumentsDescriptor::New(instr->ArgumentCount(), | 2415 ArgumentsDescriptor::New(instr->ArgumentCount(), |
| 2418 instr->argument_names())); | 2416 instr->argument_names())); |
| 2419 ArgumentsDescriptor args_desc(args_desc_array); | 2417 ArgumentsDescriptor args_desc(args_desc_array); |
| 2420 const Function& function = Function::Handle(Z, | 2418 const Function& function = Function::Handle(Z, |
| 2421 Resolver::ResolveDynamicForReceiverClass( | 2419 Resolver::ResolveDynamicForReceiverClass( |
| 2422 receiver_class, | 2420 receiver_class, |
| 2423 instr->function_name(), | 2421 instr->function_name(), |
| 2424 args_desc)); | 2422 args_desc)); |
| 2425 if (!function.IsNull()) { | 2423 if (!function.IsNull()) { |
| 2426 intptr_t subclasses = 0; | 2424 const ICData& ic_data = ICData::Handle( |
| 2427 if (!thread()->cha()->HasOverride(receiver_class, | 2425 ICData::New(flow_graph_->function(), |
| 2428 instr->function_name(), | 2426 instr->function_name(), |
| 2429 &subclasses)) { | 2427 args_desc_array, |
| 2430 if (FLAG_trace_cha) { | 2428 Thread::kNoDeoptId, |
| 2431 THR_Print(" **(CHA) Instance call needs no check, " | 2429 /* args_tested = */ 1, |
| 2432 "no overrides of '%s' '%s'\n", | 2430 false)); |
| 2433 instr->function_name().ToCString(), receiver_class.ToCString()); | 2431 ic_data.AddReceiverCheck(receiver_class.id(), function); |
| 2434 } | 2432 PolymorphicInstanceCallInstr* call = |
| 2435 | 2433 new(Z) PolymorphicInstanceCallInstr(instr, ic_data, |
| 2436 // Create fake IC data with the resolved target. | 2434 /* with_checks = */ false, |
| 2437 const ICData& ic_data = ICData::Handle( | 2435 /* complete = */ true); |
| 2438 ICData::New(flow_graph_->function(), | 2436 instr->ReplaceWith(call, current_iterator()); |
| 2439 instr->function_name(), | 2437 return; |
| 2440 args_desc_array, | |
| 2441 Thread::kNoDeoptId, | |
| 2442 /* args_tested = */ 1, | |
| 2443 false)); | |
| 2444 ic_data.AddReceiverCheck(receiver_class.id(), function); | |
| 2445 PolymorphicInstanceCallInstr* call = | |
| 2446 new(Z) PolymorphicInstanceCallInstr(instr, ic_data, | |
| 2447 /* with_checks = */ false, | |
| 2448 /* complete = */ true); | |
| 2449 instr->ReplaceWith(call, current_iterator()); | |
| 2450 return; | |
| 2451 } | |
| 2452 } | 2438 } |
| 2453 } | 2439 } |
| 2454 | 2440 |
| 2455 Definition* callee_receiver = instr->ArgumentAt(0); | 2441 Definition* callee_receiver = instr->ArgumentAt(0); |
| 2456 const Function& function = flow_graph_->function(); | 2442 const Function& function = flow_graph_->function(); |
| 2457 if (function.IsDynamicFunction() && | 2443 if (function.IsDynamicFunction() && |
| 2458 flow_graph_->IsReceiver(callee_receiver)) { | 2444 flow_graph_->IsReceiver(callee_receiver)) { |
| 2459 // Call receiver is method receiver. | 2445 // Call receiver is method receiver. |
| 2460 Class& receiver_class = Class::Handle(Z, function.Owner()); | 2446 Class& receiver_class = Class::Handle(Z, function.Owner()); |
| 2461 | 2447 |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2792 | 2778 |
| 2793 // Discard the environment from the original instruction because the store | 2779 // Discard the environment from the original instruction because the store |
| 2794 // can't deoptimize. | 2780 // can't deoptimize. |
| 2795 instr->RemoveEnvironment(); | 2781 instr->RemoveEnvironment(); |
| 2796 ReplaceCall(instr, store); | 2782 ReplaceCall(instr, store); |
| 2797 return true; | 2783 return true; |
| 2798 } | 2784 } |
| 2799 | 2785 |
| 2800 | 2786 |
| 2801 } // namespace dart | 2787 } // namespace dart |
| OLD | NEW |