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(); |