Chromium Code Reviews| Index: runtime/vm/flow_graph_compiler.cc |
| diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc |
| index 5e3bd7810648a398df14d6f269f42ee359bd1fa1..acfdab1082aed2b9d9067787d969d88ed868399f 100644 |
| --- a/runtime/vm/flow_graph_compiler.cc |
| +++ b/runtime/vm/flow_graph_compiler.cc |
| @@ -45,46 +45,70 @@ void CompilerDeoptInfoWithStub::BuildReturnAddress(DeoptInfoBuilder* builder, |
| } |
| +// Assign locations to outgoing arguments, i.e., values pushed above spill slots |
| +// with PushArgument. Recursively allocates from outer most to inner most |
|
Kevin Millikin (Google)
2012/09/18 11:01:55
"outer most" ==> "outermost", "inner most" ==> "in
zerny-google
2012/09/18 11:53:07
Done.
|
| +// environment. |
| +void CompilerDeoptInfo::AllocateIncommingParametersRecusive( |
| + Environment* env, |
| + intptr_t* stack_height) { |
| + if (env == NULL) return; |
| + AllocateIncommingParametersRecusive(env->outer(), stack_height); |
| + for (Environment::ShallowIterator it(env); !it.Done(); it.Advance()) { |
| + if (it.CurrentLocation().IsInvalid()) { |
| + ASSERT(it.CurrentValue()->definition()->IsPushArgument()); |
| + it.SetCurrentLocation(Location::StackSlot((*stack_height)++)); |
| + } |
| + } |
| +} |
| + |
| + |
| RawDeoptInfo* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler) { |
| if (deoptimization_env_ == NULL) return DeoptInfo::null(); |
| + |
| + intptr_t stack_height = compiler->StackSize(); |
| + AllocateIncommingParametersRecusive(deoptimization_env_, &stack_height); |
| + |
| const Function& function = compiler->parsed_function().function(); |
| - // For functions with optional arguments, all incoming are copied to local |
| - // area below FP, deoptimization environment does not track them. |
| - const intptr_t num_args = |
| + const intptr_t num_incoming_args = |
| function.HasOptionalParameters() ? 0 : function.num_fixed_parameters(); |
| - const intptr_t fixed_parameter_count = |
| - deoptimization_env_->fixed_parameter_count(); |
| - DeoptInfoBuilder builder(compiler->object_table(), num_args); |
| + DeoptInfoBuilder builder(compiler->object_table(), num_incoming_args); |
| intptr_t slot_ix = 0; |
| - BuildReturnAddress(&builder, function, slot_ix++); |
| - |
| - // Assign locations to values pushed above spill slots with PushArgument. |
| - intptr_t height = compiler->StackSize(); |
| - for (intptr_t i = 0; i < deoptimization_env_->Length(); i++) { |
| - if (deoptimization_env_->LocationAt(i).IsInvalid()) { |
| - ASSERT(deoptimization_env_->ValueAt(i)->definition()->IsPushArgument()); |
| - *deoptimization_env_->LocationSlotAt(i) = Location::StackSlot(height++); |
| + Environment* env = deoptimization_env_; |
| + while (env != NULL) { |
| + const Function& function = env->function(); |
| + |
| + // For functions with optional arguments, all incoming are copied to local |
|
Kevin Millikin (Google)
2012/09/18 11:01:55
Hmm. I would say they're "above" the frame pointe
zerny-google
2012/09/18 11:53:07
Also, the this comment is for num_incoming_args (r
|
| + // area below FP, deoptimization environment does not track them. |
| + const intptr_t fixed_parameter_count = env->fixed_parameter_count(); |
| + |
| + if (slot_ix == 0) { |
| + // For the inner-most environment call the virutal return builder. |
|
Kevin Millikin (Google)
2012/09/18 11:01:55
"virutal" ==> "virtual".
zerny-google
2012/09/18 11:53:07
Done.
|
| + BuildReturnAddress(&builder, function, slot_ix++); |
| + } else { |
| + // For any outer environment the deopt id is that of the call instruction |
| + // which is recorded in the outer environment. |
| + builder.AddReturnAddressAfter(function, env->deopt_id(), slot_ix++); |
| } |
| - } |
| - for (intptr_t i = deoptimization_env_->Length() - 1; |
| - i >= fixed_parameter_count; |
| - i--) { |
| - builder.AddCopy(deoptimization_env_->LocationAt(i), |
| - *deoptimization_env_->ValueAt(i), |
| - slot_ix++); |
| - } |
| + for (intptr_t i = env->Length() - 1; i >= fixed_parameter_count; i--) { |
| + builder.AddCopy(env->LocationAt(i), *env->ValueAt(i), slot_ix++); |
| + } |
| + |
| + // PC marker and caller FP. |
| + builder.AddPcMarker(function, slot_ix++); |
| + builder.AddCallerFp(slot_ix++); |
| + |
| + // On the outer-most environment set caller PC and incoming arguments. |
| + if (env->outer() == NULL) { |
| + builder.AddCallerPc(slot_ix++); |
| + for (intptr_t i = fixed_parameter_count - 1; i >= 0; i--) { |
| + builder.AddCopy(env->LocationAt(i), *env->ValueAt(i), slot_ix++); |
| + } |
| + } |
| - // PC marker, caller-fp, caller-pc. |
| - builder.AddPcMarker(function, slot_ix++); |
| - builder.AddCallerFp(slot_ix++); |
| - builder.AddCallerPc(slot_ix++); |
| - // Incoming arguments. |
| - for (intptr_t i = fixed_parameter_count - 1; i >= 0; i--) { |
| - builder.AddCopy(deoptimization_env_->LocationAt(i), |
| - *deoptimization_env_->ValueAt(i), |
| - slot_ix++); |
| + // Iterate on the outer environment. |
| + env = env->outer(); |
| } |
| const DeoptInfo& deopt_info = DeoptInfo::Handle(builder.CreateDeoptInfo()); |
| @@ -342,7 +366,7 @@ void FlowGraphCompiler::FinalizePcDescriptors(const Code& code) { |
| ASSERT(pc_descriptors_list_ != NULL); |
| const PcDescriptors& descriptors = PcDescriptors::Handle( |
| pc_descriptors_list_->FinalizePcDescriptors(code.EntryPoint())); |
| - descriptors.Verify(parsed_function_.function().is_optimizable()); |
| + if (!is_optimizing_) descriptors.Verify(parsed_function_.function()); |
| code.set_pc_descriptors(descriptors); |
| } |