diff options
Diffstat (limited to 'deps/v8/src/profiler/heap-snapshot-generator.cc')
-rw-r--r-- | deps/v8/src/profiler/heap-snapshot-generator.cc | 485 |
1 files changed, 255 insertions, 230 deletions
diff --git a/deps/v8/src/profiler/heap-snapshot-generator.cc b/deps/v8/src/profiler/heap-snapshot-generator.cc index 57f620f4ec..17daea1964 100644 --- a/deps/v8/src/profiler/heap-snapshot-generator.cc +++ b/deps/v8/src/profiler/heap-snapshot-generator.cc @@ -7,7 +7,7 @@ #include <utility> #include "src/api-inl.h" -#include "src/code-stubs.h" +#include "src/assembler-inl.h" #include "src/conversions.h" #include "src/debug/debug.h" #include "src/global-handles.h" @@ -15,6 +15,8 @@ #include "src/objects-body-descriptors.h" #include "src/objects-inl.h" #include "src/objects/api-callbacks.h" +#include "src/objects/cell-inl.h" +#include "src/objects/feedback-cell-inl.h" #include "src/objects/hash-table-inl.h" #include "src/objects/js-array-buffer-inl.h" #include "src/objects/js-array-inl.h" @@ -23,6 +25,8 @@ #include "src/objects/js-promise-inl.h" #include "src/objects/js-regexp-inl.h" #include "src/objects/literal-objects-inl.h" +#include "src/objects/slots-inl.h" +#include "src/objects/struct-inl.h" #include "src/profiler/allocation-tracker.h" #include "src/profiler/heap-profiler.h" #include "src/profiler/heap-snapshot-generator-inl.h" @@ -177,10 +181,10 @@ const char* HeapEntry::TypeAsString() { HeapSnapshot::HeapSnapshot(HeapProfiler* profiler) : profiler_(profiler) { // It is very important to keep objects that form a heap snapshot // as small as possible. Check assumptions about data structure sizes. - STATIC_ASSERT((kPointerSize == 4 && sizeof(HeapGraphEdge) == 12) || - (kPointerSize == 8 && sizeof(HeapGraphEdge) == 24)); - STATIC_ASSERT((kPointerSize == 4 && sizeof(HeapEntry) == 28) || - (kPointerSize == 8 && sizeof(HeapEntry) == 40)); + STATIC_ASSERT((kTaggedSize == 4 && sizeof(HeapGraphEdge) == 12) || + (kTaggedSize == 8 && sizeof(HeapGraphEdge) == 24)); + STATIC_ASSERT((kTaggedSize == 4 && sizeof(HeapEntry) == 28) || + (kTaggedSize == 8 && sizeof(HeapEntry) == 40)); memset(&gc_subroot_entries_, 0, sizeof(gc_subroot_entries_)); } @@ -389,7 +393,7 @@ void HeapObjectsMap::UpdateHeapObjectsMap() { heap_->PreciseCollectAllGarbage(Heap::kNoGCFlags, GarbageCollectionReason::kHeapProfiler); HeapIterator iterator(heap_); - for (HeapObject* obj = iterator.next(); obj != nullptr; + for (HeapObject obj = iterator.next(); !obj.is_null(); obj = iterator.next()) { FindOrAddEntry(obj->address(), obj->Size()); if (FLAG_heap_profiler_trace_objects) { @@ -511,31 +515,32 @@ V8HeapExplorer::V8HeapExplorer(HeapSnapshot* snapshot, global_object_name_resolver_(resolver) {} HeapEntry* V8HeapExplorer::AllocateEntry(HeapThing ptr) { - return AddEntry(reinterpret_cast<HeapObject*>(ptr)); + return AddEntry(HeapObject::cast(Object(reinterpret_cast<Address>(ptr)))); } -void V8HeapExplorer::ExtractLocation(HeapEntry* entry, HeapObject* object) { +void V8HeapExplorer::ExtractLocation(HeapEntry* entry, HeapObject object) { if (object->IsJSFunction()) { - JSFunction* func = JSFunction::cast(object); + JSFunction func = JSFunction::cast(object); ExtractLocationForJSFunction(entry, func); } else if (object->IsJSGeneratorObject()) { - JSGeneratorObject* gen = JSGeneratorObject::cast(object); + JSGeneratorObject gen = JSGeneratorObject::cast(object); ExtractLocationForJSFunction(entry, gen->function()); } else if (object->IsJSObject()) { - JSObject* obj = JSObject::cast(object); - JSFunction* maybe_constructor = GetConstructor(obj); + JSObject obj = JSObject::cast(object); + JSFunction maybe_constructor = GetConstructor(obj); - if (maybe_constructor) + if (!maybe_constructor.is_null()) { ExtractLocationForJSFunction(entry, maybe_constructor); + } } } void V8HeapExplorer::ExtractLocationForJSFunction(HeapEntry* entry, - JSFunction* func) { + JSFunction func) { if (!func->shared()->script()->IsScript()) return; - Script* script = Script::cast(func->shared()->script()); + Script script = Script::cast(func->shared()->script()); int scriptId = script->id(); int start = func->shared()->StartPosition(); int line = script->GetLineNumber(start); @@ -543,16 +548,16 @@ void V8HeapExplorer::ExtractLocationForJSFunction(HeapEntry* entry, snapshot_->AddLocation(entry, scriptId, line, col); } -HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object) { +HeapEntry* V8HeapExplorer::AddEntry(HeapObject object) { if (object->IsJSFunction()) { - JSFunction* func = JSFunction::cast(object); - SharedFunctionInfo* shared = func->shared(); + JSFunction func = JSFunction::cast(object); + SharedFunctionInfo shared = func->shared(); const char* name = names_->GetName(shared->Name()); return AddEntry(object, HeapEntry::kClosure, name); } else if (object->IsJSBoundFunction()) { return AddEntry(object, HeapEntry::kClosure, "native_bind"); } else if (object->IsJSRegExp()) { - JSRegExp* re = JSRegExp::cast(object); + JSRegExp re = JSRegExp::cast(object); return AddEntry(object, HeapEntry::kRegExp, names_->GetName(re->Pattern())); @@ -567,7 +572,7 @@ HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object) { } return AddEntry(object, HeapEntry::kObject, name); } else if (object->IsString()) { - String* string = String::cast(object); + String string = String::cast(object); if (string->IsConsString()) { return AddEntry(object, HeapEntry::kConsString, "(concatenated string)"); } else if (string->IsSlicedString()) { @@ -586,10 +591,10 @@ HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object) { } else if (object->IsCode()) { return AddEntry(object, HeapEntry::kCode, ""); } else if (object->IsSharedFunctionInfo()) { - String* name = SharedFunctionInfo::cast(object)->Name(); + String name = SharedFunctionInfo::cast(object)->Name(); return AddEntry(object, HeapEntry::kCode, names_->GetName(name)); } else if (object->IsScript()) { - Object* name = Script::cast(object)->name(); + Object name = Script::cast(object)->name(); return AddEntry( object, HeapEntry::kCode, name->IsString() ? names_->GetName(String::cast(name)) : ""); @@ -606,8 +611,7 @@ HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object) { return AddEntry(object, HeapEntry::kHidden, GetSystemEntryName(object)); } -HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object, - HeapEntry::Type type, +HeapEntry* V8HeapExplorer::AddEntry(HeapObject object, HeapEntry::Type type, const char* name) { return AddEntry(object->address(), type, name, object->Size()); } @@ -627,7 +631,7 @@ HeapEntry* V8HeapExplorer::AddEntry(Address address, return snapshot_->AddEntry(type, name, object_id, size, trace_node_id); } -const char* V8HeapExplorer::GetSystemEntryName(HeapObject* object) { +const char* V8HeapExplorer::GetSystemEntryName(HeapObject object) { switch (object->map()->instance_type()) { case MAP_TYPE: switch (Map::cast(object)->instance_type()) { @@ -655,56 +659,72 @@ const char* V8HeapExplorer::GetSystemEntryName(HeapObject* object) { int V8HeapExplorer::EstimateObjectsCount() { HeapIterator it(heap_, HeapIterator::kFilterUnreachable); int objects_count = 0; - while (it.next()) ++objects_count; + while (!it.next().is_null()) ++objects_count; return objects_count; } class IndexedReferencesExtractor : public ObjectVisitor { public: - IndexedReferencesExtractor(V8HeapExplorer* generator, HeapObject* parent_obj, + IndexedReferencesExtractor(V8HeapExplorer* generator, HeapObject parent_obj, HeapEntry* parent) : generator_(generator), parent_obj_(parent_obj), - parent_start_(HeapObject::RawField(parent_obj_, 0)), - parent_end_(HeapObject::RawField(parent_obj_, parent_obj_->Size())), - parent_(parent) {} - void VisitPointers(HeapObject* host, Object** start, Object** end) override { - VisitPointers(host, reinterpret_cast<MaybeObject**>(start), - reinterpret_cast<MaybeObject**>(end)); - } - void VisitPointers(HeapObject* host, MaybeObject** start, - MaybeObject** end) override { - int next_index = 0; - for (MaybeObject** p = start; p < end; p++) { - int index = static_cast<int>(reinterpret_cast<Object**>(p) - - HeapObject::RawField(parent_obj_, 0)); - ++next_index; - // |p| could be outside of the object, e.g., while visiting RelocInfo of - // code objects. - if (reinterpret_cast<Object**>(p) >= parent_start_ && - reinterpret_cast<Object**>(p) < parent_end_ && - generator_->visited_fields_[index]) { - generator_->visited_fields_[index] = false; + parent_start_(HeapObject::RawMaybeWeakField(parent_obj_, 0)), + parent_end_( + HeapObject::RawMaybeWeakField(parent_obj_, parent_obj_->Size())), + parent_(parent), + next_index_(0) {} + void VisitPointers(HeapObject host, ObjectSlot start, + ObjectSlot end) override { + VisitPointers(host, MaybeObjectSlot(start), MaybeObjectSlot(end)); + } + void VisitPointers(HeapObject host, MaybeObjectSlot start, + MaybeObjectSlot end) override { + // [start,end) must be a sub-region of [parent_start_, parent_end), i.e. + // all the slots must point inside the object. + CHECK_LE(parent_start_, start); + CHECK_LE(end, parent_end_); + for (MaybeObjectSlot p = start; p < end; ++p) { + int field_index = static_cast<int>(p - parent_start_); + if (generator_->visited_fields_[field_index]) { + generator_->visited_fields_[field_index] = false; continue; } - HeapObject* heap_object; - if ((*p)->GetHeapObjectIfWeak(&heap_object) || - (*p)->GetHeapObjectIfStrong(&heap_object)) { - generator_->SetHiddenReference(parent_obj_, parent_, next_index, - heap_object, index * kPointerSize); + HeapObject heap_object; + if ((*p)->GetHeapObject(&heap_object)) { + VisitHeapObjectImpl(heap_object, field_index); } } } + void VisitCodeTarget(Code host, RelocInfo* rinfo) override { + Code target = Code::GetCodeFromTargetAddress(rinfo->target_address()); + VisitHeapObjectImpl(target, -1); + } + + void VisitEmbeddedPointer(Code host, RelocInfo* rinfo) override { + VisitHeapObjectImpl(rinfo->target_object(), -1); + } + private: + V8_INLINE void VisitHeapObjectImpl(HeapObject heap_object, int field_index) { + DCHECK_LE(-1, field_index); + // The last parameter {field_offset} is only used to check some well-known + // skipped references, so passing -1 * kTaggedSize for objects embedded + // into code is fine. + generator_->SetHiddenReference(parent_obj_, parent_, next_index_++, + heap_object, field_index * kTaggedSize); + } + V8HeapExplorer* generator_; - HeapObject* parent_obj_; - Object** parent_start_; - Object** parent_end_; + HeapObject parent_obj_; + MaybeObjectSlot parent_start_; + MaybeObjectSlot parent_end_; HeapEntry* parent_; + int next_index_; }; -void V8HeapExplorer::ExtractReferences(HeapEntry* entry, HeapObject* obj) { +void V8HeapExplorer::ExtractReferences(HeapEntry* entry, HeapObject obj) { if (obj->IsJSGlobalProxy()) { ExtractJSGlobalProxyReferences(entry, JSGlobalProxy::cast(obj)); } else if (obj->IsJSArrayBuffer()) { @@ -753,6 +773,8 @@ void V8HeapExplorer::ExtractReferences(HeapEntry* entry, HeapObject* obj) { entry, ArrayBoilerplateDescription::cast(obj)); } else if (obj->IsFeedbackVector()) { ExtractFeedbackVectorReferences(entry, FeedbackVector::cast(obj)); + } else if (obj->IsDescriptorArray()) { + ExtractDescriptorArrayReferences(entry, DescriptorArray::cast(obj)); } else if (obj->IsWeakFixedArray()) { ExtractWeakArrayReferences(WeakFixedArray::kHeaderSize, entry, WeakFixedArray::cast(obj)); @@ -769,14 +791,14 @@ void V8HeapExplorer::ExtractReferences(HeapEntry* entry, HeapObject* obj) { } void V8HeapExplorer::ExtractJSGlobalProxyReferences(HeapEntry* entry, - JSGlobalProxy* proxy) { + JSGlobalProxy proxy) { SetInternalReference(entry, "native_context", proxy->native_context(), JSGlobalProxy::kNativeContextOffset); } void V8HeapExplorer::ExtractJSObjectReferences(HeapEntry* entry, - JSObject* js_obj) { - HeapObject* obj = js_obj; + JSObject js_obj) { + HeapObject obj = js_obj; ExtractPropertyReferences(js_obj, entry); ExtractElementReferences(js_obj, entry); ExtractInternalReferences(js_obj, entry); @@ -784,7 +806,7 @@ void V8HeapExplorer::ExtractJSObjectReferences(HeapEntry* entry, ReadOnlyRoots roots(heap_); SetPropertyReference(entry, roots.proto_string(), iter.GetCurrent()); if (obj->IsJSBoundFunction()) { - JSBoundFunction* js_fun = JSBoundFunction::cast(obj); + JSBoundFunction js_fun = JSBoundFunction::cast(obj); TagObject(js_fun->bound_arguments(), "(bound arguments)"); SetInternalReference(entry, "bindings", js_fun->bound_arguments(), JSBoundFunction::kBoundArgumentsOffset); @@ -793,15 +815,15 @@ void V8HeapExplorer::ExtractJSObjectReferences(HeapEntry* entry, SetInternalReference(entry, "bound_function", js_fun->bound_target_function(), JSBoundFunction::kBoundTargetFunctionOffset); - FixedArray* bindings = js_fun->bound_arguments(); + FixedArray bindings = js_fun->bound_arguments(); for (int i = 0; i < bindings->length(); i++) { const char* reference_name = names_->GetFormatted("bound_argument_%d", i); SetNativeBindReference(entry, reference_name, bindings->get(i)); } } else if (obj->IsJSFunction()) { - JSFunction* js_fun = JSFunction::cast(js_obj); + JSFunction js_fun = JSFunction::cast(js_obj); if (js_fun->has_prototype_slot()) { - Object* proto_or_map = js_fun->prototype_or_initial_map(); + Object proto_or_map = js_fun->prototype_or_initial_map(); if (!proto_or_map->IsTheHole(heap_->isolate())) { if (!proto_or_map->IsMap()) { SetPropertyReference(entry, roots.prototype_string(), proto_or_map, @@ -815,9 +837,9 @@ void V8HeapExplorer::ExtractJSObjectReferences(HeapEntry* entry, } } } - SharedFunctionInfo* shared_info = js_fun->shared(); - TagObject(js_fun->feedback_cell(), "(function feedback cell)"); - SetInternalReference(entry, "feedback_cell", js_fun->feedback_cell(), + SharedFunctionInfo shared_info = js_fun->shared(); + TagObject(js_fun->raw_feedback_cell(), "(function feedback cell)"); + SetInternalReference(entry, "feedback_cell", js_fun->raw_feedback_cell(), JSFunction::kFeedbackCellOffset); TagObject(shared_info, "(shared function info)"); SetInternalReference(entry, "shared", shared_info, @@ -825,19 +847,18 @@ void V8HeapExplorer::ExtractJSObjectReferences(HeapEntry* entry, TagObject(js_fun->context(), "(context)"); SetInternalReference(entry, "context", js_fun->context(), JSFunction::kContextOffset); - TagCodeObject(js_fun->code()); SetInternalReference(entry, "code", js_fun->code(), JSFunction::kCodeOffset); } else if (obj->IsJSGlobalObject()) { - JSGlobalObject* global_obj = JSGlobalObject::cast(obj); + JSGlobalObject global_obj = JSGlobalObject::cast(obj); SetInternalReference(entry, "native_context", global_obj->native_context(), JSGlobalObject::kNativeContextOffset); SetInternalReference(entry, "global_proxy", global_obj->global_proxy(), JSGlobalObject::kGlobalProxyOffset); STATIC_ASSERT(JSGlobalObject::kSize - JSObject::kHeaderSize == - 2 * kPointerSize); + 2 * kTaggedSize); } else if (obj->IsJSArrayBufferView()) { - JSArrayBufferView* view = JSArrayBufferView::cast(obj); + JSArrayBufferView view = JSArrayBufferView::cast(obj); SetInternalReference(entry, "buffer", view->buffer(), JSArrayBufferView::kBufferOffset); } @@ -851,47 +872,47 @@ void V8HeapExplorer::ExtractJSObjectReferences(HeapEntry* entry, JSObject::kElementsOffset); } -void V8HeapExplorer::ExtractStringReferences(HeapEntry* entry, String* string) { +void V8HeapExplorer::ExtractStringReferences(HeapEntry* entry, String string) { if (string->IsConsString()) { - ConsString* cs = ConsString::cast(string); + ConsString cs = ConsString::cast(string); SetInternalReference(entry, "first", cs->first(), ConsString::kFirstOffset); SetInternalReference(entry, "second", cs->second(), ConsString::kSecondOffset); } else if (string->IsSlicedString()) { - SlicedString* ss = SlicedString::cast(string); + SlicedString ss = SlicedString::cast(string); SetInternalReference(entry, "parent", ss->parent(), SlicedString::kParentOffset); } else if (string->IsThinString()) { - ThinString* ts = ThinString::cast(string); + ThinString ts = ThinString::cast(string); SetInternalReference(entry, "actual", ts->actual(), ThinString::kActualOffset); } } -void V8HeapExplorer::ExtractSymbolReferences(HeapEntry* entry, Symbol* symbol) { +void V8HeapExplorer::ExtractSymbolReferences(HeapEntry* entry, Symbol symbol) { SetInternalReference(entry, "name", symbol->name(), Symbol::kNameOffset); } void V8HeapExplorer::ExtractJSCollectionReferences(HeapEntry* entry, - JSCollection* collection) { + JSCollection collection) { SetInternalReference(entry, "table", collection->table(), JSCollection::kTableOffset); } void V8HeapExplorer::ExtractJSWeakCollectionReferences(HeapEntry* entry, - JSWeakCollection* obj) { + JSWeakCollection obj) { SetInternalReference(entry, "table", obj->table(), JSWeakCollection::kTableOffset); } void V8HeapExplorer::ExtractEphemeronHashTableReferences( - HeapEntry* entry, EphemeronHashTable* table) { + HeapEntry* entry, EphemeronHashTable table) { for (int i = 0, capacity = table->Capacity(); i < capacity; ++i) { int key_index = EphemeronHashTable::EntryToIndex(i) + EphemeronHashTable::kEntryKeyIndex; int value_index = EphemeronHashTable::EntryToValueIndex(i); - Object* key = table->get(key_index); - Object* value = table->get(value_index); + Object key = table->get(key_index); + Object value = table->get(value_index); SetWeakReference(entry, key_index, key, table->OffsetOfElementAt(key_index)); SetWeakReference(entry, value_index, value, @@ -916,23 +937,23 @@ static const struct { } native_context_names[] = { #define CONTEXT_FIELD_INDEX_NAME(index, _, name) {Context::index, #name}, NATIVE_CONTEXT_FIELDS(CONTEXT_FIELD_INDEX_NAME) -#undef CONTEXT_FIELD_INDEX +#undef CONTEXT_FIELD_INDEX_NAME }; void V8HeapExplorer::ExtractContextReferences(HeapEntry* entry, - Context* context) { + Context context) { if (!context->IsNativeContext() && context->is_declaration_context()) { - ScopeInfo* scope_info = context->scope_info(); + ScopeInfo scope_info = context->scope_info(); // Add context allocated locals. int context_locals = scope_info->ContextLocalCount(); for (int i = 0; i < context_locals; ++i) { - String* local_name = scope_info->ContextLocalName(i); + String local_name = scope_info->ContextLocalName(i); int idx = Context::MIN_CONTEXT_SLOTS + i; SetContextReference(entry, local_name, context->get(idx), Context::OffsetOfElementAt(idx)); } if (scope_info->HasFunctionName()) { - String* name = String::cast(scope_info->FunctionName()); + String name = String::cast(scope_info->FunctionName()); int idx = scope_info->FunctionContextSlotIndex(name); if (idx >= 0) { SetContextReference(entry, name, context->get(idx), @@ -979,9 +1000,9 @@ void V8HeapExplorer::ExtractContextReferences(HeapEntry* entry, } } -void V8HeapExplorer::ExtractMapReferences(HeapEntry* entry, Map* map) { - MaybeObject* maybe_raw_transitions_or_prototype_info = map->raw_transitions(); - HeapObject* raw_transitions_or_prototype_info; +void V8HeapExplorer::ExtractMapReferences(HeapEntry* entry, Map map) { + MaybeObject maybe_raw_transitions_or_prototype_info = map->raw_transitions(); + HeapObject raw_transitions_or_prototype_info; if (maybe_raw_transitions_or_prototype_info->GetHeapObjectIfWeak( &raw_transitions_or_prototype_info)) { DCHECK(raw_transitions_or_prototype_info->IsMap()); @@ -990,7 +1011,7 @@ void V8HeapExplorer::ExtractMapReferences(HeapEntry* entry, Map* map) { } else if (maybe_raw_transitions_or_prototype_info->GetHeapObjectIfStrong( &raw_transitions_or_prototype_info)) { if (raw_transitions_or_prototype_info->IsTransitionArray()) { - TransitionArray* transitions = + TransitionArray transitions = TransitionArray::cast(raw_transitions_or_prototype_info); if (map->CanTransition() && transitions->HasPrototypeTransitions()) { TagObject(transitions->GetPrototypeTransitions(), @@ -1012,7 +1033,7 @@ void V8HeapExplorer::ExtractMapReferences(HeapEntry* entry, Map* map) { Map::kTransitionsOrPrototypeInfoOffset); } } - DescriptorArray* descriptors = map->instance_descriptors(); + DescriptorArray descriptors = map->instance_descriptors(); TagObject(descriptors, "(map descriptors)"); SetInternalReference(entry, "descriptors", descriptors, Map::kDescriptorsOffset); @@ -1022,7 +1043,7 @@ void V8HeapExplorer::ExtractMapReferences(HeapEntry* entry, Map* map) { SetInternalReference(entry, "layout_descriptor", map->layout_descriptor(), Map::kLayoutDescriptorOffset); } - Object* constructor_or_backpointer = map->constructor_or_backpointer(); + Object constructor_or_backpointer = map->constructor_or_backpointer(); if (constructor_or_backpointer->IsMap()) { TagObject(constructor_or_backpointer, "(back pointer)"); SetInternalReference(entry, "back_pointer", constructor_or_backpointer, @@ -1042,8 +1063,8 @@ void V8HeapExplorer::ExtractMapReferences(HeapEntry* entry, Map* map) { } void V8HeapExplorer::ExtractSharedFunctionInfoReferences( - HeapEntry* entry, SharedFunctionInfo* shared) { - String* shared_name = shared->DebugName(); + HeapEntry* entry, SharedFunctionInfo shared) { + String shared_name = shared->DebugName(); const char* name = nullptr; if (shared_name != ReadOnlyRoots(heap_).empty_string()) { name = names_->GetName(shared_name); @@ -1071,7 +1092,7 @@ void V8HeapExplorer::ExtractSharedFunctionInfoReferences( SharedFunctionInfo::kOuterScopeInfoOrFeedbackMetadataOffset); } -void V8HeapExplorer::ExtractScriptReferences(HeapEntry* entry, Script* script) { +void V8HeapExplorer::ExtractScriptReferences(HeapEntry* entry, Script script) { SetInternalReference(entry, "source", script->source(), Script::kSourceOffset); SetInternalReference(entry, "name", script->name(), Script::kNameOffset); @@ -1082,8 +1103,8 @@ void V8HeapExplorer::ExtractScriptReferences(HeapEntry* entry, Script* script) { Script::kLineEndsOffset); } -void V8HeapExplorer::ExtractAccessorInfoReferences( - HeapEntry* entry, AccessorInfo* accessor_info) { +void V8HeapExplorer::ExtractAccessorInfoReferences(HeapEntry* entry, + AccessorInfo accessor_info) { SetInternalReference(entry, "name", accessor_info->name(), AccessorInfo::kNameOffset); SetInternalReference(entry, "expected_receiver_type", @@ -1098,27 +1119,18 @@ void V8HeapExplorer::ExtractAccessorInfoReferences( } void V8HeapExplorer::ExtractAccessorPairReferences(HeapEntry* entry, - AccessorPair* accessors) { + AccessorPair accessors) { SetInternalReference(entry, "getter", accessors->getter(), AccessorPair::kGetterOffset); SetInternalReference(entry, "setter", accessors->setter(), AccessorPair::kSetterOffset); } -void V8HeapExplorer::TagBuiltinCodeObject(Code* code, const char* name) { +void V8HeapExplorer::TagBuiltinCodeObject(Code code, const char* name) { TagObject(code, names_->GetFormatted("(%s builtin)", name)); } -void V8HeapExplorer::TagCodeObject(Code* code) { - if (code->kind() == Code::STUB) { - TagObject(code, names_->GetFormatted( - "(%s code)", - CodeStub::MajorName(CodeStub::GetMajorKey(code)))); - } -} - -void V8HeapExplorer::ExtractCodeReferences(HeapEntry* entry, Code* code) { - TagCodeObject(code); +void V8HeapExplorer::ExtractCodeReferences(HeapEntry* entry, Code code) { TagObject(code->relocation_info(), "(code relocation info)"); SetInternalReference(entry, "relocation_info", code->relocation_info(), Code::kRelocationInfoOffset); @@ -1132,19 +1144,19 @@ void V8HeapExplorer::ExtractCodeReferences(HeapEntry* entry, Code* code) { Code::kSourcePositionTableOffset); } -void V8HeapExplorer::ExtractCellReferences(HeapEntry* entry, Cell* cell) { +void V8HeapExplorer::ExtractCellReferences(HeapEntry* entry, Cell cell) { SetInternalReference(entry, "value", cell->value(), Cell::kValueOffset); } -void V8HeapExplorer::ExtractFeedbackCellReferences( - HeapEntry* entry, FeedbackCell* feedback_cell) { +void V8HeapExplorer::ExtractFeedbackCellReferences(HeapEntry* entry, + FeedbackCell feedback_cell) { TagObject(feedback_cell, "(feedback cell)"); SetInternalReference(entry, "value", feedback_cell->value(), FeedbackCell::kValueOffset); } void V8HeapExplorer::ExtractPropertyCellReferences(HeapEntry* entry, - PropertyCell* cell) { + PropertyCell cell) { SetInternalReference(entry, "value", cell->value(), PropertyCell::kValueOffset); TagObject(cell->dependent_code(), "(dependent code)"); @@ -1153,7 +1165,7 @@ void V8HeapExplorer::ExtractPropertyCellReferences(HeapEntry* entry, } void V8HeapExplorer::ExtractAllocationSiteReferences(HeapEntry* entry, - AllocationSite* site) { + AllocationSite site) { SetInternalReference(entry, "transition_info", site->transition_info_or_boilerplate(), AllocationSite::kTransitionInfoOrBoilerplateOffset); @@ -1165,7 +1177,7 @@ void V8HeapExplorer::ExtractAllocationSiteReferences(HeapEntry* entry, } void V8HeapExplorer::ExtractArrayBoilerplateDescriptionReferences( - HeapEntry* entry, ArrayBoilerplateDescription* value) { + HeapEntry* entry, ArrayBoilerplateDescription value) { SetInternalReference(entry, "constant_elements", value->constant_elements(), ArrayBoilerplateDescription::kConstantElementsOffset); } @@ -1187,10 +1199,9 @@ class JSArrayBufferDataEntryAllocator : public HeapEntriesAllocator { }; void V8HeapExplorer::ExtractJSArrayBufferReferences(HeapEntry* entry, - JSArrayBuffer* buffer) { + JSArrayBuffer buffer) { // Setup a reference to a native memory backing_store object. - if (!buffer->backing_store()) - return; + if (!buffer->backing_store()) return; size_t data_size = buffer->byte_length(); JSArrayBufferDataEntryAllocator allocator(data_size, this); HeapEntry* data_entry = @@ -1200,14 +1211,14 @@ void V8HeapExplorer::ExtractJSArrayBufferReferences(HeapEntry* entry, } void V8HeapExplorer::ExtractJSPromiseReferences(HeapEntry* entry, - JSPromise* promise) { + JSPromise promise) { SetInternalReference(entry, "reactions_or_result", promise->reactions_or_result(), JSPromise::kReactionsOrResultOffset); } void V8HeapExplorer::ExtractJSGeneratorObjectReferences( - HeapEntry* entry, JSGeneratorObject* generator) { + HeapEntry* entry, JSGeneratorObject generator) { SetInternalReference(entry, "function", generator->function(), JSGeneratorObject::kFunctionOffset); SetInternalReference(entry, "context", generator->context(), @@ -1220,7 +1231,7 @@ void V8HeapExplorer::ExtractJSGeneratorObjectReferences( } void V8HeapExplorer::ExtractFixedArrayReferences(HeapEntry* entry, - FixedArray* array) { + FixedArray array) { for (int i = 0, l = array->length(); i < l; ++i) { DCHECK(!HasWeakHeapObjectTag(array->get(i))); SetInternalReference(entry, i, array->get(i), array->OffsetOfElementAt(i)); @@ -1228,35 +1239,55 @@ void V8HeapExplorer::ExtractFixedArrayReferences(HeapEntry* entry, } void V8HeapExplorer::ExtractFeedbackVectorReferences( - HeapEntry* entry, FeedbackVector* feedback_vector) { - MaybeObject* code = feedback_vector->optimized_code_weak_or_smi(); - HeapObject* code_heap_object; + HeapEntry* entry, FeedbackVector feedback_vector) { + MaybeObject code = feedback_vector->optimized_code_weak_or_smi(); + HeapObject code_heap_object; if (code->GetHeapObjectIfWeak(&code_heap_object)) { SetWeakReference(entry, "optimized code", code_heap_object, FeedbackVector::kOptimizedCodeOffset); } } +void V8HeapExplorer::ExtractDescriptorArrayReferences(HeapEntry* entry, + DescriptorArray array) { + SetInternalReference(entry, "enum_cache", array->enum_cache(), + DescriptorArray::kEnumCacheOffset); + MaybeObjectSlot start = MaybeObjectSlot(array->GetDescriptorSlot(0)); + MaybeObjectSlot end = MaybeObjectSlot( + array->GetDescriptorSlot(array->number_of_all_descriptors())); + for (int i = 0; start + i < end; ++i) { + MaybeObjectSlot slot = start + i; + int offset = static_cast<int>(slot.address() - array->address()); + MaybeObject object = *slot; + HeapObject heap_object; + if (object->GetHeapObjectIfWeak(&heap_object)) { + SetWeakReference(entry, i, heap_object, offset); + } else if (object->GetHeapObjectIfStrong(&heap_object)) { + SetInternalReference(entry, i, heap_object, offset); + } + } +} + template <typename T> void V8HeapExplorer::ExtractWeakArrayReferences(int header_size, - HeapEntry* entry, T* array) { + HeapEntry* entry, T array) { for (int i = 0; i < array->length(); ++i) { - MaybeObject* object = array->Get(i); - HeapObject* heap_object; + MaybeObject object = array->Get(i); + HeapObject heap_object; if (object->GetHeapObjectIfWeak(&heap_object)) { - SetWeakReference(entry, i, heap_object, header_size + i * kPointerSize); + SetWeakReference(entry, i, heap_object, header_size + i * kTaggedSize); } else if (object->GetHeapObjectIfStrong(&heap_object)) { SetInternalReference(entry, i, heap_object, - header_size + i * kPointerSize); + header_size + i * kTaggedSize); } } } -void V8HeapExplorer::ExtractPropertyReferences(JSObject* js_obj, +void V8HeapExplorer::ExtractPropertyReferences(JSObject js_obj, HeapEntry* entry) { Isolate* isolate = js_obj->GetIsolate(); if (js_obj->HasFastProperties()) { - DescriptorArray* descs = js_obj->map()->instance_descriptors(); + DescriptorArray descs = js_obj->map()->instance_descriptors(); int real_size = js_obj->map()->NumberOfOwnDescriptors(); for (int i = 0; i < real_size; i++) { PropertyDetails details = descs->GetDetails(i); @@ -1265,9 +1296,9 @@ void V8HeapExplorer::ExtractPropertyReferences(JSObject* js_obj, Representation r = details.representation(); if (r.IsSmi() || r.IsDouble()) break; - Name* k = descs->GetKey(i); + Name k = descs->GetKey(i); FieldIndex field_index = FieldIndex::ForDescriptor(js_obj->map(), i); - Object* value = js_obj->RawFastPropertyAt(field_index); + Object value = js_obj->RawFastPropertyAt(field_index); int field_offset = field_index.is_inobject() ? field_index.offset() : -1; @@ -1284,26 +1315,26 @@ void V8HeapExplorer::ExtractPropertyReferences(JSObject* js_obj, } } else if (js_obj->IsJSGlobalObject()) { // We assume that global objects can only have slow properties. - GlobalDictionary* dictionary = + GlobalDictionary dictionary = JSGlobalObject::cast(js_obj)->global_dictionary(); int length = dictionary->Capacity(); ReadOnlyRoots roots(isolate); for (int i = 0; i < length; ++i) { if (!dictionary->IsKey(roots, dictionary->KeyAt(i))) continue; - PropertyCell* cell = dictionary->CellAt(i); - Name* name = cell->name(); - Object* value = cell->value(); + PropertyCell cell = dictionary->CellAt(i); + Name name = cell->name(); + Object value = cell->value(); PropertyDetails details = cell->property_details(); SetDataOrAccessorPropertyReference(details.kind(), entry, name, value); } } else { - NameDictionary* dictionary = js_obj->property_dictionary(); + NameDictionary dictionary = js_obj->property_dictionary(); int length = dictionary->Capacity(); ReadOnlyRoots roots(isolate); for (int i = 0; i < length; ++i) { - Object* k = dictionary->KeyAt(i); + Object k = dictionary->KeyAt(i); if (!dictionary->IsKey(roots, k)) continue; - Object* value = dictionary->ValueAt(i); + Object value = dictionary->ValueAt(i); PropertyDetails details = dictionary->DetailsAt(i); SetDataOrAccessorPropertyReference(details.kind(), entry, Name::cast(k), value); @@ -1311,27 +1342,27 @@ void V8HeapExplorer::ExtractPropertyReferences(JSObject* js_obj, } } -void V8HeapExplorer::ExtractAccessorPairProperty(HeapEntry* entry, Name* key, - Object* callback_obj, +void V8HeapExplorer::ExtractAccessorPairProperty(HeapEntry* entry, Name key, + Object callback_obj, int field_offset) { if (!callback_obj->IsAccessorPair()) return; - AccessorPair* accessors = AccessorPair::cast(callback_obj); + AccessorPair accessors = AccessorPair::cast(callback_obj); SetPropertyReference(entry, key, accessors, nullptr, field_offset); - Object* getter = accessors->getter(); + Object getter = accessors->getter(); if (!getter->IsOddball()) { SetPropertyReference(entry, key, getter, "get %s"); } - Object* setter = accessors->setter(); + Object setter = accessors->setter(); if (!setter->IsOddball()) { SetPropertyReference(entry, key, setter, "set %s"); } } -void V8HeapExplorer::ExtractElementReferences(JSObject* js_obj, +void V8HeapExplorer::ExtractElementReferences(JSObject js_obj, HeapEntry* entry) { ReadOnlyRoots roots = js_obj->GetReadOnlyRoots(); if (js_obj->HasObjectElements()) { - FixedArray* elements = FixedArray::cast(js_obj->elements()); + FixedArray elements = FixedArray::cast(js_obj->elements()); int length = js_obj->IsJSArray() ? Smi::ToInt(JSArray::cast(js_obj)->length()) : elements->length(); @@ -1341,10 +1372,10 @@ void V8HeapExplorer::ExtractElementReferences(JSObject* js_obj, } } } else if (js_obj->HasDictionaryElements()) { - NumberDictionary* dictionary = js_obj->element_dictionary(); + NumberDictionary dictionary = js_obj->element_dictionary(); int length = dictionary->Capacity(); for (int i = 0; i < length; ++i) { - Object* k = dictionary->KeyAt(i); + Object k = dictionary->KeyAt(i); if (!dictionary->IsKey(roots, k)) continue; DCHECK(k->IsNumber()); uint32_t index = static_cast<uint32_t>(k->Number()); @@ -1353,28 +1384,28 @@ void V8HeapExplorer::ExtractElementReferences(JSObject* js_obj, } } -void V8HeapExplorer::ExtractInternalReferences(JSObject* js_obj, +void V8HeapExplorer::ExtractInternalReferences(JSObject js_obj, HeapEntry* entry) { int length = js_obj->GetEmbedderFieldCount(); for (int i = 0; i < length; ++i) { - Object* o = js_obj->GetEmbedderField(i); + Object o = js_obj->GetEmbedderField(i); SetInternalReference(entry, i, o, js_obj->GetEmbedderFieldOffset(i)); } } -JSFunction* V8HeapExplorer::GetConstructor(JSReceiver* receiver) { +JSFunction V8HeapExplorer::GetConstructor(JSReceiver receiver) { Isolate* isolate = receiver->GetIsolate(); DisallowHeapAllocation no_gc; HandleScope scope(isolate); MaybeHandle<JSFunction> maybe_constructor = JSReceiver::GetConstructor(handle(receiver, isolate)); - if (maybe_constructor.is_null()) return nullptr; + if (maybe_constructor.is_null()) return JSFunction(); return *maybe_constructor.ToHandleChecked(); } -String* V8HeapExplorer::GetConstructorName(JSObject* object) { +String V8HeapExplorer::GetConstructorName(JSObject object) { Isolate* isolate = object->GetIsolate(); if (object->IsJSFunction()) return ReadOnlyRoots(isolate).closure_string(); DisallowHeapAllocation no_gc; @@ -1382,8 +1413,10 @@ String* V8HeapExplorer::GetConstructorName(JSObject* object) { return *JSReceiver::GetConstructorName(handle(object, isolate)); } -HeapEntry* V8HeapExplorer::GetEntry(Object* obj) { - return obj->IsHeapObject() ? generator_->FindOrAddEntry(obj, this) : nullptr; +HeapEntry* V8HeapExplorer::GetEntry(Object obj) { + return obj->IsHeapObject() ? generator_->FindOrAddEntry( + reinterpret_cast<void*>(obj.ptr()), this) + : nullptr; } class RootsReferencesExtractor : public RootVisitor { @@ -1394,7 +1427,7 @@ class RootsReferencesExtractor : public RootVisitor { void SetVisitingWeakRoots() { visiting_weak_roots_ = true; } void VisitRootPointer(Root root, const char* description, - Object** object) override { + FullObjectSlot object) override { if (root == Root::kBuiltins) { explorer_->TagBuiltinCodeObject(Code::cast(*object), description); } @@ -1402,10 +1435,11 @@ class RootsReferencesExtractor : public RootVisitor { *object); } - void VisitRootPointers(Root root, const char* description, Object** start, - Object** end) override { - for (Object** p = start; p < end; p++) + void VisitRootPointers(Root root, const char* description, + FullObjectSlot start, FullObjectSlot end) override { + for (FullObjectSlot p = start; p < end; ++p) { VisitRootPointer(root, description, p); + } } private: @@ -1427,7 +1461,8 @@ bool V8HeapExplorer::IterateAndExtractReferences( // first. Otherwise a particular JSFunction object could set // its custom name to a generic builtin. RootsReferencesExtractor extractor(this); - heap_->IterateRoots(&extractor, VISIT_ONLY_STRONG_FOR_SERIALIZATION); + ReadOnlyRoots(heap_).Iterate(&extractor); + heap_->IterateRoots(&extractor, VISIT_ONLY_STRONG); extractor.SetVisitingWeakRoots(); heap_->IterateWeakGlobalHandles(&extractor); @@ -1435,11 +1470,11 @@ bool V8HeapExplorer::IterateAndExtractReferences( HeapIterator iterator(heap_, HeapIterator::kFilterUnreachable); // Heap iteration with filtering must be finished in any case. - for (HeapObject *obj = iterator.next(); obj != nullptr; + for (HeapObject obj = iterator.next(); !obj.is_null(); obj = iterator.next(), progress_->ProgressStep()) { if (interrupted) continue; - size_t max_pointer = obj->Size() / kPointerSize; + size_t max_pointer = obj->Size() / kTaggedSize; if (max_pointer > visited_fields_.size()) { // Clear the current bits. std::vector<bool>().swap(visited_fields_); @@ -1470,8 +1505,7 @@ bool V8HeapExplorer::IterateAndExtractReferences( return interrupted ? false : progress_->ProgressReport(true); } - -bool V8HeapExplorer::IsEssentialObject(Object* object) { +bool V8HeapExplorer::IsEssentialObject(Object object) { ReadOnlyRoots roots(heap_); return object->IsHeapObject() && !object->IsOddball() && object != roots.empty_byte_array() && @@ -1486,7 +1520,7 @@ bool V8HeapExplorer::IsEssentialObject(Object* object) { object != roots.two_pointer_filler_map(); } -bool V8HeapExplorer::IsEssentialHiddenReference(Object* parent, +bool V8HeapExplorer::IsEssentialHiddenReference(Object parent, int field_offset) { if (parent->IsAllocationSite() && field_offset == AllocationSite::kWeakNextOffset) @@ -1501,8 +1535,8 @@ bool V8HeapExplorer::IsEssentialHiddenReference(Object* parent, } void V8HeapExplorer::SetContextReference(HeapEntry* parent_entry, - String* reference_name, - Object* child_obj, int field_offset) { + String reference_name, + Object child_obj, int field_offset) { HeapEntry* child_entry = GetEntry(child_obj); if (child_entry == nullptr) return; parent_entry->SetNamedReference(HeapGraphEdge::kContextVariable, @@ -1512,14 +1546,14 @@ void V8HeapExplorer::SetContextReference(HeapEntry* parent_entry, void V8HeapExplorer::MarkVisitedField(int offset) { if (offset < 0) return; - int index = offset / kPointerSize; + int index = offset / kTaggedSize; DCHECK(!visited_fields_[index]); visited_fields_[index] = true; } void V8HeapExplorer::SetNativeBindReference(HeapEntry* parent_entry, const char* reference_name, - Object* child_obj) { + Object child_obj) { HeapEntry* child_entry = GetEntry(child_obj); if (child_entry == nullptr) return; parent_entry->SetNamedReference(HeapGraphEdge::kShortcut, reference_name, @@ -1527,7 +1561,7 @@ void V8HeapExplorer::SetNativeBindReference(HeapEntry* parent_entry, } void V8HeapExplorer::SetElementReference(HeapEntry* parent_entry, int index, - Object* child_obj) { + Object child_obj) { HeapEntry* child_entry = GetEntry(child_obj); if (child_entry == nullptr) return; parent_entry->SetIndexedReference(HeapGraphEdge::kElement, index, @@ -1536,7 +1570,7 @@ void V8HeapExplorer::SetElementReference(HeapEntry* parent_entry, int index, void V8HeapExplorer::SetInternalReference(HeapEntry* parent_entry, const char* reference_name, - Object* child_obj, int field_offset) { + Object child_obj, int field_offset) { HeapEntry* child_entry = GetEntry(child_obj); if (child_entry == nullptr) return; if (IsEssentialObject(child_obj)) { @@ -1547,7 +1581,7 @@ void V8HeapExplorer::SetInternalReference(HeapEntry* parent_entry, } void V8HeapExplorer::SetInternalReference(HeapEntry* parent_entry, int index, - Object* child_obj, int field_offset) { + Object child_obj, int field_offset) { HeapEntry* child_entry = GetEntry(child_obj); if (child_entry == nullptr) return; if (IsEssentialObject(child_obj)) { @@ -1557,9 +1591,9 @@ void V8HeapExplorer::SetInternalReference(HeapEntry* parent_entry, int index, MarkVisitedField(field_offset); } -void V8HeapExplorer::SetHiddenReference(HeapObject* parent_obj, +void V8HeapExplorer::SetHiddenReference(HeapObject parent_obj, HeapEntry* parent_entry, int index, - Object* child_obj, int field_offset) { + Object child_obj, int field_offset) { DCHECK_EQ(parent_entry, GetEntry(parent_obj)); HeapEntry* child_entry = GetEntry(child_obj); if (child_entry != nullptr && IsEssentialObject(child_obj) && @@ -1571,7 +1605,7 @@ void V8HeapExplorer::SetHiddenReference(HeapObject* parent_obj, void V8HeapExplorer::SetWeakReference(HeapEntry* parent_entry, const char* reference_name, - Object* child_obj, int field_offset) { + Object child_obj, int field_offset) { HeapEntry* child_entry = GetEntry(child_obj); if (child_entry == nullptr) return; if (IsEssentialObject(child_obj)) { @@ -1582,7 +1616,7 @@ void V8HeapExplorer::SetWeakReference(HeapEntry* parent_entry, } void V8HeapExplorer::SetWeakReference(HeapEntry* parent_entry, int index, - Object* child_obj, int field_offset) { + Object child_obj, int field_offset) { HeapEntry* child_entry = GetEntry(child_obj); if (child_entry == nullptr) return; if (IsEssentialObject(child_obj)) { @@ -1593,8 +1627,8 @@ void V8HeapExplorer::SetWeakReference(HeapEntry* parent_entry, int index, } void V8HeapExplorer::SetDataOrAccessorPropertyReference( - PropertyKind kind, HeapEntry* parent_entry, Name* reference_name, - Object* child_obj, const char* name_format_string, int field_offset) { + PropertyKind kind, HeapEntry* parent_entry, Name reference_name, + Object child_obj, const char* name_format_string, int field_offset) { if (kind == kAccessor) { ExtractAccessorPairProperty(parent_entry, reference_name, child_obj, field_offset); @@ -1605,8 +1639,7 @@ void V8HeapExplorer::SetDataOrAccessorPropertyReference( } void V8HeapExplorer::SetPropertyReference(HeapEntry* parent_entry, - Name* reference_name, - Object* child_obj, + Name reference_name, Object child_obj, const char* name_format_string, int field_offset) { HeapEntry* child_entry = GetEntry(child_obj); @@ -1633,7 +1666,7 @@ void V8HeapExplorer::SetRootGcRootsReference() { snapshot_->gc_roots()); } -void V8HeapExplorer::SetUserGlobalReference(Object* child_obj) { +void V8HeapExplorer::SetUserGlobalReference(Object child_obj) { HeapEntry* child_entry = GetEntry(child_obj); DCHECK_NOT_NULL(child_entry); snapshot_->root()->SetNamedAutoIndexReference(HeapGraphEdge::kShortcut, @@ -1646,7 +1679,7 @@ void V8HeapExplorer::SetGcRootsReference(Root root) { } void V8HeapExplorer::SetGcSubrootReference(Root root, const char* description, - bool is_weak, Object* child_obj) { + bool is_weak, Object child_obj) { HeapEntry* child_entry = GetEntry(child_obj); if (child_entry == nullptr) return; const char* name = GetStrongGcSubrootName(child_obj); @@ -1665,7 +1698,7 @@ void V8HeapExplorer::SetGcSubrootReference(Root root, const char* description, // also used as starting points in distance calculations. if (is_weak || !child_obj->IsNativeContext()) return; - JSGlobalObject* global = Context::cast(child_obj)->global_object(); + JSGlobalObject global = Context::cast(child_obj)->global_object(); if (!global->IsJSGlobalObject()) return; if (!user_roots_.insert(global).second) return; @@ -1673,24 +1706,13 @@ void V8HeapExplorer::SetGcSubrootReference(Root root, const char* description, SetUserGlobalReference(global); } -// This static array is used to prevent excessive code-size in -// GetStrongGcSubrootName below, which would happen if we called emplace() for -// every root in a macro. -static const char* root_names[] = { -#define ROOT_NAME(type, name, CamelName) #name, - READ_ONLY_ROOT_LIST(ROOT_NAME) MUTABLE_ROOT_LIST(ROOT_NAME) -#undef ROOT_NAME -}; -STATIC_ASSERT(static_cast<uint16_t>(RootIndex::kRootListLength) == - arraysize(root_names)); - -const char* V8HeapExplorer::GetStrongGcSubrootName(Object* object) { +const char* V8HeapExplorer::GetStrongGcSubrootName(Object object) { if (strong_gc_subroot_names_.empty()) { - for (uint16_t i = 0; i < static_cast<uint16_t>(RootIndex::kRootListLength); - i++) { - const char* name = root_names[i]; - RootIndex index = static_cast<RootIndex>(i); - strong_gc_subroot_names_.emplace(heap_->root(index), name); + Isolate* isolate = heap_->isolate(); + for (RootIndex root_index = RootIndex::kFirstStrongOrReadOnlyRoot; + root_index <= RootIndex::kLastStrongOrReadOnlyRoot; ++root_index) { + const char* name = RootsTable::name(root_index); + strong_gc_subroot_names_.emplace(isolate->root(root_index), name); } CHECK(!strong_gc_subroot_names_.empty()); } @@ -1698,7 +1720,7 @@ const char* V8HeapExplorer::GetStrongGcSubrootName(Object* object) { return it != strong_gc_subroot_names_.end() ? it->second : nullptr; } -void V8HeapExplorer::TagObject(Object* obj, const char* tag) { +void V8HeapExplorer::TagObject(Object obj, const char* tag) { if (IsEssentialObject(obj)) { HeapEntry* entry = GetEntry(obj); if (entry->name()[0] == '\0') { @@ -1709,13 +1731,13 @@ void V8HeapExplorer::TagObject(Object* obj, const char* tag) { class GlobalObjectsEnumerator : public RootVisitor { public: - void VisitRootPointers(Root root, const char* description, Object** start, - Object** end) override { - for (Object** p = start; p < end; p++) { + void VisitRootPointers(Root root, const char* description, + FullObjectSlot start, FullObjectSlot end) override { + for (FullObjectSlot p = start; p < end; ++p) { if (!(*p)->IsNativeContext()) continue; - JSObject* proxy = Context::cast(*p)->global_proxy(); + JSObject proxy = Context::cast(*p)->global_proxy(); if (!proxy->IsJSGlobalProxy()) continue; - Object* global = proxy->map()->prototype(); + Object global = proxy->map()->prototype(); if (!global->IsJSGlobalObject()) continue; objects_.push_back(Handle<JSGlobalObject>(JSGlobalObject::cast(global), proxy->GetIsolate())); @@ -1759,8 +1781,8 @@ class EmbedderGraphImpl : public EmbedderGraph { class V8NodeImpl : public Node { public: - explicit V8NodeImpl(Object* object) : object_(object) {} - Object* GetObject() { return object_; } + explicit V8NodeImpl(Object object) : object_(object) {} + Object GetObject() { return object_; } // Node overrides. bool IsEmbedderNode() override { return false; } @@ -1776,7 +1798,7 @@ class EmbedderGraphImpl : public EmbedderGraph { } private: - Object* object_; + Object object_; }; Node* V8Node(const v8::Local<v8::Value>& value) final { @@ -1811,7 +1833,7 @@ class GlobalHandlesExtractor : public PersistentHandleVisitor { void VisitPersistentHandle(Persistent<Value>* value, uint16_t class_id) override { Handle<Object> object = Utils::OpenPersistent(value); - explorer_->VisitSubtreeWrapper(object.location(), class_id); + explorer_->VisitSubtreeWrapper(object, class_id); } private: @@ -1948,7 +1970,7 @@ NativeObjectsExplorer::~NativeObjectsExplorer() { for (auto map_entry : objects_by_info_) { v8::RetainedObjectInfo* info = map_entry.first; info->Dispose(); - std::vector<HeapObject*>* objects = map_entry.second; + std::vector<HeapObject>* objects = map_entry.second; delete objects; } for (auto map_entry : native_groups_) { @@ -1970,14 +1992,14 @@ void NativeObjectsExplorer::FillRetainedObjects() { v8::HeapProfiler::RetainerInfos infos = snapshot_->profiler()->GetRetainerInfos(isolate_); for (auto& pair : infos.groups) { - std::vector<HeapObject*>* info = GetVectorMaybeDisposeInfo(pair.first); + std::vector<HeapObject>* info = GetVectorMaybeDisposeInfo(pair.first); for (auto& persistent : pair.second) { if (persistent->IsEmpty()) continue; Handle<Object> object = v8::Utils::OpenHandle( *persistent->Get(reinterpret_cast<v8::Isolate*>(isolate_))); DCHECK(!object.is_null()); - HeapObject* heap_object = HeapObject::cast(*object); + HeapObject heap_object = HeapObject::cast(*object); info->push_back(heap_object); in_groups_.insert(heap_object); } @@ -1999,27 +2021,27 @@ void NativeObjectsExplorer::FillEdges() { Handle<Object> parent_object = v8::Utils::OpenHandle( *pair.first->Get(reinterpret_cast<v8::Isolate*>(isolate_))); - HeapObject* parent = HeapObject::cast(*parent_object); - HeapEntry* parent_entry = - generator_->FindOrAddEntry(parent, native_entries_allocator_.get()); + HeapObject parent = HeapObject::cast(*parent_object); + HeapEntry* parent_entry = generator_->FindOrAddEntry( + reinterpret_cast<void*>(parent.ptr()), native_entries_allocator_.get()); DCHECK_NOT_NULL(parent_entry); Handle<Object> child_object = v8::Utils::OpenHandle( *pair.second->Get(reinterpret_cast<v8::Isolate*>(isolate_))); - HeapObject* child = HeapObject::cast(*child_object); - HeapEntry* child_entry = - generator_->FindOrAddEntry(child, native_entries_allocator_.get()); + HeapObject child = HeapObject::cast(*child_object); + HeapEntry* child_entry = generator_->FindOrAddEntry( + reinterpret_cast<void*>(child.ptr()), native_entries_allocator_.get()); parent_entry->SetNamedReference(HeapGraphEdge::kInternal, "native", child_entry); } edges_.clear(); } -std::vector<HeapObject*>* NativeObjectsExplorer::GetVectorMaybeDisposeInfo( +std::vector<HeapObject>* NativeObjectsExplorer::GetVectorMaybeDisposeInfo( v8::RetainedObjectInfo* info) { if (objects_by_info_.count(info)) { info->Dispose(); } else { - objects_by_info_[info] = new std::vector<HeapObject*>(); + objects_by_info_[info] = new std::vector<HeapObject>(); } return objects_by_info_[info]; } @@ -2036,9 +2058,10 @@ HeapEntry* NativeObjectsExplorer::EntryForEmbedderGraphNode( } else { EmbedderGraphImpl::V8NodeImpl* v8_node = static_cast<EmbedderGraphImpl::V8NodeImpl*>(node); - Object* object = v8_node->GetObject(); + Object object = v8_node->GetObject(); if (object->IsSmi()) return nullptr; - return generator_->FindEntry(HeapObject::cast(object)); + return generator_->FindEntry( + reinterpret_cast<void*>(Object::cast(object).ptr())); } } @@ -2088,8 +2111,8 @@ bool NativeObjectsExplorer::IterateAndExtractReferences( for (auto map_entry : objects_by_info_) { v8::RetainedObjectInfo* info = map_entry.first; SetNativeRootReference(info); - std::vector<HeapObject*>* objects = map_entry.second; - for (HeapObject* object : *objects) { + std::vector<HeapObject>* objects = map_entry.second; + for (HeapObject object : *objects) { SetWrapperNativeReferences(object, info); } } @@ -2123,8 +2146,9 @@ void NativeObjectsExplorer::SetNativeRootReference( } void NativeObjectsExplorer::SetWrapperNativeReferences( - HeapObject* wrapper, v8::RetainedObjectInfo* info) { - HeapEntry* wrapper_entry = generator_->FindEntry(wrapper); + HeapObject wrapper, v8::RetainedObjectInfo* info) { + HeapEntry* wrapper_entry = + generator_->FindEntry(reinterpret_cast<void*>(wrapper.ptr())); DCHECK_NOT_NULL(wrapper_entry); HeapEntry* info_entry = generator_->FindOrAddEntry(info, native_entries_allocator_.get()); @@ -2146,7 +2170,8 @@ void NativeObjectsExplorer::SetRootNativeRootsReference() { } } -void NativeObjectsExplorer::VisitSubtreeWrapper(Object** p, uint16_t class_id) { +void NativeObjectsExplorer::VisitSubtreeWrapper(Handle<Object> p, + uint16_t class_id) { if (in_groups_.count(*p)) return; v8::RetainedObjectInfo* info = isolate_->heap_profiler()->ExecuteWrapperClassCallback(class_id, p); @@ -2171,13 +2196,13 @@ class NullContextScope { public: explicit NullContextScope(Isolate* isolate) : isolate_(isolate), prev_(isolate->context()) { - isolate_->set_context(nullptr); + isolate_->set_context(Context()); } ~NullContextScope() { isolate_->set_context(prev_); } private: Isolate* isolate_; - Context* prev_; + Context prev_; }; } // namespace |