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 543db79fad6bbfe0b1b48e47c90b039ca767c9d1..1523259b0dbc5aea74a44defdb917f0b9fb61f42 100644 |
| --- a/runtime/vm/flow_graph_compiler.cc |
| +++ b/runtime/vm/flow_graph_compiler.cc |
| @@ -76,38 +76,59 @@ RawDeoptInfo* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler) { |
| DeoptInfoBuilder builder(compiler->object_table(), incoming_arg_count); |
| intptr_t slot_ix = 0; |
| - Environment* env = deoptimization_env_; |
| - while (env != NULL) { |
| - const Function& function = env->function(); |
| - const intptr_t fixed_parameter_count = env->fixed_parameter_count(); |
| - |
| - if (slot_ix == 0) { |
| - // For the innermost environment call the virtual return builder. |
| - 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++); |
| + Environment* inner = deoptimization_env_; |
| + |
| + // For the innermost environment, call the virtual return builder. |
| + BuildReturnAddress(&builder, inner->function(), slot_ix++); |
| + |
| + // For the innermost environment, set outgoing arguments and the locals. |
| + for (intptr_t i = inner->Length() - 1; |
| + i >= inner->fixed_parameter_count(); |
| + i--) { |
| + builder.AddCopy(inner->LocationAt(i), *inner->ValueAt(i), slot_ix++); |
| + } |
| + |
| + // PC marker and caller FP. |
| + builder.AddPcMarker(inner->function(), slot_ix++); |
| + builder.AddCallerFp(slot_ix++); |
| + |
| + while (inner->outer() != NULL) { |
| + // Write the frame for an outer environment. |
| + const Environment* current = inner->outer(); |
| + |
| + // For any outer environment the deopt id is that of the call instruction |
| + // which is recorded in the outer environment. |
| + builder.AddReturnAddressAfter(current->function(), |
| + current->deopt_id(), |
| + slot_ix++); |
| + |
| + // Set incoming arguments from the inner frame. |
| + for (intptr_t i = inner->fixed_parameter_count() - 1; i >= 0; i--) { |
| + builder.AddCopy(inner->LocationAt(i), *inner->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++); |
| + // Set the locals, not including the outgoing arguments. |
| + for (intptr_t i = current->Length() - inner->fixed_parameter_count() - 1; |
| + i >= current->fixed_parameter_count(); |
| + i--) { |
| + builder.AddCopy(current->LocationAt(i), *current->ValueAt(i), slot_ix++); |
| } |
| // PC marker and caller FP. |
| - builder.AddPcMarker(function, slot_ix++); |
| + builder.AddPcMarker(current->function(), slot_ix++); |
| builder.AddCallerFp(slot_ix++); |
| - // On the outermost 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++); |
| - } |
| - } |
| - |
| // Iterate on the outer environment. |
| - env = env->outer(); |
| + inner = inner->outer(); |
| + } |
| + ASSERT(inner != NULL); // The inner pointer is not the outermost environment. |
|
Vyacheslav Egorov (Google)
2012/09/21 14:38:30
actually at this point is has to be the outermost
zerny-google
2012/09/21 14:55:47
Typo. That should have been "is now the outermost"
|
| + |
| + // For the outermost environment, set caller PC. |
| + builder.AddCallerPc(slot_ix++); |
| + |
| + // For the outermost environment, set the incoming arguments. |
| + for (intptr_t i = inner->fixed_parameter_count() - 1; i >= 0; i--) { |
| + builder.AddCopy(inner->LocationAt(i), *inner->ValueAt(i), slot_ix++); |
| } |
| const DeoptInfo& deopt_info = DeoptInfo::Handle(builder.CreateDeoptInfo()); |