Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-10 09:14:51

0001 // Copyright 2010 the V8 project authors. All rights reserved.
0002 // Use of this source code is governed by a BSD-style license that can be
0003 // found in the LICENSE file.
0004 
0005 #ifndef V8_V8_PROFILER_H_
0006 #define V8_V8_PROFILER_H_
0007 
0008 #include <limits.h>
0009 
0010 #include <memory>
0011 #include <unordered_set>
0012 #include <vector>
0013 
0014 #include "cppgc/common.h"          // NOLINT(build/include_directory)
0015 #include "v8-local-handle.h"       // NOLINT(build/include_directory)
0016 #include "v8-message.h"            // NOLINT(build/include_directory)
0017 #include "v8-persistent-handle.h"  // NOLINT(build/include_directory)
0018 
0019 /**
0020  * Profiler support for the V8 JavaScript engine.
0021  */
0022 namespace v8 {
0023 
0024 enum class EmbedderStateTag : uint8_t;
0025 class HeapGraphNode;
0026 struct HeapStatsUpdate;
0027 class Object;
0028 enum StateTag : uint16_t;
0029 
0030 using NativeObject = void*;
0031 using SnapshotObjectId = uint32_t;
0032 using ProfilerId = uint32_t;
0033 
0034 struct CpuProfileDeoptFrame {
0035   int script_id;
0036   size_t position;
0037 };
0038 
0039 namespace internal {
0040 class CpuProfile;
0041 }  // namespace internal
0042 
0043 }  // namespace v8
0044 
0045 #ifdef V8_OS_WIN
0046 template class V8_EXPORT std::vector<v8::CpuProfileDeoptFrame>;
0047 #endif
0048 
0049 namespace v8 {
0050 
0051 /**
0052  * Identifies which component initiated CPU profiling for proper attribution.
0053  */
0054 enum class CpuProfileSource : uint8_t {
0055   /** Default value when no explicit source is specified. */
0056   kUnspecified = 0,
0057   /** Profiling initiated via the DevTools Inspector protocol. */
0058   kInspector = 1,
0059   /** Profiling initiated by the embedder (e.g., Blink) via self-profiling API.
0060    */
0061   kSelfProfiling = 2,
0062   /** Profiling initiated internally by V8 (e.g., tracing CPU profiler). */
0063   kInternal = 3,
0064 };
0065 
0066 struct V8_EXPORT CpuProfileDeoptInfo {
0067   /** A pointer to a static string owned by v8. */
0068   const char* deopt_reason;
0069   std::vector<CpuProfileDeoptFrame> stack;
0070 };
0071 
0072 }  // namespace v8
0073 
0074 #ifdef V8_OS_WIN
0075 template class V8_EXPORT std::vector<v8::CpuProfileDeoptInfo>;
0076 #endif
0077 
0078 namespace v8 {
0079 
0080 /**
0081  * CpuProfileNode represents a node in a call graph.
0082  */
0083 class V8_EXPORT CpuProfileNode {
0084  public:
0085   struct LineTick {
0086     /** The 1-based number of the source line where the function originates. */
0087     int line;
0088 
0089     /** The 1-based number of the source column where the function originates.
0090      */
0091     int column;
0092 
0093     /** The count of samples associated with the source line. */
0094     unsigned int hit_count;
0095   };
0096 
0097   // An annotation hinting at the source of a CpuProfileNode.
0098   enum SourceType {
0099     // User-supplied script with associated resource information.
0100     kScript = 0,
0101     // Native scripts and provided builtins.
0102     kBuiltin = 1,
0103     // Callbacks into native code.
0104     kCallback = 2,
0105     // VM-internal functions or state.
0106     kInternal = 3,
0107     // A node that failed to symbolize.
0108     kUnresolved = 4,
0109   };
0110 
0111   /** Returns function name (empty string for anonymous functions.) */
0112   Local<String> GetFunctionName() const;
0113 
0114   /**
0115    * Returns function name (empty string for anonymous functions.)
0116    * The string ownership is *not* passed to the caller. It stays valid until
0117    * profile is deleted. The function is thread safe.
0118    */
0119   const char* GetFunctionNameStr() const;
0120 
0121   /** Returns id of the script where function is located. */
0122   int GetScriptId() const;
0123 
0124   /** Returns resource name for script from where the function originates. */
0125   Local<String> GetScriptResourceName() const;
0126 
0127   /**
0128    * Returns resource name for script from where the function originates.
0129    * The string ownership is *not* passed to the caller. It stays valid until
0130    * profile is deleted. The function is thread safe.
0131    */
0132   const char* GetScriptResourceNameStr() const;
0133 
0134   /**
0135    * Return true if the script from where the function originates is flagged as
0136    * being shared cross-origin.
0137    */
0138   bool IsScriptSharedCrossOrigin() const;
0139 
0140   /**
0141    * Returns the number, 1-based, of the line where the function originates.
0142    * kNoLineNumberInfo if no line number information is available.
0143    */
0144   int GetLineNumber() const;
0145 
0146   /**
0147    * Returns 1-based number of the column where the function originates.
0148    * kNoColumnNumberInfo if no column number information is available.
0149    */
0150   int GetColumnNumber() const;
0151 
0152   /**
0153    * Returns the number of the function's source lines that collect the samples.
0154    */
0155   unsigned int GetHitLineCount() const;
0156 
0157   /** Returns the set of source lines that collect the samples.
0158    *  The caller allocates buffer and responsible for releasing it.
0159    *  True if all available entries are copied, otherwise false.
0160    *  The function copies nothing if buffer is not large enough.
0161    */
0162   bool GetLineTicks(LineTick* entries, unsigned int length) const;
0163 
0164   /** Returns bailout reason for the function
0165     * if the optimization was disabled for it.
0166     */
0167   const char* GetBailoutReason() const;
0168 
0169   /**
0170     * Returns the count of samples where the function was currently executing.
0171     */
0172   unsigned GetHitCount() const;
0173 
0174   /** Returns id of the node. The id is unique within the tree */
0175   unsigned GetNodeId() const;
0176 
0177   /**
0178    * Gets the type of the source which the node was captured from.
0179    */
0180   SourceType GetSourceType() const;
0181 
0182   /** Returns child nodes count of the node. */
0183   int GetChildrenCount() const;
0184 
0185   /** Retrieves a child node by index. */
0186   const CpuProfileNode* GetChild(int index) const;
0187 
0188   /** Retrieves the ancestor node, or null if the root. */
0189   const CpuProfileNode* GetParent() const;
0190 
0191   /** Retrieves deopt infos for the node. */
0192   const std::vector<CpuProfileDeoptInfo>& GetDeoptInfos() const;
0193 
0194   static const int kNoLineNumberInfo = Message::kNoLineNumberInfo;
0195   static const int kNoColumnNumberInfo = Message::kNoColumnInfo;
0196 };
0197 
0198 /**
0199  * An interface for exporting data from V8, using "push" model.
0200  */
0201 class V8_EXPORT OutputStream {
0202  public:
0203   enum WriteResult { kContinue = 0, kAbort = 1 };
0204   virtual ~OutputStream() = default;
0205   /** Notify about the end of stream. */
0206   virtual void EndOfStream() = 0;
0207   /** Get preferred output chunk size. Called only once. */
0208   virtual int GetChunkSize() { return 1024; }
0209   /**
0210    * Writes the next chunk of snapshot data into the stream. Writing
0211    * can be stopped by returning kAbort as function result. EndOfStream
0212    * will not be called in case writing was aborted.
0213    */
0214   virtual WriteResult WriteAsciiChunk(char* data, int size) = 0;
0215   /**
0216    * Writes the next chunk of heap stats data into the stream. Writing
0217    * can be stopped by returning kAbort as function result. EndOfStream
0218    * will not be called in case writing was aborted.
0219    */
0220   virtual WriteResult WriteHeapStatsChunk(HeapStatsUpdate* data, int count) {
0221     return kAbort;
0222   }
0223 };
0224 
0225 /**
0226  * CpuProfile contains a CPU profile in a form of top-down call tree
0227  * (from main() down to functions that do all the work).
0228  */
0229 class V8_EXPORT CpuProfile {
0230  public:
0231   enum SerializationFormat {
0232     kJSON = 0  // See format description near 'Serialize' method.
0233   };
0234   /** Returns CPU profile title. */
0235   Local<String> GetTitle() const;
0236 
0237   /** Returns the root node of the top down call tree. */
0238   const CpuProfileNode* GetTopDownRoot() const;
0239 
0240   /**
0241    * Returns number of samples recorded. The samples are not recorded unless
0242    * |record_samples| parameter of CpuProfiler::StartCpuProfiling is true.
0243    */
0244   int GetSamplesCount() const;
0245 
0246   /**
0247    * Returns profile node corresponding to the top frame the sample at
0248    * the given index.
0249    */
0250   const CpuProfileNode* GetSample(int index) const;
0251 
0252   /**
0253    * Returns the timestamp of the sample. The timestamp is the number of
0254    * microseconds since some unspecified starting point.
0255    * The point is equal to the starting point used by GetStartTime.
0256    */
0257   int64_t GetSampleTimestamp(int index) const;
0258 
0259   /**
0260    * Returns time when the profile recording was started (in microseconds)
0261    * since some unspecified starting point.
0262    */
0263   int64_t GetStartTime() const;
0264 
0265   /**
0266    * Returns state of the vm when sample was captured.
0267    */
0268   StateTag GetSampleState(int index) const;
0269 
0270   /**
0271    * Returns state of the embedder when sample was captured.
0272    */
0273   EmbedderStateTag GetSampleEmbedderState(int index) const;
0274 
0275   /**
0276    * Returns time when the profile recording was stopped (in microseconds)
0277    * since some unspecified starting point.
0278    * The point is equal to the starting point used by GetStartTime.
0279    */
0280   int64_t GetEndTime() const;
0281 
0282   /**
0283    * Deletes the profile and removes it from CpuProfiler's list.
0284    * All pointers to nodes previously returned become invalid.
0285    */
0286   void Delete();
0287 
0288   /**
0289    * Prepare a serialized representation of the profile. The result
0290    * is written into the stream provided in chunks of specified size.
0291    *
0292    * For the JSON format, heap contents are represented as an object
0293    * with the following structure:
0294    *
0295    *  {
0296    *    nodes: [nodes array],
0297    *    startTime: number,
0298    *    endTime: number
0299    *    samples: [strings array]
0300    *    timeDeltas: [numbers array]
0301    *  }
0302    *
0303    */
0304   void Serialize(OutputStream* stream,
0305                  SerializationFormat format = kJSON) const;
0306 };
0307 
0308 enum CpuProfilingMode {
0309   // In the resulting CpuProfile tree, intermediate nodes in a stack trace
0310   // (from the root to a leaf) will have line numbers that point to the start
0311   // line of the function, rather than the line of the callsite of the child.
0312   kLeafNodeLineNumbers,
0313   // In the resulting CpuProfile tree, nodes are separated based on the line
0314   // number of their callsite in their parent.
0315   kCallerLineNumbers,
0316 };
0317 
0318 // Determines how names are derived for functions sampled.
0319 enum CpuProfilingNamingMode {
0320   // Use the immediate name of functions at compilation time.
0321   kStandardNaming,
0322   // Use more verbose naming for functions without names, inferred from scope
0323   // where possible.
0324   kDebugNaming,
0325 };
0326 
0327 enum CpuProfilingLoggingMode {
0328   // Enables logging when a profile is active, and disables logging when all
0329   // profiles are detached.
0330   kLazyLogging,
0331   // Enables logging for the lifetime of the CpuProfiler. Calls to
0332   // StartRecording are faster, at the expense of runtime overhead.
0333   kEagerLogging,
0334 };
0335 
0336 // Enum for returning profiling status. Once StartProfiling is called,
0337 // we want to return to clients whether the profiling was able to start
0338 // correctly, or return a descriptive error.
0339 enum class CpuProfilingStatus {
0340   kStarted,
0341   kAlreadyStarted,
0342   kErrorTooManyProfilers
0343 };
0344 
0345 /**
0346  * Result from StartProfiling returning the Profiling Status, and
0347  * id of the started profiler, or 0 if profiler is not started
0348  */
0349 struct CpuProfilingResult {
0350   const ProfilerId id;
0351   const CpuProfilingStatus status;
0352 };
0353 
0354 /**
0355  * Delegate for when max samples reached and samples are discarded.
0356  */
0357 class V8_EXPORT DiscardedSamplesDelegate {
0358  public:
0359   DiscardedSamplesDelegate() = default;
0360 
0361   virtual ~DiscardedSamplesDelegate() = default;
0362   virtual void Notify() = 0;
0363 
0364   ProfilerId GetId() const { return profiler_id_; }
0365 
0366  private:
0367   friend internal::CpuProfile;
0368 
0369   void SetId(ProfilerId id) { profiler_id_ = id; }
0370 
0371   ProfilerId profiler_id_;
0372 };
0373 
0374 /**
0375  * Optional profiling attributes.
0376  */
0377 class V8_EXPORT CpuProfilingOptions {
0378  public:
0379   // Indicates that the sample buffer size should not be explicitly limited.
0380   static const unsigned kNoSampleLimit = UINT_MAX;
0381 
0382   /**
0383    * \param mode Type of computation of stack frame line numbers.
0384    * \param max_samples The maximum number of samples that should be recorded by
0385    *                    the profiler. Samples obtained after this limit will be
0386    *                    discarded.
0387    * \param sampling_interval_us controls the profile-specific target
0388    *                             sampling interval. The provided sampling
0389    *                             interval will be snapped to the next lowest
0390    *                             non-zero multiple of the profiler's sampling
0391    *                             interval, set via SetSamplingInterval(). If
0392    *                             zero, the sampling interval will be equal to
0393    *                             the profiler's sampling interval.
0394    * \param filter_context If specified, profiles will only contain frames
0395    *                       using this context. Other frames will be elided.
0396    * \param profile_source Identifies the source of this CPU profile.
0397    */
0398   CpuProfilingOptions(
0399       CpuProfilingMode mode = kLeafNodeLineNumbers,
0400       unsigned max_samples = kNoSampleLimit, int sampling_interval_us = 0,
0401       MaybeLocal<Context> filter_context = MaybeLocal<Context>(),
0402       CpuProfileSource profile_source = CpuProfileSource::kUnspecified);
0403 
0404   CpuProfilingOptions(CpuProfilingOptions&&) = default;
0405   CpuProfilingOptions& operator=(CpuProfilingOptions&&) = default;
0406 
0407   CpuProfilingMode mode() const { return mode_; }
0408   unsigned max_samples() const { return max_samples_; }
0409   int sampling_interval_us() const { return sampling_interval_us_; }
0410   CpuProfileSource profile_source() const { return profile_source_; }
0411 
0412  private:
0413   friend class internal::CpuProfile;
0414 
0415   bool has_filter_context() const { return !filter_context_.IsEmpty(); }
0416   void* raw_filter_context() const;
0417 
0418   CpuProfilingMode mode_;
0419   unsigned max_samples_;
0420   int sampling_interval_us_;
0421   Global<Context> filter_context_;
0422   CpuProfileSource profile_source_;
0423 };
0424 
0425 /**
0426  * Interface for controlling CPU profiling. Instance of the
0427  * profiler can be created using v8::CpuProfiler::New method.
0428  */
0429 class V8_EXPORT CpuProfiler {
0430  public:
0431   /**
0432    * Creates a new CPU profiler for the |isolate|. The isolate must be
0433    * initialized. The profiler object must be disposed after use by calling
0434    * |Dispose| method.
0435    */
0436   static CpuProfiler* New(Isolate* isolate,
0437                           CpuProfilingNamingMode = kDebugNaming,
0438                           CpuProfilingLoggingMode = kLazyLogging);
0439 
0440   /**
0441    * Synchronously collect current stack sample in all profilers attached to
0442    * the |isolate|. The call does not affect number of ticks recorded for
0443    * the current top node.
0444    * |trace_id| is an optional identifier set to the collected sample.
0445    * this is useful to associate the sample with a trace event.
0446    */
0447   static void CollectSample(
0448       Isolate* isolate, const std::optional<uint64_t> trace_id = std::nullopt);
0449 
0450   /**
0451    * Disposes the CPU profiler object.
0452    */
0453   void Dispose();
0454 
0455   /**
0456    * Changes default CPU profiler sampling interval to the specified number
0457    * of microseconds. Default interval is 1000us. This method must be called
0458    * when there are no profiles being recorded.
0459    */
0460   void SetSamplingInterval(int us);
0461 
0462   /**
0463    * Sets whether or not the profiler should prioritize consistency of sample
0464    * periodicity on Windows. Disabling this can greatly reduce CPU usage, but
0465    * may result in greater variance in sample timings from the platform's
0466    * scheduler. Defaults to enabled. This method must be called when there are
0467    * no profiles being recorded.
0468    */
0469   void SetUsePreciseSampling(bool);
0470 
0471   /**
0472    * Starts collecting a CPU profile. Several profiles may be collected at once.
0473    * Generates an anonymous profiler, without a String identifier.
0474    */
0475   CpuProfilingResult Start(
0476       CpuProfilingOptions options,
0477       std::unique_ptr<DiscardedSamplesDelegate> delegate = nullptr);
0478 
0479   /**
0480    * Starts collecting a CPU profile. Title may be an empty string. Several
0481    * profiles may be collected at once. Attempts to start collecting several
0482    * profiles with the same title are silently ignored.
0483    */
0484   CpuProfilingResult Start(
0485       Local<String> title, CpuProfilingOptions options,
0486       std::unique_ptr<DiscardedSamplesDelegate> delegate = nullptr);
0487 
0488   /**
0489    * Starts profiling with the same semantics as above, except with expanded
0490    * parameters.
0491    *
0492    * |record_samples| parameter controls whether individual samples should
0493    * be recorded in addition to the aggregated tree.
0494    *
0495    * |max_samples| controls the maximum number of samples that should be
0496    * recorded by the profiler. Samples obtained after this limit will be
0497    * discarded.
0498    */
0499   CpuProfilingResult Start(
0500       Local<String> title, CpuProfilingMode mode, bool record_samples = false,
0501       unsigned max_samples = CpuProfilingOptions::kNoSampleLimit);
0502 
0503   /**
0504    * The same as StartProfiling above, but the CpuProfilingMode defaults to
0505    * kLeafNodeLineNumbers mode, which was the previous default behavior of the
0506    * profiler.
0507    */
0508   CpuProfilingResult Start(Local<String> title, bool record_samples = false);
0509 
0510   /**
0511    * Starts collecting a CPU profile. Title may be an empty string. Several
0512    * profiles may be collected at once. Attempts to start collecting several
0513    * profiles with the same title are silently ignored.
0514    */
0515   CpuProfilingStatus StartProfiling(
0516       Local<String> title, CpuProfilingOptions options,
0517       std::unique_ptr<DiscardedSamplesDelegate> delegate = nullptr);
0518 
0519   /**
0520    * Starts profiling with the same semantics as above, except with expanded
0521    * parameters.
0522    *
0523    * |record_samples| parameter controls whether individual samples should
0524    * be recorded in addition to the aggregated tree.
0525    *
0526    * |max_samples| controls the maximum number of samples that should be
0527    * recorded by the profiler. Samples obtained after this limit will be
0528    * discarded.
0529    */
0530   CpuProfilingStatus StartProfiling(
0531       Local<String> title, CpuProfilingMode mode, bool record_samples = false,
0532       unsigned max_samples = CpuProfilingOptions::kNoSampleLimit);
0533 
0534   /**
0535    * The same as StartProfiling above, but the CpuProfilingMode defaults to
0536    * kLeafNodeLineNumbers mode, which was the previous default behavior of the
0537    * profiler.
0538    */
0539   CpuProfilingStatus StartProfiling(Local<String> title,
0540                                     bool record_samples = false);
0541 
0542   /**
0543    * Stops collecting CPU profile with a given id and returns it.
0544    */
0545   CpuProfile* Stop(ProfilerId id);
0546 
0547   /**
0548    * Stops collecting CPU profile with a given title and returns it.
0549    * If the title given is empty, finishes the last profile started.
0550    */
0551   CpuProfile* StopProfiling(Local<String> title);
0552 
0553   /**
0554    * Generate more detailed source positions to code objects. This results in
0555    * better results when mapping profiling samples to script source.
0556    */
0557   static void UseDetailedSourcePositionsForProfiling(Isolate* isolate);
0558 
0559  private:
0560   CpuProfiler();
0561   ~CpuProfiler();
0562   CpuProfiler(const CpuProfiler&);
0563   CpuProfiler& operator=(const CpuProfiler&);
0564 };
0565 
0566 /**
0567  * HeapSnapshotEdge represents a directed connection between heap
0568  * graph nodes: from retainers to retained nodes.
0569  */
0570 class V8_EXPORT HeapGraphEdge {
0571  public:
0572   enum Type {
0573     kContextVariable = 0,  // A variable from a function context.
0574     kElement = 1,          // An element of an array.
0575     kProperty = 2,         // A named object property.
0576     kInternal = 3,         // A link that can't be accessed from JS,
0577                            // thus, its name isn't a real property name
0578                            // (e.g. parts of a ConsString).
0579     kHidden = 4,           // A link that is needed for proper sizes
0580                            // calculation, but may be hidden from user.
0581     kShortcut = 5,         // A link that must not be followed during
0582                            // sizes calculation.
0583     kWeak = 6              // A weak reference (ignored by the GC).
0584   };
0585 
0586   /** Returns edge type (see HeapGraphEdge::Type). */
0587   Type GetType() const;
0588 
0589   /**
0590    * Returns edge name. This can be a variable name, an element index, or
0591    * a property name.
0592    */
0593   Local<Value> GetName() const;
0594 
0595   /** Returns origin node. */
0596   const HeapGraphNode* GetFromNode() const;
0597 
0598   /** Returns destination node. */
0599   const HeapGraphNode* GetToNode() const;
0600 };
0601 
0602 
0603 /**
0604  * HeapGraphNode represents a node in a heap graph.
0605  */
0606 class V8_EXPORT HeapGraphNode {
0607  public:
0608   enum Type {
0609     kHidden = 0,         // Hidden node, may be filtered when shown to user.
0610     kArray = 1,          // An array of elements.
0611     kString = 2,         // A string.
0612     kObject = 3,         // A JS object (except for arrays and strings).
0613     kCode = 4,           // Compiled code.
0614     kClosure = 5,        // Function closure.
0615     kRegExp = 6,         // RegExp.
0616     kHeapNumber = 7,     // Number stored in the heap.
0617     kNative = 8,         // Native object (not from V8 heap).
0618     kSynthetic = 9,      // Synthetic object, usually used for grouping
0619                          // snapshot items together.
0620     kConsString = 10,    // Concatenated string. A pair of pointers to strings.
0621     kSlicedString = 11,  // Sliced string. A fragment of another string.
0622     kSymbol = 12,        // A Symbol (ES6).
0623     kBigInt = 13,        // BigInt.
0624     kObjectShape = 14,   // Internal data used for tracking the shapes (or
0625                          // "hidden classes") of JS objects.
0626   };
0627 
0628   /** Returns node type (see HeapGraphNode::Type). */
0629   Type GetType() const;
0630 
0631   /**
0632    * Returns node name. Depending on node's type this can be the name
0633    * of the constructor (for objects), the name of the function (for
0634    * closures), string value, or an empty string (for compiled code).
0635    */
0636   Local<String> GetName() const;
0637 
0638   /**
0639    * Returns node id. For the same heap object, the id remains the same
0640    * across all snapshots.
0641    */
0642   SnapshotObjectId GetId() const;
0643 
0644   /** Returns node's own size, in bytes. */
0645   size_t GetShallowSize() const;
0646 
0647   /** Returns child nodes count of the node. */
0648   int GetChildrenCount() const;
0649 
0650   /** Retrieves a child by index. */
0651   const HeapGraphEdge* GetChild(int index) const;
0652 };
0653 
0654 /**
0655  * HeapSnapshots record the state of the JS heap at some moment.
0656  */
0657 class V8_EXPORT HeapSnapshot {
0658  public:
0659   enum SerializationFormat {
0660     kJSON = 0  // See format description near 'Serialize' method.
0661   };
0662 
0663   /** Returns the root node of the heap graph. */
0664   const HeapGraphNode* GetRoot() const;
0665 
0666   /** Returns a node by its id. */
0667   const HeapGraphNode* GetNodeById(SnapshotObjectId id) const;
0668 
0669   /** Returns total nodes count in the snapshot. */
0670   int GetNodesCount() const;
0671 
0672   /** Returns a node by index. */
0673   const HeapGraphNode* GetNode(int index) const;
0674 
0675   /** Returns a max seen JS object Id. */
0676   SnapshotObjectId GetMaxSnapshotJSObjectId() const;
0677 
0678   /**
0679    * Deletes the snapshot and removes it from HeapProfiler's list.
0680    * All pointers to nodes, edges and paths previously returned become
0681    * invalid.
0682    */
0683   void Delete();
0684 
0685   /**
0686    * Prepare a serialized representation of the snapshot. The result
0687    * is written into the stream provided in chunks of specified size.
0688    * The total length of the serialized snapshot is unknown in
0689    * advance, it can be roughly equal to JS heap size (that means,
0690    * it can be really big - tens of megabytes).
0691    *
0692    * For the JSON format, heap contents are represented as an object
0693    * with the following structure:
0694    *
0695    *  {
0696    *    snapshot: {
0697    *      title: "...",
0698    *      uid: nnn,
0699    *      meta: { meta-info },
0700    *      node_count: nnn,
0701    *      edge_count: nnn
0702    *    },
0703    *    nodes: [nodes array],
0704    *    edges: [edges array],
0705    *    strings: [strings array]
0706    *  }
0707    *
0708    * Nodes reference strings, other nodes, and edges by their indexes
0709    * in corresponding arrays.
0710    */
0711   void Serialize(OutputStream* stream,
0712                  SerializationFormat format = kJSON) const;
0713 };
0714 
0715 
0716 /**
0717  * An interface for reporting progress and controlling long-running
0718  * activities.
0719  */
0720 class V8_EXPORT ActivityControl {
0721  public:
0722   enum ControlOption {
0723     kContinue = 0,
0724     kAbort = 1
0725   };
0726   virtual ~ActivityControl() = default;
0727   /**
0728    * Notify about current progress. The activity can be stopped by
0729    * returning kAbort as the callback result.
0730    */
0731   virtual ControlOption ReportProgressValue(uint32_t done, uint32_t total) = 0;
0732 };
0733 
0734 /**
0735  * AllocationProfile is a sampled profile of allocations done by the program.
0736  * This is structured as a call-graph.
0737  */
0738 class V8_EXPORT AllocationProfile {
0739  public:
0740   struct Allocation {
0741     /**
0742      * Size of the sampled allocation object.
0743      */
0744     size_t size;
0745 
0746     /**
0747      * The number of objects of such size that were sampled.
0748      */
0749     unsigned int count;
0750   };
0751 
0752   /**
0753    * Represents a node in the call-graph.
0754    */
0755   struct Node {
0756     /**
0757      * Name of the function. May be empty for anonymous functions or if the
0758      * script corresponding to this function has been unloaded.
0759      */
0760     Local<String> name;
0761 
0762     /**
0763      * Name of the script containing the function. May be empty if the script
0764      * name is not available, or if the script has been unloaded.
0765      */
0766     Local<String> script_name;
0767 
0768     /**
0769      * id of the script where the function is located. May be equal to
0770      * v8::UnboundScript::kNoScriptId in cases where the script doesn't exist.
0771      */
0772     int script_id;
0773 
0774     /**
0775      * Start position of the function in the script.
0776      */
0777     int start_position;
0778 
0779     /**
0780      * 1-indexed line number where the function starts. May be
0781      * kNoLineNumberInfo if no line number information is available.
0782      */
0783     int line_number;
0784 
0785     /**
0786      * 1-indexed column number where the function starts. May be
0787      * kNoColumnNumberInfo if no line number information is available.
0788      */
0789     int column_number;
0790 
0791     /**
0792      * Unique id of the node.
0793      */
0794     uint32_t node_id;
0795 
0796     /**
0797      * List of callees called from this node for which we have sampled
0798      * allocations. The lifetime of the children is scoped to the containing
0799      * AllocationProfile.
0800      */
0801     std::vector<Node*> children;
0802 
0803     /**
0804      * List of self allocations done by this node in the call-graph.
0805      */
0806     std::vector<Allocation> allocations;
0807   };
0808 
0809   /**
0810    * Represent a single sample recorded for an allocation.
0811    */
0812   struct Sample {
0813     /**
0814      * id of the node in the profile tree.
0815      */
0816     uint32_t node_id;
0817 
0818     /**
0819      * Size of the sampled allocation object.
0820      */
0821     size_t size;
0822 
0823     /**
0824      * The number of objects of such size that were sampled.
0825      */
0826     unsigned int count;
0827 
0828     /**
0829      * Unique time-ordered id of the allocation sample. Can be used to track
0830      * what samples were added or removed between two snapshots.
0831      */
0832     uint64_t sample_id;
0833 
0834     /**
0835      * Indicates whether the sampled allocation is still live or has already
0836      * been collected by GC.
0837      */
0838     bool is_live;
0839   };
0840 
0841   /**
0842    * Returns the root node of the call-graph. The root node corresponds to an
0843    * empty JS call-stack. The lifetime of the returned Node* is scoped to the
0844    * containing AllocationProfile.
0845    */
0846   virtual Node* GetRootNode() = 0;
0847   virtual const std::vector<Sample>& GetSamples() = 0;
0848 
0849   virtual ~AllocationProfile() = default;
0850 
0851   static const int kNoLineNumberInfo = Message::kNoLineNumberInfo;
0852   static const int kNoColumnNumberInfo = Message::kNoColumnInfo;
0853 };
0854 
0855 /**
0856  * An object graph consisting of embedder objects and V8 objects.
0857  * Edges of the graph are strong references between the objects.
0858  * The embedder can build this graph during heap snapshot generation
0859  * to include the embedder objects in the heap snapshot.
0860  * Usage:
0861  * 1) Define derived class of EmbedderGraph::Node for embedder objects.
0862  * 2) Set the build embedder graph callback on the heap profiler using
0863  *    HeapProfiler::AddBuildEmbedderGraphCallback.
0864  * 3) In the callback use graph->AddEdge(node1, node2) to add an edge from
0865  *    node1 to node2.
0866  * 4) To represent references from/to V8 object, construct V8 nodes using
0867  *    graph->V8Node(value).
0868  */
0869 class V8_EXPORT EmbedderGraph {
0870  public:
0871   class Node {
0872    public:
0873     /**
0874      * Detachedness specifies whether an object is attached or detached from the
0875      * main application state. While unkown in general, there may be objects
0876      * that specifically know their state. V8 passes this information along in
0877      * the snapshot. Users of the snapshot may use it to annotate the object
0878      * graph.
0879      */
0880     enum class Detachedness : uint8_t {
0881       kUnknown = 0,
0882       kAttached = 1,
0883       kDetached = 2,
0884     };
0885 
0886     Node() = default;
0887     virtual ~Node() = default;
0888     virtual const char* Name() = 0;
0889     virtual size_t SizeInBytes() = 0;
0890     /**
0891      * The corresponding V8 wrapper node if not null.
0892      * During heap snapshot generation the embedder node and the V8 wrapper
0893      * node will be merged into one node to simplify retaining paths.
0894      */
0895     virtual Node* WrapperNode() { return nullptr; }
0896     virtual bool IsRootNode() { return false; }
0897     /** Must return true for non-V8 nodes. */
0898     virtual bool IsEmbedderNode() { return true; }
0899     /**
0900      * Optional name prefix. It is used in Chrome for tagging detached nodes.
0901      */
0902     virtual const char* NamePrefix() { return nullptr; }
0903 
0904     /**
0905      * Returns the NativeObject that can be used for querying the
0906      * |HeapSnapshot|.
0907      */
0908     virtual NativeObject GetNativeObject() { return nullptr; }
0909 
0910     /**
0911      * Detachedness state of a given object. While unkown in general, there may
0912      * be objects that specifically know their state. V8 passes this information
0913      * along in the snapshot. Users of the snapshot may use it to annotate the
0914      * object graph.
0915      */
0916     virtual Detachedness GetDetachedness() { return Detachedness::kUnknown; }
0917 
0918     /**
0919      * Returns the address of the object in the embedder heap, or nullptr to not
0920      * specify the address. If this address is provided, then V8 can generate
0921      * consistent IDs for objects across subsequent heap snapshots, which allows
0922      * devtools to determine which objects were retained from one snapshot to
0923      * the next. This value is used only if GetNativeObject returns nullptr.
0924      */
0925     virtual const void* GetAddress() { return nullptr; }
0926 
0927     Node(const Node&) = delete;
0928     Node& operator=(const Node&) = delete;
0929   };
0930 
0931   /**
0932    * Returns a node corresponding to the given V8 value. Ownership is not
0933    * transferred. The result pointer is valid while the graph is alive.
0934    *
0935    * For now the variant that takes v8::Data is not marked as abstract for
0936    * compatibility, but embedders who subclass EmbedderGraph are expected to
0937    * implement it. Then in the implementation of the variant that takes
0938    * v8::Value, they can simply forward the call to the one that takes
0939    * v8::Local<v8::Data>.
0940    */
0941   virtual Node* V8Node(const v8::Local<v8::Value>& value) = 0;
0942 
0943   /**
0944    * Returns a node corresponding to the given V8 value. Ownership is not
0945    * transferred. The result pointer is valid while the graph is alive.
0946    *
0947    * For API compatibility, this default implementation just checks that the
0948    * data is a v8::Value and forward it to the variant that takes v8::Value,
0949    * which is currently required to be implemented. In the future we'll remove
0950    * the v8::Value variant, and make this variant that takes v8::Data abstract
0951    * instead. If the embedder subclasses v8::EmbedderGraph and also use
0952    * v8::TracedReference<v8::Data>, they must override this variant.
0953    */
0954   virtual Node* V8Node(const v8::Local<v8::Data>& value);
0955 
0956   /**
0957    * Adds the given node to the graph and takes ownership of the node.
0958    * Returns a raw pointer to the node that is valid while the graph is alive.
0959    */
0960   virtual Node* AddNode(std::unique_ptr<Node> node) = 0;
0961 
0962   /**
0963    * Adds an edge that represents a strong reference from the given
0964    * node |from| to the given node |to|. The nodes must be added to the graph
0965    * before calling this function.
0966    *
0967    * If name is nullptr, the edge will have auto-increment indexes, otherwise
0968    * it will be named accordingly.
0969    */
0970   virtual void AddEdge(Node* from, Node* to, const char* name = nullptr) = 0;
0971 
0972   /**
0973    * Adds a count of bytes that are not associated with any particular Node.
0974    * An embedder may use this to represent the size of nodes which were omitted
0975    * from this EmbedderGraph despite being retained by the graph, or other
0976    * overhead costs. This number will contribute to the total size in a heap
0977    * snapshot, without being represented in the object graph.
0978    */
0979   virtual void AddNativeSize(size_t size) {}
0980 
0981   virtual ~EmbedderGraph() = default;
0982 };
0983 
0984 class QueryObjectPredicate {
0985  public:
0986   virtual ~QueryObjectPredicate() = default;
0987   virtual bool Filter(v8::Local<v8::Object> object) = 0;
0988 };
0989 
0990 /**
0991  * Interface for controlling heap profiling. Instance of the
0992  * profiler can be retrieved using v8::Isolate::GetHeapProfiler.
0993  */
0994 class V8_EXPORT HeapProfiler {
0995  public:
0996   void QueryObjects(v8::Local<v8::Context> context,
0997                     QueryObjectPredicate* predicate,
0998                     std::vector<v8::Global<v8::Object>>* objects);
0999 
1000   enum SamplingFlags {
1001     kSamplingNoFlags = 0,
1002     kSamplingForceGC = 1 << 0,
1003     kSamplingIncludeObjectsCollectedByMajorGC = 1 << 1,
1004     kSamplingIncludeObjectsCollectedByMinorGC = 1 << 2,
1005   };
1006 
1007   /**
1008    * Callback function invoked during heap snapshot generation to retrieve
1009    * the embedder object graph. The callback should use graph->AddEdge(..) to
1010    * add references between the objects.
1011    * The callback must not trigger garbage collection in V8.
1012    */
1013   typedef void (*BuildEmbedderGraphCallback)(v8::Isolate* isolate,
1014                                              v8::EmbedderGraph* graph,
1015                                              void* data);
1016 
1017   /**
1018    * Callback function invoked during heap snapshot generation to retrieve
1019    * the detachedness state of a JS object referenced by a TracedReference.
1020    *
1021    * The callback takes Local<Value> as parameter to allow the embedder to
1022    * unpack the TracedReference into a Local and reuse that Local for different
1023    * purposes.
1024    */
1025   using GetDetachednessCallback = EmbedderGraph::Node::Detachedness (*)(
1026       v8::Isolate* isolate, const v8::Local<v8::Value>& v8_value,
1027       uint16_t class_id, void* data);
1028 
1029   /** Returns the number of snapshots taken. */
1030   int GetSnapshotCount();
1031 
1032   /** Returns a snapshot by index. */
1033   const HeapSnapshot* GetHeapSnapshot(int index);
1034 
1035   /**
1036    * Returns SnapshotObjectId for a heap object referenced by |value| if
1037    * it has been seen by the heap profiler, kUnknownObjectId otherwise.
1038    */
1039   SnapshotObjectId GetObjectId(Local<Value> value);
1040 
1041   /**
1042    * Returns SnapshotObjectId for a native object referenced by |value| if it
1043    * has been seen by the heap profiler, kUnknownObjectId otherwise.
1044    */
1045   SnapshotObjectId GetObjectId(NativeObject value);
1046 
1047   /**
1048    * Returns heap object with given SnapshotObjectId if the object is alive,
1049    * otherwise empty handle is returned.
1050    */
1051   Local<Value> FindObjectById(SnapshotObjectId id);
1052 
1053   /**
1054    * Clears internal map from SnapshotObjectId to heap object. The new objects
1055    * will not be added into it unless a heap snapshot is taken or heap object
1056    * tracking is kicked off.
1057    */
1058   void ClearObjectIds();
1059 
1060   /**
1061    * A constant for invalid SnapshotObjectId. GetSnapshotObjectId will return
1062    * it in case heap profiler cannot find id  for the object passed as
1063    * parameter. HeapSnapshot::GetNodeById will always return NULL for such id.
1064    */
1065   static const SnapshotObjectId kUnknownObjectId = 0;
1066 
1067   /**
1068    * Callback interface for retrieving user friendly names of global objects.
1069    *
1070    * This interface will soon be deprecated in favour of ContextNameResolver.
1071    */
1072   class ObjectNameResolver {
1073    public:
1074     /**
1075      * Returns name to be used in the heap snapshot for given node. Returned
1076      * string must stay alive until snapshot collection is completed.
1077      */
1078     virtual const char* GetName(Local<Object> object) = 0;
1079 
1080    protected:
1081     virtual ~ObjectNameResolver() = default;
1082   };
1083 
1084   /**
1085    * Callback interface for retrieving user friendly names of a V8::Context
1086    * objects.
1087    */
1088   class ContextNameResolver {
1089    public:
1090     /**
1091      * Returns name to be used in the heap snapshot for given node. Returned
1092      * string must stay alive until snapshot collection is completed.
1093      * If no user friendly name is available return nullptr.
1094      */
1095     virtual const char* GetName(Local<Context> context) = 0;
1096 
1097    protected:
1098     virtual ~ContextNameResolver() = default;
1099   };
1100 
1101   enum class HeapSnapshotMode {
1102     /**
1103      * Heap snapshot for regular developers.
1104      */
1105     kRegular,
1106     /**
1107      * Heap snapshot is exposing internals that may be useful for experts.
1108      */
1109     kExposeInternals,
1110   };
1111 
1112   enum class NumericsMode {
1113     /**
1114      * Numeric values are hidden as they are values of the corresponding
1115      * objects.
1116      */
1117     kHideNumericValues,
1118     /**
1119      * Numeric values are exposed in artificial fields.
1120      */
1121     kExposeNumericValues
1122   };
1123 
1124   struct HeapSnapshotOptions final {
1125     // Manually define default constructor here to be able to use it in
1126     // `TakeSnapshot()` below.
1127     // NOLINTNEXTLINE
1128     HeapSnapshotOptions() {}
1129 
1130     // TODO(https://crbug.com/333672197): remove once ObjectNameResolver is
1131     // removed.
1132     ALLOW_COPY_AND_MOVE_WITH_DEPRECATED_FIELDS(HeapSnapshotOptions)
1133 
1134     /**
1135      * The control used to report intermediate progress to.
1136      */
1137     ActivityControl* control = nullptr;
1138     /**
1139      * The resolver used by the snapshot generator to get names for V8 objects.
1140      */
1141     V8_DEPRECATED("Use context_name_resolver callback instead.")
1142     ObjectNameResolver* global_object_name_resolver = nullptr;
1143     /**
1144      * The resolver used by the snapshot generator to get names for v8::Context
1145      * objects.
1146      * In case both this and |global_object_name_resolver| callbacks are
1147      * provided, this one will be used.
1148      */
1149     ContextNameResolver* context_name_resolver = nullptr;
1150     /**
1151      * Mode for taking the snapshot, see `HeapSnapshotMode`.
1152      */
1153     HeapSnapshotMode snapshot_mode = HeapSnapshotMode::kRegular;
1154     /**
1155      * Mode for dealing with numeric values, see `NumericsMode`.
1156      */
1157     NumericsMode numerics_mode = NumericsMode::kHideNumericValues;
1158     /**
1159      * Whether stack is considered as a root set.
1160      */
1161     cppgc::EmbedderStackState stack_state =
1162         cppgc::EmbedderStackState::kMayContainHeapPointers;
1163   };
1164 
1165   /**
1166    * Takes a heap snapshot.
1167    *
1168    * \returns the snapshot.
1169    */
1170   const HeapSnapshot* TakeHeapSnapshot(
1171       const HeapSnapshotOptions& options = HeapSnapshotOptions());
1172 
1173   /**
1174    * Takes a heap snapshot. See `HeapSnapshotOptions` for details on the
1175    * parameters.
1176    *
1177    * \returns the snapshot.
1178    */
1179   V8_DEPRECATED("Use overload with ContextNameResolver* resolver instead.")
1180   const HeapSnapshot* TakeHeapSnapshot(
1181       ActivityControl* control, ObjectNameResolver* global_object_name_resolver,
1182       bool hide_internals = true, bool capture_numeric_value = false);
1183   const HeapSnapshot* TakeHeapSnapshot(ActivityControl* control,
1184                                        ContextNameResolver* resolver,
1185                                        bool hide_internals = true,
1186                                        bool capture_numeric_value = false);
1187   // TODO(333672197): remove this version once ObjectNameResolver* overload
1188   // is removed.
1189   const HeapSnapshot* TakeHeapSnapshot(ActivityControl* control,
1190                                        std::nullptr_t resolver = nullptr,
1191                                        bool hide_internals = true,
1192                                        bool capture_numeric_value = false);
1193 
1194   /**
1195    * Obtains list of Detached JS Wrapper Objects. This functon calls garbage
1196    * collection, then iterates over traced handles in the isolate
1197    */
1198   std::vector<v8::Local<v8::Value>> GetDetachedJSWrapperObjects();
1199 
1200   /**
1201    * Starts tracking of heap objects population statistics. After calling
1202    * this method, all heap objects relocations done by the garbage collector
1203    * are being registered.
1204    *
1205    * |track_allocations| parameter controls whether stack trace of each
1206    * allocation in the heap will be recorded and reported as part of
1207    * HeapSnapshot.
1208    */
1209   void StartTrackingHeapObjects(bool track_allocations = false);
1210 
1211   /**
1212    * Adds a new time interval entry to the aggregated statistics array. The
1213    * time interval entry contains information on the current heap objects
1214    * population size. The method also updates aggregated statistics and
1215    * reports updates for all previous time intervals via the OutputStream
1216    * object. Updates on each time interval are provided as a stream of the
1217    * HeapStatsUpdate structure instances.
1218    * If |timestamp_us| is supplied, timestamp of the new entry will be written
1219    * into it. The return value of the function is the last seen heap object Id.
1220    *
1221    * StartTrackingHeapObjects must be called before the first call to this
1222    * method.
1223    */
1224   SnapshotObjectId GetHeapStats(OutputStream* stream,
1225                                 int64_t* timestamp_us = nullptr);
1226 
1227   /**
1228    * Stops tracking of heap objects population statistics, cleans up all
1229    * collected data. StartHeapObjectsTracking must be called again prior to
1230    * calling GetHeapStats next time.
1231    */
1232   void StopTrackingHeapObjects();
1233 
1234   /**
1235    * Starts gathering a sampling heap profile. A sampling heap profile is
1236    * similar to tcmalloc's heap profiler and Go's mprof. It samples object
1237    * allocations and builds an online 'sampling' heap profile. At any point in
1238    * time, this profile is expected to be a representative sample of objects
1239    * currently live in the system. Each sampled allocation includes the stack
1240    * trace at the time of allocation, which makes this really useful for memory
1241    * leak detection.
1242    *
1243    * This mechanism is intended to be cheap enough that it can be used in
1244    * production with minimal performance overhead.
1245    *
1246    * Allocations are sampled using a randomized Poisson process. On average, one
1247    * allocation will be sampled every |sample_interval| bytes allocated. The
1248    * |stack_depth| parameter controls the maximum number of stack frames to be
1249    * captured on each allocation.
1250    *
1251    * NOTE: Support for native allocations doesn't exist yet, but is anticipated
1252    * in the future.
1253    *
1254    * Objects allocated before the sampling is started will not be included in
1255    * the profile.
1256    *
1257    * Returns false if a sampling heap profiler is already running.
1258    */
1259   bool StartSamplingHeapProfiler(uint64_t sample_interval = 512 * 1024,
1260                                  int stack_depth = 16,
1261                                  SamplingFlags flags = kSamplingNoFlags);
1262 
1263   /**
1264    * Stops the sampling heap profile and discards the current profile.
1265    */
1266   void StopSamplingHeapProfiler();
1267 
1268   /**
1269    * Returns the sampled profile of allocations allocated (and still live) since
1270    * StartSamplingHeapProfiler was called. The ownership of the pointer is
1271    * transferred to the caller. Returns nullptr if sampling heap profiler is not
1272    * active.
1273    */
1274   AllocationProfile* GetAllocationProfile();
1275 
1276   /**
1277    * Deletes all snapshots taken. All previously returned pointers to
1278    * snapshots and their contents become invalid after this call.
1279    */
1280   void DeleteAllHeapSnapshots();
1281 
1282   void AddBuildEmbedderGraphCallback(BuildEmbedderGraphCallback callback,
1283                                      void* data);
1284   void RemoveBuildEmbedderGraphCallback(BuildEmbedderGraphCallback callback,
1285                                         void* data);
1286 
1287   void SetGetDetachednessCallback(GetDetachednessCallback callback, void* data);
1288 
1289   /**
1290    * Returns whether the heap profiler is currently taking a snapshot.
1291    */
1292   bool IsTakingSnapshot();
1293 
1294   /**
1295    * Allocates a copy of the provided string within the heap snapshot generator
1296    * and returns a pointer to the copy. May only be called during heap snapshot
1297    * generation.
1298    */
1299   const char* CopyNameForHeapSnapshot(const char* name);
1300 
1301   /**
1302    * Default value of persistent handle class ID. Must not be used to
1303    * define a class. Can be used to reset a class of a persistent
1304    * handle.
1305    */
1306   static const uint16_t kPersistentHandleNoClassId = 0;
1307 
1308  private:
1309   HeapProfiler();
1310   ~HeapProfiler();
1311   HeapProfiler(const HeapProfiler&);
1312   HeapProfiler& operator=(const HeapProfiler&);
1313 };
1314 
1315 /**
1316  * A struct for exporting HeapStats data from V8, using "push" model.
1317  * See HeapProfiler::GetHeapStats.
1318  */
1319 struct HeapStatsUpdate {
1320   HeapStatsUpdate(uint32_t index, uint32_t count, uint32_t size)
1321     : index(index), count(count), size(size) { }
1322   uint32_t index;  // Index of the time interval that was changed.
1323   uint32_t count;  // New value of count field for the interval with this index.
1324   uint32_t size;  // New value of size field for the interval with this index.
1325 };
1326 
1327 #define CODE_EVENTS_LIST(V)                          \
1328   V(Builtin)                                         \
1329   V(Callback)                                        \
1330   V(Eval)                                            \
1331   V(Function)                                        \
1332   V(InterpretedFunction)                             \
1333   V(Handler)                                         \
1334   V(BytecodeHandler)                                 \
1335   V(LazyCompile) /* Unused, use kFunction instead */ \
1336   V(RegExp)                                          \
1337   V(Script)                                          \
1338   V(Stub)                                            \
1339   V(Relocation)
1340 
1341 /**
1342  * Note that this enum may be extended in the future. Please include a default
1343  * case if this enum is used in a switch statement.
1344  */
1345 enum CodeEventType {
1346   kUnknownType = 0
1347 #define V(Name) , k##Name##Type
1348   CODE_EVENTS_LIST(V)
1349 #undef V
1350 };
1351 
1352 /**
1353  * Representation of a code creation event
1354  */
1355 class V8_EXPORT CodeEvent {
1356  public:
1357   uintptr_t GetCodeStartAddress();
1358   size_t GetCodeSize();
1359   Local<String> GetFunctionName();
1360   Local<String> GetScriptName();
1361   int GetScriptLine();
1362   int GetScriptColumn();
1363   /**
1364    * NOTE (mmarchini): We can't allocate objects in the heap when we collect
1365    * existing code, and both the code type and the comment are not stored in the
1366    * heap, so we return those as const char*.
1367    */
1368   CodeEventType GetCodeType();
1369   const char* GetComment();
1370 
1371   static const char* GetCodeEventTypeName(CodeEventType code_event_type);
1372 
1373   uintptr_t GetPreviousCodeStartAddress();
1374 };
1375 
1376 /**
1377  * Interface to listen to code creation and code relocation events.
1378  */
1379 class V8_EXPORT CodeEventHandler {
1380  public:
1381   /**
1382    * Creates a new listener for the |isolate|. The isolate must be initialized.
1383    * The listener object must be disposed after use by calling |Dispose| method.
1384    * Multiple listeners can be created for the same isolate.
1385    */
1386   explicit CodeEventHandler(Isolate* isolate);
1387   virtual ~CodeEventHandler();
1388 
1389   /**
1390    * Handle is called every time a code object is created or moved. Information
1391    * about each code event will be available through the `code_event`
1392    * parameter.
1393    *
1394    * When the CodeEventType is kRelocationType, the code for this CodeEvent has
1395    * moved from `GetPreviousCodeStartAddress()` to `GetCodeStartAddress()`.
1396    */
1397   virtual void Handle(CodeEvent* code_event) = 0;
1398 
1399   /**
1400    * Call `Enable()` to starts listening to code creation and code relocation
1401    * events. These events will be handled by `Handle()`.
1402    */
1403   void Enable();
1404 
1405   /**
1406    * Call `Disable()` to stop listening to code creation and code relocation
1407    * events.
1408    */
1409   void Disable();
1410 
1411  private:
1412   CodeEventHandler();
1413   CodeEventHandler(const CodeEventHandler&);
1414   CodeEventHandler& operator=(const CodeEventHandler&);
1415   void* internal_listener_;
1416 };
1417 
1418 }  // namespace v8
1419 
1420 
1421 #endif  // V8_V8_PROFILER_H_