Index: src/runtime.cc |
diff --git a/src/runtime.cc b/src/runtime.cc |
index 2bac30473beb0732979c860175535e322cd016dc..f95ecdfc6f2f00e0bf13c6ef0f41dabf939c9ae3 100644 |
--- a/src/runtime.cc |
+++ b/src/runtime.cc |
@@ -8126,13 +8126,15 @@ static SmartArrayPointer<Handle<Object> > GetCallerArguments( |
List<JSFunction*> functions(2); |
frame->GetFunctions(&functions); |
if (functions.length() > 1) { |
- int inlined_frame_index = functions.length() - 1; |
- JSFunction* inlined_function = functions[inlined_frame_index]; |
- int args_count = inlined_function->shared()->formal_parameter_count(); |
- ScopedVector<SlotRef> args_slots(args_count); |
- SlotRef::ComputeSlotMappingForArguments(frame, |
- inlined_frame_index, |
- &args_slots); |
+ int inlined_jsframe_index = functions.length() - 1; |
+ JSFunction* inlined_function = functions[inlined_jsframe_index]; |
+ Vector<SlotRef> args_slots = |
+ SlotRef::ComputeSlotMappingForArguments( |
+ frame, |
+ inlined_jsframe_index, |
+ inlined_function->shared()->formal_parameter_count()); |
+ |
+ int args_count = args_slots.length(); |
*total_argc = prefix_argc + args_count; |
SmartArrayPointer<Handle<Object> > param_data( |
@@ -8141,6 +8143,9 @@ static SmartArrayPointer<Handle<Object> > GetCallerArguments( |
Handle<Object> val = args_slots[i].GetValue(); |
param_data[prefix_argc + i] = val; |
} |
+ |
+ args_slots.Dispose(); |
+ |
return param_data; |
} else { |
it.AdvanceToArgumentsFrame(); |
@@ -8486,14 +8491,14 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyDeoptimized) { |
static_cast<Deoptimizer::BailoutType>(args.smi_at(0)); |
Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate); |
ASSERT(isolate->heap()->IsAllocationAllowed()); |
- int frames = deoptimizer->output_count(); |
+ int jsframes = deoptimizer->jsframe_count(); |
deoptimizer->MaterializeHeapNumbers(); |
delete deoptimizer; |
JavaScriptFrameIterator it(isolate); |
JavaScriptFrame* frame = NULL; |
- for (int i = 0; i < frames - 1; i++) it.Advance(); |
+ for (int i = 0; i < jsframes - 1; i++) it.Advance(); |
frame = it.frame(); |
RUNTIME_ASSERT(frame->function()->IsJSFunction()); |
@@ -10703,13 +10708,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameCount) { |
class FrameInspector { |
public: |
FrameInspector(JavaScriptFrame* frame, |
- int inlined_frame_index, |
+ int inlined_jsframe_index, |
Isolate* isolate) |
: frame_(frame), deoptimized_frame_(NULL), isolate_(isolate) { |
// Calculate the deoptimized frame. |
if (frame->is_optimized()) { |
deoptimized_frame_ = Deoptimizer::DebuggerInspectableFrame( |
- frame, inlined_frame_index, isolate); |
+ frame, inlined_jsframe_index, isolate); |
} |
has_adapted_arguments_ = frame_->has_adapted_arguments(); |
is_optimized_ = frame_->is_optimized(); |
@@ -10825,8 +10830,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) { |
return heap->undefined_value(); |
} |
- int inlined_frame_index = 0; // Inlined frame index in optimized frame. |
- |
int count = 0; |
JavaScriptFrameIterator it(isolate, id); |
for (; !it.done(); it.Advance()) { |
@@ -10835,11 +10838,14 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) { |
} |
if (it.done()) return heap->undefined_value(); |
- if (it.frame()->is_optimized()) { |
- inlined_frame_index = |
+ bool is_optimized = it.frame()->is_optimized(); |
+ |
+ int inlined_jsframe_index = 0; // Inlined frame index in optimized frame. |
+ if (is_optimized) { |
+ inlined_jsframe_index = |
it.frame()->GetInlineCount() - (index - count) - 1; |
} |
- FrameInspector frame_inspector(it.frame(), inlined_frame_index, isolate); |
+ FrameInspector frame_inspector(it.frame(), inlined_jsframe_index, isolate); |
// Traverse the saved contexts chain to find the active context for the |
// selected frame. |
@@ -10853,12 +10859,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) { |
it.frame()->LookupCode()->SourcePosition(it.frame()->pc()); |
// Check for constructor frame. Inlined frames cannot be construct calls. |
- bool inlined_frame = |
- it.frame()->is_optimized() && inlined_frame_index != 0; |
+ bool inlined_frame = is_optimized && inlined_jsframe_index != 0; |
bool constructor = !inlined_frame && it.frame()->IsConstructor(); |
// Get scope info and read from it for local variable information. |
- Handle<JSFunction> function(JSFunction::cast(it.frame()->function())); |
+ Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction())); |
Handle<SharedFunctionInfo> shared(function->shared()); |
Handle<ScopeInfo> scope_info(shared->scope_info()); |
ASSERT(*scope_info != ScopeInfo::Empty()); |
@@ -10895,7 +10900,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) { |
// Check whether this frame is positioned at return. If not top |
// frame or if the frame is optimized it cannot be at a return. |
bool at_return = false; |
- if (!it.frame()->is_optimized() && index == 0) { |
+ if (!is_optimized && index == 0) { |
at_return = isolate->debug()->IsBreakAtReturn(it.frame()); |
} |
@@ -10935,7 +10940,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) { |
// the provided parameters whereas the function frame always have the number |
// of arguments matching the functions parameters. The rest of the |
// information (except for what is collected above) is the same. |
- if (it.frame()->has_adapted_arguments()) { |
+ if ((inlined_jsframe_index == 0) && it.frame()->has_adapted_arguments()) { |
it.AdvanceToArgumentsFrame(); |
frame_inspector.SetArgumentsFrame(it.frame()); |
} |
@@ -10946,11 +10951,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) { |
if (argument_count < frame_inspector.GetParametersCount()) { |
argument_count = frame_inspector.GetParametersCount(); |
} |
-#ifdef DEBUG |
- if (it.frame()->is_optimized()) { |
- ASSERT_EQ(argument_count, frame_inspector.GetParametersCount()); |
- } |
-#endif |
// Calculate the size of the result. |
int details_size = kFrameDetailsFirstDynamicIndex + |
@@ -10992,9 +10992,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) { |
if (*save->context() == *isolate->debug()->debug_context()) { |
flags |= 1 << 0; |
} |
- if (it.frame()->is_optimized()) { |
+ if (is_optimized) { |
flags |= 1 << 1; |
- flags |= inlined_frame_index << 2; |
+ flags |= inlined_jsframe_index << 2; |
} |
details->set(kFrameDetailsFlagsIndex, Smi::FromInt(flags)); |
@@ -11011,7 +11011,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) { |
} |
// Parameter value. |
- if (i < it.frame()->ComputeParametersCount()) { |
+ if (i < frame_inspector.GetParametersCount()) { |
// Get the value from the stack. |
details->set(details_index++, frame_inspector.GetParameter(i)); |
} else { |
@@ -11084,14 +11084,13 @@ static bool CopyContextLocalsToScopeObject( |
// Create a plain JSObject which materializes the local scope for the specified |
// frame. |
-static Handle<JSObject> MaterializeLocalScope( |
+static Handle<JSObject> MaterializeLocalScopeWithFrameInspector( |
Isolate* isolate, |
JavaScriptFrame* frame, |
- int inlined_frame_index) { |
- Handle<JSFunction> function(JSFunction::cast(frame->function())); |
+ FrameInspector* frame_inspector) { |
+ Handle<JSFunction> function(JSFunction::cast(frame_inspector->GetFunction())); |
Handle<SharedFunctionInfo> shared(function->shared()); |
Handle<ScopeInfo> scope_info(shared->scope_info()); |
- FrameInspector frame_inspector(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. |
@@ -11100,11 +11099,15 @@ static Handle<JSObject> MaterializeLocalScope( |
// First fill all parameters. |
for (int i = 0; i < scope_info->ParameterCount(); ++i) { |
+ Handle<Object> value( |
+ i < frame_inspector->GetParametersCount() ? |
+ frame_inspector->GetParameter(i) : isolate->heap()->undefined_value()); |
+ |
RETURN_IF_EMPTY_HANDLE_VALUE( |
isolate, |
SetProperty(local_scope, |
Handle<String>(scope_info->ParameterName(i)), |
- Handle<Object>(frame_inspector.GetParameter(i)), |
+ value, |
NONE, |
kNonStrictMode), |
Handle<JSObject>()); |
@@ -11116,7 +11119,7 @@ static Handle<JSObject> MaterializeLocalScope( |
isolate, |
SetProperty(local_scope, |
Handle<String>(scope_info->StackLocalName(i)), |
- Handle<Object>(frame_inspector.GetExpression(i)), |
+ Handle<Object>(frame_inspector->GetExpression(i)), |
NONE, |
kNonStrictMode), |
Handle<JSObject>()); |
@@ -11163,6 +11166,17 @@ static Handle<JSObject> MaterializeLocalScope( |
} |
+static Handle<JSObject> MaterializeLocalScope( |
+ Isolate* isolate, |
+ JavaScriptFrame* frame, |
+ int inlined_jsframe_index) { |
+ FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate); |
+ return MaterializeLocalScopeWithFrameInspector(isolate, |
+ frame, |
+ &frame_inspector); |
+} |
+ |
+ |
// Create a plain JSObject which materializes the closure content for the |
// context. |
static Handle<JSObject> MaterializeClosure(Isolate* isolate, |
@@ -11268,10 +11282,10 @@ class ScopeIterator { |
ScopeIterator(Isolate* isolate, |
JavaScriptFrame* frame, |
- int inlined_frame_index) |
+ int inlined_jsframe_index) |
: isolate_(isolate), |
frame_(frame), |
- inlined_frame_index_(inlined_frame_index), |
+ inlined_jsframe_index_(inlined_jsframe_index), |
function_(JSFunction::cast(frame->function())), |
context_(Context::cast(frame->context())), |
nested_scope_chain_(4) { |
@@ -11428,7 +11442,7 @@ class ScopeIterator { |
case ScopeIterator::ScopeTypeLocal: |
// Materialize the content of the local scope into a JSObject. |
ASSERT(nested_scope_chain_.length() == 1); |
- return MaterializeLocalScope(isolate_, frame_, inlined_frame_index_); |
+ return MaterializeLocalScope(isolate_, frame_, inlined_jsframe_index_); |
case ScopeIterator::ScopeTypeWith: |
// Return the with object. |
return Handle<JSObject>(JSObject::cast(CurrentContext()->extension())); |
@@ -11524,7 +11538,7 @@ class ScopeIterator { |
private: |
Isolate* isolate_; |
JavaScriptFrame* frame_; |
- int inlined_frame_index_; |
+ int inlined_jsframe_index_; |
Handle<JSFunction> function_; |
Handle<Context> context_; |
List<Handle<ScopeInfo> > nested_scope_chain_; |
@@ -11586,7 +11600,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeDetails) { |
if (!maybe_check->ToObject(&check)) return maybe_check; |
} |
CONVERT_CHECKED(Smi, wrapped_id, args[1]); |
- CONVERT_NUMBER_CHECKED(int, inlined_frame_index, Int32, args[2]); |
+ CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]); |
CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]); |
// Get the frame where the debugging is performed. |
@@ -11596,7 +11610,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeDetails) { |
// Find the requested scope. |
int n = 0; |
- ScopeIterator it(isolate, frame, inlined_frame_index); |
+ ScopeIterator it(isolate, frame, inlined_jsframe_index); |
for (; !it.Done() && n < index; it.Next()) { |
n++; |
} |
@@ -11994,12 +12008,12 @@ static Handle<Context> CopyNestedScopeContextChain(Isolate* isolate, |
Handle<JSFunction> function, |
Handle<Context> base, |
JavaScriptFrame* frame, |
- int inlined_frame_index) { |
+ int inlined_jsframe_index) { |
HandleScope scope(isolate); |
List<Handle<ScopeInfo> > scope_chain; |
List<Handle<Context> > context_chain; |
- ScopeIterator it(isolate, frame, inlined_frame_index); |
+ ScopeIterator it(isolate, frame, inlined_jsframe_index); |
for (; it.Type() != ScopeIterator::ScopeTypeGlobal && |
it.Type() != ScopeIterator::ScopeTypeLocal ; it.Next()) { |
ASSERT(!it.Done()); |
@@ -12056,8 +12070,7 @@ static Handle<Context> CopyNestedScopeContextChain(Isolate* isolate, |
// Runtime_DebugEvaluate. |
static Handle<Object> GetArgumentsObject(Isolate* isolate, |
JavaScriptFrame* frame, |
- int inlined_frame_index, |
- Handle<JSFunction> function, |
+ FrameInspector* frame_inspector, |
Handle<ScopeInfo> scope_info, |
Handle<Context> function_context) { |
// Try to find the value of 'arguments' to pass as parameter. If it is not |
@@ -12081,9 +12094,8 @@ static Handle<Object> GetArgumentsObject(Isolate* isolate, |
} |
} |
- FrameInspector frame_inspector(frame, inlined_frame_index, isolate); |
- |
- int length = frame_inspector.GetParametersCount(); |
+ Handle<JSFunction> function(JSFunction::cast(frame_inspector->GetFunction())); |
+ int length = frame_inspector->GetParametersCount(); |
Handle<JSObject> arguments = |
isolate->factory()->NewArgumentsObject(function, length); |
Handle<FixedArray> array = isolate->factory()->NewFixedArray(length); |
@@ -12091,7 +12103,7 @@ 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_inspector.GetParameter(i), mode); |
+ array->set(i, frame_inspector->GetParameter(i), mode); |
} |
arguments->set_elements(*array); |
return arguments; |
@@ -12127,7 +12139,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) { |
} |
} |
CONVERT_CHECKED(Smi, wrapped_id, args[1]); |
- CONVERT_NUMBER_CHECKED(int, inlined_frame_index, Int32, args[2]); |
+ CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]); |
CONVERT_ARG_CHECKED(String, source, 3); |
CONVERT_BOOLEAN_CHECKED(disable_break, args[4]); |
Handle<Object> additional_context(args[5]); |
@@ -12139,7 +12151,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) { |
StackFrame::Id id = UnwrapFrameId(wrapped_id); |
JavaScriptFrameIterator it(isolate, id); |
JavaScriptFrame* frame = it.frame(); |
- Handle<JSFunction> function(JSFunction::cast(frame->function())); |
+ FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate); |
+ Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction())); |
Handle<ScopeInfo> scope_info(function->shared()->scope_info()); |
// Traverse the saved contexts chain to find the active context for the |
@@ -12166,8 +12179,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) { |
#endif |
// Materialize the content of the local scope into a JSObject. |
- Handle<JSObject> local_scope = MaterializeLocalScope( |
- isolate, frame, inlined_frame_index); |
+ Handle<JSObject> local_scope = MaterializeLocalScopeWithFrameInspector( |
+ isolate, frame, &frame_inspector); |
RETURN_IF_EMPTY_HANDLE(isolate, local_scope); |
// Allocate a new context for the debug evaluation and set the extension |
@@ -12187,7 +12200,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) { |
go_between, |
context, |
frame, |
- inlined_frame_index); |
+ inlined_jsframe_index); |
if (additional_context->IsJSObject()) { |
Handle<JSObject> extension = Handle<JSObject>::cast(additional_context); |
@@ -12227,8 +12240,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) { |
Handle<Object> arguments = GetArgumentsObject(isolate, |
frame, |
- inlined_frame_index, |
- function, |
+ &frame_inspector, |
scope_info, |
function_context); |