diff options
Diffstat (limited to 'chromium/v8/tools/v8windbg')
8 files changed, 195 insertions, 11 deletions
diff --git a/chromium/v8/tools/v8windbg/base/utilities.cc b/chromium/v8/tools/v8windbg/base/utilities.cc index a59e95f46fd..1f0e2bc6708 100644 --- a/chromium/v8/tools/v8windbg/base/utilities.cc +++ b/chromium/v8/tools/v8windbg/base/utilities.cc @@ -133,6 +133,15 @@ HRESULT UnboxULong64(IModelObject* object, ULONG64* value, bool convert) { return S_OK; } +HRESULT GetInt32(IDebugHostConstant* object, int* value) { + variant_t variant; + RETURN_IF_FAIL(object->GetValue(&variant)); + + if (variant.vt != VT_I4) return E_FAIL; + *value = variant.ullVal; + return S_OK; +} + HRESULT CreateInt32(int value, IModelObject** pp_int) { HRESULT hr = S_OK; *pp_int = nullptr; diff --git a/chromium/v8/tools/v8windbg/base/utilities.h b/chromium/v8/tools/v8windbg/base/utilities.h index e26bb287804..06af6c35875 100644 --- a/chromium/v8/tools/v8windbg/base/utilities.h +++ b/chromium/v8/tools/v8windbg/base/utilities.h @@ -55,6 +55,8 @@ HRESULT CreateULong64(ULONG64 value, IModelObject** pp_int); HRESULT UnboxULong64(IModelObject* object, ULONG64* value, bool convert = false); +HRESULT GetInt32(IDebugHostConstant* object, int* value); + HRESULT CreateInt32(int value, IModelObject** pp_int); HRESULT CreateUInt32(uint32_t value, IModelObject** pp_int); diff --git a/chromium/v8/tools/v8windbg/src/object-inspection.cc b/chromium/v8/tools/v8windbg/src/object-inspection.cc index ce0370a697f..6f90614bd5c 100644 --- a/chromium/v8/tools/v8windbg/src/object-inspection.cc +++ b/chromium/v8/tools/v8windbg/src/object-inspection.cc @@ -585,6 +585,79 @@ IFACEMETHODIMP V8LocalValueProperty::SetValue( return E_NOTIMPL; } +IFACEMETHODIMP V8InternalCompilerNodeIdProperty::GetValue( + PCWSTR pwsz_key, IModelObject* p_v8_compiler_node_instance, + IModelObject** pp_value) noexcept { + WRL::ComPtr<IModelObject> sp_bit_field; + RETURN_IF_FAIL(p_v8_compiler_node_instance->GetRawValue( + SymbolKind::SymbolField, L"bit_field_", RawSearchNone, &sp_bit_field)); + + uint64_t bit_field_value; + RETURN_IF_FAIL( + UnboxULong64(sp_bit_field.Get(), &bit_field_value, true /*convert*/)); + + WRL::ComPtr<IDebugHostContext> sp_host_context; + RETURN_IF_FAIL(p_v8_compiler_node_instance->GetContext(&sp_host_context)); + + WRL::ComPtr<IDebugHostType> sp_id_field_type; + RETURN_IF_FAIL(Extension::Current() + ->GetV8Module(sp_host_context) + ->FindTypeByName(L"v8::internal::compiler::Node::IdField", + &sp_id_field_type)); + + // Get 2nd template parameter as 24 in class. + // v8::base::BitField<v8::internal::compiler::NodeId, 0, 24>. + bool is_generic; + RETURN_IF_FAIL(sp_id_field_type->IsGeneric(&is_generic)); + if (!is_generic) return E_FAIL; + + WRL::ComPtr<IDebugHostSymbol> sp_k_size_arg; + RETURN_IF_FAIL(sp_id_field_type->GetGenericArgumentAt(2, &sp_k_size_arg)); + + WRL::ComPtr<IDebugHostConstant> sp_k_size_constant; + RETURN_IF_FAIL(sp_k_size_arg.As(&sp_k_size_constant)); + + int k_size; + RETURN_IF_FAIL(GetInt32(sp_k_size_constant.Get(), &k_size)); + + // Compute node_id. + uint32_t node_id = bit_field_value & (0xFFFFFFFF >> k_size); + RETURN_IF_FAIL(CreateUInt32(node_id, pp_value)); + + return S_OK; +} + +IFACEMETHODIMP V8InternalCompilerNodeIdProperty::SetValue( + PCWSTR /*pwsz_key*/, IModelObject* /*p_process_instance*/, + IModelObject* /*p_value*/) noexcept { + return E_NOTIMPL; +} + +IFACEMETHODIMP V8InternalCompilerBitsetNameProperty::GetValue( + PCWSTR pwsz_key, IModelObject* p_v8_compiler_type_instance, + IModelObject** pp_value) noexcept { + WRL::ComPtr<IModelObject> sp_payload; + RETURN_IF_FAIL(p_v8_compiler_type_instance->GetRawValue( + SymbolKind::SymbolField, L"payload_", RawSearchNone, &sp_payload)); + + uint64_t payload_value; + RETURN_IF_FAIL( + UnboxULong64(sp_payload.Get(), &payload_value, true /*convert*/)); + + const char* bitset_name = ::BitsetName(payload_value); + if (!bitset_name) return E_FAIL; + std::string name(bitset_name); + RETURN_IF_FAIL(CreateString(ConvertToU16String(name), pp_value)); + + return S_OK; +} + +IFACEMETHODIMP V8InternalCompilerBitsetNameProperty::SetValue( + PCWSTR /*pwsz_key*/, IModelObject* /*p_process_instance*/, + IModelObject* /*p_value*/) noexcept { + return E_NOTIMPL; +} + constexpr wchar_t usage[] = LR"(Invalid arguments. First argument should be a uint64 representing the tagged value to investigate. diff --git a/chromium/v8/tools/v8windbg/src/object-inspection.h b/chromium/v8/tools/v8windbg/src/object-inspection.h index 27283ca5569..a280b05cade 100644 --- a/chromium/v8/tools/v8windbg/src/object-inspection.h +++ b/chromium/v8/tools/v8windbg/src/object-inspection.h @@ -245,6 +245,38 @@ class V8LocalValueProperty IModelObject* /*p_value*/); }; +// The implemention of the "NodeId" getter for v8::internal::compiler::Node +// type. +class V8InternalCompilerNodeIdProperty + : public WRL::RuntimeClass< + WRL::RuntimeClassFlags<WRL::RuntimeClassType::ClassicCom>, + IModelPropertyAccessor> { + public: + IFACEMETHOD(GetValue) + (PCWSTR pwsz_key, IModelObject* p_v8_object_instance, + IModelObject** pp_value); + + IFACEMETHOD(SetValue) + (PCWSTR /*pwsz_key*/, IModelObject* /*p_process_instance*/, + IModelObject* /*p_value*/); +}; + +// The implemention of the "bitset_name" getter for v8::internal::compiler::Type +// type. +class V8InternalCompilerBitsetNameProperty + : public WRL::RuntimeClass< + WRL::RuntimeClassFlags<WRL::RuntimeClassType::ClassicCom>, + IModelPropertyAccessor> { + public: + IFACEMETHOD(GetValue) + (PCWSTR pwsz_key, IModelObject* p_v8_compiler_type_instance, + IModelObject** pp_value); + + IFACEMETHOD(SetValue) + (PCWSTR /*pwsz_key*/, IModelObject* /*p_process_instance*/, + IModelObject* /*p_value*/); +}; + // A way that someone can directly inspect a tagged value, even if that value // isn't in memory (from a register, or the user's imagination, etc.). class InspectV8ObjectMethod diff --git a/chromium/v8/tools/v8windbg/src/v8-debug-helper-interop.cc b/chromium/v8/tools/v8windbg/src/v8-debug-helper-interop.cc index 4a8dcc9add7..0767ff5f09e 100644 --- a/chromium/v8/tools/v8windbg/src/v8-debug-helper-interop.cc +++ b/chromium/v8/tools/v8windbg/src/v8-debug-helper-interop.cc @@ -155,3 +155,5 @@ std::vector<std::u16string> ListObjectClasses() { } return result; } + +const char* BitsetName(uint64_t payload) { return d::BitsetName(payload); } diff --git a/chromium/v8/tools/v8windbg/src/v8-debug-helper-interop.h b/chromium/v8/tools/v8windbg/src/v8-debug-helper-interop.h index 96bd59b30ea..9208f098327 100644 --- a/chromium/v8/tools/v8windbg/src/v8-debug-helper-interop.h +++ b/chromium/v8/tools/v8windbg/src/v8-debug-helper-interop.h @@ -135,4 +135,6 @@ inline uint64_t ExpandCompressedPointer(uint32_t ptr) { return ptr; } std::vector<std::u16string> ListObjectClasses(); +const char* BitsetName(uint64_t payload); + #endif // V8_TOOLS_V8WINDBG_SRC_V8_DEBUG_HELPER_INTEROP_H_ diff --git a/chromium/v8/tools/v8windbg/src/v8windbg-extension.cc b/chromium/v8/tools/v8windbg/src/v8windbg-extension.cc index 68c90d2833b..58a520cff1f 100644 --- a/chromium/v8/tools/v8windbg/src/v8windbg-extension.cc +++ b/chromium/v8/tools/v8windbg/src/v8windbg-extension.cc @@ -215,7 +215,8 @@ HRESULT Extension::Initialize() { &sp_object_type_signature)); RETURN_IF_FAIL(sp_data_model_manager->RegisterModelForTypeSignature( sp_object_type_signature.Get(), sp_object_data_model_.Get())); - registered_object_types_.push_back(sp_object_type_signature); + registered_types_.push_back( + {sp_object_type_signature.Get(), sp_object_data_model_.Get()}); } // Create an instance of the DataModel parent for custom iterable fields. @@ -244,7 +245,7 @@ HRESULT Extension::Initialize() { sp_debug_host_symbols->CreateTypeSignature(name, nullptr, &signature)); RETURN_IF_FAIL(sp_data_model_manager->RegisterModelForTypeSignature( signature.Get(), sp_local_data_model_.Get())); - registered_handle_types_.push_back(signature); + registered_types_.push_back({signature.Get(), sp_local_data_model_.Get()}); } // Add the 'Value' property to the parent model. @@ -279,6 +280,46 @@ HRESULT Extension::Initialize() { RETURN_IF_FAIL(OverrideLocalsGetter(stack_frame.Get(), L"Parameters", /*is_parameters=*/true)); + // Add node_id property for v8::internal::compiler::Node. + RETURN_IF_FAIL( + RegisterAndAddPropertyForClass<V8InternalCompilerNodeIdProperty>( + L"v8::internal::compiler::Node", L"node_id", + sp_compiler_node_data_model_)); + + // Add bitset_name property for v8::internal::compiler::Type. + RETURN_IF_FAIL( + RegisterAndAddPropertyForClass<V8InternalCompilerBitsetNameProperty>( + L"v8::internal::compiler::Type", L"bitset_name", + sp_compiler_type_data_model_)); + + return S_OK; +} + +template <class PropertyClass> +HRESULT Extension::RegisterAndAddPropertyForClass( + const wchar_t* class_name, const wchar_t* property_name, + WRL::ComPtr<IModelObject> sp_data_model) { + // Create an instance of the DataModel parent class. + auto instance_data_model{WRL::Make<V8LocalDataModel>()}; + RETURN_IF_FAIL(sp_data_model_manager->CreateDataModelObject( + instance_data_model.Get(), &sp_data_model)); + + // Register that parent model. + WRL::ComPtr<IDebugHostTypeSignature> class_signature; + RETURN_IF_FAIL(sp_debug_host_symbols->CreateTypeSignature(class_name, nullptr, + &class_signature)); + RETURN_IF_FAIL(sp_data_model_manager->RegisterModelForTypeSignature( + class_signature.Get(), sp_data_model.Get())); + registered_types_.push_back({class_signature.Get(), sp_data_model.Get()}); + + // Add the property to the parent model. + auto property{WRL::Make<PropertyClass>()}; + WRL::ComPtr<IModelObject> sp_property_model; + RETURN_IF_FAIL(CreateProperty(sp_data_model_manager.Get(), property.Get(), + &sp_property_model)); + RETURN_IF_FAIL( + sp_data_model->SetKey(property_name, sp_property_model.Get(), nullptr)); + return S_OK; } @@ -318,18 +359,24 @@ Extension::PropertyOverride::PropertyOverride(const PropertyOverride&) = Extension::PropertyOverride& Extension::PropertyOverride::operator=( const PropertyOverride&) = default; +Extension::RegistrationType::RegistrationType() = default; +Extension::RegistrationType::RegistrationType( + IDebugHostTypeSignature* sp_signature, IModelObject* sp_data_model) + : sp_signature(sp_signature), sp_data_model(sp_data_model) {} +Extension::RegistrationType::~RegistrationType() = default; +Extension::RegistrationType::RegistrationType(const RegistrationType&) = + default; +Extension::RegistrationType& Extension::RegistrationType::operator=( + const RegistrationType&) = default; + Extension::~Extension() { sp_debug_host_extensibility->DestroyFunctionAlias(pcur_isolate); sp_debug_host_extensibility->DestroyFunctionAlias(plist_chunks); sp_debug_host_extensibility->DestroyFunctionAlias(pv8_object); - for (const auto& registered : registered_object_types_) { - sp_data_model_manager->UnregisterModelForTypeSignature( - sp_object_data_model_.Get(), registered.Get()); - } - for (const auto& registered : registered_handle_types_) { + for (const auto& registered : registered_types_) { sp_data_model_manager->UnregisterModelForTypeSignature( - sp_local_data_model_.Get(), registered.Get()); + registered.sp_data_model.Get(), registered.sp_signature.Get()); } for (const auto& override : overridden_properties_) { diff --git a/chromium/v8/tools/v8windbg/src/v8windbg-extension.h b/chromium/v8/tools/v8windbg/src/v8windbg-extension.h index d54f43c847e..46331611523 100644 --- a/chromium/v8/tools/v8windbg/src/v8windbg-extension.h +++ b/chromium/v8/tools/v8windbg/src/v8windbg-extension.h @@ -46,6 +46,11 @@ class Extension { HRESULT OverrideLocalsGetter(IModelObject* parent, const wchar_t* key_name, bool is_parameters); + template <class PropertyClass> + HRESULT RegisterAndAddPropertyForClass( + const wchar_t* class_name, const wchar_t* property_name, + WRL::ComPtr<IModelObject> sp_data_model); + // A property that has been overridden by this extension. The original value // must be put back in place during ~Extension. struct PropertyOverride { @@ -62,20 +67,32 @@ class Extension { WRL::ComPtr<IKeyStore> original_metadata; }; + struct RegistrationType { + RegistrationType(); + RegistrationType(IDebugHostTypeSignature* sp_signature, + IModelObject* sp_data_model); + ~RegistrationType(); + RegistrationType(const RegistrationType&); + RegistrationType& operator=(const RegistrationType&); + + WRL::ComPtr<IDebugHostTypeSignature> sp_signature; + WRL::ComPtr<IModelObject> sp_data_model; + }; + static std::unique_ptr<Extension> current_extension_; WRL::ComPtr<IModelObject> sp_object_data_model_; WRL::ComPtr<IModelObject> sp_local_data_model_; + WRL::ComPtr<IModelObject> sp_compiler_node_data_model_; + WRL::ComPtr<IModelObject> sp_compiler_type_data_model_; WRL::ComPtr<IModelObject> sp_indexed_field_model_; WRL::ComPtr<IDebugHostModule> sp_v8_module_; std::unordered_map<std::u16string, WRL::ComPtr<IDebugHostType>> cached_v8_module_types_; - std::vector<WRL::ComPtr<IDebugHostTypeSignature>> registered_object_types_; - std::vector<WRL::ComPtr<IDebugHostTypeSignature>> registered_handle_types_; + std::vector<RegistrationType> registered_types_; std::vector<PropertyOverride> overridden_properties_; WRL::ComPtr<IDebugHostContext> sp_v8_module_ctx_; ULONG v8_module_proc_id_; }; - #endif // V8_TOOLS_V8WINDBG_SRC_V8WINDBG_EXTENSION_H_ |