| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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/globals.h" // Needed here to get TARGET_ARCH_XXX. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_XXX. |
| 6 | 6 |
| 7 #include "vm/flow_graph_compiler.h" | 7 #include "vm/flow_graph_compiler.h" |
| 8 | 8 |
| 9 #include "vm/dart_entry.h" | 9 #include "vm/dart_entry.h" |
| 10 #include "vm/debugger.h" | 10 #include "vm/debugger.h" |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 } | 38 } |
| 39 | 39 |
| 40 | 40 |
| 41 void CompilerDeoptInfoWithStub::BuildReturnAddress(DeoptInfoBuilder* builder, | 41 void CompilerDeoptInfoWithStub::BuildReturnAddress(DeoptInfoBuilder* builder, |
| 42 const Function& function, | 42 const Function& function, |
| 43 intptr_t slot_ix) { | 43 intptr_t slot_ix) { |
| 44 builder->AddReturnAddressBefore(function, deopt_id(), slot_ix); | 44 builder->AddReturnAddressBefore(function, deopt_id(), slot_ix); |
| 45 } | 45 } |
| 46 | 46 |
| 47 | 47 |
| 48 // Assign locations to incoming arguments, i.e., values pushed above spill slots | |
| 49 // with PushArgument. Recursively allocates from outermost to innermost | |
| 50 // environment. | |
| 51 void CompilerDeoptInfo::AllocateIncomingParametersRecursive( | |
| 52 Environment* env, | |
| 53 intptr_t* stack_height) { | |
| 54 if (env == NULL) return; | |
| 55 AllocateIncomingParametersRecursive(env->outer(), stack_height); | |
| 56 for (Environment::ShallowIterator it(env); !it.Done(); it.Advance()) { | |
| 57 if (it.CurrentLocation().IsInvalid()) { | |
| 58 ASSERT(it.CurrentValue()->definition()->IsPushArgument()); | |
| 59 it.SetCurrentLocation(Location::StackSlot((*stack_height)++)); | |
| 60 } | |
| 61 } | |
| 62 } | |
| 63 | |
| 64 | |
| 65 RawDeoptInfo* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler) { | 48 RawDeoptInfo* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler) { |
| 66 if (deoptimization_env_ == NULL) return DeoptInfo::null(); | 49 if (deoptimization_env_ == NULL) return DeoptInfo::null(); |
| 67 | |
| 68 intptr_t stack_height = compiler->StackSize(); | |
| 69 AllocateIncomingParametersRecursive(deoptimization_env_, &stack_height); | |
| 70 | |
| 71 const Function& function = compiler->parsed_function().function(); | 50 const Function& function = compiler->parsed_function().function(); |
| 72 // For functions with optional arguments, all incoming arguments are copied | 51 // For functions with optional arguments, all incoming are copied to local |
| 73 // to spill slots. The deoptimization environment does not track them. | 52 // area below FP, deoptimization environment does not track them. |
| 74 const intptr_t incoming_arg_count = | 53 const intptr_t num_args = |
| 75 function.HasOptionalParameters() ? 0 : function.num_fixed_parameters(); | 54 function.HasOptionalParameters() ? 0 : function.num_fixed_parameters(); |
| 76 DeoptInfoBuilder builder(compiler->object_table(), incoming_arg_count); | 55 const intptr_t fixed_parameter_count = |
| 56 deoptimization_env_->fixed_parameter_count(); |
| 57 DeoptInfoBuilder builder(compiler->object_table(), num_args); |
| 77 | 58 |
| 78 intptr_t slot_ix = 0; | 59 intptr_t slot_ix = 0; |
| 79 Environment* env = deoptimization_env_; | 60 BuildReturnAddress(&builder, function, slot_ix++); |
| 80 while (env != NULL) { | |
| 81 const Function& function = env->function(); | |
| 82 const intptr_t fixed_parameter_count = env->fixed_parameter_count(); | |
| 83 | 61 |
| 84 if (slot_ix == 0) { | 62 // Assign locations to values pushed above spill slots with PushArgument. |
| 85 // For the innermost environment call the virtual return builder. | 63 intptr_t height = compiler->StackSize(); |
| 86 BuildReturnAddress(&builder, function, slot_ix++); | 64 for (intptr_t i = 0; i < deoptimization_env_->Length(); i++) { |
| 87 } else { | 65 if (deoptimization_env_->LocationAt(i).IsInvalid()) { |
| 88 // For any outer environment the deopt id is that of the call instruction | 66 ASSERT(deoptimization_env_->ValueAt(i)->definition()->IsPushArgument()); |
| 89 // which is recorded in the outer environment. | 67 *deoptimization_env_->LocationSlotAt(i) = Location::StackSlot(height++); |
| 90 builder.AddReturnAddressAfter(function, env->deopt_id(), slot_ix++); | |
| 91 } | 68 } |
| 69 } |
| 92 | 70 |
| 93 for (intptr_t i = env->Length() - 1; i >= fixed_parameter_count; i--) { | 71 for (intptr_t i = deoptimization_env_->Length() - 1; |
| 94 builder.AddCopy(env->LocationAt(i), *env->ValueAt(i), slot_ix++); | 72 i >= fixed_parameter_count; |
| 95 } | 73 i--) { |
| 74 builder.AddCopy(deoptimization_env_->LocationAt(i), |
| 75 *deoptimization_env_->ValueAt(i), |
| 76 slot_ix++); |
| 77 } |
| 96 | 78 |
| 97 // PC marker and caller FP. | 79 // PC marker, caller-fp, caller-pc. |
| 98 builder.AddPcMarker(function, slot_ix++); | 80 builder.AddPcMarker(function, slot_ix++); |
| 99 builder.AddCallerFp(slot_ix++); | 81 builder.AddCallerFp(slot_ix++); |
| 100 | 82 builder.AddCallerPc(slot_ix++); |
| 101 // On the outermost environment set caller PC and incoming arguments. | 83 // Incoming arguments. |
| 102 if (env->outer() == NULL) { | 84 for (intptr_t i = fixed_parameter_count - 1; i >= 0; i--) { |
| 103 builder.AddCallerPc(slot_ix++); | 85 builder.AddCopy(deoptimization_env_->LocationAt(i), |
| 104 for (intptr_t i = fixed_parameter_count - 1; i >= 0; i--) { | 86 *deoptimization_env_->ValueAt(i), |
| 105 builder.AddCopy(env->LocationAt(i), *env->ValueAt(i), slot_ix++); | 87 slot_ix++); |
| 106 } | |
| 107 } | |
| 108 | |
| 109 // Iterate on the outer environment. | |
| 110 env = env->outer(); | |
| 111 } | 88 } |
| 112 | 89 |
| 113 const DeoptInfo& deopt_info = DeoptInfo::Handle(builder.CreateDeoptInfo()); | 90 const DeoptInfo& deopt_info = DeoptInfo::Handle(builder.CreateDeoptInfo()); |
| 114 return deopt_info.raw(); | 91 return deopt_info.raw(); |
| 115 } | 92 } |
| 116 | 93 |
| 117 | 94 |
| 118 FlowGraphCompiler::FlowGraphCompiler(Assembler* assembler, | 95 FlowGraphCompiler::FlowGraphCompiler(Assembler* assembler, |
| 119 const FlowGraph& flow_graph, | 96 const FlowGraph& flow_graph, |
| 120 bool is_optimizing, | 97 bool is_optimizing, |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 358 const ExceptionHandlers& handlers = ExceptionHandlers::Handle( | 335 const ExceptionHandlers& handlers = ExceptionHandlers::Handle( |
| 359 exception_handlers_list_->FinalizeExceptionHandlers(code.EntryPoint())); | 336 exception_handlers_list_->FinalizeExceptionHandlers(code.EntryPoint())); |
| 360 code.set_exception_handlers(handlers); | 337 code.set_exception_handlers(handlers); |
| 361 } | 338 } |
| 362 | 339 |
| 363 | 340 |
| 364 void FlowGraphCompiler::FinalizePcDescriptors(const Code& code) { | 341 void FlowGraphCompiler::FinalizePcDescriptors(const Code& code) { |
| 365 ASSERT(pc_descriptors_list_ != NULL); | 342 ASSERT(pc_descriptors_list_ != NULL); |
| 366 const PcDescriptors& descriptors = PcDescriptors::Handle( | 343 const PcDescriptors& descriptors = PcDescriptors::Handle( |
| 367 pc_descriptors_list_->FinalizePcDescriptors(code.EntryPoint())); | 344 pc_descriptors_list_->FinalizePcDescriptors(code.EntryPoint())); |
| 368 if (!is_optimizing_) descriptors.Verify(parsed_function_.function()); | 345 descriptors.Verify(parsed_function_.function().is_optimizable()); |
| 369 code.set_pc_descriptors(descriptors); | 346 code.set_pc_descriptors(descriptors); |
| 370 } | 347 } |
| 371 | 348 |
| 372 | 349 |
| 373 void FlowGraphCompiler::FinalizeDeoptInfo(const Code& code) { | 350 void FlowGraphCompiler::FinalizeDeoptInfo(const Code& code) { |
| 374 const Array& array = | 351 const Array& array = |
| 375 Array::Handle(Array::New(deopt_infos_.length(), Heap::kOld)); | 352 Array::Handle(Array::New(deopt_infos_.length(), Heap::kOld)); |
| 376 DeoptInfo& info = DeoptInfo::Handle(); | 353 DeoptInfo& info = DeoptInfo::Handle(); |
| 377 for (intptr_t i = 0; i < deopt_infos_.length(); i++) { | 354 for (intptr_t i = 0; i < deopt_infos_.length(); i++) { |
| 378 info = deopt_infos_[i]->CreateDeoptInfo(this); | 355 info = deopt_infos_[i]->CreateDeoptInfo(this); |
| (...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 876 case ABOVE: return unsigned_left > unsigned_right; | 853 case ABOVE: return unsigned_left > unsigned_right; |
| 877 case ABOVE_EQUAL: return unsigned_left >= unsigned_right; | 854 case ABOVE_EQUAL: return unsigned_left >= unsigned_right; |
| 878 default: | 855 default: |
| 879 UNIMPLEMENTED(); | 856 UNIMPLEMENTED(); |
| 880 return false; | 857 return false; |
| 881 } | 858 } |
| 882 } | 859 } |
| 883 | 860 |
| 884 | 861 |
| 885 } // namespace dart | 862 } // namespace dart |
| OLD | NEW |