Reland "[v8windbg] Add more items in the Locals pane"

This is a reland of 19b62d0b4e

Fixing the misalignment issue founded in usban build by doing four-byte
comparison: compressing the "expected" values such as script.name() and
passing them to CheckProp as type Tagged_t

Original change's description:
> [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: Seth Brenith <seth.brenith@microsoft.com>
> Cr-Commit-Position: refs/heads/master@{#73282}

Change-Id: Idd77f61905651fbcfae5f5b590094639bc205834
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2744959
Reviewed-by: Seth Brenith <seth.brenith@microsoft.com>
Commit-Queue: Z Nguyen-Huu <duongn@microsoft.com>
Cr-Commit-Position: refs/heads/master@{#73359}
This commit is contained in:
Z Nguyen-Huu 2021-03-11 18:15:30 -08:00 committed by Commit Bot
parent d9d13b3814
commit d193e90c03
2 changed files with 124 additions and 2 deletions

View File

@ -422,9 +422,29 @@ static void FrameIterationCheck(
d::StackFrameResultPtr props = d::GetStackFrame(frame->fp(), &ReadMemory);
if (frame->is_java_script()) {
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",
"currently_executing_jsfunction", js_frame->function().ptr());
"currently_executing_jsfunction", js_function.ptr());
auto shared_function_info = js_function.shared();
auto script = i::Script::cast(shared_function_info.script());
CheckProp(*props->properties[1], "v8::internal::Object", "script_name",
static_cast<i::Tagged_t>(script.name().ptr()));
CheckProp(*props->properties[2], "v8::internal::Object", "script_source",
static_cast<i::Tagged_t>(script.source().ptr()));
auto scope_info = shared_function_info.scope_info();
CheckProp(*props->properties[3], "v8::internal::Object", "function_name",
static_cast<i::Tagged_t>(scope_info.FunctionName().ptr()));
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 {
CHECK_EQ(props->num_properties, 0);
}

View File

@ -14,6 +14,7 @@
#include "src/objects/string-inl.h"
#include "src/strings/unicode-inl.h"
#include "torque-generated/class-debug-readers.h"
#include "torque-generated/debug-macros.h"
namespace i = v8::internal;
@ -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,
const char* type_hint,
const d::HeapAddresses& heap_addresses) {
@ -654,6 +672,90 @@ std::unique_ptr<StackFrameResult> GetStackFrame(
sizeof(v8::internal::JSFunction),
std::vector<std::unique_ptr<StructProperty>>(),
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 doesnt 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", kObjectAsStoredInHeap, kObject,
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", kObjectAsStoredInHeap, kObject, 0, 0, 0));
position_info_struct_field_list.push_back(
std::make_unique<StructProperty>("end", kObjectAsStoredInHeap,
kObject, 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));
}
}
}
}
}
}
}