Home | History | Annotate | Download | only in include
      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 <vector>
      9 #include "v8.h"  // NOLINT(build/include)
     10 
     11 /**
     12  * Profiler support for the V8 JavaScript engine.
     13  */
     14 namespace v8 {
     15 
     16 class HeapGraphNode;
     17 struct HeapStatsUpdate;
     18 
     19 typedef uint32_t SnapshotObjectId;
     20 
     21 
     22 struct CpuProfileDeoptFrame {
     23   int script_id;
     24   size_t position;
     25 };
     26 
     27 }  // namespace v8
     28 
     29 #ifdef V8_OS_WIN
     30 template class V8_EXPORT std::vector<v8::CpuProfileDeoptFrame>;
     31 #endif
     32 
     33 namespace v8 {
     34 
     35 struct V8_EXPORT CpuProfileDeoptInfo {
     36   /** A pointer to a static string owned by v8. */
     37   const char* deopt_reason;
     38   std::vector<CpuProfileDeoptFrame> stack;
     39 };
     40 
     41 }  // namespace v8
     42 
     43 #ifdef V8_OS_WIN
     44 template class V8_EXPORT std::vector<v8::CpuProfileDeoptInfo>;
     45 #endif
     46 
     47 namespace v8 {
     48 
     49 /**
     50  * CpuProfileNode represents a node in a call graph.
     51  */
     52 class V8_EXPORT CpuProfileNode {
     53  public:
     54   struct LineTick {
     55     /** The 1-based number of the source line where the function originates. */
     56     int line;
     57 
     58     /** The count of samples associated with the source line. */
     59     unsigned int hit_count;
     60   };
     61 
     62   /** Returns function name (empty string for anonymous functions.) */
     63   Local<String> GetFunctionName() const;
     64 
     65   /** Returns id of the script where function is located. */
     66   int GetScriptId() const;
     67 
     68   /** Returns resource name for script from where the function originates. */
     69   Local<String> GetScriptResourceName() const;
     70 
     71   /**
     72    * Returns the number, 1-based, of the line where the function originates.
     73    * kNoLineNumberInfo if no line number information is available.
     74    */
     75   int GetLineNumber() const;
     76 
     77   /**
     78    * Returns 1-based number of the column where the function originates.
     79    * kNoColumnNumberInfo if no column number information is available.
     80    */
     81   int GetColumnNumber() const;
     82 
     83   /**
     84    * Returns the number of the function's source lines that collect the samples.
     85    */
     86   unsigned int GetHitLineCount() const;
     87 
     88   /** Returns the set of source lines that collect the samples.
     89    *  The caller allocates buffer and responsible for releasing it.
     90    *  True if all available entries are copied, otherwise false.
     91    *  The function copies nothing if buffer is not large enough.
     92    */
     93   bool GetLineTicks(LineTick* entries, unsigned int length) const;
     94 
     95   /** Returns bailout reason for the function
     96     * if the optimization was disabled for it.
     97     */
     98   const char* GetBailoutReason() const;
     99 
    100   /**
    101     * Returns the count of samples where the function was currently executing.
    102     */
    103   unsigned GetHitCount() const;
    104 
    105   /** Returns function entry UID. */
    106   unsigned GetCallUid() const;
    107 
    108   /** Returns id of the node. The id is unique within the tree */
    109   unsigned GetNodeId() const;
    110 
    111   /** Returns child nodes count of the node. */
    112   int GetChildrenCount() const;
    113 
    114   /** Retrieves a child node by index. */
    115   const CpuProfileNode* GetChild(int index) const;
    116 
    117   /** Retrieves deopt infos for the node. */
    118   const std::vector<CpuProfileDeoptInfo>& GetDeoptInfos() const;
    119 
    120   static const int kNoLineNumberInfo = Message::kNoLineNumberInfo;
    121   static const int kNoColumnNumberInfo = Message::kNoColumnInfo;
    122 };
    123 
    124 
    125 /**
    126  * CpuProfile contains a CPU profile in a form of top-down call tree
    127  * (from main() down to functions that do all the work).
    128  */
    129 class V8_EXPORT CpuProfile {
    130  public:
    131   /** Returns CPU profile title. */
    132   Local<String> GetTitle() const;
    133 
    134   /** Returns the root node of the top down call tree. */
    135   const CpuProfileNode* GetTopDownRoot() const;
    136 
    137   /**
    138    * Returns number of samples recorded. The samples are not recorded unless
    139    * |record_samples| parameter of CpuProfiler::StartCpuProfiling is true.
    140    */
    141   int GetSamplesCount() const;
    142 
    143   /**
    144    * Returns profile node corresponding to the top frame the sample at
    145    * the given index.
    146    */
    147   const CpuProfileNode* GetSample(int index) const;
    148 
    149   /**
    150    * Returns the timestamp of the sample. The timestamp is the number of
    151    * microseconds since some unspecified starting point.
    152    * The point is equal to the starting point used by GetStartTime.
    153    */
    154   int64_t GetSampleTimestamp(int index) const;
    155 
    156   /**
    157    * Returns time when the profile recording was started (in microseconds)
    158    * since some unspecified starting point.
    159    */
    160   int64_t GetStartTime() const;
    161 
    162   /**
    163    * Returns time when the profile recording was stopped (in microseconds)
    164    * since some unspecified starting point.
    165    * The point is equal to the starting point used by GetStartTime.
    166    */
    167   int64_t GetEndTime() const;
    168 
    169   /**
    170    * Deletes the profile and removes it from CpuProfiler's list.
    171    * All pointers to nodes previously returned become invalid.
    172    */
    173   void Delete();
    174 };
    175 
    176 
    177 /**
    178  * Interface for controlling CPU profiling. Instance of the
    179  * profiler can be retrieved using v8::Isolate::GetCpuProfiler.
    180  */
    181 class V8_EXPORT CpuProfiler {
    182  public:
    183   /**
    184    * Changes default CPU profiler sampling interval to the specified number
    185    * of microseconds. Default interval is 1000us. This method must be called
    186    * when there are no profiles being recorded.
    187    */
    188   void SetSamplingInterval(int us);
    189 
    190   /**
    191    * Starts collecting CPU profile. Title may be an empty string. It
    192    * is allowed to have several profiles being collected at
    193    * once. Attempts to start collecting several profiles with the same
    194    * title are silently ignored. While collecting a profile, functions
    195    * from all security contexts are included in it. The token-based
    196    * filtering is only performed when querying for a profile.
    197    *
    198    * |record_samples| parameter controls whether individual samples should
    199    * be recorded in addition to the aggregated tree.
    200    */
    201   void StartProfiling(Local<String> title, bool record_samples = false);
    202 
    203   /**
    204    * Stops collecting CPU profile with a given title and returns it.
    205    * If the title given is empty, finishes the last profile started.
    206    */
    207   CpuProfile* StopProfiling(Local<String> title);
    208 
    209   /**
    210    * Force collection of a sample. Must be called on the VM thread.
    211    * Recording the forced sample does not contribute to the aggregated
    212    * profile statistics.
    213    */
    214   void CollectSample();
    215 
    216   /**
    217    * Tells the profiler whether the embedder is idle.
    218    */
    219   void SetIdle(bool is_idle);
    220 
    221  private:
    222   CpuProfiler();
    223   ~CpuProfiler();
    224   CpuProfiler(const CpuProfiler&);
    225   CpuProfiler& operator=(const CpuProfiler&);
    226 };
    227 
    228 
    229 /**
    230  * HeapSnapshotEdge represents a directed connection between heap
    231  * graph nodes: from retainers to retained nodes.
    232  */
    233 class V8_EXPORT HeapGraphEdge {
    234  public:
    235   enum Type {
    236     kContextVariable = 0,  // A variable from a function context.
    237     kElement = 1,          // An element of an array.
    238     kProperty = 2,         // A named object property.
    239     kInternal = 3,         // A link that can't be accessed from JS,
    240                            // thus, its name isn't a real property name
    241                            // (e.g. parts of a ConsString).
    242     kHidden = 4,           // A link that is needed for proper sizes
    243                            // calculation, but may be hidden from user.
    244     kShortcut = 5,         // A link that must not be followed during
    245                            // sizes calculation.
    246     kWeak = 6              // A weak reference (ignored by the GC).
    247   };
    248 
    249   /** Returns edge type (see HeapGraphEdge::Type). */
    250   Type GetType() const;
    251 
    252   /**
    253    * Returns edge name. This can be a variable name, an element index, or
    254    * a property name.
    255    */
    256   Local<Value> GetName() const;
    257 
    258   /** Returns origin node. */
    259   const HeapGraphNode* GetFromNode() const;
    260 
    261   /** Returns destination node. */
    262   const HeapGraphNode* GetToNode() const;
    263 };
    264 
    265 
    266 /**
    267  * HeapGraphNode represents a node in a heap graph.
    268  */
    269 class V8_EXPORT HeapGraphNode {
    270  public:
    271   enum Type {
    272     kHidden = 0,         // Hidden node, may be filtered when shown to user.
    273     kArray = 1,          // An array of elements.
    274     kString = 2,         // A string.
    275     kObject = 3,         // A JS object (except for arrays and strings).
    276     kCode = 4,           // Compiled code.
    277     kClosure = 5,        // Function closure.
    278     kRegExp = 6,         // RegExp.
    279     kHeapNumber = 7,     // Number stored in the heap.
    280     kNative = 8,         // Native object (not from V8 heap).
    281     kSynthetic = 9,      // Synthetic object, usualy used for grouping
    282                          // snapshot items together.
    283     kConsString = 10,    // Concatenated string. A pair of pointers to strings.
    284     kSlicedString = 11,  // Sliced string. A fragment of another string.
    285     kSymbol = 12,        // A Symbol (ES6).
    286     kSimdValue = 13      // A SIMD value stored in the heap (Proposed ES7).
    287   };
    288 
    289   /** Returns node type (see HeapGraphNode::Type). */
    290   Type GetType() const;
    291 
    292   /**
    293    * Returns node name. Depending on node's type this can be the name
    294    * of the constructor (for objects), the name of the function (for
    295    * closures), string value, or an empty string (for compiled code).
    296    */
    297   Local<String> GetName() const;
    298 
    299   /**
    300    * Returns node id. For the same heap object, the id remains the same
    301    * across all snapshots.
    302    */
    303   SnapshotObjectId GetId() const;
    304 
    305   /** Returns node's own size, in bytes. */
    306   size_t GetShallowSize() const;
    307 
    308   /** Returns child nodes count of the node. */
    309   int GetChildrenCount() const;
    310 
    311   /** Retrieves a child by index. */
    312   const HeapGraphEdge* GetChild(int index) const;
    313 };
    314 
    315 
    316 /**
    317  * An interface for exporting data from V8, using "push" model.
    318  */
    319 class V8_EXPORT OutputStream {  // NOLINT
    320  public:
    321   enum WriteResult {
    322     kContinue = 0,
    323     kAbort = 1
    324   };
    325   virtual ~OutputStream() {}
    326   /** Notify about the end of stream. */
    327   virtual void EndOfStream() = 0;
    328   /** Get preferred output chunk size. Called only once. */
    329   virtual int GetChunkSize() { return 1024; }
    330   /**
    331    * Writes the next chunk of snapshot data into the stream. Writing
    332    * can be stopped by returning kAbort as function result. EndOfStream
    333    * will not be called in case writing was aborted.
    334    */
    335   virtual WriteResult WriteAsciiChunk(char* data, int size) = 0;
    336   /**
    337    * Writes the next chunk of heap stats data into the stream. Writing
    338    * can be stopped by returning kAbort as function result. EndOfStream
    339    * will not be called in case writing was aborted.
    340    */
    341   virtual WriteResult WriteHeapStatsChunk(HeapStatsUpdate* data, int count) {
    342     return kAbort;
    343   }
    344 };
    345 
    346 
    347 /**
    348  * HeapSnapshots record the state of the JS heap at some moment.
    349  */
    350 class V8_EXPORT HeapSnapshot {
    351  public:
    352   enum SerializationFormat {
    353     kJSON = 0  // See format description near 'Serialize' method.
    354   };
    355 
    356   /** Returns the root node of the heap graph. */
    357   const HeapGraphNode* GetRoot() const;
    358 
    359   /** Returns a node by its id. */
    360   const HeapGraphNode* GetNodeById(SnapshotObjectId id) const;
    361 
    362   /** Returns total nodes count in the snapshot. */
    363   int GetNodesCount() const;
    364 
    365   /** Returns a node by index. */
    366   const HeapGraphNode* GetNode(int index) const;
    367 
    368   /** Returns a max seen JS object Id. */
    369   SnapshotObjectId GetMaxSnapshotJSObjectId() const;
    370 
    371   /**
    372    * Deletes the snapshot and removes it from HeapProfiler's list.
    373    * All pointers to nodes, edges and paths previously returned become
    374    * invalid.
    375    */
    376   void Delete();
    377 
    378   /**
    379    * Prepare a serialized representation of the snapshot. The result
    380    * is written into the stream provided in chunks of specified size.
    381    * The total length of the serialized snapshot is unknown in
    382    * advance, it can be roughly equal to JS heap size (that means,
    383    * it can be really big - tens of megabytes).
    384    *
    385    * For the JSON format, heap contents are represented as an object
    386    * with the following structure:
    387    *
    388    *  {
    389    *    snapshot: {
    390    *      title: "...",
    391    *      uid: nnn,
    392    *      meta: { meta-info },
    393    *      node_count: nnn,
    394    *      edge_count: nnn
    395    *    },
    396    *    nodes: [nodes array],
    397    *    edges: [edges array],
    398    *    strings: [strings array]
    399    *  }
    400    *
    401    * Nodes reference strings, other nodes, and edges by their indexes
    402    * in corresponding arrays.
    403    */
    404   void Serialize(OutputStream* stream,
    405                  SerializationFormat format = kJSON) const;
    406 };
    407 
    408 
    409 /**
    410  * An interface for reporting progress and controlling long-running
    411  * activities.
    412  */
    413 class V8_EXPORT ActivityControl {  // NOLINT
    414  public:
    415   enum ControlOption {
    416     kContinue = 0,
    417     kAbort = 1
    418   };
    419   virtual ~ActivityControl() {}
    420   /**
    421    * Notify about current progress. The activity can be stopped by
    422    * returning kAbort as the callback result.
    423    */
    424   virtual ControlOption ReportProgressValue(int done, int total) = 0;
    425 };
    426 
    427 
    428 /**
    429  * AllocationProfile is a sampled profile of allocations done by the program.
    430  * This is structured as a call-graph.
    431  */
    432 class V8_EXPORT AllocationProfile {
    433  public:
    434   struct Allocation {
    435     /**
    436      * Size of the sampled allocation object.
    437      */
    438     size_t size;
    439 
    440     /**
    441      * The number of objects of such size that were sampled.
    442      */
    443     unsigned int count;
    444   };
    445 
    446   /**
    447    * Represents a node in the call-graph.
    448    */
    449   struct Node {
    450     /**
    451      * Name of the function. May be empty for anonymous functions or if the
    452      * script corresponding to this function has been unloaded.
    453      */
    454     Local<String> name;
    455 
    456     /**
    457      * Name of the script containing the function. May be empty if the script
    458      * name is not available, or if the script has been unloaded.
    459      */
    460     Local<String> script_name;
    461 
    462     /**
    463      * id of the script where the function is located. May be equal to
    464      * v8::UnboundScript::kNoScriptId in cases where the script doesn't exist.
    465      */
    466     int script_id;
    467 
    468     /**
    469      * Start position of the function in the script.
    470      */
    471     int start_position;
    472 
    473     /**
    474      * 1-indexed line number where the function starts. May be
    475      * kNoLineNumberInfo if no line number information is available.
    476      */
    477     int line_number;
    478 
    479     /**
    480      * 1-indexed column number where the function starts. May be
    481      * kNoColumnNumberInfo if no line number information is available.
    482      */
    483     int column_number;
    484 
    485     /**
    486      * List of callees called from this node for which we have sampled
    487      * allocations. The lifetime of the children is scoped to the containing
    488      * AllocationProfile.
    489      */
    490     std::vector<Node*> children;
    491 
    492     /**
    493      * List of self allocations done by this node in the call-graph.
    494      */
    495     std::vector<Allocation> allocations;
    496   };
    497 
    498   /**
    499    * Returns the root node of the call-graph. The root node corresponds to an
    500    * empty JS call-stack. The lifetime of the returned Node* is scoped to the
    501    * containing AllocationProfile.
    502    */
    503   virtual Node* GetRootNode() = 0;
    504 
    505   virtual ~AllocationProfile() {}
    506 
    507   static const int kNoLineNumberInfo = Message::kNoLineNumberInfo;
    508   static const int kNoColumnNumberInfo = Message::kNoColumnInfo;
    509 };
    510 
    511 
    512 /**
    513  * Interface for controlling heap profiling. Instance of the
    514  * profiler can be retrieved using v8::Isolate::GetHeapProfiler.
    515  */
    516 class V8_EXPORT HeapProfiler {
    517  public:
    518   enum SamplingFlags {
    519     kSamplingNoFlags = 0,
    520     kSamplingForceGC = 1 << 0,
    521   };
    522 
    523   /**
    524    * Callback function invoked for obtaining RetainedObjectInfo for
    525    * the given JavaScript wrapper object. It is prohibited to enter V8
    526    * while the callback is running: only getters on the handle and
    527    * GetPointerFromInternalField on the objects are allowed.
    528    */
    529   typedef RetainedObjectInfo* (*WrapperInfoCallback)(uint16_t class_id,
    530                                                      Local<Value> wrapper);
    531 
    532   /** Returns the number of snapshots taken. */
    533   int GetSnapshotCount();
    534 
    535   /** Returns a snapshot by index. */
    536   const HeapSnapshot* GetHeapSnapshot(int index);
    537 
    538   /**
    539    * Returns SnapshotObjectId for a heap object referenced by |value| if
    540    * it has been seen by the heap profiler, kUnknownObjectId otherwise.
    541    */
    542   SnapshotObjectId GetObjectId(Local<Value> value);
    543 
    544   /**
    545    * Returns heap object with given SnapshotObjectId if the object is alive,
    546    * otherwise empty handle is returned.
    547    */
    548   Local<Value> FindObjectById(SnapshotObjectId id);
    549 
    550   /**
    551    * Clears internal map from SnapshotObjectId to heap object. The new objects
    552    * will not be added into it unless a heap snapshot is taken or heap object
    553    * tracking is kicked off.
    554    */
    555   void ClearObjectIds();
    556 
    557   /**
    558    * A constant for invalid SnapshotObjectId. GetSnapshotObjectId will return
    559    * it in case heap profiler cannot find id  for the object passed as
    560    * parameter. HeapSnapshot::GetNodeById will always return NULL for such id.
    561    */
    562   static const SnapshotObjectId kUnknownObjectId = 0;
    563 
    564   /**
    565    * Callback interface for retrieving user friendly names of global objects.
    566    */
    567   class ObjectNameResolver {
    568    public:
    569     /**
    570      * Returns name to be used in the heap snapshot for given node. Returned
    571      * string must stay alive until snapshot collection is completed.
    572      */
    573     virtual const char* GetName(Local<Object> object) = 0;
    574 
    575    protected:
    576     virtual ~ObjectNameResolver() {}
    577   };
    578 
    579   /**
    580    * Takes a heap snapshot and returns it.
    581    */
    582   const HeapSnapshot* TakeHeapSnapshot(
    583       ActivityControl* control = NULL,
    584       ObjectNameResolver* global_object_name_resolver = NULL);
    585 
    586   /**
    587    * Starts tracking of heap objects population statistics. After calling
    588    * this method, all heap objects relocations done by the garbage collector
    589    * are being registered.
    590    *
    591    * |track_allocations| parameter controls whether stack trace of each
    592    * allocation in the heap will be recorded and reported as part of
    593    * HeapSnapshot.
    594    */
    595   void StartTrackingHeapObjects(bool track_allocations = false);
    596 
    597   /**
    598    * Adds a new time interval entry to the aggregated statistics array. The
    599    * time interval entry contains information on the current heap objects
    600    * population size. The method also updates aggregated statistics and
    601    * reports updates for all previous time intervals via the OutputStream
    602    * object. Updates on each time interval are provided as a stream of the
    603    * HeapStatsUpdate structure instances.
    604    * If |timestamp_us| is supplied, timestamp of the new entry will be written
    605    * into it. The return value of the function is the last seen heap object Id.
    606    *
    607    * StartTrackingHeapObjects must be called before the first call to this
    608    * method.
    609    */
    610   SnapshotObjectId GetHeapStats(OutputStream* stream,
    611                                 int64_t* timestamp_us = NULL);
    612 
    613   /**
    614    * Stops tracking of heap objects population statistics, cleans up all
    615    * collected data. StartHeapObjectsTracking must be called again prior to
    616    * calling GetHeapStats next time.
    617    */
    618   void StopTrackingHeapObjects();
    619 
    620   /**
    621    * Starts gathering a sampling heap profile. A sampling heap profile is
    622    * similar to tcmalloc's heap profiler and Go's mprof. It samples object
    623    * allocations and builds an online 'sampling' heap profile. At any point in
    624    * time, this profile is expected to be a representative sample of objects
    625    * currently live in the system. Each sampled allocation includes the stack
    626    * trace at the time of allocation, which makes this really useful for memory
    627    * leak detection.
    628    *
    629    * This mechanism is intended to be cheap enough that it can be used in
    630    * production with minimal performance overhead.
    631    *
    632    * Allocations are sampled using a randomized Poisson process. On average, one
    633    * allocation will be sampled every |sample_interval| bytes allocated. The
    634    * |stack_depth| parameter controls the maximum number of stack frames to be
    635    * captured on each allocation.
    636    *
    637    * NOTE: This is a proof-of-concept at this point. Right now we only sample
    638    * newspace allocations. Support for paged space allocation (e.g. pre-tenured
    639    * objects, large objects, code objects, etc.) and native allocations
    640    * doesn't exist yet, but is anticipated in the future.
    641    *
    642    * Objects allocated before the sampling is started will not be included in
    643    * the profile.
    644    *
    645    * Returns false if a sampling heap profiler is already running.
    646    */
    647   bool StartSamplingHeapProfiler(uint64_t sample_interval = 512 * 1024,
    648                                  int stack_depth = 16,
    649                                  SamplingFlags flags = kSamplingNoFlags);
    650 
    651   /**
    652    * Stops the sampling heap profile and discards the current profile.
    653    */
    654   void StopSamplingHeapProfiler();
    655 
    656   /**
    657    * Returns the sampled profile of allocations allocated (and still live) since
    658    * StartSamplingHeapProfiler was called. The ownership of the pointer is
    659    * transfered to the caller. Returns nullptr if sampling heap profiler is not
    660    * active.
    661    */
    662   AllocationProfile* GetAllocationProfile();
    663 
    664   /**
    665    * Deletes all snapshots taken. All previously returned pointers to
    666    * snapshots and their contents become invalid after this call.
    667    */
    668   void DeleteAllHeapSnapshots();
    669 
    670   /** Binds a callback to embedder's class ID. */
    671   void SetWrapperClassInfoProvider(
    672       uint16_t class_id,
    673       WrapperInfoCallback callback);
    674 
    675   /**
    676    * Default value of persistent handle class ID. Must not be used to
    677    * define a class. Can be used to reset a class of a persistent
    678    * handle.
    679    */
    680   static const uint16_t kPersistentHandleNoClassId = 0;
    681 
    682   /** Returns memory used for profiler internal data and snapshots. */
    683   size_t GetProfilerMemorySize();
    684 
    685   /**
    686    * Sets a RetainedObjectInfo for an object group (see V8::SetObjectGroupId).
    687    */
    688   void SetRetainedObjectInfo(UniqueId id, RetainedObjectInfo* info);
    689 
    690  private:
    691   HeapProfiler();
    692   ~HeapProfiler();
    693   HeapProfiler(const HeapProfiler&);
    694   HeapProfiler& operator=(const HeapProfiler&);
    695 };
    696 
    697 /**
    698  * Interface for providing information about embedder's objects
    699  * held by global handles. This information is reported in two ways:
    700  *
    701  *  1. When calling AddObjectGroup, an embedder may pass
    702  *     RetainedObjectInfo instance describing the group.  To collect
    703  *     this information while taking a heap snapshot, V8 calls GC
    704  *     prologue and epilogue callbacks.
    705  *
    706  *  2. When a heap snapshot is collected, V8 additionally
    707  *     requests RetainedObjectInfos for persistent handles that
    708  *     were not previously reported via AddObjectGroup.
    709  *
    710  * Thus, if an embedder wants to provide information about native
    711  * objects for heap snapshots, it can do it in a GC prologue
    712  * handler, and / or by assigning wrapper class ids in the following way:
    713  *
    714  *  1. Bind a callback to class id by calling SetWrapperClassInfoProvider.
    715  *  2. Call SetWrapperClassId on certain persistent handles.
    716  *
    717  * V8 takes ownership of RetainedObjectInfo instances passed to it and
    718  * keeps them alive only during snapshot collection. Afterwards, they
    719  * are freed by calling the Dispose class function.
    720  */
    721 class V8_EXPORT RetainedObjectInfo {  // NOLINT
    722  public:
    723   /** Called by V8 when it no longer needs an instance. */
    724   virtual void Dispose() = 0;
    725 
    726   /** Returns whether two instances are equivalent. */
    727   virtual bool IsEquivalent(RetainedObjectInfo* other) = 0;
    728 
    729   /**
    730    * Returns hash value for the instance. Equivalent instances
    731    * must have the same hash value.
    732    */
    733   virtual intptr_t GetHash() = 0;
    734 
    735   /**
    736    * Returns human-readable label. It must be a null-terminated UTF-8
    737    * encoded string. V8 copies its contents during a call to GetLabel.
    738    */
    739   virtual const char* GetLabel() = 0;
    740 
    741   /**
    742    * Returns human-readable group label. It must be a null-terminated UTF-8
    743    * encoded string. V8 copies its contents during a call to GetGroupLabel.
    744    * Heap snapshot generator will collect all the group names, create
    745    * top level entries with these names and attach the objects to the
    746    * corresponding top level group objects. There is a default
    747    * implementation which is required because embedders don't have their
    748    * own implementation yet.
    749    */
    750   virtual const char* GetGroupLabel() { return GetLabel(); }
    751 
    752   /**
    753    * Returns element count in case if a global handle retains
    754    * a subgraph by holding one of its nodes.
    755    */
    756   virtual intptr_t GetElementCount() { return -1; }
    757 
    758   /** Returns embedder's object size in bytes. */
    759   virtual intptr_t GetSizeInBytes() { return -1; }
    760 
    761  protected:
    762   RetainedObjectInfo() {}
    763   virtual ~RetainedObjectInfo() {}
    764 
    765  private:
    766   RetainedObjectInfo(const RetainedObjectInfo&);
    767   RetainedObjectInfo& operator=(const RetainedObjectInfo&);
    768 };
    769 
    770 
    771 /**
    772  * A struct for exporting HeapStats data from V8, using "push" model.
    773  * See HeapProfiler::GetHeapStats.
    774  */
    775 struct HeapStatsUpdate {
    776   HeapStatsUpdate(uint32_t index, uint32_t count, uint32_t size)
    777     : index(index), count(count), size(size) { }
    778   uint32_t index;  // Index of the time interval that was changed.
    779   uint32_t count;  // New value of count field for the interval with this index.
    780   uint32_t size;  // New value of size field for the interval with this index.
    781 };
    782 
    783 
    784 }  // namespace v8
    785 
    786 
    787 #endif  // V8_V8_PROFILER_H_
    788