| 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 |