5#ifndef V8_PROFILER_HEAP_SNAPSHOT_GENERATOR_H_
6#define V8_PROFILER_HEAP_SNAPSHOT_GENERATOR_H_
11#include <unordered_map>
12#include <unordered_set>
29#ifdef V8_ENABLE_HEAP_SNAPSHOT_VERIFY
35class AllocationTraceNode;
39class HeapSnapshotGenerator;
40class IsolateSafepointScope;
43class JSGeneratorObject;
47class JSWeakCollection;
187 int max_depth,
int indent)
const;
203#ifdef V8_TARGET_ARCH_64_BIT
241 const std::vector<EntrySourceLocation>&
locations()
const {
265 unsigned trace_node_id);
273 void Print(
int max_depth);
301 std::unordered_map<ScriptId, String::LineEndsVector>;
334 Address addr,
unsigned int size,
355 int64_t* timestamp_us);
423 uint32_t EstimateObjectsCount();
424 void PopulateLineEnds();
428 std::vector<std::pair<v8::Global<v8::Object>,
const char*>>;
437 void TagBuiltinCodeObject(
Tagged<Code> code,
const char* name);
449 void MarkVisitedField(
int offset);
462 void ExtractJSGlobalProxyReferences(
HeapEntry* entry,
467 void ExtractJSCollectionReferences(
HeapEntry* entry,
469 void ExtractJSWeakCollectionReferences(
HeapEntry* entry,
471 void ExtractEphemeronHashTableReferences(
HeapEntry* entry,
475 void ExtractSharedFunctionInfoReferences(
HeapEntry* entry,
478 void ExtractAccessorInfoReferences(
HeapEntry* entry,
480 void ExtractAccessorPairReferences(
HeapEntry* entry,
483 void ExtractInstructionStreamReferences(
HeapEntry* entry,
486 void ExtractJSWeakRefReferences(
HeapEntry* entry,
489 void ExtractFeedbackCellReferences(
HeapEntry* entry,
491 void ExtractPropertyCellReferences(
HeapEntry* entry,
493 void ExtractPrototypeInfoReferences(
HeapEntry* entry,
495 void ExtractAllocationSiteReferences(
HeapEntry* entry,
497 void ExtractArrayBoilerplateDescriptionReferences(
499 void ExtractRegExpBoilerplateDescriptionReferences(
501 void ExtractJSArrayBufferReferences(
HeapEntry* entry,
504 void ExtractJSGeneratorObjectReferences(
HeapEntry* entry,
508 void ExtractBytecodeArrayReferences(
HeapEntry* entry,
511 void ExtractFeedbackVectorReferences(
HeapEntry* entry,
513 void ExtractDescriptorArrayReferences(
HeapEntry* entry,
516 void ExtractTransitionArrayReferences(
HeapEntry* entry,
518 template <
typename T>
519 void ExtractWeakArrayReferences(
int header_size,
HeapEntry* entry,
524 int field_offset = -1);
528#if V8_ENABLE_WEBASSEMBLY
531 void ExtractWasmTrustedInstanceDataReferences(
540 bool IsEssentialHiddenReference(
Tagged<Object> parent,
int field_offset);
542 void SetContextReference(
HeapEntry* parent_entry,
545 void SetNativeBindReference(
HeapEntry* parent_entry,
547 void SetElementReference(
HeapEntry* parent_entry,
int index,
549 void SetInternalReference(
HeapEntry* parent_entry,
const char* reference_name,
551 void SetInternalReference(
HeapEntry* parent_entry,
int index,
556 void SetWeakReference(
557 HeapEntry* parent_entry,
const char* reference_name,
560 void SetWeakReference(
HeapEntry* parent_entry,
int index,
562 std::optional<int> field_offset);
563 void SetPropertyReference(
HeapEntry* parent_entry,
565 const char* name_format_string =
nullptr,
566 int field_offset = -1);
567 void SetDataOrAccessorPropertyReference(
570 int field_offset = -1);
573 void SetRootGcRootsReference();
574 void SetGcRootsReference(
Root root);
575 void SetGcSubrootReference(
Root root,
const char* description,
bool is_weak,
579 std::optional<HeapEntry::Type> type = {},
580 bool overwrite_existing_name =
false);
581 void RecursivelyTagConstantPool(
Tagged<Object> obj,
const char* tag,
592 std::unordered_map<Tagged<JSGlobalObject>,
const char*,
Object::Hasher>
634class HeapEntryVerifier;
661 return it !=
smis_map_.end() ? it->second :
nullptr;
664#ifdef V8_ENABLE_HEAP_SNAPSHOT_VERIFY
670 auto it = reverse_entries_map_.find(entry);
671 return it == reverse_entries_map_.end() ?
nullptr : it->second;
674 HeapEntryVerifier* verifier()
const {
return verifier_; }
675 void set_verifier(HeapEntryVerifier* verifier) {
682 return smis_map_.emplace(smi.value(), allocator->AllocateEntry(smi))
689 if (entry->
value !=
nullptr) {
694#ifdef V8_ENABLE_HEAP_SNAPSHOT_VERIFY
695 if (
v8_flags.heap_snapshot_verify) {
696 reverse_entries_map_.emplace(
result, ptr);
704 return entry !=
nullptr ? entry :
AddEntry(smi, allocator);
728#ifdef V8_ENABLE_HEAP_SNAPSHOT_VERIFY
729 std::unordered_map<HeapEntry*, HeapThing> reverse_entries_map_;
751 return strcmp(
reinterpret_cast<char*
>(key1),
752 reinterpret_cast<char*
>(key2)) == 0;
static constexpr T decode(U value)
Entry * LookupOrInsert(const Key &key, uint32_t hash)
Entry * Lookup(const Key &key, uint32_t hash) const
virtual HeapEntry * AllocateEntry(HeapThing ptr)=0
virtual HeapEntry * AllocateEntry(Tagged< Smi > smi)=0
virtual ~HeapEntriesAllocator()=default
V8_INLINE std::vector< HeapGraphEdge * >::iterator children_end() const
void set_detachedness(v8::EmbedderGraph::Node::Detachedness value)
V8_EXPORT_PRIVATE void Print(const char *prefix, const char *edge_name, int max_depth, int indent) const
void SetIndexedAutoIndexReference(HeapGraphEdge::Type type, HeapEntry *child, HeapSnapshotGenerator *generator, ReferenceVerification verification=kVerify)
HeapEntry(HeapSnapshot *snapshot, int index, Type type, const char *name, SnapshotObjectId id, size_t self_size, unsigned trace_node_id)
const char * TypeAsString() const
uint8_t detachedness() const
SnapshotObjectId id() const
V8_INLINE void add_child(HeapGraphEdge *edge)
void VerifyReference(HeapGraphEdge::Type type, HeapEntry *entry, HeapSnapshotGenerator *generator, ReferenceVerification verification)
HeapSnapshot * snapshot()
void SetNamedAutoIndexReference(HeapGraphEdge::Type type, const char *description, HeapEntry *child, StringsStorage *strings, HeapSnapshotGenerator *generator, ReferenceVerification verification=kVerify)
V8_INLINE int set_children_index(int index)
void SetIndexedReference(HeapGraphEdge::Type type, int index, HeapEntry *entry, HeapSnapshotGenerator *generator, ReferenceVerification verification=kVerify)
V8_INLINE std::vector< HeapGraphEdge * >::iterator children_begin() const
unsigned trace_node_id() const
void set_name(const char *name)
V8_INLINE HeapGraphEdge * child(int i)
void add_self_size(size_t size)
V8_INLINE Isolate * isolate() const
const char * name() const
void SetNamedReference(HeapGraphEdge::Type type, const char *name, HeapEntry *entry, HeapSnapshotGenerator *generator, ReferenceVerification verification=kVerify)
unsigned children_end_index_
V8_INLINE int children_count() const
V8_INLINE Isolate * isolate() const
HeapGraphEdge(Type type, const char *name, HeapEntry *from, HeapEntry *to)
V8_INLINE HeapSnapshot * snapshot() const
const char * name() const
V8_INLINE HeapEntry * from() const
static const SnapshotObjectId kFirstAvailableObjectId
static const SnapshotObjectId kInternalRootObjectId
static const int kObjectIdStep
static const SnapshotObjectId kGcRootsFirstSubrootId
void UpdateObjectSize(Address addr, int size)
SnapshotObjectId next_native_id_
HeapObjectsMap(const HeapObjectsMap &)=delete
SnapshotObjectId FindOrAddEntry(Address addr, unsigned int size, MarkEntryAccessed accessed=MarkEntryAccessed::kYes, IsNativeObject is_native_object=IsNativeObject::kNo)
bool MoveObject(Address from, Address to, int size)
SnapshotObjectId last_assigned_id() const
const std::vector< TimeInterval > & samples() const
SnapshotObjectId FindMergedNativeEntry(NativeObject addr)
SnapshotObjectId get_next_native_id()
void StopHeapObjectsTracking()
HeapObjectsMap & operator=(const HeapObjectsMap &)=delete
SnapshotObjectId get_next_id()
SnapshotObjectId PushHeapObjectsStats(OutputStream *stream, int64_t *timestamp_us)
static const SnapshotObjectId kFirstAvailableNativeId
SnapshotObjectId next_id_
SnapshotObjectId FindEntry(Address addr)
static const SnapshotObjectId kGcRootsObjectId
std::unordered_map< NativeObject, size_t > merged_native_entries_map_
void AddMergedNativeEntry(NativeObject addr, Address canonical_addr)
HeapObjectsMap(Heap *heap)
std::vector< EntryInfo > entries_
void UpdateHeapObjectsMap()
std::vector< TimeInterval > time_intervals_
base::HashMap entries_map_
HeapSnapshotGenerator & operator=(const HeapSnapshotGenerator &)=delete
bool GenerateSnapshotAfterGC()
HeapEntriesMap entries_map_
HeapEntry * FindEntry(Tagged< Smi > smi)
std::unordered_map< int, HeapEntry * > SmiEntriesMap
NativeObjectsExplorer dom_explorer_
void InitProgressCounter()
bool ProgressReport(bool force=false) override
HeapEntry * FindOrAddEntry(HeapThing ptr, HeapEntriesAllocator *allocator)
HeapSnapshotGenerator(const HeapSnapshotGenerator &)=delete
cppgc::EmbedderStackState stack_state_
uint32_t progress_counter_
HeapEntry * FindEntry(HeapThing ptr)
HeapSnapshotGenerator(HeapSnapshot *snapshot, v8::ActivityControl *control, v8::HeapProfiler::ObjectNameResolver *resolver, Heap *heap, cppgc::EmbedderStackState stack_state)
V8HeapExplorer v8_heap_explorer_
void ProgressStep() override
HeapEntry * AddEntry(Tagged< Smi > smi, HeapEntriesAllocator *allocator)
HeapEntry * FindOrAddEntry(Tagged< Smi > smi, HeapEntriesAllocator *allocator)
v8::ActivityControl * control_
void SerializeTraceNode(AllocationTraceNode *node)
static const int kNodeFieldsCountWithTraceNodeId
void Serialize(v8::OutputStream *stream)
void SerializeTraceNodeInfos()
void SerializeTraceTree()
static V8_INLINE uint32_t StringHash(const void *string)
void SerializeLocation(const EntrySourceLocation &location)
void SerializeEdge(HeapGraphEdge *edge, bool first_edge)
void SerializeNode(const HeapEntry *entry)
V8_INLINE int to_node_index(const HeapEntry *e)
HeapSnapshotJSONSerializer & operator=(const HeapSnapshotJSONSerializer &)=delete
OutputStreamWriter * writer_
friend class HeapSnapshotJSONSerializerIterator
static const int kEdgeFieldsCount
void SerializeLocations()
static V8_INLINE bool StringsMatch(void *key1, void *key2)
friend class HeapSnapshotJSONSerializerEnumerator
void SerializeString(const unsigned char *s)
HeapSnapshotJSONSerializer(HeapSnapshot *snapshot)
HeapSnapshotJSONSerializer(const HeapSnapshotJSONSerializer &)=delete
uint32_t trace_function_count_
int GetStringId(const char *s)
static const int kNodeFieldsCountWithoutTraceNodeId
base::CustomMatcherHashMap strings_
HeapSnapshot(HeapProfiler *profiler, v8::HeapProfiler::HeapSnapshotMode snapshot_mode, v8::HeapProfiler::NumericsMode numerics_mode)
void AddSyntheticRootEntries()
void AddScriptLineEnds(int script_id, String::LineEndsVector &&line_ends)
std::deque< HeapEntry > & entries()
String::LineEndsVector & GetScriptLineEnds(int script_id)
std::deque< HeapGraphEdge > edges_
v8::HeapProfiler::NumericsMode numerics_mode_
SnapshotObjectId max_snapshot_js_object_id_
SnapshotObjectId max_snapshot_js_object_id() const
size_t extra_native_bytes() const
void Print(int max_depth)
const std::deque< HeapEntry > & entries() const
v8::HeapProfiler::HeapSnapshotMode snapshot_mode_
std::deque< HeapEntry > entries_
void RememberLastJSObjectId()
HeapEntry * gc_roots() const
void AddLocation(HeapEntry *entry, int scriptId, int line, int col)
HeapEntry * AddEntry(HeapEntry::Type type, const char *name, SnapshotObjectId id, size_t size, unsigned trace_node_id)
HeapProfiler * profiler() const
const std::deque< HeapGraphEdge > & edges() const
std::vector< EntrySourceLocation > locations_
std::deque< HeapGraphEdge > & edges()
void set_extra_native_bytes(size_t bytes)
HeapEntry * GetEntryById(SnapshotObjectId id)
std::unordered_map< SnapshotObjectId, HeapEntry * > entries_by_id_cache_
HeapSnapshot(const HeapSnapshot &)=delete
std::unordered_map< ScriptId, String::LineEndsVector > ScriptsLineEndsMap
size_t extra_native_bytes_
const std::vector< EntrySourceLocation > & locations() const
HeapEntry * gc_subroot_entries_[static_cast< int >(Root::kNumberOfRoots)]
ScriptsLineEndsMap scripts_line_ends_map_
HeapSnapshot & operator=(const HeapSnapshot &)=delete
HeapEntry * gc_roots_entry_
void AddGcSubrootEntry(Root root, SnapshotObjectId id)
bool expose_internals() const
std::vector< HeapGraphEdge * > children_
HeapEntry * gc_subroot(Root root) const
bool capture_numeric_value() const
std::vector< HeapGraphEdge * > & children()
NativeObjectsExplorer(const NativeObjectsExplorer &)=delete
static HeapThing const kNativesRootObject
NativeObjectsExplorer & operator=(const NativeObjectsExplorer &)=delete
HeapSnapshotGenerator * generator_
HeapEntry * EntryForEmbedderGraphNode(EmbedderGraph::Node *node)
bool IterateAndExtractReferences(HeapSnapshotGenerator *generator)
NativeObjectsExplorer(HeapSnapshot *snapshot, SnapshottingProgressReportingInterface *progress)
HeapObjectsMap * heap_object_map_
void MergeNodeIntoEntry(HeapEntry *entry, EmbedderGraph::Node *original_node, EmbedderGraph::Node *wrapper_node)
std::unique_ptr< HeapEntriesAllocator > embedder_graph_entries_allocator_
friend class GlobalHandlesExtractor
virtual bool ProgressReport(bool force)=0
virtual void ProgressStep()=0
virtual ~SnapshottingProgressReportingInterface()=default
std::vector< bool > visited_fields_
HeapObjectsMap * heap_object_map_
SnapshottingProgressReportingInterface * progress_
std::unordered_set< Tagged< JSGlobalObject >, Object::Hasher > user_roots_
v8::HeapProfiler::ObjectNameResolver * global_object_name_resolver_
V8HeapExplorer & operator=(const V8HeapExplorer &)=delete
V8_INLINE Isolate * isolate()
UnorderedHeapObjectMap< const char * > strong_gc_subroot_names_
std::unordered_map< Tagged< JSGlobalObject >, const char *, Object::Hasher > global_object_tag_map_
V8HeapExplorer(const V8HeapExplorer &)=delete
std::vector< std::pair< v8::Global< v8::Object >, const char * > > TemporaryGlobalObjectTags
~V8HeapExplorer() override=default
std::unique_ptr< icu::DateTimePatternGenerator > generator_
ZoneVector< RpoNumber > & result
PointerTemplateHashMapImpl< DefaultAllocationPolicy > HashMap
uint32_t ComputePointerHash(void *ptr)
V8_EXPORT_PRIVATE FlagValues v8_flags
refactor address components for immediate indexing make OptimizeMaglevOnNextCall optimize to turbofan instead of maglev filter for tracing turbofan compilation nullptr
std::unordered_map< Tagged< HeapObject >, T, Object::Hasher, Object::KeyEqualSafe > UnorderedHeapObjectMap
uint32_t SnapshotObjectId
SimplifiedLoweringVerifier * verifier_
#define DCHECK_IMPLIES(v1, v2)
#define DCHECK(condition)
#define V8_EXPORT_PRIVATE
EntrySourceLocation(int entry_index, int scriptId, int line, int col)
EntryInfo(SnapshotObjectId id, Address addr, unsigned int size, bool accessed)
TimeInterval(SnapshotObjectId id)
base::TimeTicks timestamp
SnapshotObjectId last_assigned_id() const
std::unique_ptr< ValueMirror > key