Commit 19b62d0b authored by Z Nguyen-Huu's avatar Z Nguyen-Huu Committed by Commit Bot

[v8windbg] Add more items in the Locals pane

Add more items in the Locals pane representing the JS function name,
source file name, and character offset within the source file, so
that the user doesn’t need to dig through the shared_function_info to
find them.

Change-Id: I5d42b3c9542885a72e81613503d1d5abf51870b5
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2712310
Commit-Queue: Z Nguyen-Huu <duongn@microsoft.com>
Reviewed-by: 's avatarSeth Brenith <seth.brenith@microsoft.com>
Cr-Commit-Position: refs/heads/master@{#73282}
parent b6a96f27
...@@ -421,9 +421,27 @@ static void FrameIterationCheck( ...@@ -421,9 +421,27 @@ static void FrameIterationCheck(
d::StackFrameResultPtr props = d::GetStackFrame(frame->fp(), &ReadMemory); d::StackFrameResultPtr props = d::GetStackFrame(frame->fp(), &ReadMemory);
if (frame->is_java_script()) { if (frame->is_java_script()) {
JavaScriptFrame* js_frame = JavaScriptFrame::cast(frame); JavaScriptFrame* js_frame = JavaScriptFrame::cast(frame);
CHECK_EQ(props->num_properties, 1); CHECK_EQ(props->num_properties, 5);
auto js_function = js_frame->function();
CheckProp(*props->properties[0], "v8::internal::JSFunction", CheckProp(*props->properties[0], "v8::internal::JSFunction",
"currently_executing_jsfunction", js_frame->function().ptr()); "currently_executing_jsfunction", js_function.ptr());
auto script = i::Script::cast(js_function.shared().script());
CheckProp(*props->properties[1], "v8::internal::Object", "script_name",
script.name());
CheckProp(*props->properties[2], "v8::internal::Object", "script_source",
script.source());
auto scope_info = js_function.shared().scope_info();
CheckProp(*props->properties[3], "v8::internal::Object", "function_name",
scope_info.FunctionName());
CheckProp(*props->properties[4], "", "function_character_offset");
const d::ObjectProperty& function_character_offset =
*props->properties[4];
CHECK_EQ(function_character_offset.num_struct_fields, 2);
CheckStructProp(*function_character_offset.struct_fields[0],
"v8::internal::Object", "start", 0);
CheckStructProp(*function_character_offset.struct_fields[1],
"v8::internal::Object", "end", 4);
} else { } else {
CHECK_EQ(props->num_properties, 0); CHECK_EQ(props->num_properties, 0);
} }
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "src/objects/string-inl.h" #include "src/objects/string-inl.h"
#include "src/strings/unicode-inl.h" #include "src/strings/unicode-inl.h"
#include "torque-generated/class-debug-readers.h" #include "torque-generated/class-debug-readers.h"
#include "torque-generated/debug-macros.h"
namespace i = v8::internal; namespace i = v8::internal;
...@@ -133,6 +134,23 @@ TypedObject GetTypedObjectByInstanceType(uintptr_t address, ...@@ -133,6 +134,23 @@ TypedObject GetTypedObjectByInstanceType(uintptr_t address,
} }
} }
bool IsTypedHeapObjectInstanceTypeOf(uintptr_t address,
d::MemoryAccessor accessor,
i::InstanceType instance_type) {
auto heap_object = std::make_unique<TqHeapObject>(address);
Value<uintptr_t> map_ptr = heap_object->GetMapValue(accessor);
if (map_ptr.validity == d::MemoryAccessResult::kOk) {
Value<i::InstanceType> type =
TqMap(map_ptr.value).GetInstanceTypeValue(accessor);
if (type.validity == d::MemoryAccessResult::kOk) {
return instance_type == type.value;
}
}
return false;
}
TypedObject GetTypedHeapObject(uintptr_t address, d::MemoryAccessor accessor, TypedObject GetTypedHeapObject(uintptr_t address, d::MemoryAccessor accessor,
const char* type_hint, const char* type_hint,
const d::HeapAddresses& heap_addresses) { const d::HeapAddresses& heap_addresses) {
...@@ -654,6 +672,93 @@ std::unique_ptr<StackFrameResult> GetStackFrame( ...@@ -654,6 +672,93 @@ std::unique_ptr<StackFrameResult> GetStackFrame(
sizeof(v8::internal::JSFunction), sizeof(v8::internal::JSFunction),
std::vector<std::unique_ptr<StructProperty>>(), std::vector<std::unique_ptr<StructProperty>>(),
d::PropertyKind::kSingle)); d::PropertyKind::kSingle));
// Add more items in the Locals pane representing the JS function name,
// source file name, and line & column numbers within the source file, so
// that the user doesn’t need to dig through the shared_function_info to
// find them.
intptr_t js_function_ptr = 0;
validity = memory_accessor(
frame_pointer + StandardFrameConstants::kFunctionOffset,
reinterpret_cast<void*>(&js_function_ptr), sizeof(intptr_t));
if (validity == d::MemoryAccessResult::kOk) {
TqJSFunction js_function(js_function_ptr);
auto shared_function_info_ptr =
js_function.GetSharedFunctionInfoValue(memory_accessor);
if (shared_function_info_ptr.validity == d::MemoryAccessResult::kOk) {
TqSharedFunctionInfo shared_function_info(
shared_function_info_ptr.value);
auto script_or_debug_info_ptr =
shared_function_info.GetScriptOrDebugInfoValue(memory_accessor);
if (script_or_debug_info_ptr.validity == d::MemoryAccessResult::kOk) {
// Make sure script_or_debug_info_ptr is script.
auto address = script_or_debug_info_ptr.value;
if (IsTypedHeapObjectInstanceTypeOf(address, memory_accessor,
i::InstanceType::SCRIPT_TYPE)) {
TqScript script(script_or_debug_info_ptr.value);
props.push_back(std::make_unique<ObjectProperty>(
"script_name", kObjectAsStoredInHeap, kObject,
script.GetNameAddress(), 1, i::kTaggedSize,
std::vector<std::unique_ptr<StructProperty>>(),
d::PropertyKind::kSingle));
props.push_back(std::make_unique<ObjectProperty>(
"script_source", kObjectAsStoredInHeap, kObject,
script.GetSourceAddress(), 1, i::kTaggedSize,
std::vector<std::unique_ptr<StructProperty>>(),
d::PropertyKind::kSingle));
}
}
auto name_or_scope_info_ptr =
shared_function_info.GetNameOrScopeInfoValue(memory_accessor);
if (name_or_scope_info_ptr.validity == d::MemoryAccessResult::kOk) {
auto scope_info_address = name_or_scope_info_ptr.value;
// Make sure name_or_scope_info_ptr is scope info.
if (IsTypedHeapObjectInstanceTypeOf(
scope_info_address, memory_accessor,
i::InstanceType::SCOPE_INFO_TYPE)) {
auto indexed_field_slice_function_variable_info =
TqDebugFieldSliceScopeInfoFunctionVariableInfo(
memory_accessor, scope_info_address);
if (indexed_field_slice_function_variable_info.validity ==
d::MemoryAccessResult::kOk) {
props.push_back(std::make_unique<ObjectProperty>(
"function_name", "v8::internal::TaggedValue",
"v8::internal::Object",
scope_info_address - i::kHeapObjectTag +
std::get<1>(
indexed_field_slice_function_variable_info.value),
std::get<2>(
indexed_field_slice_function_variable_info.value),
i::kTaggedSize,
std::vector<std::unique_ptr<StructProperty>>(),
d::PropertyKind::kSingle));
}
std::vector<std::unique_ptr<StructProperty>>
position_info_struct_field_list;
position_info_struct_field_list.push_back(
std::make_unique<StructProperty>(
"start", "v8::internal::TaggedValue",
"v8::internal::Object", 0, 0, 0));
position_info_struct_field_list.push_back(
std::make_unique<StructProperty>(
"end", "v8::internal::TaggedValue",
"v8::internal::Object", 4, 0, 0));
auto indexed_field_slice_position_info =
TqDebugFieldSliceScopeInfoPositionInfo(memory_accessor,
scope_info_address);
if (indexed_field_slice_position_info.validity ==
d::MemoryAccessResult::kOk) {
props.push_back(std::make_unique<ObjectProperty>(
"function_character_offset", "", "",
scope_info_address - i::kHeapObjectTag +
std::get<1>(indexed_field_slice_position_info.value),
std::get<2>(indexed_field_slice_position_info.value),
i::kTaggedSize, std::move(position_info_struct_field_list),
d::PropertyKind::kSingle));
}
}
}
}
}
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment