/src/node/deps/v8/include/v8-profiler.h
Line  | Count  | Source  | 
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 "cppgc/common.h"          // NOLINT(build/include_directory)  | 
15  |  | #include "v8-local-handle.h"       // NOLINT(build/include_directory)  | 
16  |  | #include "v8-message.h"            // NOLINT(build/include_directory)  | 
17  |  | #include "v8-persistent-handle.h"  // NOLINT(build/include_directory)  | 
18  |  |  | 
19  |  | /**  | 
20  |  |  * Profiler support for the V8 JavaScript engine.  | 
21  |  |  */  | 
22  |  | namespace v8 { | 
23  |  |  | 
24  |  | enum class EmbedderStateTag : uint8_t;  | 
25  |  | class HeapGraphNode;  | 
26  |  | struct HeapStatsUpdate;  | 
27  |  | class Object;  | 
28  |  | enum StateTag : uint16_t;  | 
29  |  |  | 
30  |  | using NativeObject = void*;  | 
31  |  | using SnapshotObjectId = uint32_t;  | 
32  |  | using ProfilerId = uint32_t;  | 
33  |  |  | 
34  |  | struct CpuProfileDeoptFrame { | 
35  |  |   int script_id;  | 
36  |  |   size_t position;  | 
37  |  | };  | 
38  |  |  | 
39  |  | namespace internal { | 
40  |  | class CpuProfile;  | 
41  |  | }  // namespace internal  | 
42  |  |  | 
43  |  | }  // namespace v8  | 
44  |  |  | 
45  |  | #ifdef V8_OS_WIN  | 
46  |  | template class V8_EXPORT std::vector<v8::CpuProfileDeoptFrame>;  | 
47  |  | #endif  | 
48  |  |  | 
49  |  | namespace v8 { | 
50  |  |  | 
51  |  | struct V8_EXPORT CpuProfileDeoptInfo { | 
52  |  |   /** A pointer to a static string owned by v8. */  | 
53  |  |   const char* deopt_reason;  | 
54  |  |   std::vector<CpuProfileDeoptFrame> stack;  | 
55  |  | };  | 
56  |  |  | 
57  |  | }  // namespace v8  | 
58  |  |  | 
59  |  | #ifdef V8_OS_WIN  | 
60  |  | template class V8_EXPORT std::vector<v8::CpuProfileDeoptInfo>;  | 
61  |  | #endif  | 
62  |  |  | 
63  |  | namespace v8 { | 
64  |  |  | 
65  |  | /**  | 
66  |  |  * CpuProfileNode represents a node in a call graph.  | 
67  |  |  */  | 
68  |  | class V8_EXPORT CpuProfileNode { | 
69  |  |  public:  | 
70  |  |   struct LineTick { | 
71  |  |     /** The 1-based number of the source line where the function originates. */  | 
72  |  |     int line;  | 
73  |  |  | 
74  |  |     /** The 1-based number of the source column where the function originates.  | 
75  |  |      */  | 
76  |  |     int column;  | 
77  |  |  | 
78  |  |     /** The count of samples associated with the source line. */  | 
79  |  |     unsigned int hit_count;  | 
80  |  |   };  | 
81  |  |  | 
82  |  |   // An annotation hinting at the source of a CpuProfileNode.  | 
83  |  |   enum SourceType { | 
84  |  |     // User-supplied script with associated resource information.  | 
85  |  |     kScript = 0,  | 
86  |  |     // Native scripts and provided builtins.  | 
87  |  |     kBuiltin = 1,  | 
88  |  |     // Callbacks into native code.  | 
89  |  |     kCallback = 2,  | 
90  |  |     // VM-internal functions or state.  | 
91  |  |     kInternal = 3,  | 
92  |  |     // A node that failed to symbolize.  | 
93  |  |     kUnresolved = 4,  | 
94  |  |   };  | 
95  |  |  | 
96  |  |   /** Returns function name (empty string for anonymous functions.) */  | 
97  |  |   Local<String> GetFunctionName() const;  | 
98  |  |  | 
99  |  |   /**  | 
100  |  |    * Returns function name (empty string for anonymous functions.)  | 
101  |  |    * The string ownership is *not* passed to the caller. It stays valid until  | 
102  |  |    * profile is deleted. The function is thread safe.  | 
103  |  |    */  | 
104  |  |   const char* GetFunctionNameStr() const;  | 
105  |  |  | 
106  |  |   /** Returns id of the script where function is located. */  | 
107  |  |   int GetScriptId() const;  | 
108  |  |  | 
109  |  |   /** Returns resource name for script from where the function originates. */  | 
110  |  |   Local<String> GetScriptResourceName() const;  | 
111  |  |  | 
112  |  |   /**  | 
113  |  |    * Returns resource name for script from where the function originates.  | 
114  |  |    * The string ownership is *not* passed to the caller. It stays valid until  | 
115  |  |    * profile is deleted. The function is thread safe.  | 
116  |  |    */  | 
117  |  |   const char* GetScriptResourceNameStr() const;  | 
118  |  |  | 
119  |  |   /**  | 
120  |  |    * Return true if the script from where the function originates is flagged as  | 
121  |  |    * being shared cross-origin.  | 
122  |  |    */  | 
123  |  |   bool IsScriptSharedCrossOrigin() const;  | 
124  |  |  | 
125  |  |   /**  | 
126  |  |    * Returns the number, 1-based, of the line where the function originates.  | 
127  |  |    * kNoLineNumberInfo if no line number information is available.  | 
128  |  |    */  | 
129  |  |   int GetLineNumber() const;  | 
130  |  |  | 
131  |  |   /**  | 
132  |  |    * Returns 1-based number of the column where the function originates.  | 
133  |  |    * kNoColumnNumberInfo if no column number information is available.  | 
134  |  |    */  | 
135  |  |   int GetColumnNumber() const;  | 
136  |  |  | 
137  |  |   /**  | 
138  |  |    * Returns the number of the function's source lines that collect the samples.  | 
139  |  |    */  | 
140  |  |   unsigned int GetHitLineCount() const;  | 
141  |  |  | 
142  |  |   /** Returns the set of source lines that collect the samples.  | 
143  |  |    *  The caller allocates buffer and responsible for releasing it.  | 
144  |  |    *  True if all available entries are copied, otherwise false.  | 
145  |  |    *  The function copies nothing if buffer is not large enough.  | 
146  |  |    */  | 
147  |  |   bool GetLineTicks(LineTick* entries, unsigned int length) const;  | 
148  |  |  | 
149  |  |   /** Returns bailout reason for the function  | 
150  |  |     * if the optimization was disabled for it.  | 
151  |  |     */  | 
152  |  |   const char* GetBailoutReason() const;  | 
153  |  |  | 
154  |  |   /**  | 
155  |  |     * Returns the count of samples where the function was currently executing.  | 
156  |  |     */  | 
157  |  |   unsigned GetHitCount() const;  | 
158  |  |  | 
159  |  |   /** Returns id of the node. The id is unique within the tree */  | 
160  |  |   unsigned GetNodeId() const;  | 
161  |  |  | 
162  |  |   /**  | 
163  |  |    * Gets the type of the source which the node was captured from.  | 
164  |  |    */  | 
165  |  |   SourceType GetSourceType() const;  | 
166  |  |  | 
167  |  |   /** Returns child nodes count of the node. */  | 
168  |  |   int GetChildrenCount() const;  | 
169  |  |  | 
170  |  |   /** Retrieves a child node by index. */  | 
171  |  |   const CpuProfileNode* GetChild(int index) const;  | 
172  |  |  | 
173  |  |   /** Retrieves the ancestor node, or null if the root. */  | 
174  |  |   const CpuProfileNode* GetParent() const;  | 
175  |  |  | 
176  |  |   /** Retrieves deopt infos for the node. */  | 
177  |  |   const std::vector<CpuProfileDeoptInfo>& GetDeoptInfos() const;  | 
178  |  |  | 
179  |  |   static const int kNoLineNumberInfo = Message::kNoLineNumberInfo;  | 
180  |  |   static const int kNoColumnNumberInfo = Message::kNoColumnInfo;  | 
181  |  | };  | 
182  |  |  | 
183  |  | /**  | 
184  |  |  * An interface for exporting data from V8, using "push" model.  | 
185  |  |  */  | 
186  |  | class V8_EXPORT OutputStream { | 
187  |  |  public:  | 
188  |  |   enum WriteResult { kContinue = 0, kAbort = 1 }; | 
189  | 0  |   virtual ~OutputStream() = default;  | 
190  |  |   /** Notify about the end of stream. */  | 
191  |  |   virtual void EndOfStream() = 0;  | 
192  |  |   /** Get preferred output chunk size. Called only once. */  | 
193  | 0  |   virtual int GetChunkSize() { return 1024; } | 
194  |  |   /**  | 
195  |  |    * Writes the next chunk of snapshot data into the stream. Writing  | 
196  |  |    * can be stopped by returning kAbort as function result. EndOfStream  | 
197  |  |    * will not be called in case writing was aborted.  | 
198  |  |    */  | 
199  |  |   virtual WriteResult WriteAsciiChunk(char* data, int size) = 0;  | 
200  |  |   /**  | 
201  |  |    * Writes the next chunk of heap stats data into the stream. Writing  | 
202  |  |    * can be stopped by returning kAbort as function result. EndOfStream  | 
203  |  |    * will not be called in case writing was aborted.  | 
204  |  |    */  | 
205  | 0  |   virtual WriteResult WriteHeapStatsChunk(HeapStatsUpdate* data, int count) { | 
206  | 0  |     return kAbort;  | 
207  | 0  |   }  | 
208  |  | };  | 
209  |  |  | 
210  |  | /**  | 
211  |  |  * CpuProfile contains a CPU profile in a form of top-down call tree  | 
212  |  |  * (from main() down to functions that do all the work).  | 
213  |  |  */  | 
214  |  | class V8_EXPORT CpuProfile { | 
215  |  |  public:  | 
216  |  |   enum SerializationFormat { | 
217  |  |     kJSON = 0  // See format description near 'Serialize' method.  | 
218  |  |   };  | 
219  |  |   /** Returns CPU profile title. */  | 
220  |  |   Local<String> GetTitle() const;  | 
221  |  |  | 
222  |  |   /** Returns the root node of the top down call tree. */  | 
223  |  |   const CpuProfileNode* GetTopDownRoot() const;  | 
224  |  |  | 
225  |  |   /**  | 
226  |  |    * Returns number of samples recorded. The samples are not recorded unless  | 
227  |  |    * |record_samples| parameter of CpuProfiler::StartCpuProfiling is true.  | 
228  |  |    */  | 
229  |  |   int GetSamplesCount() const;  | 
230  |  |  | 
231  |  |   /**  | 
232  |  |    * Returns profile node corresponding to the top frame the sample at  | 
233  |  |    * the given index.  | 
234  |  |    */  | 
235  |  |   const CpuProfileNode* GetSample(int index) const;  | 
236  |  |  | 
237  |  |   /**  | 
238  |  |    * Returns the timestamp of the sample. The timestamp is the number of  | 
239  |  |    * microseconds since some unspecified starting point.  | 
240  |  |    * The point is equal to the starting point used by GetStartTime.  | 
241  |  |    */  | 
242  |  |   int64_t GetSampleTimestamp(int index) const;  | 
243  |  |  | 
244  |  |   /**  | 
245  |  |    * Returns time when the profile recording was started (in microseconds)  | 
246  |  |    * since some unspecified starting point.  | 
247  |  |    */  | 
248  |  |   int64_t GetStartTime() const;  | 
249  |  |  | 
250  |  |   /**  | 
251  |  |    * Returns state of the vm when sample was captured.  | 
252  |  |    */  | 
253  |  |   StateTag GetSampleState(int index) const;  | 
254  |  |  | 
255  |  |   /**  | 
256  |  |    * Returns state of the embedder when sample was captured.  | 
257  |  |    */  | 
258  |  |   EmbedderStateTag GetSampleEmbedderState(int index) const;  | 
259  |  |  | 
260  |  |   /**  | 
261  |  |    * Returns time when the profile recording was stopped (in microseconds)  | 
262  |  |    * since some unspecified starting point.  | 
263  |  |    * The point is equal to the starting point used by GetStartTime.  | 
264  |  |    */  | 
265  |  |   int64_t GetEndTime() const;  | 
266  |  |  | 
267  |  |   /**  | 
268  |  |    * Deletes the profile and removes it from CpuProfiler's list.  | 
269  |  |    * All pointers to nodes previously returned become invalid.  | 
270  |  |    */  | 
271  |  |   void Delete();  | 
272  |  |  | 
273  |  |   /**  | 
274  |  |    * Prepare a serialized representation of the profile. The result  | 
275  |  |    * is written into the stream provided in chunks of specified size.  | 
276  |  |    *  | 
277  |  |    * For the JSON format, heap contents are represented as an object  | 
278  |  |    * with the following structure:  | 
279  |  |    *  | 
280  |  |    *  { | 
281  |  |    *    nodes: [nodes array],  | 
282  |  |    *    startTime: number,  | 
283  |  |    *    endTime: number  | 
284  |  |    *    samples: [strings array]  | 
285  |  |    *    timeDeltas: [numbers array]  | 
286  |  |    *  }  | 
287  |  |    *  | 
288  |  |    */  | 
289  |  |   void Serialize(OutputStream* stream,  | 
290  |  |                  SerializationFormat format = kJSON) const;  | 
291  |  | };  | 
292  |  |  | 
293  |  | enum CpuProfilingMode { | 
294  |  |   // In the resulting CpuProfile tree, intermediate nodes in a stack trace  | 
295  |  |   // (from the root to a leaf) will have line numbers that point to the start  | 
296  |  |   // line of the function, rather than the line of the callsite of the child.  | 
297  |  |   kLeafNodeLineNumbers,  | 
298  |  |   // In the resulting CpuProfile tree, nodes are separated based on the line  | 
299  |  |   // number of their callsite in their parent.  | 
300  |  |   kCallerLineNumbers,  | 
301  |  | };  | 
302  |  |  | 
303  |  | // Determines how names are derived for functions sampled.  | 
304  |  | enum CpuProfilingNamingMode { | 
305  |  |   // Use the immediate name of functions at compilation time.  | 
306  |  |   kStandardNaming,  | 
307  |  |   // Use more verbose naming for functions without names, inferred from scope  | 
308  |  |   // where possible.  | 
309  |  |   kDebugNaming,  | 
310  |  | };  | 
311  |  |  | 
312  |  | enum CpuProfilingLoggingMode { | 
313  |  |   // Enables logging when a profile is active, and disables logging when all  | 
314  |  |   // profiles are detached.  | 
315  |  |   kLazyLogging,  | 
316  |  |   // Enables logging for the lifetime of the CpuProfiler. Calls to  | 
317  |  |   // StartRecording are faster, at the expense of runtime overhead.  | 
318  |  |   kEagerLogging,  | 
319  |  | };  | 
320  |  |  | 
321  |  | // Enum for returning profiling status. Once StartProfiling is called,  | 
322  |  | // we want to return to clients whether the profiling was able to start  | 
323  |  | // correctly, or return a descriptive error.  | 
324  |  | enum class CpuProfilingStatus { | 
325  |  |   kStarted,  | 
326  |  |   kAlreadyStarted,  | 
327  |  |   kErrorTooManyProfilers  | 
328  |  | };  | 
329  |  |  | 
330  |  | /**  | 
331  |  |  * Result from StartProfiling returning the Profiling Status, and  | 
332  |  |  * id of the started profiler, or 0 if profiler is not started  | 
333  |  |  */  | 
334  |  | struct CpuProfilingResult { | 
335  |  |   const ProfilerId id;  | 
336  |  |   const CpuProfilingStatus status;  | 
337  |  | };  | 
338  |  |  | 
339  |  | /**  | 
340  |  |  * Delegate for when max samples reached and samples are discarded.  | 
341  |  |  */  | 
342  |  | class V8_EXPORT DiscardedSamplesDelegate { | 
343  |  |  public:  | 
344  |  |   DiscardedSamplesDelegate() = default;  | 
345  |  |  | 
346  |  |   virtual ~DiscardedSamplesDelegate() = default;  | 
347  |  |   virtual void Notify() = 0;  | 
348  |  |  | 
349  | 0  |   ProfilerId GetId() const { return profiler_id_; } | 
350  |  |  | 
351  |  |  private:  | 
352  |  |   friend internal::CpuProfile;  | 
353  |  |  | 
354  | 0  |   void SetId(ProfilerId id) { profiler_id_ = id; } | 
355  |  |  | 
356  |  |   ProfilerId profiler_id_;  | 
357  |  | };  | 
358  |  |  | 
359  |  | /**  | 
360  |  |  * Optional profiling attributes.  | 
361  |  |  */  | 
362  |  | class V8_EXPORT CpuProfilingOptions { | 
363  |  |  public:  | 
364  |  |   // Indicates that the sample buffer size should not be explicitly limited.  | 
365  |  |   static const unsigned kNoSampleLimit = UINT_MAX;  | 
366  |  |  | 
367  |  |   /**  | 
368  |  |    * \param mode Type of computation of stack frame line numbers.  | 
369  |  |    * \param max_samples The maximum number of samples that should be recorded by  | 
370  |  |    *                    the profiler. Samples obtained after this limit will be  | 
371  |  |    *                    discarded.  | 
372  |  |    * \param sampling_interval_us controls the profile-specific target  | 
373  |  |    *                             sampling interval. The provided sampling  | 
374  |  |    *                             interval will be snapped to the next lowest  | 
375  |  |    *                             non-zero multiple of the profiler's sampling  | 
376  |  |    *                             interval, set via SetSamplingInterval(). If  | 
377  |  |    *                             zero, the sampling interval will be equal to  | 
378  |  |    *                             the profiler's sampling interval.  | 
379  |  |    * \param filter_context If specified, profiles will only contain frames  | 
380  |  |    *                       using this context. Other frames will be elided.  | 
381  |  |    */  | 
382  |  |   CpuProfilingOptions(  | 
383  |  |       CpuProfilingMode mode = kLeafNodeLineNumbers,  | 
384  |  |       unsigned max_samples = kNoSampleLimit, int sampling_interval_us = 0,  | 
385  |  |       MaybeLocal<Context> filter_context = MaybeLocal<Context>());  | 
386  |  |  | 
387  |  |   CpuProfilingOptions(CpuProfilingOptions&&) = default;  | 
388  |  |   CpuProfilingOptions& operator=(CpuProfilingOptions&&) = default;  | 
389  |  |  | 
390  | 0  |   CpuProfilingMode mode() const { return mode_; } | 
391  | 0  |   unsigned max_samples() const { return max_samples_; } | 
392  | 0  |   int sampling_interval_us() const { return sampling_interval_us_; } | 
393  |  |  | 
394  |  |  private:  | 
395  |  |   friend class internal::CpuProfile;  | 
396  |  |  | 
397  | 0  |   bool has_filter_context() const { return !filter_context_.IsEmpty(); } | 
398  |  |   void* raw_filter_context() const;  | 
399  |  |  | 
400  |  |   CpuProfilingMode mode_;  | 
401  |  |   unsigned max_samples_;  | 
402  |  |   int sampling_interval_us_;  | 
403  |  |   Global<Context> filter_context_;  | 
404  |  | };  | 
405  |  |  | 
406  |  | /**  | 
407  |  |  * Interface for controlling CPU profiling. Instance of the  | 
408  |  |  * profiler can be created using v8::CpuProfiler::New method.  | 
409  |  |  */  | 
410  |  | class V8_EXPORT CpuProfiler { | 
411  |  |  public:  | 
412  |  |   /**  | 
413  |  |    * Creates a new CPU profiler for the |isolate|. The isolate must be  | 
414  |  |    * initialized. The profiler object must be disposed after use by calling  | 
415  |  |    * |Dispose| method.  | 
416  |  |    */  | 
417  |  |   static CpuProfiler* New(Isolate* isolate,  | 
418  |  |                           CpuProfilingNamingMode = kDebugNaming,  | 
419  |  |                           CpuProfilingLoggingMode = kLazyLogging);  | 
420  |  |  | 
421  |  |   /**  | 
422  |  |    * Synchronously collect current stack sample in all profilers attached to  | 
423  |  |    * the |isolate|. The call does not affect number of ticks recorded for  | 
424  |  |    * the current top node.  | 
425  |  |    * |trace_id| is an optional identifier set to the collected sample.  | 
426  |  |    * this is useful to associate the sample with a trace event.  | 
427  |  |    */  | 
428  |  |   static void CollectSample(  | 
429  |  |       Isolate* isolate, const std::optional<uint64_t> trace_id = std::nullopt);  | 
430  |  |  | 
431  |  |   /**  | 
432  |  |    * Disposes the CPU profiler object.  | 
433  |  |    */  | 
434  |  |   void Dispose();  | 
435  |  |  | 
436  |  |   /**  | 
437  |  |    * Changes default CPU profiler sampling interval to the specified number  | 
438  |  |    * of microseconds. Default interval is 1000us. This method must be called  | 
439  |  |    * when there are no profiles being recorded.  | 
440  |  |    */  | 
441  |  |   void SetSamplingInterval(int us);  | 
442  |  |  | 
443  |  |   /**  | 
444  |  |    * Sets whether or not the profiler should prioritize consistency of sample  | 
445  |  |    * periodicity on Windows. Disabling this can greatly reduce CPU usage, but  | 
446  |  |    * may result in greater variance in sample timings from the platform's  | 
447  |  |    * scheduler. Defaults to enabled. This method must be called when there are  | 
448  |  |    * no profiles being recorded.  | 
449  |  |    */  | 
450  |  |   void SetUsePreciseSampling(bool);  | 
451  |  |  | 
452  |  |   /**  | 
453  |  |    * Starts collecting a CPU profile. Several profiles may be collected at once.  | 
454  |  |    * Generates an anonymous profiler, without a String identifier.  | 
455  |  |    */  | 
456  |  |   CpuProfilingResult Start(  | 
457  |  |       CpuProfilingOptions options,  | 
458  |  |       std::unique_ptr<DiscardedSamplesDelegate> delegate = nullptr);  | 
459  |  |  | 
460  |  |   /**  | 
461  |  |    * Starts collecting a CPU profile. Title may be an empty string. Several  | 
462  |  |    * profiles may be collected at once. Attempts to start collecting several  | 
463  |  |    * profiles with the same title are silently ignored.  | 
464  |  |    */  | 
465  |  |   CpuProfilingResult Start(  | 
466  |  |       Local<String> title, CpuProfilingOptions options,  | 
467  |  |       std::unique_ptr<DiscardedSamplesDelegate> delegate = nullptr);  | 
468  |  |  | 
469  |  |   /**  | 
470  |  |    * Starts profiling with the same semantics as above, except with expanded  | 
471  |  |    * parameters.  | 
472  |  |    *  | 
473  |  |    * |record_samples| parameter controls whether individual samples should  | 
474  |  |    * be recorded in addition to the aggregated tree.  | 
475  |  |    *  | 
476  |  |    * |max_samples| controls the maximum number of samples that should be  | 
477  |  |    * recorded by the profiler. Samples obtained after this limit will be  | 
478  |  |    * discarded.  | 
479  |  |    */  | 
480  |  |   CpuProfilingResult Start(  | 
481  |  |       Local<String> title, CpuProfilingMode mode, bool record_samples = false,  | 
482  |  |       unsigned max_samples = CpuProfilingOptions::kNoSampleLimit);  | 
483  |  |  | 
484  |  |   /**  | 
485  |  |    * The same as StartProfiling above, but the CpuProfilingMode defaults to  | 
486  |  |    * kLeafNodeLineNumbers mode, which was the previous default behavior of the  | 
487  |  |    * profiler.  | 
488  |  |    */  | 
489  |  |   CpuProfilingResult Start(Local<String> title, bool record_samples = false);  | 
490  |  |  | 
491  |  |   /**  | 
492  |  |    * Starts collecting a CPU profile. Title may be an empty string. Several  | 
493  |  |    * profiles may be collected at once. Attempts to start collecting several  | 
494  |  |    * profiles with the same title are silently ignored.  | 
495  |  |    */  | 
496  |  |   CpuProfilingStatus StartProfiling(  | 
497  |  |       Local<String> title, CpuProfilingOptions options,  | 
498  |  |       std::unique_ptr<DiscardedSamplesDelegate> delegate = nullptr);  | 
499  |  |  | 
500  |  |   /**  | 
501  |  |    * Starts profiling with the same semantics as above, except with expanded  | 
502  |  |    * parameters.  | 
503  |  |    *  | 
504  |  |    * |record_samples| parameter controls whether individual samples should  | 
505  |  |    * be recorded in addition to the aggregated tree.  | 
506  |  |    *  | 
507  |  |    * |max_samples| controls the maximum number of samples that should be  | 
508  |  |    * recorded by the profiler. Samples obtained after this limit will be  | 
509  |  |    * discarded.  | 
510  |  |    */  | 
511  |  |   CpuProfilingStatus StartProfiling(  | 
512  |  |       Local<String> title, CpuProfilingMode mode, bool record_samples = false,  | 
513  |  |       unsigned max_samples = CpuProfilingOptions::kNoSampleLimit);  | 
514  |  |  | 
515  |  |   /**  | 
516  |  |    * The same as StartProfiling above, but the CpuProfilingMode defaults to  | 
517  |  |    * kLeafNodeLineNumbers mode, which was the previous default behavior of the  | 
518  |  |    * profiler.  | 
519  |  |    */  | 
520  |  |   CpuProfilingStatus StartProfiling(Local<String> title,  | 
521  |  |                                     bool record_samples = false);  | 
522  |  |  | 
523  |  |   /**  | 
524  |  |    * Stops collecting CPU profile with a given id and returns it.  | 
525  |  |    */  | 
526  |  |   CpuProfile* Stop(ProfilerId id);  | 
527  |  |  | 
528  |  |   /**  | 
529  |  |    * Stops collecting CPU profile with a given title and returns it.  | 
530  |  |    * If the title given is empty, finishes the last profile started.  | 
531  |  |    */  | 
532  |  |   CpuProfile* StopProfiling(Local<String> title);  | 
533  |  |  | 
534  |  |   /**  | 
535  |  |    * Generate more detailed source positions to code objects. This results in  | 
536  |  |    * better results when mapping profiling samples to script source.  | 
537  |  |    */  | 
538  |  |   static void UseDetailedSourcePositionsForProfiling(Isolate* isolate);  | 
539  |  |  | 
540  |  |  private:  | 
541  |  |   CpuProfiler();  | 
542  |  |   ~CpuProfiler();  | 
543  |  |   CpuProfiler(const CpuProfiler&);  | 
544  |  |   CpuProfiler& operator=(const CpuProfiler&);  | 
545  |  | };  | 
546  |  |  | 
547  |  | /**  | 
548  |  |  * HeapSnapshotEdge represents a directed connection between heap  | 
549  |  |  * graph nodes: from retainers to retained nodes.  | 
550  |  |  */  | 
551  |  | class V8_EXPORT HeapGraphEdge { | 
552  |  |  public:  | 
553  |  |   enum Type { | 
554  |  |     kContextVariable = 0,  // A variable from a function context.  | 
555  |  |     kElement = 1,          // An element of an array.  | 
556  |  |     kProperty = 2,         // A named object property.  | 
557  |  |     kInternal = 3,         // A link that can't be accessed from JS,  | 
558  |  |                            // thus, its name isn't a real property name  | 
559  |  |                            // (e.g. parts of a ConsString).  | 
560  |  |     kHidden = 4,           // A link that is needed for proper sizes  | 
561  |  |                            // calculation, but may be hidden from user.  | 
562  |  |     kShortcut = 5,         // A link that must not be followed during  | 
563  |  |                            // sizes calculation.  | 
564  |  |     kWeak = 6              // A weak reference (ignored by the GC).  | 
565  |  |   };  | 
566  |  |  | 
567  |  |   /** Returns edge type (see HeapGraphEdge::Type). */  | 
568  |  |   Type GetType() const;  | 
569  |  |  | 
570  |  |   /**  | 
571  |  |    * Returns edge name. This can be a variable name, an element index, or  | 
572  |  |    * a property name.  | 
573  |  |    */  | 
574  |  |   Local<Value> GetName() const;  | 
575  |  |  | 
576  |  |   /** Returns origin node. */  | 
577  |  |   const HeapGraphNode* GetFromNode() const;  | 
578  |  |  | 
579  |  |   /** Returns destination node. */  | 
580  |  |   const HeapGraphNode* GetToNode() const;  | 
581  |  | };  | 
582  |  |  | 
583  |  |  | 
584  |  | /**  | 
585  |  |  * HeapGraphNode represents a node in a heap graph.  | 
586  |  |  */  | 
587  |  | class V8_EXPORT HeapGraphNode { | 
588  |  |  public:  | 
589  |  |   enum Type { | 
590  |  |     kHidden = 0,         // Hidden node, may be filtered when shown to user.  | 
591  |  |     kArray = 1,          // An array of elements.  | 
592  |  |     kString = 2,         // A string.  | 
593  |  |     kObject = 3,         // A JS object (except for arrays and strings).  | 
594  |  |     kCode = 4,           // Compiled code.  | 
595  |  |     kClosure = 5,        // Function closure.  | 
596  |  |     kRegExp = 6,         // RegExp.  | 
597  |  |     kHeapNumber = 7,     // Number stored in the heap.  | 
598  |  |     kNative = 8,         // Native object (not from V8 heap).  | 
599  |  |     kSynthetic = 9,      // Synthetic object, usually used for grouping  | 
600  |  |                          // snapshot items together.  | 
601  |  |     kConsString = 10,    // Concatenated string. A pair of pointers to strings.  | 
602  |  |     kSlicedString = 11,  // Sliced string. A fragment of another string.  | 
603  |  |     kSymbol = 12,        // A Symbol (ES6).  | 
604  |  |     kBigInt = 13,        // BigInt.  | 
605  |  |     kObjectShape = 14,   // Internal data used for tracking the shapes (or  | 
606  |  |                          // "hidden classes") of JS objects.  | 
607  |  |   };  | 
608  |  |  | 
609  |  |   /** Returns node type (see HeapGraphNode::Type). */  | 
610  |  |   Type GetType() const;  | 
611  |  |  | 
612  |  |   /**  | 
613  |  |    * Returns node name. Depending on node's type this can be the name  | 
614  |  |    * of the constructor (for objects), the name of the function (for  | 
615  |  |    * closures), string value, or an empty string (for compiled code).  | 
616  |  |    */  | 
617  |  |   Local<String> GetName() const;  | 
618  |  |  | 
619  |  |   /**  | 
620  |  |    * Returns node id. For the same heap object, the id remains the same  | 
621  |  |    * across all snapshots.  | 
622  |  |    */  | 
623  |  |   SnapshotObjectId GetId() const;  | 
624  |  |  | 
625  |  |   /** Returns node's own size, in bytes. */  | 
626  |  |   size_t GetShallowSize() const;  | 
627  |  |  | 
628  |  |   /** Returns child nodes count of the node. */  | 
629  |  |   int GetChildrenCount() const;  | 
630  |  |  | 
631  |  |   /** Retrieves a child by index. */  | 
632  |  |   const HeapGraphEdge* GetChild(int index) const;  | 
633  |  | };  | 
634  |  |  | 
635  |  | /**  | 
636  |  |  * HeapSnapshots record the state of the JS heap at some moment.  | 
637  |  |  */  | 
638  |  | class V8_EXPORT HeapSnapshot { | 
639  |  |  public:  | 
640  |  |   enum SerializationFormat { | 
641  |  |     kJSON = 0  // See format description near 'Serialize' method.  | 
642  |  |   };  | 
643  |  |  | 
644  |  |   /** Returns the root node of the heap graph. */  | 
645  |  |   const HeapGraphNode* GetRoot() const;  | 
646  |  |  | 
647  |  |   /** Returns a node by its id. */  | 
648  |  |   const HeapGraphNode* GetNodeById(SnapshotObjectId id) const;  | 
649  |  |  | 
650  |  |   /** Returns total nodes count in the snapshot. */  | 
651  |  |   int GetNodesCount() const;  | 
652  |  |  | 
653  |  |   /** Returns a node by index. */  | 
654  |  |   const HeapGraphNode* GetNode(int index) const;  | 
655  |  |  | 
656  |  |   /** Returns a max seen JS object Id. */  | 
657  |  |   SnapshotObjectId GetMaxSnapshotJSObjectId() const;  | 
658  |  |  | 
659  |  |   /**  | 
660  |  |    * Deletes the snapshot and removes it from HeapProfiler's list.  | 
661  |  |    * All pointers to nodes, edges and paths previously returned become  | 
662  |  |    * invalid.  | 
663  |  |    */  | 
664  |  |   void Delete();  | 
665  |  |  | 
666  |  |   /**  | 
667  |  |    * Prepare a serialized representation of the snapshot. The result  | 
668  |  |    * is written into the stream provided in chunks of specified size.  | 
669  |  |    * The total length of the serialized snapshot is unknown in  | 
670  |  |    * advance, it can be roughly equal to JS heap size (that means,  | 
671  |  |    * it can be really big - tens of megabytes).  | 
672  |  |    *  | 
673  |  |    * For the JSON format, heap contents are represented as an object  | 
674  |  |    * with the following structure:  | 
675  |  |    *  | 
676  |  |    *  { | 
677  |  |    *    snapshot: { | 
678  |  |    *      title: "...",  | 
679  |  |    *      uid: nnn,  | 
680  |  |    *      meta: { meta-info }, | 
681  |  |    *      node_count: nnn,  | 
682  |  |    *      edge_count: nnn  | 
683  |  |    *    },  | 
684  |  |    *    nodes: [nodes array],  | 
685  |  |    *    edges: [edges array],  | 
686  |  |    *    strings: [strings array]  | 
687  |  |    *  }  | 
688  |  |    *  | 
689  |  |    * Nodes reference strings, other nodes, and edges by their indexes  | 
690  |  |    * in corresponding arrays.  | 
691  |  |    */  | 
692  |  |   void Serialize(OutputStream* stream,  | 
693  |  |                  SerializationFormat format = kJSON) const;  | 
694  |  | };  | 
695  |  |  | 
696  |  |  | 
697  |  | /**  | 
698  |  |  * An interface for reporting progress and controlling long-running  | 
699  |  |  * activities.  | 
700  |  |  */  | 
701  |  | class V8_EXPORT ActivityControl { | 
702  |  |  public:  | 
703  |  |   enum ControlOption { | 
704  |  |     kContinue = 0,  | 
705  |  |     kAbort = 1  | 
706  |  |   };  | 
707  |  |   virtual ~ActivityControl() = default;  | 
708  |  |   /**  | 
709  |  |    * Notify about current progress. The activity can be stopped by  | 
710  |  |    * returning kAbort as the callback result.  | 
711  |  |    */  | 
712  |  |   virtual ControlOption ReportProgressValue(uint32_t done, uint32_t total) = 0;  | 
713  |  | };  | 
714  |  |  | 
715  |  | /**  | 
716  |  |  * AllocationProfile is a sampled profile of allocations done by the program.  | 
717  |  |  * This is structured as a call-graph.  | 
718  |  |  */  | 
719  |  | class V8_EXPORT AllocationProfile { | 
720  |  |  public:  | 
721  |  |   struct Allocation { | 
722  |  |     /**  | 
723  |  |      * Size of the sampled allocation object.  | 
724  |  |      */  | 
725  |  |     size_t size;  | 
726  |  |  | 
727  |  |     /**  | 
728  |  |      * The number of objects of such size that were sampled.  | 
729  |  |      */  | 
730  |  |     unsigned int count;  | 
731  |  |   };  | 
732  |  |  | 
733  |  |   /**  | 
734  |  |    * Represents a node in the call-graph.  | 
735  |  |    */  | 
736  |  |   struct Node { | 
737  |  |     /**  | 
738  |  |      * Name of the function. May be empty for anonymous functions or if the  | 
739  |  |      * script corresponding to this function has been unloaded.  | 
740  |  |      */  | 
741  |  |     Local<String> name;  | 
742  |  |  | 
743  |  |     /**  | 
744  |  |      * Name of the script containing the function. May be empty if the script  | 
745  |  |      * name is not available, or if the script has been unloaded.  | 
746  |  |      */  | 
747  |  |     Local<String> script_name;  | 
748  |  |  | 
749  |  |     /**  | 
750  |  |      * id of the script where the function is located. May be equal to  | 
751  |  |      * v8::UnboundScript::kNoScriptId in cases where the script doesn't exist.  | 
752  |  |      */  | 
753  |  |     int script_id;  | 
754  |  |  | 
755  |  |     /**  | 
756  |  |      * Start position of the function in the script.  | 
757  |  |      */  | 
758  |  |     int start_position;  | 
759  |  |  | 
760  |  |     /**  | 
761  |  |      * 1-indexed line number where the function starts. May be  | 
762  |  |      * kNoLineNumberInfo if no line number information is available.  | 
763  |  |      */  | 
764  |  |     int line_number;  | 
765  |  |  | 
766  |  |     /**  | 
767  |  |      * 1-indexed column number where the function starts. May be  | 
768  |  |      * kNoColumnNumberInfo if no line number information is available.  | 
769  |  |      */  | 
770  |  |     int column_number;  | 
771  |  |  | 
772  |  |     /**  | 
773  |  |      * Unique id of the node.  | 
774  |  |      */  | 
775  |  |     uint32_t node_id;  | 
776  |  |  | 
777  |  |     /**  | 
778  |  |      * List of callees called from this node for which we have sampled  | 
779  |  |      * allocations. The lifetime of the children is scoped to the containing  | 
780  |  |      * AllocationProfile.  | 
781  |  |      */  | 
782  |  |     std::vector<Node*> children;  | 
783  |  |  | 
784  |  |     /**  | 
785  |  |      * List of self allocations done by this node in the call-graph.  | 
786  |  |      */  | 
787  |  |     std::vector<Allocation> allocations;  | 
788  |  |   };  | 
789  |  |  | 
790  |  |   /**  | 
791  |  |    * Represent a single sample recorded for an allocation.  | 
792  |  |    */  | 
793  |  |   struct Sample { | 
794  |  |     /**  | 
795  |  |      * id of the node in the profile tree.  | 
796  |  |      */  | 
797  |  |     uint32_t node_id;  | 
798  |  |  | 
799  |  |     /**  | 
800  |  |      * Size of the sampled allocation object.  | 
801  |  |      */  | 
802  |  |     size_t size;  | 
803  |  |  | 
804  |  |     /**  | 
805  |  |      * The number of objects of such size that were sampled.  | 
806  |  |      */  | 
807  |  |     unsigned int count;  | 
808  |  |  | 
809  |  |     /**  | 
810  |  |      * Unique time-ordered id of the allocation sample. Can be used to track  | 
811  |  |      * what samples were added or removed between two snapshots.  | 
812  |  |      */  | 
813  |  |     uint64_t sample_id;  | 
814  |  |   };  | 
815  |  |  | 
816  |  |   /**  | 
817  |  |    * Returns the root node of the call-graph. The root node corresponds to an  | 
818  |  |    * empty JS call-stack. The lifetime of the returned Node* is scoped to the  | 
819  |  |    * containing AllocationProfile.  | 
820  |  |    */  | 
821  |  |   virtual Node* GetRootNode() = 0;  | 
822  |  |   virtual const std::vector<Sample>& GetSamples() = 0;  | 
823  |  |  | 
824  |  |   virtual ~AllocationProfile() = default;  | 
825  |  |  | 
826  |  |   static const int kNoLineNumberInfo = Message::kNoLineNumberInfo;  | 
827  |  |   static const int kNoColumnNumberInfo = Message::kNoColumnInfo;  | 
828  |  | };  | 
829  |  |  | 
830  |  | /**  | 
831  |  |  * An object graph consisting of embedder objects and V8 objects.  | 
832  |  |  * Edges of the graph are strong references between the objects.  | 
833  |  |  * The embedder can build this graph during heap snapshot generation  | 
834  |  |  * to include the embedder objects in the heap snapshot.  | 
835  |  |  * Usage:  | 
836  |  |  * 1) Define derived class of EmbedderGraph::Node for embedder objects.  | 
837  |  |  * 2) Set the build embedder graph callback on the heap profiler using  | 
838  |  |  *    HeapProfiler::AddBuildEmbedderGraphCallback.  | 
839  |  |  * 3) In the callback use graph->AddEdge(node1, node2) to add an edge from  | 
840  |  |  *    node1 to node2.  | 
841  |  |  * 4) To represent references from/to V8 object, construct V8 nodes using  | 
842  |  |  *    graph->V8Node(value).  | 
843  |  |  */  | 
844  |  | class V8_EXPORT EmbedderGraph { | 
845  |  |  public:  | 
846  |  |   class Node { | 
847  |  |    public:  | 
848  |  |     /**  | 
849  |  |      * Detachedness specifies whether an object is attached or detached from the  | 
850  |  |      * main application state. While unkown in general, there may be objects  | 
851  |  |      * that specifically know their state. V8 passes this information along in  | 
852  |  |      * the snapshot. Users of the snapshot may use it to annotate the object  | 
853  |  |      * graph.  | 
854  |  |      */  | 
855  |  |     enum class Detachedness : uint8_t { | 
856  |  |       kUnknown = 0,  | 
857  |  |       kAttached = 1,  | 
858  |  |       kDetached = 2,  | 
859  |  |     };  | 
860  |  |  | 
861  | 0  |     Node() = default;  | 
862  | 0  |     virtual ~Node() = default;  | 
863  |  |     virtual const char* Name() = 0;  | 
864  |  |     virtual size_t SizeInBytes() = 0;  | 
865  |  |     /**  | 
866  |  |      * The corresponding V8 wrapper node if not null.  | 
867  |  |      * During heap snapshot generation the embedder node and the V8 wrapper  | 
868  |  |      * node will be merged into one node to simplify retaining paths.  | 
869  |  |      */  | 
870  | 0  |     virtual Node* WrapperNode() { return nullptr; } | 
871  | 0  |     virtual bool IsRootNode() { return false; } | 
872  |  |     /** Must return true for non-V8 nodes. */  | 
873  | 0  |     virtual bool IsEmbedderNode() { return true; } | 
874  |  |     /**  | 
875  |  |      * Optional name prefix. It is used in Chrome for tagging detached nodes.  | 
876  |  |      */  | 
877  | 0  |     virtual const char* NamePrefix() { return nullptr; } | 
878  |  |  | 
879  |  |     /**  | 
880  |  |      * Returns the NativeObject that can be used for querying the  | 
881  |  |      * |HeapSnapshot|.  | 
882  |  |      */  | 
883  | 0  |     virtual NativeObject GetNativeObject() { return nullptr; } | 
884  |  |  | 
885  |  |     /**  | 
886  |  |      * Detachedness state of a given object. While unkown in general, there may  | 
887  |  |      * be objects that specifically know their state. V8 passes this information  | 
888  |  |      * along in the snapshot. Users of the snapshot may use it to annotate the  | 
889  |  |      * object graph.  | 
890  |  |      */  | 
891  | 0  |     virtual Detachedness GetDetachedness() { return Detachedness::kUnknown; } | 
892  |  |  | 
893  |  |     /**  | 
894  |  |      * Returns the address of the object in the embedder heap, or nullptr to not  | 
895  |  |      * specify the address. If this address is provided, then V8 can generate  | 
896  |  |      * consistent IDs for objects across subsequent heap snapshots, which allows  | 
897  |  |      * devtools to determine which objects were retained from one snapshot to  | 
898  |  |      * the next. This value is used only if GetNativeObject returns nullptr.  | 
899  |  |      */  | 
900  | 0  |     virtual const void* GetAddress() { return nullptr; } | 
901  |  |  | 
902  |  |     Node(const Node&) = delete;  | 
903  |  |     Node& operator=(const Node&) = delete;  | 
904  |  |   };  | 
905  |  |  | 
906  |  |   /**  | 
907  |  |    * Returns a node corresponding to the given V8 value. Ownership is not  | 
908  |  |    * transferred. The result pointer is valid while the graph is alive.  | 
909  |  |    *  | 
910  |  |    * For now the variant that takes v8::Data is not marked as abstract for  | 
911  |  |    * compatibility, but embedders who subclass EmbedderGraph are expected to  | 
912  |  |    * implement it. Then in the implementation of the variant that takes  | 
913  |  |    * v8::Value, they can simply forward the call to the one that takes  | 
914  |  |    * v8::Local<v8::Data>.  | 
915  |  |    */  | 
916  |  |   virtual Node* V8Node(const v8::Local<v8::Value>& value) = 0;  | 
917  |  |  | 
918  |  |   /**  | 
919  |  |    * Returns a node corresponding to the given V8 value. Ownership is not  | 
920  |  |    * transferred. The result pointer is valid while the graph is alive.  | 
921  |  |    *  | 
922  |  |    * For API compatibility, this default implementation just checks that the  | 
923  |  |    * data is a v8::Value and forward it to the variant that takes v8::Value,  | 
924  |  |    * which is currently required to be implemented. In the future we'll remove  | 
925  |  |    * the v8::Value variant, and make this variant that takes v8::Data abstract  | 
926  |  |    * instead. If the embedder subclasses v8::EmbedderGraph and also use  | 
927  |  |    * v8::TracedReference<v8::Data>, they must override this variant.  | 
928  |  |    */  | 
929  |  |   virtual Node* V8Node(const v8::Local<v8::Data>& value);  | 
930  |  |  | 
931  |  |   /**  | 
932  |  |    * Adds the given node to the graph and takes ownership of the node.  | 
933  |  |    * Returns a raw pointer to the node that is valid while the graph is alive.  | 
934  |  |    */  | 
935  |  |   virtual Node* AddNode(std::unique_ptr<Node> node) = 0;  | 
936  |  |  | 
937  |  |   /**  | 
938  |  |    * Adds an edge that represents a strong reference from the given  | 
939  |  |    * node |from| to the given node |to|. The nodes must be added to the graph  | 
940  |  |    * before calling this function.  | 
941  |  |    *  | 
942  |  |    * If name is nullptr, the edge will have auto-increment indexes, otherwise  | 
943  |  |    * it will be named accordingly.  | 
944  |  |    */  | 
945  |  |   virtual void AddEdge(Node* from, Node* to, const char* name = nullptr) = 0;  | 
946  |  |  | 
947  |  |   /**  | 
948  |  |    * Adds a count of bytes that are not associated with any particular Node.  | 
949  |  |    * An embedder may use this to represent the size of nodes which were omitted  | 
950  |  |    * from this EmbedderGraph despite being retained by the graph, or other  | 
951  |  |    * overhead costs. This number will contribute to the total size in a heap  | 
952  |  |    * snapshot, without being represented in the object graph.  | 
953  |  |    */  | 
954  | 0  |   virtual void AddNativeSize(size_t size) {} | 
955  |  |  | 
956  | 0  |   virtual ~EmbedderGraph() = default;  | 
957  |  | };  | 
958  |  |  | 
959  |  | class QueryObjectPredicate { | 
960  |  |  public:  | 
961  | 0  |   virtual ~QueryObjectPredicate() = default;  | 
962  |  |   virtual bool Filter(v8::Local<v8::Object> object) = 0;  | 
963  |  | };  | 
964  |  |  | 
965  |  | /**  | 
966  |  |  * Interface for controlling heap profiling. Instance of the  | 
967  |  |  * profiler can be retrieved using v8::Isolate::GetHeapProfiler.  | 
968  |  |  */  | 
969  |  | class V8_EXPORT HeapProfiler { | 
970  |  |  public:  | 
971  |  |   void QueryObjects(v8::Local<v8::Context> context,  | 
972  |  |                     QueryObjectPredicate* predicate,  | 
973  |  |                     std::vector<v8::Global<v8::Object>>* objects);  | 
974  |  |  | 
975  |  |   enum SamplingFlags { | 
976  |  |     kSamplingNoFlags = 0,  | 
977  |  |     kSamplingForceGC = 1 << 0,  | 
978  |  |     kSamplingIncludeObjectsCollectedByMajorGC = 1 << 1,  | 
979  |  |     kSamplingIncludeObjectsCollectedByMinorGC = 1 << 2,  | 
980  |  |   };  | 
981  |  |  | 
982  |  |   /**  | 
983  |  |    * Callback function invoked during heap snapshot generation to retrieve  | 
984  |  |    * the embedder object graph. The callback should use graph->AddEdge(..) to  | 
985  |  |    * add references between the objects.  | 
986  |  |    * The callback must not trigger garbage collection in V8.  | 
987  |  |    */  | 
988  |  |   typedef void (*BuildEmbedderGraphCallback)(v8::Isolate* isolate,  | 
989  |  |                                              v8::EmbedderGraph* graph,  | 
990  |  |                                              void* data);  | 
991  |  |  | 
992  |  |   /**  | 
993  |  |    * Callback function invoked during heap snapshot generation to retrieve  | 
994  |  |    * the detachedness state of a JS object referenced by a TracedReference.  | 
995  |  |    *  | 
996  |  |    * The callback takes Local<Value> as parameter to allow the embedder to  | 
997  |  |    * unpack the TracedReference into a Local and reuse that Local for different  | 
998  |  |    * purposes.  | 
999  |  |    */  | 
1000  |  |   using GetDetachednessCallback = EmbedderGraph::Node::Detachedness (*)(  | 
1001  |  |       v8::Isolate* isolate, const v8::Local<v8::Value>& v8_value,  | 
1002  |  |       uint16_t class_id, void* data);  | 
1003  |  |  | 
1004  |  |   /** Returns the number of snapshots taken. */  | 
1005  |  |   int GetSnapshotCount();  | 
1006  |  |  | 
1007  |  |   /** Returns a snapshot by index. */  | 
1008  |  |   const HeapSnapshot* GetHeapSnapshot(int index);  | 
1009  |  |  | 
1010  |  |   /**  | 
1011  |  |    * Returns SnapshotObjectId for a heap object referenced by |value| if  | 
1012  |  |    * it has been seen by the heap profiler, kUnknownObjectId otherwise.  | 
1013  |  |    */  | 
1014  |  |   SnapshotObjectId GetObjectId(Local<Value> value);  | 
1015  |  |  | 
1016  |  |   /**  | 
1017  |  |    * Returns SnapshotObjectId for a native object referenced by |value| if it  | 
1018  |  |    * has been seen by the heap profiler, kUnknownObjectId otherwise.  | 
1019  |  |    */  | 
1020  |  |   SnapshotObjectId GetObjectId(NativeObject value);  | 
1021  |  |  | 
1022  |  |   /**  | 
1023  |  |    * Returns heap object with given SnapshotObjectId if the object is alive,  | 
1024  |  |    * otherwise empty handle is returned.  | 
1025  |  |    */  | 
1026  |  |   Local<Value> FindObjectById(SnapshotObjectId id);  | 
1027  |  |  | 
1028  |  |   /**  | 
1029  |  |    * Clears internal map from SnapshotObjectId to heap object. The new objects  | 
1030  |  |    * will not be added into it unless a heap snapshot is taken or heap object  | 
1031  |  |    * tracking is kicked off.  | 
1032  |  |    */  | 
1033  |  |   void ClearObjectIds();  | 
1034  |  |  | 
1035  |  |   /**  | 
1036  |  |    * A constant for invalid SnapshotObjectId. GetSnapshotObjectId will return  | 
1037  |  |    * it in case heap profiler cannot find id  for the object passed as  | 
1038  |  |    * parameter. HeapSnapshot::GetNodeById will always return NULL for such id.  | 
1039  |  |    */  | 
1040  |  |   static const SnapshotObjectId kUnknownObjectId = 0;  | 
1041  |  |  | 
1042  |  |   /**  | 
1043  |  |    * Callback interface for retrieving user friendly names of global objects.  | 
1044  |  |    *  | 
1045  |  |    * This interface will soon be deprecated in favour of ContextNameResolver.  | 
1046  |  |    */  | 
1047  |  |   class ObjectNameResolver { | 
1048  |  |    public:  | 
1049  |  |     /**  | 
1050  |  |      * Returns name to be used in the heap snapshot for given node. Returned  | 
1051  |  |      * string must stay alive until snapshot collection is completed.  | 
1052  |  |      */  | 
1053  |  |     virtual const char* GetName(Local<Object> object) = 0;  | 
1054  |  |  | 
1055  |  |    protected:  | 
1056  |  |     virtual ~ObjectNameResolver() = default;  | 
1057  |  |   };  | 
1058  |  |  | 
1059  |  |   /**  | 
1060  |  |    * Callback interface for retrieving user friendly names of a V8::Context  | 
1061  |  |    * objects.  | 
1062  |  |    */  | 
1063  |  |   class ContextNameResolver { | 
1064  |  |    public:  | 
1065  |  |     /**  | 
1066  |  |      * Returns name to be used in the heap snapshot for given node. Returned  | 
1067  |  |      * string must stay alive until snapshot collection is completed.  | 
1068  |  |      * If no user friendly name is available return nullptr.  | 
1069  |  |      */  | 
1070  |  |     virtual const char* GetName(Local<Context> context) = 0;  | 
1071  |  |  | 
1072  |  |    protected:  | 
1073  |  |     virtual ~ContextNameResolver() = default;  | 
1074  |  |   };  | 
1075  |  |  | 
1076  |  |   enum class HeapSnapshotMode { | 
1077  |  |     /**  | 
1078  |  |      * Heap snapshot for regular developers.  | 
1079  |  |      */  | 
1080  |  |     kRegular,  | 
1081  |  |     /**  | 
1082  |  |      * Heap snapshot is exposing internals that may be useful for experts.  | 
1083  |  |      */  | 
1084  |  |     kExposeInternals,  | 
1085  |  |   };  | 
1086  |  |  | 
1087  |  |   enum class NumericsMode { | 
1088  |  |     /**  | 
1089  |  |      * Numeric values are hidden as they are values of the corresponding  | 
1090  |  |      * objects.  | 
1091  |  |      */  | 
1092  |  |     kHideNumericValues,  | 
1093  |  |     /**  | 
1094  |  |      * Numeric values are exposed in artificial fields.  | 
1095  |  |      */  | 
1096  |  |     kExposeNumericValues  | 
1097  |  |   };  | 
1098  |  |  | 
1099  |  |   struct HeapSnapshotOptions final { | 
1100  |  |     // Manually define default constructor here to be able to use it in  | 
1101  |  |     // `TakeSnapshot()` below.  | 
1102  |  |     // NOLINTNEXTLINE  | 
1103  | 0  |     HeapSnapshotOptions() {} | 
1104  |  |  | 
1105  |  |     // TODO(https://crbug.com/333672197): remove once ObjectNameResolver is  | 
1106  |  |     // removed.  | 
1107  |  |     ALLOW_COPY_AND_MOVE_WITH_DEPRECATED_FIELDS(HeapSnapshotOptions)  | 
1108  |  |  | 
1109  |  |     /**  | 
1110  |  |      * The control used to report intermediate progress to.  | 
1111  |  |      */  | 
1112  |  |     ActivityControl* control = nullptr;  | 
1113  |  |     /**  | 
1114  |  |      * The resolver used by the snapshot generator to get names for V8 objects.  | 
1115  |  |      */  | 
1116  |  |     V8_DEPRECATE_SOON("Use context_name_resolver callback instead.") | 
1117  |  |     ObjectNameResolver* global_object_name_resolver = nullptr;  | 
1118  |  |     /**  | 
1119  |  |      * The resolver used by the snapshot generator to get names for v8::Context  | 
1120  |  |      * objects.  | 
1121  |  |      * In case both this and |global_object_name_resolver| callbacks are  | 
1122  |  |      * provided, this one will be used.  | 
1123  |  |      */  | 
1124  |  |     ContextNameResolver* context_name_resolver = nullptr;  | 
1125  |  |     /**  | 
1126  |  |      * Mode for taking the snapshot, see `HeapSnapshotMode`.  | 
1127  |  |      */  | 
1128  |  |     HeapSnapshotMode snapshot_mode = HeapSnapshotMode::kRegular;  | 
1129  |  |     /**  | 
1130  |  |      * Mode for dealing with numeric values, see `NumericsMode`.  | 
1131  |  |      */  | 
1132  |  |     NumericsMode numerics_mode = NumericsMode::kHideNumericValues;  | 
1133  |  |     /**  | 
1134  |  |      * Whether stack is considered as a root set.  | 
1135  |  |      */  | 
1136  |  |     cppgc::EmbedderStackState stack_state =  | 
1137  |  |         cppgc::EmbedderStackState::kMayContainHeapPointers;  | 
1138  |  |   };  | 
1139  |  |  | 
1140  |  |   /**  | 
1141  |  |    * Takes a heap snapshot.  | 
1142  |  |    *  | 
1143  |  |    * \returns the snapshot.  | 
1144  |  |    */  | 
1145  |  |   const HeapSnapshot* TakeHeapSnapshot(  | 
1146  |  |       const HeapSnapshotOptions& options = HeapSnapshotOptions());  | 
1147  |  |  | 
1148  |  |   /**  | 
1149  |  |    * Takes a heap snapshot. See `HeapSnapshotOptions` for details on the  | 
1150  |  |    * parameters.  | 
1151  |  |    *  | 
1152  |  |    * \returns the snapshot.  | 
1153  |  |    */  | 
1154  |  |   V8_DEPRECATE_SOON("Use overload with ContextNameResolver* resolver instead.") | 
1155  |  |   const HeapSnapshot* TakeHeapSnapshot(  | 
1156  |  |       ActivityControl* control, ObjectNameResolver* global_object_name_resolver,  | 
1157  |  |       bool hide_internals = true, bool capture_numeric_value = false);  | 
1158  |  |   const HeapSnapshot* TakeHeapSnapshot(ActivityControl* control,  | 
1159  |  |                                        ContextNameResolver* resolver,  | 
1160  |  |                                        bool hide_internals = true,  | 
1161  |  |                                        bool capture_numeric_value = false);  | 
1162  |  |   // TODO(333672197): remove this version once ObjectNameResolver* overload  | 
1163  |  |   // is removed.  | 
1164  |  |   const HeapSnapshot* TakeHeapSnapshot(ActivityControl* control,  | 
1165  |  |                                        std::nullptr_t resolver = nullptr,  | 
1166  |  |                                        bool hide_internals = true,  | 
1167  |  |                                        bool capture_numeric_value = false);  | 
1168  |  |  | 
1169  |  |   /**  | 
1170  |  |    * Obtains list of Detached JS Wrapper Objects. This functon calls garbage  | 
1171  |  |    * collection, then iterates over traced handles in the isolate  | 
1172  |  |    */  | 
1173  |  |   std::vector<v8::Local<v8::Value>> GetDetachedJSWrapperObjects();  | 
1174  |  |  | 
1175  |  |   /**  | 
1176  |  |    * Starts tracking of heap objects population statistics. After calling  | 
1177  |  |    * this method, all heap objects relocations done by the garbage collector  | 
1178  |  |    * are being registered.  | 
1179  |  |    *  | 
1180  |  |    * |track_allocations| parameter controls whether stack trace of each  | 
1181  |  |    * allocation in the heap will be recorded and reported as part of  | 
1182  |  |    * HeapSnapshot.  | 
1183  |  |    */  | 
1184  |  |   void StartTrackingHeapObjects(bool track_allocations = false);  | 
1185  |  |  | 
1186  |  |   /**  | 
1187  |  |    * Adds a new time interval entry to the aggregated statistics array. The  | 
1188  |  |    * time interval entry contains information on the current heap objects  | 
1189  |  |    * population size. The method also updates aggregated statistics and  | 
1190  |  |    * reports updates for all previous time intervals via the OutputStream  | 
1191  |  |    * object. Updates on each time interval are provided as a stream of the  | 
1192  |  |    * HeapStatsUpdate structure instances.  | 
1193  |  |    * If |timestamp_us| is supplied, timestamp of the new entry will be written  | 
1194  |  |    * into it. The return value of the function is the last seen heap object Id.  | 
1195  |  |    *  | 
1196  |  |    * StartTrackingHeapObjects must be called before the first call to this  | 
1197  |  |    * method.  | 
1198  |  |    */  | 
1199  |  |   SnapshotObjectId GetHeapStats(OutputStream* stream,  | 
1200  |  |                                 int64_t* timestamp_us = nullptr);  | 
1201  |  |  | 
1202  |  |   /**  | 
1203  |  |    * Stops tracking of heap objects population statistics, cleans up all  | 
1204  |  |    * collected data. StartHeapObjectsTracking must be called again prior to  | 
1205  |  |    * calling GetHeapStats next time.  | 
1206  |  |    */  | 
1207  |  |   void StopTrackingHeapObjects();  | 
1208  |  |  | 
1209  |  |   /**  | 
1210  |  |    * Starts gathering a sampling heap profile. A sampling heap profile is  | 
1211  |  |    * similar to tcmalloc's heap profiler and Go's mprof. It samples object  | 
1212  |  |    * allocations and builds an online 'sampling' heap profile. At any point in  | 
1213  |  |    * time, this profile is expected to be a representative sample of objects  | 
1214  |  |    * currently live in the system. Each sampled allocation includes the stack  | 
1215  |  |    * trace at the time of allocation, which makes this really useful for memory  | 
1216  |  |    * leak detection.  | 
1217  |  |    *  | 
1218  |  |    * This mechanism is intended to be cheap enough that it can be used in  | 
1219  |  |    * production with minimal performance overhead.  | 
1220  |  |    *  | 
1221  |  |    * Allocations are sampled using a randomized Poisson process. On average, one  | 
1222  |  |    * allocation will be sampled every |sample_interval| bytes allocated. The  | 
1223  |  |    * |stack_depth| parameter controls the maximum number of stack frames to be  | 
1224  |  |    * captured on each allocation.  | 
1225  |  |    *  | 
1226  |  |    * NOTE: Support for native allocations doesn't exist yet, but is anticipated  | 
1227  |  |    * in the future.  | 
1228  |  |    *  | 
1229  |  |    * Objects allocated before the sampling is started will not be included in  | 
1230  |  |    * the profile.  | 
1231  |  |    *  | 
1232  |  |    * Returns false if a sampling heap profiler is already running.  | 
1233  |  |    */  | 
1234  |  |   bool StartSamplingHeapProfiler(uint64_t sample_interval = 512 * 1024,  | 
1235  |  |                                  int stack_depth = 16,  | 
1236  |  |                                  SamplingFlags flags = kSamplingNoFlags);  | 
1237  |  |  | 
1238  |  |   /**  | 
1239  |  |    * Stops the sampling heap profile and discards the current profile.  | 
1240  |  |    */  | 
1241  |  |   void StopSamplingHeapProfiler();  | 
1242  |  |  | 
1243  |  |   /**  | 
1244  |  |    * Returns the sampled profile of allocations allocated (and still live) since  | 
1245  |  |    * StartSamplingHeapProfiler was called. The ownership of the pointer is  | 
1246  |  |    * transferred to the caller. Returns nullptr if sampling heap profiler is not  | 
1247  |  |    * active.  | 
1248  |  |    */  | 
1249  |  |   AllocationProfile* GetAllocationProfile();  | 
1250  |  |  | 
1251  |  |   /**  | 
1252  |  |    * Deletes all snapshots taken. All previously returned pointers to  | 
1253  |  |    * snapshots and their contents become invalid after this call.  | 
1254  |  |    */  | 
1255  |  |   void DeleteAllHeapSnapshots();  | 
1256  |  |  | 
1257  |  |   void AddBuildEmbedderGraphCallback(BuildEmbedderGraphCallback callback,  | 
1258  |  |                                      void* data);  | 
1259  |  |   void RemoveBuildEmbedderGraphCallback(BuildEmbedderGraphCallback callback,  | 
1260  |  |                                         void* data);  | 
1261  |  |  | 
1262  |  |   void SetGetDetachednessCallback(GetDetachednessCallback callback, void* data);  | 
1263  |  |  | 
1264  |  |   /**  | 
1265  |  |    * Returns whether the heap profiler is currently taking a snapshot.  | 
1266  |  |    */  | 
1267  |  |   bool IsTakingSnapshot();  | 
1268  |  |  | 
1269  |  |   /**  | 
1270  |  |    * Allocates a copy of the provided string within the heap snapshot generator  | 
1271  |  |    * and returns a pointer to the copy. May only be called during heap snapshot  | 
1272  |  |    * generation.  | 
1273  |  |    */  | 
1274  |  |   const char* CopyNameForHeapSnapshot(const char* name);  | 
1275  |  |  | 
1276  |  |   /**  | 
1277  |  |    * Default value of persistent handle class ID. Must not be used to  | 
1278  |  |    * define a class. Can be used to reset a class of a persistent  | 
1279  |  |    * handle.  | 
1280  |  |    */  | 
1281  |  |   static const uint16_t kPersistentHandleNoClassId = 0;  | 
1282  |  |  | 
1283  |  |  private:  | 
1284  |  |   HeapProfiler();  | 
1285  |  |   ~HeapProfiler();  | 
1286  |  |   HeapProfiler(const HeapProfiler&);  | 
1287  |  |   HeapProfiler& operator=(const HeapProfiler&);  | 
1288  |  | };  | 
1289  |  |  | 
1290  |  | /**  | 
1291  |  |  * A struct for exporting HeapStats data from V8, using "push" model.  | 
1292  |  |  * See HeapProfiler::GetHeapStats.  | 
1293  |  |  */  | 
1294  |  | struct HeapStatsUpdate { | 
1295  |  |   HeapStatsUpdate(uint32_t index, uint32_t count, uint32_t size)  | 
1296  | 0  |     : index(index), count(count), size(size) { } | 
1297  |  |   uint32_t index;  // Index of the time interval that was changed.  | 
1298  |  |   uint32_t count;  // New value of count field for the interval with this index.  | 
1299  |  |   uint32_t size;  // New value of size field for the interval with this index.  | 
1300  |  | };  | 
1301  |  |  | 
1302  |  | #define CODE_EVENTS_LIST(V)                          \  | 
1303  |  |   V(Builtin)                                         \  | 
1304  |  |   V(Callback)                                        \  | 
1305  |  |   V(Eval)                                            \  | 
1306  |  |   V(Function)                                        \  | 
1307  |  |   V(InterpretedFunction)                             \  | 
1308  |  |   V(Handler)                                         \  | 
1309  |  |   V(BytecodeHandler)                                 \  | 
1310  |  |   V(LazyCompile) /* Unused, use kFunction instead */ \  | 
1311  |  |   V(RegExp)                                          \  | 
1312  |  |   V(Script)                                          \  | 
1313  |  |   V(Stub)                                            \  | 
1314  |  |   V(Relocation)  | 
1315  |  |  | 
1316  |  | /**  | 
1317  |  |  * Note that this enum may be extended in the future. Please include a default  | 
1318  |  |  * case if this enum is used in a switch statement.  | 
1319  |  |  */  | 
1320  |  | enum CodeEventType { | 
1321  |  |   kUnknownType = 0  | 
1322  |  | #define V(Name) , k##Name##Type  | 
1323  |  |   CODE_EVENTS_LIST(V)  | 
1324  |  | #undef V  | 
1325  |  | };  | 
1326  |  |  | 
1327  |  | /**  | 
1328  |  |  * Representation of a code creation event  | 
1329  |  |  */  | 
1330  |  | class V8_EXPORT CodeEvent { | 
1331  |  |  public:  | 
1332  |  |   uintptr_t GetCodeStartAddress();  | 
1333  |  |   size_t GetCodeSize();  | 
1334  |  |   Local<String> GetFunctionName();  | 
1335  |  |   Local<String> GetScriptName();  | 
1336  |  |   int GetScriptLine();  | 
1337  |  |   int GetScriptColumn();  | 
1338  |  |   /**  | 
1339  |  |    * NOTE (mmarchini): We can't allocate objects in the heap when we collect  | 
1340  |  |    * existing code, and both the code type and the comment are not stored in the  | 
1341  |  |    * heap, so we return those as const char*.  | 
1342  |  |    */  | 
1343  |  |   CodeEventType GetCodeType();  | 
1344  |  |   const char* GetComment();  | 
1345  |  |  | 
1346  |  |   static const char* GetCodeEventTypeName(CodeEventType code_event_type);  | 
1347  |  |  | 
1348  |  |   uintptr_t GetPreviousCodeStartAddress();  | 
1349  |  | };  | 
1350  |  |  | 
1351  |  | /**  | 
1352  |  |  * Interface to listen to code creation and code relocation events.  | 
1353  |  |  */  | 
1354  |  | class V8_EXPORT CodeEventHandler { | 
1355  |  |  public:  | 
1356  |  |   /**  | 
1357  |  |    * Creates a new listener for the |isolate|. The isolate must be initialized.  | 
1358  |  |    * The listener object must be disposed after use by calling |Dispose| method.  | 
1359  |  |    * Multiple listeners can be created for the same isolate.  | 
1360  |  |    */  | 
1361  |  |   explicit CodeEventHandler(Isolate* isolate);  | 
1362  |  |   virtual ~CodeEventHandler();  | 
1363  |  |  | 
1364  |  |   /**  | 
1365  |  |    * Handle is called every time a code object is created or moved. Information  | 
1366  |  |    * about each code event will be available through the `code_event`  | 
1367  |  |    * parameter.  | 
1368  |  |    *  | 
1369  |  |    * When the CodeEventType is kRelocationType, the code for this CodeEvent has  | 
1370  |  |    * moved from `GetPreviousCodeStartAddress()` to `GetCodeStartAddress()`.  | 
1371  |  |    */  | 
1372  |  |   virtual void Handle(CodeEvent* code_event) = 0;  | 
1373  |  |  | 
1374  |  |   /**  | 
1375  |  |    * Call `Enable()` to starts listening to code creation and code relocation  | 
1376  |  |    * events. These events will be handled by `Handle()`.  | 
1377  |  |    */  | 
1378  |  |   void Enable();  | 
1379  |  |  | 
1380  |  |   /**  | 
1381  |  |    * Call `Disable()` to stop listening to code creation and code relocation  | 
1382  |  |    * events.  | 
1383  |  |    */  | 
1384  |  |   void Disable();  | 
1385  |  |  | 
1386  |  |  private:  | 
1387  |  |   CodeEventHandler();  | 
1388  |  |   CodeEventHandler(const CodeEventHandler&);  | 
1389  |  |   CodeEventHandler& operator=(const CodeEventHandler&);  | 
1390  |  |   void* internal_listener_;  | 
1391  |  | };  | 
1392  |  |  | 
1393  |  | }  // namespace v8  | 
1394  |  |  | 
1395  |  |  | 
1396  |  | #endif  // V8_V8_PROFILER_H_  |