Index: runtime/vm/flow_graph_compiler.cc |
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc |
index c84d82475cee94a851d580466902ca1a9be167f5..506023305a5a730a2a3030a6369054f46027fdf0 100644 |
--- a/runtime/vm/flow_graph_compiler.cc |
+++ b/runtime/vm/flow_graph_compiler.cc |
@@ -62,77 +62,73 @@ void CompilerDeoptInfo::AllocateIncomingParametersRecursive( |
} |
-RawDeoptInfo* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler) { |
+RawDeoptInfo* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler, |
+ DeoptInfoBuilder* builder) { |
if (deoptimization_env_ == NULL) return DeoptInfo::null(); |
intptr_t stack_height = compiler->StackSize(); |
AllocateIncomingParametersRecursive(deoptimization_env_, &stack_height); |
- const Function& function = compiler->parsed_function().function(); |
- // For functions with optional arguments, all incoming arguments are copied |
- // to spill slots. The deoptimization environment does not track them. |
- const intptr_t incoming_arg_count = |
- function.HasOptionalParameters() ? 0 : function.num_fixed_parameters(); |
- DeoptInfoBuilder builder(compiler->object_table(), incoming_arg_count); |
- |
intptr_t slot_ix = 0; |
- Environment* inner = deoptimization_env_; |
+ Environment* current = deoptimization_env_; |
// For the innermost environment, call the virtual return builder. |
- BuildReturnAddress(&builder, inner->function(), slot_ix++); |
+ BuildReturnAddress(builder, current->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(); |
+ for (intptr_t i = current->Length() - 1; |
+ i >= current->fixed_parameter_count(); |
i--) { |
- builder.AddCopy(inner->LocationAt(i), *inner->ValueAt(i), slot_ix++); |
+ builder->AddCopy(current->LocationAt(i), *current->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(); |
+ builder->AddPcMarker(current->function(), slot_ix++); |
+ builder->AddCallerFp(slot_ix++); |
+ Environment* previous = current; |
+ current = current->outer(); |
+ while (current != NULL) { |
// 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++); |
+ builder->AddReturnAddressAfter(current->function(), |
+ current->deopt_id(), |
+ slot_ix++); |
// The values of outgoing arguments can be changed from the inlined call so |
- // we must read them from the inner environment. |
- for (intptr_t i = inner->fixed_parameter_count() - 1; i >= 0; i--) { |
- builder.AddCopy(inner->LocationAt(i), *inner->ValueAt(i), slot_ix++); |
+ // we must read them from the previous environment. |
+ for (intptr_t i = previous->fixed_parameter_count() - 1; i >= 0; i--) { |
+ builder->AddCopy(previous->LocationAt(i), *previous->ValueAt(i), |
+ slot_ix++); |
} |
// Set the locals, note that outgoing arguments are not in the environment. |
for (intptr_t i = current->Length() - 1; |
i >= current->fixed_parameter_count(); |
i--) { |
- builder.AddCopy(current->LocationAt(i), *current->ValueAt(i), slot_ix++); |
+ builder->AddCopy(current->LocationAt(i), *current->ValueAt(i), slot_ix++); |
} |
// PC marker and caller FP. |
- builder.AddPcMarker(current->function(), slot_ix++); |
- builder.AddCallerFp(slot_ix++); |
+ builder->AddPcMarker(current->function(), slot_ix++); |
+ builder->AddCallerFp(slot_ix++); |
// Iterate on the outer environment. |
- inner = inner->outer(); |
+ previous = current; |
+ current = current->outer(); |
} |
- ASSERT(inner != NULL); // The inner pointer is now the outermost environment. |
+ // The previous pointer is now the outermost environment. |
+ ASSERT(previous != NULL); |
// For the outermost environment, set caller PC. |
- builder.AddCallerPc(slot_ix++); |
+ 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++); |
+ for (intptr_t i = previous->fixed_parameter_count() - 1; i >= 0; i--) { |
+ builder->AddCopy(previous->LocationAt(i), *previous->ValueAt(i), slot_ix++); |
} |
- const DeoptInfo& deopt_info = DeoptInfo::Handle(builder.CreateDeoptInfo()); |
+ const DeoptInfo& deopt_info = DeoptInfo::Handle(builder->CreateDeoptInfo()); |
return deopt_info.raw(); |
} |
@@ -151,7 +147,6 @@ FlowGraphCompiler::FlowGraphCompiler(Assembler* assembler, |
is_optimizing ? new StackmapTableBuilder() : NULL), |
block_info_(block_order_.length()), |
deopt_infos_(), |
- object_table_(GrowableObjectArray::Handle(GrowableObjectArray::New())), |
is_optimizing_(is_optimizing), |
is_dart_leaf_(is_leaf), |
bool_true_(Bool::ZoneHandle(Bool::True())), |
@@ -389,6 +384,13 @@ void FlowGraphCompiler::FinalizePcDescriptors(const Code& code) { |
void FlowGraphCompiler::FinalizeDeoptInfo(const Code& code) { |
+ // For functions with optional arguments, all incoming arguments are copied |
+ // to spill slots. The deoptimization environment does not track them. |
+ const Function& function = parsed_function().function(); |
+ const intptr_t incoming_arg_count = |
+ function.HasOptionalParameters() ? 0 : function.num_fixed_parameters(); |
+ DeoptInfoBuilder builder(incoming_arg_count); |
+ |
const Array& array = |
Array::Handle(Array::New(DeoptTable::SizeFor(deopt_infos_.length()), |
Heap::kOld)); |
@@ -397,12 +399,13 @@ void FlowGraphCompiler::FinalizeDeoptInfo(const Code& code) { |
Smi& reason = Smi::Handle(); |
for (intptr_t i = 0; i < deopt_infos_.length(); i++) { |
offset = Smi::New(deopt_infos_[i]->pc_offset()); |
- info = deopt_infos_[i]->CreateDeoptInfo(this); |
+ info = deopt_infos_[i]->CreateDeoptInfo(this, &builder); |
reason = Smi::New(deopt_infos_[i]->reason()); |
DeoptTable::SetEntry(array, i, offset, info, reason); |
} |
code.set_deopt_info_array(array); |
- const Array& object_array = Array::Handle(Array::MakeArray(object_table_)); |
+ const Array& object_array = |
+ Array::Handle(Array::MakeArray(builder.object_table())); |
code.set_object_table(object_array); |
} |