| Index: runtime/vm/flow_graph_compiler.cc
|
| diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
|
| index cc03069de1b83fa3e11504e6c25b48ac1f249b52..222501c292f07162f7d9fe1dbaf41f404729ea2e 100644
|
| --- a/runtime/vm/flow_graph_compiler.cc
|
| +++ b/runtime/vm/flow_graph_compiler.cc
|
| @@ -41,14 +41,27 @@ void CompilerDeoptInfo::AllocateIncomingParametersRecursive(
|
| if (env == NULL) return;
|
| AllocateIncomingParametersRecursive(env->outer(), stack_height);
|
| for (Environment::ShallowIterator it(env); !it.Done(); it.Advance()) {
|
| - if (it.CurrentLocation().IsInvalid()) {
|
| - ASSERT(it.CurrentValue()->definition()->IsPushArgument());
|
| + if (it.CurrentLocation().IsInvalid() &&
|
| + it.CurrentValue()->definition()->IsPushArgument()) {
|
| it.SetCurrentLocation(Location::StackSlot((*stack_height)++));
|
| }
|
| }
|
| }
|
|
|
|
|
| +void CompilerDeoptInfo::EmitMaterializations(Environment* env,
|
| + DeoptInfoBuilder* builder) {
|
| + for (Environment::DeepIterator it(env); !it.Done(); it.Advance()) {
|
| + if (it.CurrentLocation().IsInvalid()) {
|
| + MaterializeObjectInstr* mat =
|
| + it.CurrentValue()->definition()->AsMaterializeObject();
|
| + ASSERT(mat != NULL);
|
| + builder->AddMaterialization(mat);
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| RawDeoptInfo* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
|
| DeoptInfoBuilder* builder) {
|
| if (deoptimization_env_ == NULL) return DeoptInfo::null();
|
| @@ -59,10 +72,21 @@ RawDeoptInfo* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
|
| intptr_t slot_ix = 0;
|
| Environment* current = deoptimization_env_;
|
|
|
| + // Emit all kMaterializeObject instructions describing objects to be
|
| + // materialized on the deoptimization as a prefix to the deoptimization info.
|
| + EmitMaterializations(deoptimization_env_, builder);
|
| +
|
| + // The real frame starts here.
|
| + builder->MarkFrameStart();
|
| builder->AddReturnAddress(current->function(),
|
| deopt_id(),
|
| slot_ix++);
|
|
|
| + // Emit all values that are needed for materialization as a part of the
|
| + // expression stack for the bottom-most frame. This guarantees that GC
|
| + // will be able to find them during materialization.
|
| + slot_ix = builder->EmitMaterializationArguments();
|
| +
|
| // For the innermost environment, set outgoing arguments and the locals.
|
| for (intptr_t i = current->Length() - 1;
|
| i >= current->fixed_parameter_count();
|
|
|