[profiler] Support WasmGC objects in heap snapshots
Since the heap snapshot generator is based on generic objects-visiting infrastructure, it already reported all objects, but it showed WasmGC objects as generic "system" objects. This patch adds proper categorization, including support for named types and fields. Bug: v8:7748 Change-Id: I1b0997059c9cf0290fe5d6c5402412ba09ecf143 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4181031 Auto-Submit: Jakob Kummerow <jkummerow@chromium.org> Commit-Queue: Camillo Bruni <cbruni@chromium.org> Reviewed-by: Camillo Bruni <cbruni@chromium.org> Cr-Commit-Position: refs/heads/main@{#85435}
This commit is contained in:
parent
186068ad3f
commit
4724f988ae
@ -596,6 +596,7 @@ class V8_EXPORT HeapGraphNode {
|
||||
kBigInt = 13, // BigInt.
|
||||
kObjectShape = 14, // Internal data used for tracking the shapes (or
|
||||
// "hidden classes") of JS objects.
|
||||
kWasmObject = 15, // A WasmGC struct or array.
|
||||
};
|
||||
|
||||
/** Returns node type (see HeapGraphNode::Type). */
|
||||
|
@ -41,6 +41,12 @@
|
||||
#include "src/profiler/heap-snapshot-generator-inl.h"
|
||||
#include "src/profiler/output-stream-writer.h"
|
||||
|
||||
#if V8_ENABLE_WEBASSEMBLY
|
||||
#include "src/wasm/names-provider.h"
|
||||
#include "src/wasm/string-builder.h"
|
||||
#include "src/wasm/wasm-objects.h"
|
||||
#endif // V8_ENABLE_WEBASSEMBLY
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
@ -385,6 +391,8 @@ const char* HeapEntry::TypeAsString() const {
|
||||
return "/bigint/";
|
||||
case kObjectShape:
|
||||
return "/object shape/";
|
||||
case kWasmObject:
|
||||
return "/wasm object/";
|
||||
default: return "???";
|
||||
}
|
||||
}
|
||||
@ -873,6 +881,23 @@ HeapEntry* V8HeapExplorer::AddEntry(HeapObject object) {
|
||||
} else if (InstanceTypeChecker::IsHeapNumber(instance_type)) {
|
||||
return AddEntry(object, HeapEntry::kHeapNumber, "heap number");
|
||||
}
|
||||
#if V8_ENABLE_WEBASSEMBLY
|
||||
if (InstanceTypeChecker::IsWasmObject(instance_type)) {
|
||||
WasmTypeInfo info = object.map().wasm_type_info();
|
||||
wasm::NamesProvider* names =
|
||||
info.instance().module_object().native_module()->GetNamesProvider();
|
||||
wasm::StringBuilder sb;
|
||||
if (InstanceTypeChecker::IsWasmStruct(instance_type)) {
|
||||
sb << "wasm struct / ";
|
||||
} else {
|
||||
sb << "wasm array / ";
|
||||
}
|
||||
names->PrintTypeName(sb, info.type_index());
|
||||
sb << '\0';
|
||||
const char* name = names_->GetCopy(sb.start());
|
||||
return AddEntry(object, HeapEntry::kWasmObject, name);
|
||||
}
|
||||
#endif // V8_ENABLE_WEBASSEMBLY
|
||||
return AddEntry(object, GetSystemEntryType(object),
|
||||
GetSystemEntryName(object));
|
||||
}
|
||||
@ -1192,6 +1217,12 @@ void V8HeapExplorer::ExtractReferences(HeapEntry* entry, HeapObject obj) {
|
||||
ExtractBytecodeArrayReferences(entry, BytecodeArray::cast(obj));
|
||||
} else if (obj.IsScopeInfo()) {
|
||||
ExtractScopeInfoReferences(entry, ScopeInfo::cast(obj));
|
||||
#if V8_ENABLE_WEBASSEMBLY
|
||||
} else if (obj.IsWasmStruct()) {
|
||||
ExtractWasmStructReferences(WasmStruct::cast(obj), entry);
|
||||
} else if (obj.IsWasmArray()) {
|
||||
ExtractWasmArrayReferences(WasmArray::cast(obj), entry);
|
||||
#endif // V8_ENABLE_WEBASSEMBLY
|
||||
}
|
||||
}
|
||||
|
||||
@ -1936,6 +1967,39 @@ void V8HeapExplorer::ExtractInternalReferences(JSObject js_obj,
|
||||
}
|
||||
}
|
||||
|
||||
#if V8_ENABLE_WEBASSEMBLY
|
||||
|
||||
void V8HeapExplorer::ExtractWasmStructReferences(WasmStruct obj,
|
||||
HeapEntry* entry) {
|
||||
wasm::StructType* type = obj.type();
|
||||
WasmTypeInfo info = obj.map().wasm_type_info();
|
||||
wasm::NamesProvider* names =
|
||||
info.instance().module_object().native_module()->GetNamesProvider();
|
||||
for (uint32_t i = 0; i < type->field_count(); i++) {
|
||||
if (!type->field(i).is_reference()) continue;
|
||||
wasm::StringBuilder sb;
|
||||
names->PrintFieldName(sb, info.type_index(), i);
|
||||
sb << '\0';
|
||||
const char* field_name = names_->GetCopy(sb.start());
|
||||
int field_offset = type->field_offset(i);
|
||||
Object value = obj.RawField(field_offset).load(entry->isolate());
|
||||
HeapEntry* value_entry = GetEntry(value);
|
||||
entry->SetNamedReference(HeapGraphEdge::kProperty, field_name, value_entry,
|
||||
generator_);
|
||||
MarkVisitedField(WasmStruct::kHeaderSize + field_offset);
|
||||
}
|
||||
}
|
||||
void V8HeapExplorer::ExtractWasmArrayReferences(WasmArray obj,
|
||||
HeapEntry* entry) {
|
||||
if (!obj.type()->element_type().is_reference()) return;
|
||||
for (uint32_t i = 0; i < obj.length(); i++) {
|
||||
SetElementReference(entry, i, obj.ElementSlot(i).load(entry->isolate()));
|
||||
MarkVisitedField(obj.element_offset(i));
|
||||
}
|
||||
}
|
||||
|
||||
#endif // V8_ENABLE_WEBASSEMBLY
|
||||
|
||||
JSFunction V8HeapExplorer::GetConstructor(Isolate* isolate,
|
||||
JSReceiver receiver) {
|
||||
DisallowGarbageCollection no_gc;
|
||||
@ -3001,7 +3065,8 @@ void HeapSnapshotJSONSerializer::SerializeSnapshot() {
|
||||
JSON_S("sliced string") ","
|
||||
JSON_S("symbol") ","
|
||||
JSON_S("bigint") ","
|
||||
JSON_S("object shape")) ","
|
||||
JSON_S("object shape") ","
|
||||
JSON_S("wasm object")) ","
|
||||
JSON_S("string") ","
|
||||
JSON_S("number") ","
|
||||
JSON_S("number") ","
|
||||
|
@ -120,6 +120,8 @@ class HeapEntry {
|
||||
kSymbol = v8::HeapGraphNode::kSymbol,
|
||||
kBigInt = v8::HeapGraphNode::kBigInt,
|
||||
kObjectShape = v8::HeapGraphNode::kObjectShape,
|
||||
kWasmObject = v8::HeapGraphNode::kWasmObject,
|
||||
kNumTypes,
|
||||
};
|
||||
|
||||
HeapEntry(HeapSnapshot* snapshot, int index, Type type, const char* name,
|
||||
@ -189,7 +191,8 @@ class HeapEntry {
|
||||
V8_INLINE std::vector<HeapGraphEdge*>::iterator children_end() const;
|
||||
const char* TypeAsString() const;
|
||||
|
||||
unsigned type_: 4;
|
||||
static_assert(kNumTypes <= 1 << 4);
|
||||
unsigned type_ : 4;
|
||||
unsigned index_ : 28; // Supports up to ~250M objects.
|
||||
union {
|
||||
// The count is used during the snapshot build phase,
|
||||
@ -466,6 +469,11 @@ class V8_EXPORT_PRIVATE V8HeapExplorer : public HeapEntriesAllocator {
|
||||
void ExtractElementReferences(JSObject js_obj, HeapEntry* entry);
|
||||
void ExtractInternalReferences(JSObject js_obj, HeapEntry* entry);
|
||||
|
||||
#if V8_ENABLE_WEBASSEMBLY
|
||||
void ExtractWasmStructReferences(WasmStruct obj, HeapEntry* entry);
|
||||
void ExtractWasmArrayReferences(WasmArray obj, HeapEntry* entry);
|
||||
#endif // V8_ENABLE_WEBASSEMBLY
|
||||
|
||||
bool IsEssentialObject(Object object);
|
||||
bool IsEssentialHiddenReference(Object parent, int field_offset);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user