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