Coverage Report

Created: 2025-10-31 09:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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_