Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(108)

Unified Diff: src/runtime.cc

Issue 7230045: Support debugger inspection of locals in optimized frames (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebase Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/objects.cc ('k') | src/x64/deoptimizer-x64.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/runtime.cc
diff --git a/src/runtime.cc b/src/runtime.cc
index df99fdc671ff48d25e3e0cb75c6cbd8d04a7f1b1..bd9f516503ced013de57ead704621ec1ef5b17cc 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -9938,7 +9938,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameCount) {
// If there is no JavaScript stack frame count is 0.
return Smi::FromInt(0);
}
- for (JavaScriptFrameIterator it(isolate, id); !it.done(); it.Advance()) n++;
+
+ for (JavaScriptFrameIterator it(isolate, id); !it.done(); it.Advance()) {
+ n += it.frame()->GetInlineCount();
+ }
return Smi::FromInt(n);
}
@@ -9951,7 +9954,7 @@ static const int kFrameDetailsLocalCountIndex = 4;
static const int kFrameDetailsSourcePositionIndex = 5;
static const int kFrameDetailsConstructCallIndex = 6;
static const int kFrameDetailsAtReturnIndex = 7;
-static const int kFrameDetailsDebuggerFrameIndex = 8;
+static const int kFrameDetailsFlagsIndex = 8;
static const int kFrameDetailsFirstDynamicIndex = 9;
// Return an array with frame details
@@ -9967,7 +9970,7 @@ static const int kFrameDetailsFirstDynamicIndex = 9;
// 5: Source position
// 6: Constructor call
// 7: Is at return
-// 8: Debugger frame
+// 8: Flags
// Arguments name, value
// Locals name, value
// Return value if any
@@ -9990,16 +9993,26 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
// If there are no JavaScript stack frames return undefined.
return heap->undefined_value();
}
+
+ int deoptimized_frame_index = -1; // Frame index in optimized frame.
+ DeoptimizedFrameInfo* deoptimized_frame = NULL;
+
int count = 0;
JavaScriptFrameIterator it(isolate, id);
for (; !it.done(); it.Advance()) {
- if (count == index) break;
- count++;
+ if (index < count + it.frame()->GetInlineCount()) break;
+ count += it.frame()->GetInlineCount();
}
if (it.done()) return heap->undefined_value();
- bool is_optimized_frame =
- it.frame()->LookupCode()->kind() == Code::OPTIMIZED_FUNCTION;
+ if (it.frame()->is_optimized()) {
+ deoptimized_frame_index =
+ it.frame()->GetInlineCount() - (index - count) - 1;
+ deoptimized_frame = Deoptimizer::DebuggerInspectableFrame(
+ it.frame(),
+ deoptimized_frame_index,
+ isolate);
+ }
// Traverse the saved contexts chain to find the active context for the
// selected frame.
@@ -10022,6 +10035,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
// Get scope info and read from it for local variable information.
Handle<JSFunction> function(JSFunction::cast(it.frame()->function()));
Handle<SerializedScopeInfo> scope_info(function->shared()->scope_info());
+ ASSERT(*scope_info != SerializedScopeInfo::Empty());
ScopeInfo<> info(*scope_info);
// Get the locals names and values into a temporary array.
@@ -10033,38 +10047,33 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
isolate->factory()->NewFixedArray(info.NumberOfLocals() * 2);
// Fill in the values of the locals.
- if (is_optimized_frame) {
- // If we are inspecting an optimized frame use undefined as the
- // value for all locals.
- //
- // TODO(1140): We should be able to get the correct values
- // for locals in optimized frames.
- for (int i = 0; i < info.NumberOfLocals(); i++) {
- locals->set(i * 2, *info.LocalName(i));
- locals->set(i * 2 + 1, isolate->heap()->undefined_value());
- }
- } else {
- int i = 0;
- for (; i < info.number_of_stack_slots(); ++i) {
- // Use the value from the stack.
- locals->set(i * 2, *info.LocalName(i));
- locals->set(i * 2 + 1, it.frame()->GetExpression(i));
- }
- // Get the context containing declarations.
- Handle<Context> context(
- Context::cast(it.frame()->context())->declaration_context());
- for (; i < info.NumberOfLocals(); ++i) {
- Handle<String> name = info.LocalName(i);
- locals->set(i * 2, *name);
+ int i = 0;
+ for (; i < info.number_of_stack_slots(); ++i) {
+ // Use the value from the stack.
+ locals->set(i * 2, *info.LocalName(i));
+ if (it.frame()->is_optimized()) {
+ // Get the value from the deoptimized frame.
locals->set(i * 2 + 1,
- context->get(scope_info->ContextSlotIndex(*name, NULL)));
+ deoptimized_frame->GetExpression(i));
+ } else {
+ // Get the value from the stack.
+ locals->set(i * 2 + 1, it.frame()->GetExpression(i));
}
}
+ // Get the context containing declarations.
+ Handle<Context> context(
+ Context::cast(it.frame()->context())->declaration_context());
+ for (; i < info.NumberOfLocals(); ++i) {
+ Handle<String> name = info.LocalName(i);
+ locals->set(i * 2, *name);
+ locals->set(i * 2 + 1,
+ context->get(scope_info->ContextSlotIndex(*name, NULL)));
+ }
// 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 (!is_optimized_frame && index == 0) {
+ if (!it.frame()->is_optimized() && index == 0) {
at_return = isolate->debug()->IsBreakAtReturn(it.frame());
}
@@ -10145,10 +10154,21 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
// Add the at return information.
details->set(kFrameDetailsAtReturnIndex, heap->ToBoolean(at_return));
- // Add information on whether this frame is invoked in the debugger context.
- details->set(kFrameDetailsDebuggerFrameIndex,
- heap->ToBoolean(*save->context() ==
- *isolate->debug()->debug_context()));
+ // Add flags to indicate information on whether this frame is
+ // bit 0: invoked in the debugger context.
+ // bit 1: optimized frame.
+ // bit 2: inlined in optimized frame
+ int flags = 0;
+ if (*save->context() == *isolate->debug()->debug_context()) {
+ flags |= 1 << 0;
+ }
+ if (it.frame()->is_optimized()) {
+ flags |= 1 << 1;
+ if (deoptimized_frame_index > 0) {
+ flags |= 1 << 2;
+ }
+ }
+ details->set(kFrameDetailsFlagsIndex, Smi::FromInt(flags));
// Fill the dynamic part.
int details_index = kFrameDetailsFirstDynamicIndex;
@@ -10167,7 +10187,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
//
// TODO(3141533): We should be able to get the actual parameter
// value for optimized frames.
- if (!is_optimized_frame &&
+ if (!it.frame()->is_optimized() &&
(i < it.frame()->ComputeParametersCount())) {
details->set(details_index++, it.frame()->GetParameter(i));
} else {
@@ -10203,6 +10223,12 @@ 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);
}
« no previous file with comments | « src/objects.cc ('k') | src/x64/deoptimizer-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698