diff options
author | Michaël Zasso <targos@protonmail.com> | 2018-12-04 08:20:37 +0100 |
---|---|---|
committer | Michaël Zasso <targos@protonmail.com> | 2018-12-06 15:23:33 +0100 |
commit | 9b4bf7de6c9a7c25f116c7a502384c20b5cfaea3 (patch) | |
tree | 2b0c843168dafb939d8df8a15b2aa72b76dee51d /deps/v8/src/profiler/heap-snapshot-generator.h | |
parent | b8fbe69db1292307adb2c2b2e0d5ef48c4ab2faf (diff) | |
download | android-node-v8-9b4bf7de6c9a7c25f116c7a502384c20b5cfaea3.tar.gz android-node-v8-9b4bf7de6c9a7c25f116c7a502384c20b5cfaea3.tar.bz2 android-node-v8-9b4bf7de6c9a7c25f116c7a502384c20b5cfaea3.zip |
deps: update V8 to 7.1.302.28
PR-URL: https://github.com/nodejs/node/pull/23423
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Diffstat (limited to 'deps/v8/src/profiler/heap-snapshot-generator.h')
-rw-r--r-- | deps/v8/src/profiler/heap-snapshot-generator.h | 314 |
1 files changed, 140 insertions, 174 deletions
diff --git a/deps/v8/src/profiler/heap-snapshot-generator.h b/deps/v8/src/profiler/heap-snapshot-generator.h index f25bee9f46..1f8f364912 100644 --- a/deps/v8/src/profiler/heap-snapshot-generator.h +++ b/deps/v8/src/profiler/heap-snapshot-generator.h @@ -7,6 +7,7 @@ #include <deque> #include <unordered_map> +#include <unordered_set> #include <vector> #include "include/v8-profiler.h" @@ -28,10 +29,14 @@ class HeapEntry; class HeapIterator; class HeapProfiler; class HeapSnapshot; +class HeapSnapshotGenerator; class JSArrayBuffer; class JSCollection; +class JSGeneratorObject; +class JSGlobalObject; +class JSGlobalProxy; +class JSPromise; class JSWeakCollection; -class SnapshotFiller; struct SourceLocation { SourceLocation(int entry_index, int scriptId, int line, int col) @@ -43,7 +48,7 @@ struct SourceLocation { const int col; }; -class HeapGraphEdge BASE_EMBEDDED { +class HeapGraphEdge { public: enum Type { kContextVariable = v8::HeapGraphEdge::kContextVariable, @@ -55,9 +60,8 @@ class HeapGraphEdge BASE_EMBEDDED { kWeak = v8::HeapGraphEdge::kWeak }; - HeapGraphEdge(Type type, const char* name, int from, int to); - HeapGraphEdge(Type type, int index, int from, int to); - void ReplaceToIndexWithEntry(HeapSnapshot* snapshot); + HeapGraphEdge(Type type, const char* name, HeapEntry* from, HeapEntry* to); + HeapGraphEdge(Type type, int index, HeapEntry* from, HeapEntry* to); Type type() const { return TypeField::decode(bit_field_); } int index() const { @@ -81,12 +85,7 @@ class HeapGraphEdge BASE_EMBEDDED { class TypeField : public BitField<Type, 0, 3> {}; class FromIndexField : public BitField<int, 3, 29> {}; uint32_t bit_field_; - union { - // During entries population |to_index_| is used for storing the index, - // afterwards it is replaced with a pointer to the entry. - int to_index_; - HeapEntry* to_entry_; - }; + HeapEntry* to_entry_; union { int index_; const char* name_; @@ -96,7 +95,7 @@ class HeapGraphEdge BASE_EMBEDDED { // HeapEntry instances represent an entity from the heap (or a special // virtual node, e.g. root). -class HeapEntry BASE_EMBEDDED { +class HeapEntry { public: enum Type { kHidden = v8::HeapGraphNode::kHidden, @@ -114,15 +113,9 @@ class HeapEntry BASE_EMBEDDED { kSymbol = v8::HeapGraphNode::kSymbol, kBigInt = v8::HeapGraphNode::kBigInt }; - static const int kNoEntry; - HeapEntry() { } - HeapEntry(HeapSnapshot* snapshot, - Type type, - const char* name, - SnapshotObjectId id, - size_t self_size, - unsigned trace_node_id); + HeapEntry(HeapSnapshot* snapshot, int index, Type type, const char* name, + SnapshotObjectId id, size_t self_size, unsigned trace_node_id); HeapSnapshot* snapshot() { return snapshot_; } Type type() const { return static_cast<Type>(type_); } @@ -132,8 +125,8 @@ class HeapEntry BASE_EMBEDDED { SnapshotObjectId id() const { return id_; } size_t self_size() const { return self_size_; } unsigned trace_node_id() const { return trace_node_id_; } - V8_INLINE int index() const; - int children_count() const { return children_count_; } + int index() const { return index_; } + V8_INLINE int children_count() const; V8_INLINE int set_children_index(int index); V8_INLINE void add_child(HeapGraphEdge* edge); V8_INLINE HeapGraphEdge* child(int i); @@ -143,18 +136,30 @@ class HeapEntry BASE_EMBEDDED { HeapGraphEdge::Type type, int index, HeapEntry* entry); void SetNamedReference( HeapGraphEdge::Type type, const char* name, HeapEntry* entry); + void SetIndexedAutoIndexReference(HeapGraphEdge::Type type, + HeapEntry* child) { + SetIndexedReference(type, children_count_ + 1, child); + } + void SetNamedAutoIndexReference(HeapGraphEdge::Type type, + const char* description, HeapEntry* child, + StringsStorage* strings); void Print( const char* prefix, const char* edge_name, int max_depth, int indent); private: - V8_INLINE std::deque<HeapGraphEdge*>::iterator children_begin(); - V8_INLINE std::deque<HeapGraphEdge*>::iterator children_end(); + V8_INLINE std::vector<HeapGraphEdge*>::iterator children_begin() const; + V8_INLINE std::vector<HeapGraphEdge*>::iterator children_end() const; const char* TypeAsString(); unsigned type_: 4; - int children_count_: 28; - int children_index_; + unsigned index_ : 28; // Supports up to ~250M objects. + union { + // The count is used during the snapshot build phase, + // then it gets converted into the index by the |FillChildren| function. + unsigned children_count_; + unsigned children_end_index_; + }; size_t self_size_; HeapSnapshot* snapshot_; const char* name_; @@ -163,7 +168,6 @@ class HeapEntry BASE_EMBEDDED { unsigned trace_node_id_; }; - // HeapSnapshot represents a single heap snapshot. It is stored in // HeapProfiler, which is also a factory for // HeapSnapshots. All HeapSnapshots share strings copied from JS heap @@ -174,22 +178,23 @@ class HeapSnapshot { explicit HeapSnapshot(HeapProfiler* profiler); void Delete(); - HeapProfiler* profiler() { return profiler_; } - HeapEntry* root() { return &entries_[root_index_]; } - HeapEntry* gc_roots() { return &entries_[gc_roots_index_]; } - HeapEntry* gc_subroot(Root root) { - return &entries_[gc_subroot_indexes_[static_cast<int>(root)]]; + HeapProfiler* profiler() const { return profiler_; } + HeapEntry* root() const { return root_entry_; } + HeapEntry* gc_roots() const { return gc_roots_entry_; } + HeapEntry* gc_subroot(Root root) const { + return gc_subroot_entries_[static_cast<int>(root)]; } - std::vector<HeapEntry>& entries() { return entries_; } + std::deque<HeapEntry>& entries() { return entries_; } std::deque<HeapGraphEdge>& edges() { return edges_; } - std::deque<HeapGraphEdge*>& children() { return children_; } + std::vector<HeapGraphEdge*>& children() { return children_; } const std::vector<SourceLocation>& locations() const { return locations_; } void RememberLastJSObjectId(); SnapshotObjectId max_snapshot_js_object_id() const { return max_snapshot_js_object_id_; } + bool is_complete() const { return !children_.empty(); } - void AddLocation(int entry, int scriptId, int line, int col); + void AddLocation(HeapEntry* entry, int scriptId, int line, int col); HeapEntry* AddEntry(HeapEntry::Type type, const char* name, SnapshotObjectId id, @@ -197,28 +202,28 @@ class HeapSnapshot { unsigned trace_node_id); void AddSyntheticRootEntries(); HeapEntry* GetEntryById(SnapshotObjectId id); - std::vector<HeapEntry*>* GetSortedEntriesList(); void FillChildren(); void Print(int max_depth); private: - HeapEntry* AddRootEntry(); - HeapEntry* AddGcRootsEntry(); - HeapEntry* AddGcSubrootEntry(Root root, SnapshotObjectId id); + void AddRootEntry(); + void AddGcRootsEntry(); + void AddGcSubrootEntry(Root root, SnapshotObjectId id); HeapProfiler* profiler_; - int root_index_; - int gc_roots_index_; - int gc_subroot_indexes_[static_cast<int>(Root::kNumberOfRoots)]; - std::vector<HeapEntry> entries_; + HeapEntry* root_entry_ = nullptr; + HeapEntry* gc_roots_entry_ = nullptr; + HeapEntry* gc_subroot_entries_[static_cast<int>(Root::kNumberOfRoots)]; + // For |entries_| we rely on the deque property, that it never reallocates + // backing storage, thus all entry pointers remain valid for the duration + // of snapshotting. + std::deque<HeapEntry> entries_; std::deque<HeapGraphEdge> edges_; - std::deque<HeapGraphEdge*> children_; - std::vector<HeapEntry*> sorted_entries_; + std::vector<HeapGraphEdge*> children_; + std::unordered_map<SnapshotObjectId, HeapEntry*> entries_by_id_cache_; std::vector<SourceLocation> locations_; - SnapshotObjectId max_snapshot_js_object_id_; - - friend class HeapSnapshotTester; + SnapshotObjectId max_snapshot_js_object_id_ = -1; DISALLOW_COPY_AND_ASSIGN(HeapSnapshot); }; @@ -294,68 +299,28 @@ typedef void* HeapThing; // An interface that creates HeapEntries by HeapThings. class HeapEntriesAllocator { public: - virtual ~HeapEntriesAllocator() { } + virtual ~HeapEntriesAllocator() = default; virtual HeapEntry* AllocateEntry(HeapThing ptr) = 0; }; -// The HeapEntriesMap instance is used to track a mapping between -// real heap objects and their representations in heap snapshots. -class HeapEntriesMap { - public: - HeapEntriesMap(); - - int Map(HeapThing thing); - void Pair(HeapThing thing, int entry); - - private: - static uint32_t Hash(HeapThing thing) { - return ComputeUnseededHash( - static_cast<uint32_t>(reinterpret_cast<uintptr_t>(thing))); - } - - base::HashMap entries_; - - friend class HeapObjectsSet; - - DISALLOW_COPY_AND_ASSIGN(HeapEntriesMap); -}; - - -class HeapObjectsSet { - public: - HeapObjectsSet(); - void Clear(); - bool Contains(Object* object); - void Insert(Object* obj); - const char* GetTag(Object* obj); - void SetTag(Object* obj, const char* tag); - bool is_empty() const { return entries_.occupancy() == 0; } - - private: - base::HashMap entries_; - - DISALLOW_COPY_AND_ASSIGN(HeapObjectsSet); -}; - - class SnapshottingProgressReportingInterface { public: - virtual ~SnapshottingProgressReportingInterface() { } + virtual ~SnapshottingProgressReportingInterface() = default; virtual void ProgressStep() = 0; virtual bool ProgressReport(bool force) = 0; }; - // An implementation of V8 heap graph extractor. class V8HeapExplorer : public HeapEntriesAllocator { public: V8HeapExplorer(HeapSnapshot* snapshot, SnapshottingProgressReportingInterface* progress, v8::HeapProfiler::ObjectNameResolver* resolver); - virtual ~V8HeapExplorer(); - virtual HeapEntry* AllocateEntry(HeapThing ptr); + ~V8HeapExplorer() override = default; + + HeapEntry* AllocateEntry(HeapThing ptr) override; int EstimateObjectsCount(); - bool IterateAndExtractReferences(SnapshotFiller* filler); + bool IterateAndExtractReferences(HeapSnapshotGenerator* generator); void TagGlobalObjects(); void TagCodeObject(Code* code); void TagBuiltinCodeObject(Code* code, const char* name); @@ -377,91 +342,74 @@ class V8HeapExplorer : public HeapEntriesAllocator { const char* GetSystemEntryName(HeapObject* object); - void ExtractLocation(int entry, HeapObject* object); - void ExtractLocationForJSFunction(int entry, JSFunction* func); - void ExtractReferences(int entry, HeapObject* obj); - void ExtractJSGlobalProxyReferences(int entry, JSGlobalProxy* proxy); - void ExtractJSObjectReferences(int entry, JSObject* js_obj); - void ExtractStringReferences(int entry, String* obj); - void ExtractSymbolReferences(int entry, Symbol* symbol); - void ExtractJSCollectionReferences(int entry, JSCollection* collection); - void ExtractJSWeakCollectionReferences(int entry, + void ExtractLocation(HeapEntry* entry, HeapObject* object); + void ExtractLocationForJSFunction(HeapEntry* entry, JSFunction* func); + void ExtractReferences(HeapEntry* entry, HeapObject* obj); + void ExtractJSGlobalProxyReferences(HeapEntry* entry, JSGlobalProxy* proxy); + void ExtractJSObjectReferences(HeapEntry* entry, JSObject* js_obj); + void ExtractStringReferences(HeapEntry* entry, String* obj); + void ExtractSymbolReferences(HeapEntry* entry, Symbol* symbol); + void ExtractJSCollectionReferences(HeapEntry* entry, + JSCollection* collection); + void ExtractJSWeakCollectionReferences(HeapEntry* entry, JSWeakCollection* collection); - void ExtractEphemeronHashTableReferences(int entry, + void ExtractEphemeronHashTableReferences(HeapEntry* entry, EphemeronHashTable* table); - void ExtractContextReferences(int entry, Context* context); - void ExtractMapReferences(int entry, Map* map); - void ExtractSharedFunctionInfoReferences(int entry, + void ExtractContextReferences(HeapEntry* entry, Context* context); + void ExtractMapReferences(HeapEntry* entry, Map* map); + void ExtractSharedFunctionInfoReferences(HeapEntry* entry, SharedFunctionInfo* shared); - void ExtractScriptReferences(int entry, Script* script); - void ExtractAccessorInfoReferences(int entry, AccessorInfo* accessor_info); - void ExtractAccessorPairReferences(int entry, AccessorPair* accessors); - void ExtractCodeReferences(int entry, Code* code); - void ExtractCellReferences(int entry, Cell* cell); - void ExtractFeedbackCellReferences(int entry, FeedbackCell* feedback_cell); - void ExtractPropertyCellReferences(int entry, PropertyCell* cell); - void ExtractAllocationSiteReferences(int entry, AllocationSite* site); + void ExtractScriptReferences(HeapEntry* entry, Script* script); + void ExtractAccessorInfoReferences(HeapEntry* entry, + AccessorInfo* accessor_info); + void ExtractAccessorPairReferences(HeapEntry* entry, AccessorPair* accessors); + void ExtractCodeReferences(HeapEntry* entry, Code* code); + void ExtractCellReferences(HeapEntry* entry, Cell* cell); + void ExtractFeedbackCellReferences(HeapEntry* entry, + FeedbackCell* feedback_cell); + void ExtractPropertyCellReferences(HeapEntry* entry, PropertyCell* cell); + void ExtractAllocationSiteReferences(HeapEntry* entry, AllocationSite* site); void ExtractArrayBoilerplateDescriptionReferences( - int entry, ArrayBoilerplateDescription* value); - void ExtractJSArrayBufferReferences(int entry, JSArrayBuffer* buffer); - void ExtractJSPromiseReferences(int entry, JSPromise* promise); - void ExtractJSGeneratorObjectReferences(int entry, + HeapEntry* entry, ArrayBoilerplateDescription* value); + void ExtractJSArrayBufferReferences(HeapEntry* entry, JSArrayBuffer* buffer); + void ExtractJSPromiseReferences(HeapEntry* entry, JSPromise* promise); + void ExtractJSGeneratorObjectReferences(HeapEntry* entry, JSGeneratorObject* generator); - void ExtractFixedArrayReferences(int entry, FixedArray* array); - void ExtractFeedbackVectorReferences(int entry, + void ExtractFixedArrayReferences(HeapEntry* entry, FixedArray* array); + void ExtractFeedbackVectorReferences(HeapEntry* entry, FeedbackVector* feedback_vector); template <typename T> - void ExtractWeakArrayReferences(int header_size, int entry, T* array); - void ExtractPropertyReferences(JSObject* js_obj, int entry); - void ExtractAccessorPairProperty(JSObject* js_obj, int entry, Name* key, + void ExtractWeakArrayReferences(int header_size, HeapEntry* entry, T* array); + void ExtractPropertyReferences(JSObject* js_obj, HeapEntry* entry); + void ExtractAccessorPairProperty(HeapEntry* entry, Name* key, Object* callback_obj, int field_offset = -1); - void ExtractElementReferences(JSObject* js_obj, int entry); - void ExtractInternalReferences(JSObject* js_obj, int entry); + void ExtractElementReferences(JSObject* js_obj, HeapEntry* entry); + void ExtractInternalReferences(JSObject* js_obj, HeapEntry* entry); bool IsEssentialObject(Object* object); bool IsEssentialHiddenReference(Object* parent, int field_offset); - void SetContextReference(HeapObject* parent_obj, - int parent, - String* reference_name, - Object* child, - int field_offset); - void SetNativeBindReference(HeapObject* parent_obj, - int parent, - const char* reference_name, - Object* child); - void SetElementReference(HeapObject* parent_obj, - int parent, - int index, - Object* child); - void SetInternalReference(HeapObject* parent_obj, - int parent, - const char* reference_name, - Object* child, - int field_offset = -1); - void SetInternalReference(HeapObject* parent_obj, - int parent, - int index, - Object* child, + void SetContextReference(HeapEntry* parent_entry, String* reference_name, + Object* child, int field_offset); + void SetNativeBindReference(HeapEntry* parent_entry, + const char* reference_name, Object* child); + void SetElementReference(HeapEntry* parent_entry, int index, Object* child); + void SetInternalReference(HeapEntry* parent_entry, const char* reference_name, + Object* child, int field_offset = -1); + void SetInternalReference(HeapEntry* parent_entry, int index, Object* child, int field_offset = -1); - void SetHiddenReference(HeapObject* parent_obj, int parent, int index, - Object* child, int field_offset); - void SetWeakReference(HeapObject* parent_obj, - int parent, - const char* reference_name, - Object* child_obj, + void SetHiddenReference(HeapObject* parent_obj, HeapEntry* parent_entry, + int index, Object* child, int field_offset); + void SetWeakReference(HeapEntry* parent_entry, const char* reference_name, + Object* child_obj, int field_offset); + void SetWeakReference(HeapEntry* parent_entry, int index, Object* child_obj, int field_offset); - void SetWeakReference(HeapObject* parent_obj, - int parent, - int index, - Object* child_obj, - int field_offset); - void SetPropertyReference(HeapObject* parent_obj, int parent, - Name* reference_name, Object* child, + void SetPropertyReference(HeapEntry* parent_entry, Name* reference_name, + Object* child, const char* name_format_string = nullptr, int field_offset = -1); void SetDataOrAccessorPropertyReference( - PropertyKind kind, JSObject* parent_obj, int parent, Name* reference_name, + PropertyKind kind, HeapEntry* parent_entry, Name* reference_name, Object* child, const char* name_format_string = nullptr, int field_offset = -1); @@ -480,10 +428,10 @@ class V8HeapExplorer : public HeapEntriesAllocator { StringsStorage* names_; HeapObjectsMap* heap_object_map_; SnapshottingProgressReportingInterface* progress_; - SnapshotFiller* filler_; - HeapObjectsSet objects_tags_; - HeapObjectsSet strong_gc_subroot_names_; - HeapObjectsSet user_roots_; + HeapSnapshotGenerator* generator_ = nullptr; + std::unordered_map<JSGlobalObject*, const char*> objects_tags_; + std::unordered_map<Object*, const char*> strong_gc_subroot_names_; + std::unordered_set<JSGlobalObject*> user_roots_; v8::HeapProfiler::ObjectNameResolver* global_object_name_resolver_; std::vector<bool> visited_fields_; @@ -505,7 +453,7 @@ class NativeObjectsExplorer { SnapshottingProgressReportingInterface* progress); virtual ~NativeObjectsExplorer(); int EstimateObjectsCount(); - bool IterateAndExtractReferences(SnapshotFiller* filler); + bool IterateAndExtractReferences(HeapSnapshotGenerator* generator); private: void FillRetainedObjects(); @@ -538,7 +486,7 @@ class NativeObjectsExplorer { HeapSnapshot* snapshot_; StringsStorage* names_; bool embedder_queried_; - HeapObjectsSet in_groups_; + std::unordered_set<Object*> in_groups_; std::unordered_map<v8::RetainedObjectInfo*, std::vector<HeapObject*>*, RetainedInfoHasher, RetainedInfoEquals> objects_by_info_; @@ -549,7 +497,7 @@ class NativeObjectsExplorer { std::unique_ptr<HeapEntriesAllocator> native_entries_allocator_; std::unique_ptr<HeapEntriesAllocator> embedder_graph_entries_allocator_; // Used during references extraction. - SnapshotFiller* filler_; + HeapSnapshotGenerator* generator_ = nullptr; v8::HeapProfiler::RetainerEdges edges_; static HeapThing const kNativesRootObject; @@ -559,27 +507,45 @@ class NativeObjectsExplorer { DISALLOW_COPY_AND_ASSIGN(NativeObjectsExplorer); }; - class HeapSnapshotGenerator : public SnapshottingProgressReportingInterface { public: + // The HeapEntriesMap instance is used to track a mapping between + // real heap objects and their representations in heap snapshots. + using HeapEntriesMap = std::unordered_map<HeapThing, HeapEntry*>; + HeapSnapshotGenerator(HeapSnapshot* snapshot, v8::ActivityControl* control, v8::HeapProfiler::ObjectNameResolver* resolver, Heap* heap); bool GenerateSnapshot(); + HeapEntry* FindEntry(HeapThing ptr) { + auto it = entries_map_.find(ptr); + return it != entries_map_.end() ? it->second : nullptr; + } + + HeapEntry* AddEntry(HeapThing ptr, HeapEntriesAllocator* allocator) { + return entries_map_.emplace(ptr, allocator->AllocateEntry(ptr)) + .first->second; + } + + HeapEntry* FindOrAddEntry(HeapThing ptr, HeapEntriesAllocator* allocator) { + HeapEntry* entry = FindEntry(ptr); + return entry != nullptr ? entry : AddEntry(ptr, allocator); + } + private: bool FillReferences(); - void ProgressStep(); - bool ProgressReport(bool force = false); + void ProgressStep() override; + bool ProgressReport(bool force = false) override; void InitProgressCounter(); HeapSnapshot* snapshot_; v8::ActivityControl* control_; V8HeapExplorer v8_heap_explorer_; NativeObjectsExplorer dom_explorer_; - // Mapping from HeapThing pointers to HeapEntry* pointers. - HeapEntriesMap entries_; + // Mapping from HeapThing pointers to HeapEntry indices. + HeapEntriesMap entries_map_; // Used during snapshot generation. int progress_counter_; int progress_total_; |