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

Unified Diff: src/runtime/runtime-debug.cc

Issue 2069823003: [wasm] Enable wasm frame inspection for debugging (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@split-wasm-debug
Patch Set: rebase & address more comments Created 4 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
Index: src/runtime/runtime-debug.cc
diff --git a/src/runtime/runtime-debug.cc b/src/runtime/runtime-debug.cc
index dcdffb748051a55f51d983823b21f8af7c34a9fc..c9137b317cf2b156271d6d23acac5b1373af8193 100644
--- a/src/runtime/runtime-debug.cc
+++ b/src/runtime/runtime-debug.cc
@@ -14,6 +14,7 @@
#include "src/interpreter/interpreter.h"
#include "src/isolate-inl.h"
#include "src/runtime/runtime.h"
+#include "src/wasm/wasm-module.h"
namespace v8 {
namespace internal {
@@ -453,12 +454,16 @@ RUNTIME_FUNCTION(Runtime_GetFrameCount) {
return Smi::FromInt(0);
}
- for (JavaScriptFrameIterator it(isolate, id); !it.done(); it.Advance()) {
+ for (StackTraceFrameIterator it(isolate, id); !it.done(); it.Advance()) {
List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
- it.frame()->Summarize(&frames);
- for (int i = frames.length() - 1; i >= 0; i--) {
- // Omit functions from native and extension scripts.
- if (frames[i].function()->shared()->IsSubjectToDebugging()) n++;
+ if (it.is_wasm()) {
+ n++;
+ } else {
+ it.javascript_frame()->Summarize(&frames);
+ for (int i = frames.length() - 1; i >= 0; i--) {
+ // Omit functions from native and extension scripts.
+ if (frames[i].function()->shared()->IsSubjectToDebugging()) n++;
+ }
}
}
return Smi::FromInt(n);
@@ -468,14 +473,14 @@ RUNTIME_FUNCTION(Runtime_GetFrameCount) {
static const int kFrameDetailsFrameIdIndex = 0;
static const int kFrameDetailsReceiverIndex = 1;
static const int kFrameDetailsFunctionIndex = 2;
-static const int kFrameDetailsArgumentCountIndex = 3;
-static const int kFrameDetailsLocalCountIndex = 4;
-static const int kFrameDetailsSourcePositionIndex = 5;
-static const int kFrameDetailsConstructCallIndex = 6;
-static const int kFrameDetailsAtReturnIndex = 7;
-static const int kFrameDetailsFlagsIndex = 8;
-static const int kFrameDetailsFirstDynamicIndex = 9;
-
+static const int kFrameDetailsScriptIndex = 3;
+static const int kFrameDetailsArgumentCountIndex = 4;
+static const int kFrameDetailsLocalCountIndex = 5;
+static const int kFrameDetailsSourcePositionIndex = 6;
+static const int kFrameDetailsConstructCallIndex = 7;
+static const int kFrameDetailsAtReturnIndex = 8;
+static const int kFrameDetailsFlagsIndex = 9;
+static const int kFrameDetailsFirstDynamicIndex = 10;
// Return an array with frame details
// args[0]: number: break id
@@ -485,12 +490,13 @@ static const int kFrameDetailsFirstDynamicIndex = 9;
// 0: Frame id
// 1: Receiver
// 2: Function
-// 3: Argument count
-// 4: Local count
-// 5: Source position
-// 6: Constructor call
-// 7: Is at return
-// 8: Flags
+// 3: Script
+// 4: Argument count
+// 5: Local count
+// 6: Source position
+// 7: Constructor call
+// 8: Is at return
+// 9: Flags
// Arguments name, value
// Locals name, value
// Return value if any
@@ -510,7 +516,7 @@ RUNTIME_FUNCTION(Runtime_GetFrameDetails) {
return heap->undefined_value();
}
- JavaScriptFrameIterator it(isolate, id);
+ StackTraceFrameIterator it(isolate, id);
// Inlined frame index in optimized frame, starting from outer function.
int inlined_jsframe_index =
DebugFrameHelper::FindIndexedNonNativeFrame(&it, index);
@@ -534,61 +540,67 @@ RUNTIME_FUNCTION(Runtime_GetFrameDetails) {
// Check for constructor frame.
bool constructor = frame_inspector.IsConstructor();
- // Get scope info and read from it for local variable information.
- Handle<JSFunction> function =
- Handle<JSFunction>::cast(frame_inspector.GetFunction());
- RUNTIME_ASSERT(function->shared()->IsSubjectToDebugging());
- Handle<SharedFunctionInfo> shared(function->shared());
- Handle<ScopeInfo> scope_info(shared->scope_info());
- DCHECK(*scope_info != ScopeInfo::Empty(isolate));
+ Handle<ScopeInfo> scope_info;
// Get the locals names and values into a temporary array.
- int local_count = scope_info->LocalCount();
- for (int slot = 0; slot < scope_info->LocalCount(); ++slot) {
- // Hide compiler-introduced temporary variables, whether on the stack or on
- // the context.
- if (ScopeInfo::VariableIsSynthetic(scope_info->LocalName(slot))) {
- local_count--;
+ Handle<FixedArray> locals;
Yang 2016/06/24 05:56:37 Can we re-organize this file like this? if (it.is
Clemens Hammacher 2016/06/24 09:23:31 Done.
+ if (it.is_wasm()) {
+ // TODO(clemensh): add names and values of local variables.
+ locals = isolate->factory()->NewFixedArray(0);
+ } else {
+ // Get scope info and read from it for local variable information.
+ SharedFunctionInfo* shared = frame_inspector.GetFunction()->shared();
+ RUNTIME_ASSERT(shared->IsSubjectToDebugging());
+ scope_info = handle(shared->scope_info(), isolate);
+ DCHECK(*scope_info != ScopeInfo::Empty(isolate));
+
+ int local_count = scope_info->LocalCount();
+ for (int slot = 0; slot < scope_info->LocalCount(); ++slot) {
+ // Hide compiler-introduced temporary variables, whether on the stack or
+ // on the context.
+ if (ScopeInfo::VariableIsSynthetic(scope_info->LocalName(slot))) {
+ local_count--;
+ }
}
- }
- Handle<FixedArray> locals =
- isolate->factory()->NewFixedArray(local_count * 2);
-
- // Fill in the values of the locals.
- int local = 0;
- int i = 0;
- for (; i < scope_info->StackLocalCount(); ++i) {
- // Use the value from the stack.
- if (ScopeInfo::VariableIsSynthetic(scope_info->LocalName(i))) continue;
- locals->set(local * 2, scope_info->LocalName(i));
- Handle<Object> value =
- frame_inspector.GetExpression(scope_info->StackLocalIndex(i));
- // TODO(yangguo): We convert optimized out values to {undefined} when they
- // are passed to the debugger. Eventually we should handle them somehow.
- if (value->IsOptimizedOut(isolate)) {
- value = isolate->factory()->undefined_value();
- }
- locals->set(local * 2 + 1, *value);
- local++;
- }
- if (local < local_count) {
- // Get the context containing declarations.
- Handle<Context> context(
- Handle<Context>::cast(frame_inspector.GetContext())->closure_context());
- for (; i < scope_info->LocalCount(); ++i) {
- Handle<String> name(scope_info->LocalName(i));
- if (ScopeInfo::VariableIsSynthetic(*name)) continue;
- VariableMode mode;
- InitializationFlag init_flag;
- MaybeAssignedFlag maybe_assigned_flag;
- locals->set(local * 2, *name);
- int context_slot_index = ScopeInfo::ContextSlotIndex(
- scope_info, name, &mode, &init_flag, &maybe_assigned_flag);
- Object* value = context->get(context_slot_index);
- locals->set(local * 2 + 1, value);
+ locals = isolate->factory()->NewFixedArray(local_count * 2);
+
+ // Fill in the values of the locals.
+ int local = 0;
+ int i = 0;
+ for (; i < scope_info->StackLocalCount(); ++i) {
+ // Use the value from the stack.
+ if (ScopeInfo::VariableIsSynthetic(scope_info->LocalName(i))) continue;
+ locals->set(local * 2, scope_info->LocalName(i));
+ Handle<Object> value =
+ frame_inspector.GetExpression(scope_info->StackLocalIndex(i));
+ // TODO(yangguo): We convert optimized out values to {undefined} when they
+ // are passed to the debugger. Eventually we should handle them somehow.
+ if (value->IsOptimizedOut(isolate)) {
+ value = isolate->factory()->undefined_value();
+ }
+ locals->set(local * 2 + 1, *value);
local++;
}
+ if (local < local_count) {
+ // Get the context containing declarations.
+ Handle<Context> context(
+ Handle<Context>::cast(frame_inspector.GetContext())
+ ->closure_context());
+ for (; i < scope_info->LocalCount(); ++i) {
+ Handle<String> name(scope_info->LocalName(i));
+ if (ScopeInfo::VariableIsSynthetic(*name)) continue;
+ VariableMode mode;
+ InitializationFlag init_flag;
+ MaybeAssignedFlag maybe_assigned_flag;
+ locals->set(local * 2, *name);
+ int context_slot_index = ScopeInfo::ContextSlotIndex(
+ scope_info, name, &mode, &init_flag, &maybe_assigned_flag);
+ Object* value = context->get(context_slot_index);
+ locals->set(local * 2 + 1, value);
+ local++;
+ }
+ }
}
// Check whether this frame is positioned at return. If not top
@@ -609,34 +621,50 @@ RUNTIME_FUNCTION(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 ((inlined_jsframe_index == 0) && it.frame()->has_adapted_arguments()) {
+ if ((inlined_jsframe_index == 0) && it.frame()->is_java_script() &&
+ it.javascript_frame()->has_adapted_arguments()) {
it.AdvanceToArgumentsFrame();
frame_inspector.SetArgumentsFrame(it.frame());
}
// Find the number of arguments to fill. At least fill the number of
// parameters for the function and fill more if more parameters are provided.
- int argument_count = scope_info->ParameterCount();
- if (argument_count < frame_inspector.GetParametersCount()) {
- argument_count = frame_inspector.GetParametersCount();
+ int argument_count = frame_inspector.GetParametersCount();
+ if (!it.is_wasm()) {
+ int scope_param_count = scope_info->ParameterCount();
+ if (scope_param_count > argument_count) argument_count = scope_param_count;
}
// Calculate the size of the result.
- int details_size = kFrameDetailsFirstDynamicIndex +
- 2 * (argument_count + local_count) + (at_return ? 1 : 0);
+ int details_size = kFrameDetailsFirstDynamicIndex + 2 * argument_count +
+ locals->length() + (at_return ? 1 : 0);
Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size);
// Add the frame id.
details->set(kFrameDetailsFrameIdIndex, *frame_id);
// Add the function (same as in function frame).
- details->set(kFrameDetailsFunctionIndex, *(frame_inspector.GetFunction()));
+ if (it.is_wasm()) {
+ Handle<Object> wasm_obj(it.wasm_frame()->wasm_obj(), isolate);
+ int func_index = it.wasm_frame()->function_index();
+ Handle<String> func_name =
+ wasm::GetWasmFunctionName(isolate, wasm_obj, func_index);
+ details->set(kFrameDetailsFunctionIndex, *func_name);
+ } else {
+ details->set(kFrameDetailsFunctionIndex, *frame_inspector.GetFunction());
+ }
+
+ // Add the script wrapper
+ Handle<Object> script_wrapper =
+ Script::GetWrapper(frame_inspector.GetScript());
+ details->set(kFrameDetailsScriptIndex, *script_wrapper);
// Add the arguments count.
details->set(kFrameDetailsArgumentCountIndex, Smi::FromInt(argument_count));
// Add the locals count
- details->set(kFrameDetailsLocalCountIndex, Smi::FromInt(local_count));
+ details->set(kFrameDetailsLocalCountIndex,
+ Smi::FromInt(locals->length() / 2));
// Add the source position.
if (position != RelocInfo::kNoPosition) {
@@ -669,25 +697,21 @@ RUNTIME_FUNCTION(Runtime_GetFrameDetails) {
int details_index = kFrameDetailsFirstDynamicIndex;
// Add arguments name and value.
- for (int i = 0; i < argument_count; i++) {
+ for (int i = 0; i < argument_count; i++, details_index += 2) {
// Name of the argument.
- if (i < scope_info->ParameterCount()) {
- details->set(details_index++, scope_info->ParameterName(i));
- } else {
- details->set(details_index++, heap->undefined_value());
+ if (!scope_info.is_null() && i < scope_info->ParameterCount()) {
+ details->set(details_index, scope_info->ParameterName(i));
}
// Parameter value.
if (i < frame_inspector.GetParametersCount()) {
// Get the value from the stack.
- details->set(details_index++, *(frame_inspector.GetParameter(i)));
- } else {
- details->set(details_index++, heap->undefined_value());
+ details->set(details_index + 1, *frame_inspector.GetParameter(i));
}
}
// Add locals name and value from the temporary copy from the function frame.
- for (int i = 0; i < local_count * 2; i++) {
+ for (int i = 0, l = locals->length(); i < l; ++i) {
details->set(details_index++, locals->get(i));
}
@@ -698,8 +722,11 @@ RUNTIME_FUNCTION(Runtime_GetFrameDetails) {
// Add the receiver (same as in function frame).
Handle<Object> receiver(it.frame()->receiver(), isolate);
- DCHECK(!function->shared()->IsBuiltin());
- DCHECK_IMPLIES(is_sloppy(shared->language_mode()), receiver->IsJSReceiver());
+ DCHECK(it.is_wasm() || !frame_inspector.GetFunction()->shared()->IsBuiltin());
+ DCHECK_IMPLIES(
+ !it.is_wasm() &&
+ is_sloppy(frame_inspector.GetFunction()->shared()->language_mode()),
+ receiver->IsJSReceiver());
details->set(kFrameDetailsReceiverIndex, *receiver);
DCHECK_EQ(details_size, details_index);
@@ -795,8 +822,8 @@ RUNTIME_FUNCTION(Runtime_GetAllScopesDetails) {
// Get the frame where the debugging is performed.
StackFrame::Id id = DebugFrameHelper::UnwrapFrameId(wrapped_id);
- JavaScriptFrameIterator frame_it(isolate, id);
- JavaScriptFrame* frame = frame_it.frame();
+ StackTraceFrameIterator frame_it(isolate, id);
+ StandardFrame* frame = frame_it.frame();
Yang 2016/06/24 05:56:37 We need to return an empty array if the frame is n
Clemens Hammacher 2016/06/24 09:23:31 This happens implicitely, as the ScopeIterator wil
Yang 2016/06/24 10:02:57 It will be empty because of the check in ScopeIter
Clemens Hammacher 2016/06/24 10:45:42 The check is in debug-scopes.cc:25: if (!frame_ins
Yang 2016/06/24 10:52:25 I see. Can we at least add an assertion in ScopeIt
Clemens Hammacher 2016/06/24 15:11:58 Done.
FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
List<Handle<JSObject> > result(4);
@@ -1555,8 +1582,10 @@ static Handle<Object> GetJSPositionInfo(Handle<Script> script, int position,
}
Handle<String> source = handle(String::cast(script->source()), isolate);
- Handle<String> sourceText =
- isolate->factory()->NewSubString(source, info.line_start, info.line_end);
+ Handle<String> sourceText = info.line_end > source->length()
Yang 2016/06/24 05:56:37 can we do a script->is_wasm check instead?
Clemens Hammacher 2016/06/24 09:23:31 Done.
+ ? isolate->factory()->empty_string()
+ : isolate->factory()->NewSubString(
+ source, info.line_start, info.line_end);
Handle<JSObject> jsinfo =
isolate->factory()->NewJSObject(isolate->object_function());
« src/debug/debug.cc ('K') | « src/objects.cc ('k') | src/runtime/runtime-liveedit.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698