v8 10.2.154 (node 18.16.0)
V8 is Google's open source JavaScript engine
Loading...
Searching...
No Matches
v8-profiler.h
Go to the documentation of this file.
1// Copyright 2010 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_V8_PROFILER_H_
6#define V8_V8_PROFILER_H_
7
8#include <limits.h>
9
10#include <memory>
11#include <unordered_set>
12#include <vector>
13
14#include "v8-local-handle.h" // NOLINT(build/include_directory)
15#include "v8-message.h" // NOLINT(build/include_directory)
16#include "v8-persistent-handle.h" // NOLINT(build/include_directory)
17
21namespace v8 {
22
23enum class EmbedderStateTag : uint8_t;
24class HeapGraphNode;
25struct HeapStatsUpdate;
26class Object;
27enum StateTag : int;
28
29using NativeObject = void*;
30using SnapshotObjectId = uint32_t;
31using ProfilerId = uint32_t;
32
35 size_t position;
36};
37
38namespace internal {
39class CpuProfile;
40} // namespace internal
41
42} // namespace v8
43
44#ifdef V8_OS_WIN
45template class V8_EXPORT std::vector<v8::CpuProfileDeoptFrame>;
46#endif
47
48namespace v8 {
49
52 const char* deopt_reason;
53 std::vector<CpuProfileDeoptFrame> stack;
54};
55
56} // namespace v8
57
58#ifdef V8_OS_WIN
59template class V8_EXPORT std::vector<v8::CpuProfileDeoptInfo>;
60#endif
61
62namespace v8 {
63
68 public:
69 struct LineTick {
71 int line;
72
74 unsigned int hit_count;
75 };
76
77 // An annotation hinting at the source of a CpuProfileNode.
79 // User-supplied script with associated resource information.
80 kScript = 0,
81 // Native scripts and provided builtins.
82 kBuiltin = 1,
83 // Callbacks into native code.
84 kCallback = 2,
85 // VM-internal functions or state.
86 kInternal = 3,
87 // A node that failed to symbolize.
88 kUnresolved = 4,
89 };
90
93
99 const char* GetFunctionNameStr() const;
100
102 int GetScriptId() const;
103
106
112 const char* GetScriptResourceNameStr() const;
113
119
124 int GetLineNumber() const;
125
130 int GetColumnNumber() const;
131
135 unsigned int GetHitLineCount() const;
136
142 bool GetLineTicks(LineTick* entries, unsigned int length) const;
143
147 const char* GetBailoutReason() const;
148
152 unsigned GetHitCount() const;
153
155 unsigned GetNodeId() const;
156
161
163 int GetChildrenCount() const;
164
166 const CpuProfileNode* GetChild(int index) const;
167
169 const CpuProfileNode* GetParent() const;
170
172 const std::vector<CpuProfileDeoptInfo>& GetDeoptInfos() const;
173
174 static const int kNoLineNumberInfo = Message::kNoLineNumberInfo;
175 static const int kNoColumnNumberInfo = Message::kNoColumnInfo;
176};
177
178
184 public:
187
190
195 int GetSamplesCount() const;
196
201 const CpuProfileNode* GetSample(int index) const;
202
208 int64_t GetSampleTimestamp(int index) const;
209
214 int64_t GetStartTime() const;
215
219 StateTag GetSampleState(int index) const;
220
225
231 int64_t GetEndTime() const;
232
237 void Delete();
238};
239
241 // In the resulting CpuProfile tree, intermediate nodes in a stack trace
242 // (from the root to a leaf) will have line numbers that point to the start
243 // line of the function, rather than the line of the callsite of the child.
245 // In the resulting CpuProfile tree, nodes are separated based on the line
246 // number of their callsite in their parent.
248};
249
250// Determines how names are derived for functions sampled.
252 // Use the immediate name of functions at compilation time.
254 // Use more verbose naming for functions without names, inferred from scope
255 // where possible.
257};
258
260 // Enables logging when a profile is active, and disables logging when all
261 // profiles are detached.
263 // Enables logging for the lifetime of the CpuProfiler. Calls to
264 // StartRecording are faster, at the expense of runtime overhead.
266};
267
268// Enum for returning profiling status. Once StartProfiling is called,
269// we want to return to clients whether the profiling was able to start
270// correctly, or return a descriptive error.
272 kStarted,
275};
276
284};
285
290 public:
292
293 virtual ~DiscardedSamplesDelegate() = default;
294 virtual void Notify() = 0;
295
296 ProfilerId GetId() const { return profiler_id_; }
297
298 private:
299 friend internal::CpuProfile;
300
301 void SetId(ProfilerId id) { profiler_id_ = id; }
302
303 ProfilerId profiler_id_;
304};
305
310 public:
311 // Indicates that the sample buffer size should not be explicitly limited.
312 static const unsigned kNoSampleLimit = UINT_MAX;
313
330 CpuProfilingMode mode = kLeafNodeLineNumbers,
331 unsigned max_samples = kNoSampleLimit, int sampling_interval_us = 0,
332 MaybeLocal<Context> filter_context = MaybeLocal<Context>());
333
334 CpuProfilingMode mode() const { return mode_; }
335 unsigned max_samples() const { return max_samples_; }
336 int sampling_interval_us() const { return sampling_interval_us_; }
337
338 private:
339 friend class internal::CpuProfile;
340
341 bool has_filter_context() const { return !filter_context_.IsEmpty(); }
342 void* raw_filter_context() const;
343
344 CpuProfilingMode mode_;
345 unsigned max_samples_;
346 int sampling_interval_us_;
348};
349
355 public:
361 static CpuProfiler* New(Isolate* isolate,
362 CpuProfilingNamingMode = kDebugNaming,
363 CpuProfilingLoggingMode = kLazyLogging);
364
370 static void CollectSample(Isolate* isolate);
371
375 void Dispose();
376
383
392
398 CpuProfilingOptions options,
399 std::unique_ptr<DiscardedSamplesDelegate> delegate = nullptr);
400
407 Local<String> title, CpuProfilingOptions options,
408 std::unique_ptr<DiscardedSamplesDelegate> delegate = nullptr);
409
422 Local<String> title, CpuProfilingMode mode, bool record_samples = false,
423 unsigned max_samples = CpuProfilingOptions::kNoSampleLimit);
424
430 CpuProfilingResult Start(Local<String> title, bool record_samples = false);
431
438 Local<String> title, CpuProfilingOptions options,
439 std::unique_ptr<DiscardedSamplesDelegate> delegate = nullptr);
440
453 Local<String> title, CpuProfilingMode mode, bool record_samples = false,
454 unsigned max_samples = CpuProfilingOptions::kNoSampleLimit);
455
462 bool record_samples = false);
463
468
474
480
481 private:
482 CpuProfiler();
483 ~CpuProfiler();
484 CpuProfiler(const CpuProfiler&);
485 CpuProfiler& operator=(const CpuProfiler&);
486};
487
493 public:
494 enum Type {
495 kContextVariable = 0, // A variable from a function context.
496 kElement = 1, // An element of an array.
497 kProperty = 2, // A named object property.
498 kInternal = 3, // A link that can't be accessed from JS,
499 // thus, its name isn't a real property name
500 // (e.g. parts of a ConsString).
501 kHidden = 4, // A link that is needed for proper sizes
502 // calculation, but may be hidden from user.
503 kShortcut = 5, // A link that must not be followed during
504 // sizes calculation.
505 kWeak = 6 // A weak reference (ignored by the GC).
506 };
507
509 Type GetType() const;
510
516
519
521 const HeapGraphNode* GetToNode() const;
522};
523
524
529 public:
530 enum Type {
531 kHidden = 0, // Hidden node, may be filtered when shown to user.
532 kArray = 1, // An array of elements.
533 kString = 2, // A string.
534 kObject = 3, // A JS object (except for arrays and strings).
535 kCode = 4, // Compiled code.
536 kClosure = 5, // Function closure.
537 kRegExp = 6, // RegExp.
538 kHeapNumber = 7, // Number stored in the heap.
539 kNative = 8, // Native object (not from V8 heap).
540 kSynthetic = 9, // Synthetic object, usually used for grouping
541 // snapshot items together.
542 kConsString = 10, // Concatenated string. A pair of pointers to strings.
543 kSlicedString = 11, // Sliced string. A fragment of another string.
544 kSymbol = 12, // A Symbol (ES6).
545 kBigInt = 13 // BigInt.
546 };
547
549 Type GetType() const;
550
557
563
565 size_t GetShallowSize() const;
566
568 int GetChildrenCount() const;
569
571 const HeapGraphEdge* GetChild(int index) const;
572};
573
574
579 public:
581 kContinue = 0,
582 kAbort = 1
583 };
584 virtual ~OutputStream() = default;
586 virtual void EndOfStream() = 0;
588 virtual int GetChunkSize() { return 1024; }
594 virtual WriteResult WriteAsciiChunk(char* data, int size) = 0;
601 return kAbort;
602 }
603};
604
609 public:
611 kJSON = 0 // See format description near 'Serialize' method.
612 };
613
615 const HeapGraphNode* GetRoot() const;
616
619
621 int GetNodesCount() const;
622
624 const HeapGraphNode* GetNode(int index) const;
625
628
634 void Delete();
635
663 SerializationFormat format = kJSON) const;
664};
665
666
672 public:
674 kContinue = 0,
675 kAbort = 1
676 };
677 virtual ~ActivityControl() = default;
682 virtual ControlOption ReportProgressValue(uint32_t done, uint32_t total) = 0;
683};
684
690 public:
691 struct Allocation {
695 size_t size;
696
700 unsigned int count;
701 };
702
706 struct Node {
712
718
724
729
735
741
745 uint32_t node_id;
746
752 std::vector<Node*> children;
753
757 std::vector<Allocation> allocations;
758 };
759
763 struct Sample {
767 uint32_t node_id;
768
772 size_t size;
773
777 unsigned int count;
778
783 uint64_t sample_id;
784 };
785
791 virtual Node* GetRootNode() = 0;
792 virtual const std::vector<Sample>& GetSamples() = 0;
793
794 virtual ~AllocationProfile() = default;
795
796 static const int kNoLineNumberInfo = Message::kNoLineNumberInfo;
797 static const int kNoColumnNumberInfo = Message::kNoColumnInfo;
798};
799
815 public:
816 class Node {
817 public:
825 enum class Detachedness : uint8_t {
826 kUnknown = 0,
827 kAttached = 1,
828 kDetached = 2,
829 };
830
831 Node() = default;
832 virtual ~Node() = default;
833 virtual const char* Name() = 0;
834 virtual size_t SizeInBytes() = 0;
840 virtual Node* WrapperNode() { return nullptr; }
841 virtual bool IsRootNode() { return false; }
843 virtual bool IsEmbedderNode() { return true; }
847 virtual const char* NamePrefix() { return nullptr; }
848
853 virtual NativeObject GetNativeObject() { return nullptr; }
854
861 virtual Detachedness GetDetachedness() { return Detachedness::kUnknown; }
862
863 Node(const Node&) = delete;
864 Node& operator=(const Node&) = delete;
865 };
866
871 virtual Node* V8Node(const v8::Local<v8::Value>& value) = 0;
872
877 virtual Node* AddNode(std::unique_ptr<Node> node) = 0;
878
887 virtual void AddEdge(Node* from, Node* to, const char* name = nullptr) = 0;
888
889 virtual ~EmbedderGraph() = default;
890};
891
897 public:
899 kSamplingNoFlags = 0,
900 kSamplingForceGC = 1 << 0,
901 };
902
909 typedef void (*BuildEmbedderGraphCallback)(v8::Isolate* isolate,
910 v8::EmbedderGraph* graph,
911 void* data);
912
922 v8::Isolate* isolate, const v8::Local<v8::Value>& v8_value,
923 uint16_t class_id, void* data);
924
927
929 const HeapSnapshot* GetHeapSnapshot(int index);
930
936
942
948
955
961 static const SnapshotObjectId kUnknownObjectId = 0;
962
967 public:
972 virtual const char* GetName(Local<Object> object) = 0;
973
974 protected:
975 virtual ~ObjectNameResolver() = default;
976 };
977
982 ActivityControl* control = nullptr,
983 ObjectNameResolver* global_object_name_resolver = nullptr,
984 bool treat_global_objects_as_roots = true,
985 bool capture_numeric_value = false);
986
996 void StartTrackingHeapObjects(bool track_allocations = false);
997
1012 int64_t* timestamp_us = nullptr);
1013
1020
1048 bool StartSamplingHeapProfiler(uint64_t sample_interval = 512 * 1024,
1049 int stack_depth = 16,
1050 SamplingFlags flags = kSamplingNoFlags);
1051
1056
1064
1070
1071 void AddBuildEmbedderGraphCallback(BuildEmbedderGraphCallback callback,
1072 void* data);
1073 void RemoveBuildEmbedderGraphCallback(BuildEmbedderGraphCallback callback,
1074 void* data);
1075
1077
1083 static const uint16_t kPersistentHandleNoClassId = 0;
1084
1085 private:
1086 HeapProfiler();
1087 ~HeapProfiler();
1088 HeapProfiler(const HeapProfiler&);
1089 HeapProfiler& operator=(const HeapProfiler&);
1090};
1091
1097 HeapStatsUpdate(uint32_t index, uint32_t count, uint32_t size)
1098 : index(index), count(count), size(size) { }
1099 uint32_t index; // Index of the time interval that was changed.
1100 uint32_t count; // New value of count field for the interval with this index.
1101 uint32_t size; // New value of size field for the interval with this index.
1102};
1103
1104#define CODE_EVENTS_LIST(V) \
1105 V(Builtin) \
1106 V(Callback) \
1107 V(Eval) \
1108 V(Function) \
1109 V(InterpretedFunction) \
1110 V(Handler) \
1111 V(BytecodeHandler) \
1112 V(LazyCompile) \
1113 V(RegExp) \
1114 V(Script) \
1115 V(Stub) \
1116 V(Relocation)
1117
1123 kUnknownType = 0
1124#define V(Name) , k##Name##Type
1126#undef V
1128
1133 public:
1135 size_t GetCodeSize();
1146 const char* GetComment();
1147
1148 static const char* GetCodeEventTypeName(CodeEventType code_event_type);
1149
1151};
1152
1157 public:
1163 explicit CodeEventHandler(Isolate* isolate);
1165
1174 virtual void Handle(CodeEvent* code_event) = 0;
1175
1180 void Enable();
1181
1186 void Disable();
1187
1188 private:
1191 CodeEventHandler& operator=(const CodeEventHandler&);
1192 void* internal_listener_;
1193};
1194
1195} // namespace v8
1196
1197
1198#endif // V8_V8_PROFILER_H_
virtual ~ActivityControl()=default
virtual ControlOption ReportProgressValue(uint32_t done, uint32_t total)=0
virtual ~AllocationProfile()=default
virtual Node * GetRootNode()=0
virtual const std::vector< Sample > & GetSamples()=0
virtual void Handle(CodeEvent *code_event)=0
virtual ~CodeEventHandler()
CodeEventHandler(Isolate *isolate)
int GetScriptLine()
CodeEventType GetCodeType()
size_t GetCodeSize()
Local< String > GetFunctionName()
int GetScriptColumn()
Local< String > GetScriptName()
uintptr_t GetCodeStartAddress()
const char * GetComment()
static const char * GetCodeEventTypeName(CodeEventType code_event_type)
uintptr_t GetPreviousCodeStartAddress()
int64_t GetStartTime() const
StateTag GetSampleState(int index) const
const CpuProfileNode * GetTopDownRoot() const
EmbedderStateTag GetSampleEmbedderState(int index) const
int64_t GetSampleTimestamp(int index) const
Local< String > GetTitle() const
int GetSamplesCount() const
int64_t GetEndTime() const
const CpuProfileNode * GetSample(int index) const
const char * GetBailoutReason() const
const CpuProfileNode * GetParent() const
Local< String > GetFunctionName() const
int GetChildrenCount() const
const std::vector< CpuProfileDeoptInfo > & GetDeoptInfos() const
unsigned GetNodeId() const
const char * GetScriptResourceNameStr() const
bool IsScriptSharedCrossOrigin() const
Local< String > GetScriptResourceName() const
bool GetLineTicks(LineTick *entries, unsigned int length) const
int GetLineNumber() const
const CpuProfileNode * GetChild(int index) const
int GetColumnNumber() const
unsigned int GetHitLineCount() const
int GetScriptId() const
SourceType GetSourceType() const
const char * GetFunctionNameStr() const
unsigned GetHitCount() const
CpuProfilingResult Start(Local< String > title, bool record_samples=false)
CpuProfile * StopProfiling(Local< String > title)
CpuProfilingResult Start(Local< String > title, CpuProfilingOptions options, std::unique_ptr< DiscardedSamplesDelegate > delegate=nullptr)
static void CollectSample(Isolate *isolate)
CpuProfilingResult Start(Local< String > title, CpuProfilingMode mode, bool record_samples=false, unsigned max_samples=CpuProfilingOptions::kNoSampleLimit)
CpuProfile * Stop(ProfilerId id)
void SetSamplingInterval(int us)
CpuProfilingStatus StartProfiling(Local< String > title, CpuProfilingMode mode, bool record_samples=false, unsigned max_samples=CpuProfilingOptions::kNoSampleLimit)
CpuProfilingStatus StartProfiling(Local< String > title, bool record_samples=false)
static void UseDetailedSourcePositionsForProfiling(Isolate *isolate)
void SetUsePreciseSampling(bool)
CpuProfilingStatus StartProfiling(Local< String > title, CpuProfilingOptions options, std::unique_ptr< DiscardedSamplesDelegate > delegate=nullptr)
CpuProfilingResult Start(CpuProfilingOptions options, std::unique_ptr< DiscardedSamplesDelegate > delegate=nullptr)
static CpuProfiler * New(Isolate *isolate, CpuProfilingNamingMode=kDebugNaming, CpuProfilingLoggingMode=kLazyLogging)
unsigned max_samples() const
CpuProfilingMode mode() const
int sampling_interval_us() const
CpuProfilingOptions(CpuProfilingMode mode=kLeafNodeLineNumbers, unsigned max_samples=kNoSampleLimit, int sampling_interval_us=0, MaybeLocal< Context > filter_context=MaybeLocal< Context >())
virtual ~DiscardedSamplesDelegate()=default
ProfilerId GetId() const
virtual const char * NamePrefix()
virtual const char * Name()=0
virtual bool IsRootNode()
virtual Node * WrapperNode()
Node & operator=(const Node &)=delete
Node(const Node &)=delete
virtual NativeObject GetNativeObject()
virtual ~Node()=default
virtual Detachedness GetDetachedness()
virtual size_t SizeInBytes()=0
virtual bool IsEmbedderNode()
virtual Node * V8Node(const v8::Local< v8::Value > &value)=0
virtual ~EmbedderGraph()=default
virtual void AddEdge(Node *from, Node *to, const char *name=nullptr)=0
virtual Node * AddNode(std::unique_ptr< Node > node)=0
const HeapGraphNode * GetToNode() const
Type GetType() const
Local< Value > GetName() const
const HeapGraphNode * GetFromNode() const
const HeapGraphEdge * GetChild(int index) const
Type GetType() const
SnapshotObjectId GetId() const
int GetChildrenCount() const
Local< String > GetName() const
size_t GetShallowSize() const
virtual const char * GetName(Local< Object > object)=0
bool StartSamplingHeapProfiler(uint64_t sample_interval=512 *1024, int stack_depth=16, SamplingFlags flags=kSamplingNoFlags)
SnapshotObjectId GetObjectId(Local< Value > value)
void RemoveBuildEmbedderGraphCallback(BuildEmbedderGraphCallback callback, void *data)
void DeleteAllHeapSnapshots()
EmbedderGraph::Node::Detachedness(*)(v8::Isolate *isolate, const v8::Local< v8::Value > &v8_value, uint16_t class_id, void *data) GetDetachednessCallback
AllocationProfile * GetAllocationProfile()
void StopTrackingHeapObjects()
const HeapSnapshot * TakeHeapSnapshot(ActivityControl *control=nullptr, ObjectNameResolver *global_object_name_resolver=nullptr, bool treat_global_objects_as_roots=true, bool capture_numeric_value=false)
void SetGetDetachednessCallback(GetDetachednessCallback callback, void *data)
SnapshotObjectId GetHeapStats(OutputStream *stream, int64_t *timestamp_us=nullptr)
const HeapSnapshot * GetHeapSnapshot(int index)
Local< Value > FindObjectById(SnapshotObjectId id)
void StartTrackingHeapObjects(bool track_allocations=false)
void StopSamplingHeapProfiler()
SnapshotObjectId GetObjectId(NativeObject value)
void AddBuildEmbedderGraphCallback(BuildEmbedderGraphCallback callback, void *data)
const HeapGraphNode * GetNodeById(SnapshotObjectId id) const
SnapshotObjectId GetMaxSnapshotJSObjectId() const
const HeapGraphNode * GetNode(int index) const
void Serialize(OutputStream *stream, SerializationFormat format=kJSON) const
int GetNodesCount() const
const HeapGraphNode * GetRoot() const
virtual WriteResult WriteHeapStatsChunk(HeapStatsUpdate *data, int count)
virtual WriteResult WriteAsciiChunk(char *data, int size)=0
virtual int GetChunkSize()
virtual void EndOfStream()=0
virtual ~OutputStream()=default
void * NativeObject
Definition v8-profiler.h:29
CpuProfilingStatus
CpuProfilingLoggingMode
@ kLazyLogging
@ kEagerLogging
CpuProfilingMode
@ kLeafNodeLineNumbers
@ kCallerLineNumbers
StateTag
Definition v8-unwinder.h:36
uint32_t ProfilerId
Definition v8-profiler.h:31
CodeEventType
@ kUnknownType
CpuProfilingNamingMode
@ kDebugNaming
@ kStandardNaming
uint32_t SnapshotObjectId
Definition v8-profiler.h:30
std::vector< Node * > children
Local< String > script_name
std::vector< Allocation > allocations
const char * deopt_reason
Definition v8-profiler.h:52
std::vector< CpuProfileDeoptFrame > stack
Definition v8-profiler.h:53
const CpuProfilingStatus status
const ProfilerId id
HeapStatsUpdate(uint32_t index, uint32_t count, uint32_t size)
#define V(Name)
#define CODE_EVENTS_LIST(V)
#define V8_EXPORT
Definition v8config.h:578