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/flow_graph_optimizer.h" | 5 #include "vm/flow_graph_optimizer.h" |
6 | 6 |
7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
8 #include "vm/cha.h" | 8 #include "vm/cha.h" |
9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
10 #include "vm/cpu.h" | 10 #include "vm/cpu.h" |
(...skipping 4254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4265 PolymorphicInstanceCallInstr* call = | 4265 PolymorphicInstanceCallInstr* call = |
4266 new(Z) PolymorphicInstanceCallInstr(instr, unary_checks, | 4266 new(Z) PolymorphicInstanceCallInstr(instr, unary_checks, |
4267 /* with_checks = */ true); | 4267 /* with_checks = */ true); |
4268 instr->ReplaceWith(call, current_iterator()); | 4268 instr->ReplaceWith(call, current_iterator()); |
4269 return; | 4269 return; |
4270 } | 4270 } |
4271 | 4271 |
4272 // No IC data checks. Try resolve target using the propagated type. | 4272 // No IC data checks. Try resolve target using the propagated type. |
4273 // If the propagated type has a method with the target name and there are | 4273 // If the propagated type has a method with the target name and there are |
4274 // no overrides with that name according to CHA, call the method directly. | 4274 // no overrides with that name according to CHA, call the method directly. |
4275 const AbstractType* receiver_type = | 4275 const intptr_t receiver_cid = |
4276 instr->PushArgumentAt(0)->value()->Type()->ToAbstractType(); | 4276 instr->PushArgumentAt(0)->value()->Type()->ToCid(); |
4277 if (receiver_type->IsDynamicType()) return; | 4277 if (receiver_cid == kDynamicCid) return; |
4278 if (receiver_type->HasResolvedTypeClass()) { | 4278 const Class& receiver_class = Class::Handle(Z, |
4279 const Class& receiver_class = Class::Handle(Z, | 4279 isolate()->class_table()->At(receiver_cid)); |
4280 receiver_type->type_class()); | 4280 |
4281 const Array& args_desc_array = Array::Handle(Z, | 4281 const Array& args_desc_array = Array::Handle(Z, |
4282 ArgumentsDescriptor::New(instr->ArgumentCount(), | 4282 ArgumentsDescriptor::New(instr->ArgumentCount(), |
4283 instr->argument_names())); | 4283 instr->argument_names())); |
4284 ArgumentsDescriptor args_desc(args_desc_array); | 4284 ArgumentsDescriptor args_desc(args_desc_array); |
4285 const Function& function = Function::Handle(Z, | 4285 const Function& function = Function::Handle(Z, |
4286 Resolver::ResolveDynamicForReceiverClass( | 4286 Resolver::ResolveDynamicForReceiverClass( |
4287 receiver_class, | 4287 receiver_class, |
4288 instr->function_name(), | 4288 instr->function_name(), |
4289 args_desc)); | 4289 args_desc)); |
4290 if (function.IsNull()) { | 4290 if (function.IsNull()) { |
4291 return; | 4291 return; |
| 4292 } |
| 4293 if (!thread()->cha()->HasOverride(receiver_class, instr->function_name())) { |
| 4294 if (FLAG_trace_cha) { |
| 4295 THR_Print(" **(CHA) Instance call needs no check, " |
| 4296 "no overrides of '%s' '%s'\n", |
| 4297 instr->function_name().ToCString(), receiver_class.ToCString()); |
4292 } | 4298 } |
4293 if (!thread()->cha()->HasOverride(receiver_class, instr->function_name())) { | 4299 thread()->cha()->AddToLeafClasses(receiver_class); |
4294 if (FLAG_trace_cha) { | |
4295 THR_Print(" **(CHA) Instance call needs no check, " | |
4296 "no overrides of '%s' '%s'\n", | |
4297 instr->function_name().ToCString(), receiver_class.ToCString()); | |
4298 } | |
4299 thread()->cha()->AddToLeafClasses(receiver_class); | |
4300 | 4300 |
4301 // Create fake IC data with the resolved target. | 4301 // Create fake IC data with the resolved target. |
4302 const ICData& ic_data = ICData::Handle( | 4302 const ICData& ic_data = ICData::Handle( |
4303 ICData::New(flow_graph_->function(), | 4303 ICData::New(flow_graph_->function(), |
4304 instr->function_name(), | 4304 instr->function_name(), |
4305 args_desc_array, | 4305 args_desc_array, |
4306 Thread::kNoDeoptId, | 4306 Thread::kNoDeoptId, |
4307 /* args_tested = */ 1)); | 4307 /* args_tested = */ 1)); |
4308 ic_data.AddReceiverCheck(receiver_class.id(), function); | 4308 ic_data.AddReceiverCheck(receiver_class.id(), function); |
4309 PolymorphicInstanceCallInstr* call = | 4309 PolymorphicInstanceCallInstr* call = |
4310 new(Z) PolymorphicInstanceCallInstr(instr, ic_data, | 4310 new(Z) PolymorphicInstanceCallInstr(instr, ic_data, |
4311 /* with_checks = */ false); | 4311 /* with_checks = */ false); |
4312 instr->ReplaceWith(call, current_iterator()); | 4312 instr->ReplaceWith(call, current_iterator()); |
4313 return; | 4313 return; |
4314 } | |
4315 } | 4314 } |
4316 } | 4315 } |
4317 | 4316 |
4318 | 4317 |
4319 // Tries to optimize instance call by replacing it with a faster instruction | 4318 // Tries to optimize instance call by replacing it with a faster instruction |
4320 // (e.g, binary op, field load, ..). | 4319 // (e.g, binary op, field load, ..). |
4321 void FlowGraphOptimizer::VisitInstanceCall(InstanceCallInstr* instr) { | 4320 void FlowGraphOptimizer::VisitInstanceCall(InstanceCallInstr* instr) { |
4322 if (Compiler::always_optimize()) { | 4321 if (Compiler::always_optimize()) { |
4323 InstanceCallNoopt(instr); | 4322 InstanceCallNoopt(instr); |
4324 return; | 4323 return; |
(...skipping 4461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8786 | 8785 |
8787 // Insert materializations at environment uses. | 8786 // Insert materializations at environment uses. |
8788 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { | 8787 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { |
8789 CreateMaterializationAt( | 8788 CreateMaterializationAt( |
8790 exits_collector_.exits()[i], alloc, *slots); | 8789 exits_collector_.exits()[i], alloc, *slots); |
8791 } | 8790 } |
8792 } | 8791 } |
8793 | 8792 |
8794 | 8793 |
8795 } // namespace dart | 8794 } // namespace dart |
OLD | NEW |