Index: src/runtime.cc |
diff --git a/src/runtime.cc b/src/runtime.cc |
index 117e5ab36f6f7b7743ea43ef2e666220ee090e23..fc1c0aa38608f0c5e6688db5e0ab582107dfc14b 100644 |
--- a/src/runtime.cc |
+++ b/src/runtime.cc |
@@ -10024,8 +10024,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) { |
return heap->undefined_value(); |
} |
- int deoptimized_frame_index = -1; // Frame index in optimized frame. |
- DeoptimizedFrameInfo* deoptimized_frame = NULL; |
+ int inlined_frame_index = 0; // Inlined frame index in optimized frame. |
int count = 0; |
JavaScriptFrameIterator it(isolate, id); |
@@ -10036,13 +10035,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) { |
if (it.done()) return heap->undefined_value(); |
if (it.frame()->is_optimized()) { |
- deoptimized_frame_index = |
+ inlined_frame_index = |
it.frame()->GetInlineCount() - (index - count) - 1; |
- deoptimized_frame = Deoptimizer::DebuggerInspectableFrame( |
- it.frame(), |
- deoptimized_frame_index, |
- isolate); |
} |
+ ScopedDeoptimizedFrameInfo deoptimized_frame( |
+ it.frame(), inlined_frame_index, isolate); |
// Traverse the saved contexts chain to find the active context for the |
// selected frame. |
@@ -10061,7 +10058,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) { |
// Check for constructor frame. Inlined frames cannot be construct calls. |
bool inlined_frame = |
- it.frame()->is_optimized() && deoptimized_frame_index != 0; |
+ it.frame()->is_optimized() && inlined_frame_index != 0; |
bool constructor = !inlined_frame && it.frame()->IsConstructor(); |
// Get scope info and read from it for local variable information. |
@@ -10086,7 +10083,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) { |
if (it.frame()->is_optimized()) { |
// Get the value from the deoptimized frame. |
locals->set(i * 2 + 1, |
- deoptimized_frame->GetExpression(i)); |
+ deoptimized_frame.GetExpression(i)); |
} else { |
// Get the value from the stack. |
locals->set(i * 2 + 1, it.frame()->GetExpression(i)); |
@@ -10153,7 +10150,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) { |
// parameters for the function and fill more if more parameters are provided. |
int argument_count = info.number_of_parameters(); |
if (it.frame()->is_optimized()) { |
- ASSERT_EQ(argument_count, deoptimized_frame->parameters_count()); |
+ ASSERT_EQ(argument_count, deoptimized_frame.parameters_count()); |
} else { |
if (argument_count < it.frame()->ComputeParametersCount()) { |
argument_count = it.frame()->ComputeParametersCount(); |
@@ -10172,7 +10169,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) { |
// Add the function (same as in function frame). |
if (it.frame()->is_optimized()) { |
// Get the function from the deoptimized frame. |
- details->set(kFrameDetailsFunctionIndex, deoptimized_frame->GetFunction()); |
+ details->set(kFrameDetailsFunctionIndex, deoptimized_frame.GetFunction()); |
} else { |
// Get the function from the stack. |
details->set(kFrameDetailsFunctionIndex, it.frame()->function()); |
@@ -10208,9 +10205,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) { |
} |
if (it.frame()->is_optimized()) { |
flags |= 1 << 1; |
- if (deoptimized_frame_index > 0) { |
- flags |= 1 << 2; |
- } |
+ flags |= inlined_frame_index << 2; |
} |
details->set(kFrameDetailsFlagsIndex, Smi::FromInt(flags)); |
@@ -10229,7 +10224,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) { |
// Parameter value. |
if (it.frame()->is_optimized()) { |
// Get the value from the deoptimized frame. |
- details->set(details_index++, deoptimized_frame->GetParameter(i)); |
+ details->set(details_index++, deoptimized_frame.GetParameter(i)); |
} else { |
if (i < it.frame()->ComputeParametersCount()) { |
// Get the value from the stack. |
@@ -10268,12 +10263,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) { |
} |
details->set(kFrameDetailsReceiverIndex, *receiver); |
- // Get rid of the calculated deoptimized frame if any. |
- if (deoptimized_frame != NULL) { |
- Deoptimizer::DeleteDebuggerInspectableFrame(deoptimized_frame, |
- isolate); |
- } |
- |
ASSERT_EQ(details_size, details_index); |
return *isolate->factory()->NewJSArrayWithElements(details); |
} |
@@ -10309,12 +10298,16 @@ static bool CopyContextLocalsToScopeObject( |
// Create a plain JSObject which materializes the local scope for the specified |
// frame. |
-static Handle<JSObject> MaterializeLocalScope(Isolate* isolate, |
- JavaScriptFrame* frame) { |
+static Handle<JSObject> MaterializeLocalScope( |
+ Isolate* isolate, |
+ JavaScriptFrame* frame, |
+ int inlined_frame_index) { |
Handle<JSFunction> function(JSFunction::cast(frame->function())); |
Handle<SharedFunctionInfo> shared(function->shared()); |
Handle<SerializedScopeInfo> serialized_scope_info(shared->scope_info()); |
ScopeInfo<> scope_info(*serialized_scope_info); |
+ ScopedDeoptimizedFrameInfo deoptimized_frame( |
+ frame, inlined_frame_index, isolate); |
// Allocate and initialize a JSObject with all the arguments, stack locals |
// heap locals and extension properties of the debugged function. |
@@ -10323,11 +10316,17 @@ static Handle<JSObject> MaterializeLocalScope(Isolate* isolate, |
// First fill all parameters. |
for (int i = 0; i < scope_info.number_of_parameters(); ++i) { |
+ Handle<Object> parameter; |
+ if (frame->is_optimized()) { |
+ parameter = Handle<Object>(deoptimized_frame.GetParameter(i)); |
+ } else { |
+ parameter = Handle<Object>(frame->GetParameter(i)); |
+ } |
RETURN_IF_EMPTY_HANDLE_VALUE( |
isolate, |
SetProperty(local_scope, |
scope_info.parameter_name(i), |
- Handle<Object>(frame->GetParameter(i), isolate), |
+ parameter, |
NONE, |
kNonStrictMode), |
Handle<JSObject>()); |
@@ -10335,11 +10334,17 @@ static Handle<JSObject> MaterializeLocalScope(Isolate* isolate, |
// Second fill all stack locals. |
for (int i = 0; i < scope_info.number_of_stack_slots(); ++i) { |
+ Handle<Object> expression; |
+ if (frame->is_optimized()) { |
+ expression = Handle<Object>(deoptimized_frame.GetExpression(i)); |
+ } else { |
+ expression = Handle<Object>(frame->GetExpression(i)); |
+ } |
RETURN_IF_EMPTY_HANDLE_VALUE( |
isolate, |
SetProperty(local_scope, |
scope_info.stack_slot_name(i), |
- Handle<Object>(frame->GetExpression(i), isolate), |
+ expression, |
NONE, |
kNonStrictMode), |
Handle<JSObject>()); |
@@ -10459,9 +10464,12 @@ class ScopeIterator { |
ScopeTypeCatch |
}; |
- ScopeIterator(Isolate* isolate, JavaScriptFrame* frame) |
+ ScopeIterator(Isolate* isolate, |
+ JavaScriptFrame* frame, |
+ int inlined_frame_index) |
: isolate_(isolate), |
frame_(frame), |
+ inlined_frame_index_(inlined_frame_index), |
function_(JSFunction::cast(frame->function())), |
context_(Context::cast(frame->context())), |
local_done_(false), |
@@ -10546,7 +10554,7 @@ class ScopeIterator { |
return Handle<JSObject>(CurrentContext()->global()); |
case ScopeIterator::ScopeTypeLocal: |
// Materialize the content of the local scope into a JSObject. |
- return MaterializeLocalScope(isolate_, frame_); |
+ return MaterializeLocalScope(isolate_, frame_, inlined_frame_index_); |
case ScopeIterator::ScopeTypeWith: |
// Return the with object. |
return Handle<JSObject>(JSObject::cast(CurrentContext()->extension())); |
@@ -10626,6 +10634,7 @@ class ScopeIterator { |
private: |
Isolate* isolate_; |
JavaScriptFrame* frame_; |
+ int inlined_frame_index_; |
Handle<JSFunction> function_; |
Handle<Context> context_; |
bool local_done_; |
@@ -10654,7 +10663,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeCount) { |
// Count the visible scopes. |
int n = 0; |
- for (ScopeIterator it(isolate, frame); !it.Done(); it.Next()) { |
+ for (ScopeIterator it(isolate, frame, 0); |
+ !it.Done(); |
+ it.Next()) { |
n++; |
} |
@@ -10669,14 +10680,15 @@ static const int kScopeDetailsSize = 2; |
// Return an array with scope details |
// args[0]: number: break id |
// args[1]: number: frame index |
-// args[2]: number: scope index |
+// args[2]: number: inlined frame index |
+// args[3]: number: scope index |
// |
// The array returned contains the following information: |
// 0: Scope type |
// 1: Scope object |
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeDetails) { |
HandleScope scope(isolate); |
- ASSERT(args.length() == 3); |
+ ASSERT(args.length() == 4); |
// Check arguments. |
Object* check; |
@@ -10685,7 +10697,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeDetails) { |
if (!maybe_check->ToObject(&check)) return maybe_check; |
} |
CONVERT_CHECKED(Smi, wrapped_id, args[1]); |
- CONVERT_NUMBER_CHECKED(int, index, Int32, args[2]); |
+ CONVERT_NUMBER_CHECKED(int, inlined_frame_index, Int32, args[2]); |
+ CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]); |
// Get the frame where the debugging is performed. |
StackFrame::Id id = UnwrapFrameId(wrapped_id); |
@@ -10694,7 +10707,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeDetails) { |
// Find the requested scope. |
int n = 0; |
- ScopeIterator it(isolate, frame); |
+ ScopeIterator it(isolate, frame, inlined_frame_index); |
for (; !it.Done() && n < index; it.Next()) { |
n++; |
} |
@@ -10724,7 +10737,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPrintScopes) { |
// Print the scopes for the top frame. |
StackFrameLocator locator; |
JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); |
- for (ScopeIterator it(isolate, frame); !it.Done(); it.Next()) { |
+ for (ScopeIterator it(isolate, frame, 0); |
+ !it.Done(); |
+ it.Next()) { |
it.DebugPrint(); |
} |
#endif |
@@ -11117,6 +11132,7 @@ static Handle<Context> CopyWithContextChain(Isolate* isolate, |
// Runtime_DebugEvaluate. |
static Handle<Object> GetArgumentsObject(Isolate* isolate, |
JavaScriptFrame* frame, |
+ int inlined_frame_index, |
Handle<JSFunction> function, |
Handle<SerializedScopeInfo> scope_info, |
const ScopeInfo<>* sinfo, |
@@ -11128,6 +11144,7 @@ static Handle<Object> GetArgumentsObject(Isolate* isolate, |
if (sinfo->number_of_stack_slots() > 0) { |
index = scope_info->StackSlotIndex(isolate->heap()->arguments_symbol()); |
if (index != -1) { |
+ CHECK(false); |
return Handle<Object>(frame->GetExpression(index), isolate); |
} |
} |
@@ -11140,7 +11157,15 @@ static Handle<Object> GetArgumentsObject(Isolate* isolate, |
} |
} |
- const int length = frame->ComputeParametersCount(); |
+ ScopedDeoptimizedFrameInfo deoptimized_frame( |
+ frame, inlined_frame_index, isolate); |
+ |
+ int length; |
+ if (frame->is_optimized()) { |
+ length = deoptimized_frame.parameters_count(); |
+ } else { |
+ length = frame->ComputeParametersCount(); |
+ } |
Handle<JSObject> arguments = |
isolate->factory()->NewArgumentsObject(function, length); |
Handle<FixedArray> array = isolate->factory()->NewFixedArray(length); |
@@ -11148,7 +11173,11 @@ static Handle<Object> GetArgumentsObject(Isolate* isolate, |
AssertNoAllocation no_gc; |
WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc); |
for (int i = 0; i < length; i++) { |
- array->set(i, frame->GetParameter(i), mode); |
+ if (frame->is_optimized()) { |
+ array->set(i, deoptimized_frame.GetParameter(i), mode); |
+ } else { |
+ array->set(i, frame->GetParameter(i), mode); |
+ } |
} |
arguments->set_elements(*array); |
return arguments; |
@@ -11175,7 +11204,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) { |
// Check the execution state and decode arguments frame and source to be |
// evaluated. |
- ASSERT(args.length() == 5); |
+ ASSERT(args.length() == 6); |
Object* check_result; |
{ MaybeObject* maybe_check_result = Runtime_CheckExecutionState( |
RUNTIME_ARGUMENTS(isolate, args)); |
@@ -11184,9 +11213,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) { |
} |
} |
CONVERT_CHECKED(Smi, wrapped_id, args[1]); |
- CONVERT_ARG_CHECKED(String, source, 2); |
- CONVERT_BOOLEAN_CHECKED(disable_break, args[3]); |
- Handle<Object> additional_context(args[4]); |
+ CONVERT_NUMBER_CHECKED(int, inlined_frame_index, Int32, args[2]); |
+ CONVERT_ARG_CHECKED(String, source, 3); |
+ CONVERT_BOOLEAN_CHECKED(disable_break, args[4]); |
+ Handle<Object> additional_context(args[5]); |
// Handle the processing of break. |
DisableBreak disable_break_save(disable_break); |
@@ -11226,7 +11256,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) { |
#endif |
// Materialize the content of the local scope into a JSObject. |
- Handle<JSObject> local_scope = MaterializeLocalScope(isolate, frame); |
+ Handle<JSObject> local_scope = MaterializeLocalScope( |
+ isolate, frame, inlined_frame_index); |
RETURN_IF_EMPTY_HANDLE(isolate, local_scope); |
// Allocate a new context for the debug evaluation and set the extension |
@@ -11275,7 +11306,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) { |
&has_pending_exception); |
if (has_pending_exception) return Failure::Exception(); |
- Handle<Object> arguments = GetArgumentsObject(isolate, frame, |
+ Handle<Object> arguments = GetArgumentsObject(isolate, |
+ frame, inlined_frame_index, |
function, scope_info, |
&sinfo, function_context); |