27 is_tracking_object_moves_(false),
28 is_taking_snapshot_(false) {}
47 [&](
const std::unique_ptr<HeapSnapshot>& entry) {
48 return entry.get() == snapshot;
55 std::vector<v8::Local<v8::Value>> js_objects_found;
58 obj = iterator.
Next()) {
73 js_objects_found.push_back(data);
76 return js_objects_found;
96 cb.first(
reinterpret_cast<v8::Isolate*
>(isolate), graph, cb.second);
115 return names_->GetCopy(name);
122 new HeapSnapshot(
this, options.snapshot_mode, options.numerics_mode);
127 heap()->
stack().SetMarkerIfNeededAndCallback([
this, &options, &
result]() {
128 std::optional<CppClassNamesAsHeapObjectNameScope> use_cpp_class_name;
129 if (
result->expose_internals() &&
heap()->cpp_heap()) {
130 use_cpp_class_name.emplace(
heap()->cpp_heap());
134 options.global_object_name_resolver,
heap(),
135 options.stack_state);
136 if (!generator.GenerateSnapshot()) {
143 ids_->RemoveDeadEntries();
160 os_.write(data, size);
174 heap()->
stack().SetMarkerIfNeededAndCallback([
this, snapshot_mode]() {
176 std::string
filename =
"v8-heap-" + std::to_string(time) +
".heapsnapshot";
178 std::unique_ptr<HeapSnapshot>
result(
179 new HeapSnapshot(
this, snapshot_mode, options.numerics_mode));
181 options.global_object_name_resolver,
heap(),
182 options.stack_state);
183 if (!generator.GenerateSnapshotAfterGC())
return;
200 uint64_t sample_interval,
int stack_depth,
204 heap(),
names_.get(), sample_interval, stack_depth, flags));
222 ids_->UpdateHeapObjectsMap();
229 if (track_allocations) {
236 int64_t* timestamp_us) {
237 return ids_->PushHeapObjectsStats(stream, timestamp_us);
241 ids_->StopHeapObjectsTracking();
270 id =
ids_->FindMergedNativeEntry(obj);
281 bool is_native_object) {
283 bool known_object =
ids_->MoveObject(from, to, size);
297 ids_->UpdateObjectSize(addr, size);
305 obj = iterator.
Next()) {
306 if (
ids_->FindEntry(obj.address()) ==
id)
333 heap()->
stack().SetMarkerIfNeededAndCallback([
this, predicate, objects]() {
336 std::vector<Handle<JSTypedArray>> on_heap_typed_arrays;
340 !heap_obj.
is_null(); heap_obj = heap_iterator.
Next()) {
341 if (IsFeedbackVector(heap_obj)) {
343 }
else if (IsJSTypedArray(heap_obj) &&
347 on_heap_typed_arrays.push_back(
351 for (
auto& typed_array : on_heap_typed_arrays) {
354 typed_array->GetBuffer();
364 !heap_obj.
is_null(); heap_obj = heap_iterator.
Next()) {
365 if (!IsJSObject(heap_obj, cage_base) ||
366 IsJSExternalObject(heap_obj, cage_base))
370 if (!predicate->
Filter(v8_obj))
continue;
union v8::internal::@341::BuiltinMetadata::KindSpecificData data
EmbedderGraph::Node::Detachedness(*)( v8::Isolate *isolate, const v8::Local< v8::Value > &v8_value, uint16_t class_id, void *data) GetDetachednessCallback
static const SnapshotObjectId kUnknownObjectId
void(*) BuildEmbedderGraphCallback(v8::Isolate *isolate, v8::EmbedderGraph *graph, void *data)
virtual bool Filter(v8::Local< v8::Object > object)=0
Tagged< HeapObject > Next()
~FileOutputStream() override
void EndOfStream() override
FileOutputStream(const char *filename)
WriteResult WriteAsciiChunk(char *data, int size) override
static V8_INLINE bool InCodeSpace(Tagged< HeapObject > object)
Tagged< HeapObject > Next()
void ObjectMoveEvent(Address from, Address to, int size)
std::vector< std::pair< v8::HeapProfiler::BuildEmbedderGraphCallback, void * > > build_embedder_graph_callbacks_
base::Mutex profiler_mutex_
const char * CopyNameForHeapSnapshot(const char *name)
std::vector< std::unique_ptr< HeapSnapshot > > snapshots_
std::unique_ptr< StringsStorage > names_
DirectHandle< HeapObject > FindHeapObjectById(SnapshotObjectId id)
std::vector< v8::Local< v8::Value > > GetDetachedJSWrapperObjects()
v8::EmbedderGraph::Node::Detachedness GetDetachedness(const v8::Local< v8::Value > v8_value, uint16_t class_id)
SnapshotObjectId GetSnapshotObjectId(DirectHandle< Object > obj)
SnapshotObjectId PushHeapObjectsStats(OutputStream *stream, int64_t *timestamp_us)
int GetSnapshotsCount() const
std::unique_ptr< SamplingHeapProfiler > sampling_heap_profiler_
void StopSamplingHeapProfiler()
void TakeSnapshotToFile(const v8::HeapProfiler::HeapSnapshotOptions options, std::string filename)
void StopHeapObjectsTracking()
void SetGetDetachednessCallback(v8::HeapProfiler::GetDetachednessCallback callback, void *data)
void AllocationEvent(Address addr, int size) override
void MaybeClearStringsStorage()
bool IsTakingSnapshot() const
HeapSnapshot * GetSnapshot(int index)
void RemoveBuildEmbedderGraphCallback(v8::HeapProfiler::BuildEmbedderGraphCallback callback, void *data)
bool HasGetDetachednessCallback() const
void StartHeapObjectsTracking(bool track_allocations)
void WriteSnapshotToDiskAfterGC(HeapSnapshotMode snapshot_mode=HeapSnapshotMode::kRegular)
std::unique_ptr< HeapObjectsMap > ids_
void ObjectMoveEvent(Address from, Address to, int size, bool is_native_object)
std::unique_ptr< HeapProfilerNativeMoveListener > native_move_listener_
void AddBuildEmbedderGraphCallback(v8::HeapProfiler::BuildEmbedderGraphCallback callback, void *data)
void DeleteAllSnapshots()
AllocationProfile * GetAllocationProfile()
void UpdateObjectSizeEvent(Address addr, int size) override
bool StartSamplingHeapProfiler(uint64_t sample_interval, int stack_depth, v8::HeapProfiler::SamplingFlags)
void ClearHeapObjectMap()
void RemoveSnapshot(HeapSnapshot *snapshot)
std::unique_ptr< AllocationTracker > allocation_tracker_
Isolate * isolate() const
bool is_tracking_object_moves_
void QueryObjects(DirectHandle< Context > context, QueryObjectPredicate *predicate, std::vector< v8::Global< v8::Object > > *objects)
HeapSnapshot * TakeSnapshot(const v8::HeapProfiler::HeapSnapshotOptions options)
std::pair< v8::HeapProfiler::GetDetachednessCallback, void * > get_detachedness_callback_
void BuildEmbedderGraph(Isolate *isolate, v8::EmbedderGraph *graph)
void Serialize(v8::OutputStream *stream)
V8_EXPORT_PRIVATE void RemoveHeapObjectAllocationTracker(HeapObjectAllocationTracker *tracker)
V8_EXPORT_PRIVATE void CollectAllAvailableGarbage(GarbageCollectionReason gc_reason)
V8_EXPORT_PRIVATE void AddHeapObjectAllocationTracker(HeapObjectAllocationTracker *tracker)
V8_EXPORT_PRIVATE::heap::base::Stack & stack()
Isolate * isolate() const
void UpdateLogObjectRelocation()
V8_INLINE void * GetCppHeapWrappable(IsolateForPointerCompression isolate) const
V8_INLINE constexpr bool is_null() const
static V8_EXPORT_PRIVATE v8::Platform * GetCurrentPlatform()
DirectHandle< JSReceiver > options
ZoneVector< RpoNumber > & result
V8_INLINE IndirectHandle< T > handle(Tagged< T > object, Isolate *isolate)
void PrintF(const char *format,...)
V8_INLINE DirectHandle< T > direct_handle(Tagged< T > object, Isolate *isolate)
V8_INLINE constexpr bool IsHeapObject(TaggedImpl< kRefType, StorageType > obj)
bool IsJSApiWrapperObject(Tagged< Map > map)
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
constexpr CppHeapPointerTagRange kAnyCppHeapPointer(CppHeapPointerTag::kFirstTag, CppHeapPointerTag::kLastTag)
uint32_t SnapshotObjectId
#define DCHECK(condition)