Index: runtime/vm/flow_graph.cc |
=================================================================== |
--- runtime/vm/flow_graph.cc (revision 31538) |
+++ runtime/vm/flow_graph.cc (working copy) |
@@ -6,9 +6,10 @@ |
#include "vm/bit_vector.h" |
#include "vm/flow_graph_builder.h" |
+#include "vm/growable_array.h" |
#include "vm/intermediate_language.h" |
#include "vm/longjump.h" |
-#include "vm/growable_array.h" |
+#include "vm/stack_frame.h" |
namespace dart { |
@@ -77,6 +78,8 @@ |
ConstantInstr* FlowGraph::GetConstant(const Object& object) { |
+ // Not all objects can be embedded in code. |
+ ASSERT(object.IsSmi() || object.InVMHeap() || object.IsOld()); |
// Check if the constant is already in the pool. |
GrowableArray<Definition*>* pool = graph_entry_->initial_definitions(); |
for (intptr_t i = 0; i < pool->length(); ++i) { |
@@ -695,6 +698,47 @@ |
} |
+void FlowGraph::InitializeOsrLocalRange(GrowableArray<Definition*>* env, |
+ RawObject** base, |
+ intptr_t count) { |
+ for (intptr_t i = 0; i < count; ++i) { |
+ // Variables go from high to low addresses as they go from left to |
+ // right. |
+ const Object& value = Object::ZoneHandle(base[-i]); |
+ Definition* definition = NULL; |
+ if (value.IsSmi() || value.InVMHeap() || value.IsOld()) { |
+ definition = GetConstant(value); |
+ } else { |
+ definition = new ParameterInstr(env->length(), graph_entry()); |
+ definition->set_ssa_temp_index(alloc_ssa_temp_index()); |
+ AddToInitialDefinitions(definition); |
+ } |
+ env->Add(definition); |
+ } |
+} |
+ |
+ |
+void FlowGraph::InitializeOsrLocals(GrowableArray<Definition*>* env) { |
+ DartFrameIterator iterator; |
+ StackFrame* frame = iterator.NextFrame(); |
+ const Code& code = Code::Handle(frame->LookupDartCode()); |
+ ASSERT(!code.is_optimized()); |
+ ASSERT(frame->LookupDartFunction() == parsed_function().function().raw()); |
+ |
+ // Initialize parameters and locals in the order they appear in the |
+ // environment (left-to-right, parameters first). |
+ intptr_t count = num_non_copied_params(); |
+ RawObject** base = reinterpret_cast<RawObject**>(frame->fp()) |
+ + kParamEndSlotFromFp // One past the last parameter. |
+ + count; |
+ InitializeOsrLocalRange(env, base, count); |
+ |
+ count = num_copied_params() + num_stack_locals(); |
+ base = reinterpret_cast<RawObject**>(frame->fp()) + kFirstLocalSlotFromFp; |
+ InitializeOsrLocalRange(env, base, count); |
+} |
+ |
+ |
void FlowGraph::Rename(GrowableArray<PhiInstr*>* live_phis, |
VariableLivenessAnalysis* variable_liveness, |
ZoneGrowableArray<Definition*>* inlining_parameters) { |
@@ -712,7 +756,7 @@ |
// Add parameters to the initial definitions and renaming environment. |
if (inlining_parameters != NULL) { |
- // Use known parameters. |
+ // When inlining, use the known parameter definitions. |
ASSERT(parameter_count() == inlining_parameters->length()); |
for (intptr_t i = 0; i < parameter_count(); ++i) { |
Definition* defn = (*inlining_parameters)[i]; |
@@ -720,11 +764,13 @@ |
AddToInitialDefinitions(defn); |
env.Add(defn); |
} |
+ } else if (IsCompiledForOsr()) { |
+ // For functions compiled for OSR, use the constants found in the |
+ // unoptimized frame. |
+ InitializeOsrLocals(&env); |
} else { |
- // Create new parameters. For functions compiled for OSR, the locals |
- // are unknown and so treated like parameters. |
- intptr_t count = IsCompiledForOsr() ? variable_count() : parameter_count(); |
- for (intptr_t i = 0; i < count; ++i) { |
+ // Create fresh (unknown) parameters. |
+ for (intptr_t i = 0; i < parameter_count(); ++i) { |
ParameterInstr* param = new ParameterInstr(i, entry); |
param->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. |
AddToInitialDefinitions(param); |
@@ -740,12 +786,6 @@ |
} |
} |
- if (entry->SuccessorCount() > 1) { |
- // Functions with try-catch have a fixed area of stack slots reserved |
- // so that all local variables are stored at a known location when |
- // on entry to the catch. |
- entry->set_fixed_slot_count(num_stack_locals() + num_copied_params()); |
- } |
RenameRecursive(entry, &env, live_phis, variable_liveness); |
} |