Home | History | Annotate | Download | only in include
      1 // Copyright 2010 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 #ifndef V8_V8_PROFILER_H_
     29 #define V8_V8_PROFILER_H_
     30 
     31 #include "v8.h"
     32 
     33 /**
     34  * Profiler support for the V8 JavaScript engine.
     35  */
     36 namespace v8 {
     37 
     38 typedef uint32_t SnapshotObjectId;
     39 
     40 /**
     41  * CpuProfileNode represents a node in a call graph.
     42  */
     43 class V8_EXPORT CpuProfileNode {
     44  public:
     45   /** Returns function name (empty string for anonymous functions.) */
     46   Handle<String> GetFunctionName() const;
     47 
     48   /** Returns id of the script where function is located. */
     49   int GetScriptId() const;
     50 
     51   /** Returns resource name for script from where the function originates. */
     52   Handle<String> GetScriptResourceName() const;
     53 
     54   /**
     55    * Returns the number, 1-based, of the line where the function originates.
     56    * kNoLineNumberInfo if no line number information is available.
     57    */
     58   int GetLineNumber() const;
     59 
     60   /**
     61    * Returns 1-based number of the column where the function originates.
     62    * kNoColumnNumberInfo if no column number information is available.
     63    */
     64   int GetColumnNumber() const;
     65 
     66   /** Returns bailout reason for the function
     67     * if the optimization was disabled for it.
     68     */
     69   const char* GetBailoutReason() const;
     70 
     71   /**
     72     * Returns the count of samples where the function was currently executing.
     73     */
     74   unsigned GetHitCount() const;
     75 
     76   /** Returns function entry UID. */
     77   unsigned GetCallUid() const;
     78 
     79   /** Returns id of the node. The id is unique within the tree */
     80   unsigned GetNodeId() const;
     81 
     82   /** Returns child nodes count of the node. */
     83   int GetChildrenCount() const;
     84 
     85   /** Retrieves a child node by index. */
     86   const CpuProfileNode* GetChild(int index) const;
     87 
     88   static const int kNoLineNumberInfo = Message::kNoLineNumberInfo;
     89   static const int kNoColumnNumberInfo = Message::kNoColumnInfo;
     90 };
     91 
     92 
     93 /**
     94  * CpuProfile contains a CPU profile in a form of top-down call tree
     95  * (from main() down to functions that do all the work).
     96  */
     97 class V8_EXPORT CpuProfile {
     98  public:
     99   /** Returns CPU profile UID (assigned by the profiler.) */
    100   unsigned GetUid() const;
    101 
    102   /** Returns CPU profile title. */
    103   Handle<String> GetTitle() const;
    104 
    105   /** Returns the root node of the top down call tree. */
    106   const CpuProfileNode* GetTopDownRoot() const;
    107 
    108   /**
    109     * Returns number of samples recorded. The samples are not recorded unless
    110     * |record_samples| parameter of CpuProfiler::StartCpuProfiling is true.
    111     */
    112   int GetSamplesCount() const;
    113 
    114   /**
    115     * Returns profile node corresponding to the top frame the sample at
    116     * the given index.
    117     */
    118   const CpuProfileNode* GetSample(int index) const;
    119 
    120   /**
    121     * Returns time when the profile recording started (in microseconds
    122     * since the Epoch).
    123     */
    124   int64_t GetStartTime() const;
    125 
    126   /**
    127     * Returns time when the profile recording was stopped (in microseconds
    128     * since the Epoch).
    129     */
    130   int64_t GetEndTime() const;
    131 
    132   /**
    133    * Deletes the profile and removes it from CpuProfiler's list.
    134    * All pointers to nodes previously returned become invalid.
    135    * Profiles with the same uid but obtained using different
    136    * security token are not deleted, but become inaccessible
    137    * using FindProfile method. It is embedder's responsibility
    138    * to call Delete on these profiles.
    139    */
    140   void Delete();
    141 };
    142 
    143 
    144 /**
    145  * Interface for controlling CPU profiling. Instance of the
    146  * profiler can be retrieved using v8::Isolate::GetCpuProfiler.
    147  */
    148 class V8_EXPORT CpuProfiler {
    149  public:
    150   /**
    151    * Changes default CPU profiler sampling interval to the specified number
    152    * of microseconds. Default interval is 1000us. This method must be called
    153    * when there are no profiles being recorded.
    154    */
    155   void SetSamplingInterval(int us);
    156 
    157   /**
    158    * Returns the number of profiles collected (doesn't include
    159    * profiles that are being collected at the moment of call.)
    160    */
    161   int GetProfileCount();
    162 
    163   /** Returns a profile by index. */
    164   const CpuProfile* GetCpuProfile(int index);
    165 
    166   /**
    167    * Starts collecting CPU profile. Title may be an empty string. It
    168    * is allowed to have several profiles being collected at
    169    * once. Attempts to start collecting several profiles with the same
    170    * title are silently ignored. While collecting a profile, functions
    171    * from all security contexts are included in it. The token-based
    172    * filtering is only performed when querying for a profile.
    173    *
    174    * |record_samples| parameter controls whether individual samples should
    175    * be recorded in addition to the aggregated tree.
    176    */
    177   void StartCpuProfiling(Handle<String> title, bool record_samples = false);
    178 
    179   /**
    180    * Stops collecting CPU profile with a given title and returns it.
    181    * If the title given is empty, finishes the last profile started.
    182    */
    183   const CpuProfile* StopCpuProfiling(Handle<String> title);
    184 
    185   /**
    186    * Deletes all existing profiles, also cancelling all profiling
    187    * activity.  All previously returned pointers to profiles and their
    188    * contents become invalid after this call.
    189    */
    190   void DeleteAllCpuProfiles();
    191 
    192   /**
    193    * Tells the profiler whether the embedder is idle.
    194    */
    195   void SetIdle(bool is_idle);
    196 
    197  private:
    198   CpuProfiler();
    199   ~CpuProfiler();
    200   CpuProfiler(const CpuProfiler&);
    201   CpuProfiler& operator=(const CpuProfiler&);
    202 };
    203 
    204 
    205 class HeapGraphNode;
    206 
    207 
    208 /**
    209  * HeapSnapshotEdge represents a directed connection between heap
    210  * graph nodes: from retainers to retained nodes.
    211  */
    212 class V8_EXPORT HeapGraphEdge {
    213  public:
    214   enum Type {
    215     kContextVariable = 0,  // A variable from a function context.
    216     kElement = 1,          // An element of an array.
    217     kProperty = 2,         // A named object property.
    218     kInternal = 3,         // A link that can't be accessed from JS,
    219                            // thus, its name isn't a real property name
    220                            // (e.g. parts of a ConsString).
    221     kHidden = 4,           // A link that is needed for proper sizes
    222                            // calculation, but may be hidden from user.
    223     kShortcut = 5,         // A link that must not be followed during
    224                            // sizes calculation.
    225     kWeak = 6              // A weak reference (ignored by the GC).
    226   };
    227 
    228   /** Returns edge type (see HeapGraphEdge::Type). */
    229   Type GetType() const;
    230 
    231   /**
    232    * Returns edge name. This can be a variable name, an element index, or
    233    * a property name.
    234    */
    235   Handle<Value> GetName() const;
    236 
    237   /** Returns origin node. */
    238   const HeapGraphNode* GetFromNode() const;
    239 
    240   /** Returns destination node. */
    241   const HeapGraphNode* GetToNode() const;
    242 };
    243 
    244 
    245 /**
    246  * HeapGraphNode represents a node in a heap graph.
    247  */
    248 class V8_EXPORT HeapGraphNode {
    249  public:
    250   enum Type {
    251     kHidden = 0,        // Hidden node, may be filtered when shown to user.
    252     kArray = 1,         // An array of elements.
    253     kString = 2,        // A string.
    254     kObject = 3,        // A JS object (except for arrays and strings).
    255     kCode = 4,          // Compiled code.
    256     kClosure = 5,       // Function closure.
    257     kRegExp = 6,        // RegExp.
    258     kHeapNumber = 7,    // Number stored in the heap.
    259     kNative = 8,        // Native object (not from V8 heap).
    260     kSynthetic = 9,     // Synthetic object, usualy used for grouping
    261                         // snapshot items together.
    262     kConsString = 10,   // Concatenated string. A pair of pointers to strings.
    263     kSlicedString = 11  // Sliced string. A fragment of another string.
    264   };
    265 
    266   /** Returns node type (see HeapGraphNode::Type). */
    267   Type GetType() const;
    268 
    269   /**
    270    * Returns node name. Depending on node's type this can be the name
    271    * of the constructor (for objects), the name of the function (for
    272    * closures), string value, or an empty string (for compiled code).
    273    */
    274   Handle<String> GetName() const;
    275 
    276   /**
    277    * Returns node id. For the same heap object, the id remains the same
    278    * across all snapshots.
    279    */
    280   SnapshotObjectId GetId() const;
    281 
    282   /** Returns node's own size, in bytes. */
    283   int GetSelfSize() const;
    284 
    285   /** Returns child nodes count of the node. */
    286   int GetChildrenCount() const;
    287 
    288   /** Retrieves a child by index. */
    289   const HeapGraphEdge* GetChild(int index) const;
    290 
    291   /**
    292    * Finds and returns a value from the heap corresponding to this node,
    293    * if the value is still reachable.
    294    */
    295   Handle<Value> GetHeapValue() const;
    296 };
    297 
    298 
    299 /**
    300  * HeapSnapshots record the state of the JS heap at some moment.
    301  */
    302 class V8_EXPORT HeapSnapshot {
    303  public:
    304   enum SerializationFormat {
    305     kJSON = 0  // See format description near 'Serialize' method.
    306   };
    307 
    308   /** Returns heap snapshot UID (assigned by the profiler.) */
    309   unsigned GetUid() const;
    310 
    311   /** Returns heap snapshot title. */
    312   Handle<String> GetTitle() const;
    313 
    314   /** Returns the root node of the heap graph. */
    315   const HeapGraphNode* GetRoot() const;
    316 
    317   /** Returns a node by its id. */
    318   const HeapGraphNode* GetNodeById(SnapshotObjectId id) const;
    319 
    320   /** Returns total nodes count in the snapshot. */
    321   int GetNodesCount() const;
    322 
    323   /** Returns a node by index. */
    324   const HeapGraphNode* GetNode(int index) const;
    325 
    326   /** Returns a max seen JS object Id. */
    327   SnapshotObjectId GetMaxSnapshotJSObjectId() const;
    328 
    329   /**
    330    * Deletes the snapshot and removes it from HeapProfiler's list.
    331    * All pointers to nodes, edges and paths previously returned become
    332    * invalid.
    333    */
    334   void Delete();
    335 
    336   /**
    337    * Prepare a serialized representation of the snapshot. The result
    338    * is written into the stream provided in chunks of specified size.
    339    * The total length of the serialized snapshot is unknown in
    340    * advance, it can be roughly equal to JS heap size (that means,
    341    * it can be really big - tens of megabytes).
    342    *
    343    * For the JSON format, heap contents are represented as an object
    344    * with the following structure:
    345    *
    346    *  {
    347    *    snapshot: {
    348    *      title: "...",
    349    *      uid: nnn,
    350    *      meta: { meta-info },
    351    *      node_count: nnn,
    352    *      edge_count: nnn
    353    *    },
    354    *    nodes: [nodes array],
    355    *    edges: [edges array],
    356    *    strings: [strings array]
    357    *  }
    358    *
    359    * Nodes reference strings, other nodes, and edges by their indexes
    360    * in corresponding arrays.
    361    */
    362   void Serialize(OutputStream* stream, SerializationFormat format) const;
    363 };
    364 
    365 
    366 class RetainedObjectInfo;
    367 
    368 /**
    369  * Interface for controlling heap profiling. Instance of the
    370  * profiler can be retrieved using v8::Isolate::GetHeapProfiler.
    371  */
    372 class V8_EXPORT HeapProfiler {
    373  public:
    374   /**
    375    * Callback function invoked for obtaining RetainedObjectInfo for
    376    * the given JavaScript wrapper object. It is prohibited to enter V8
    377    * while the callback is running: only getters on the handle and
    378    * GetPointerFromInternalField on the objects are allowed.
    379    */
    380   typedef RetainedObjectInfo* (*WrapperInfoCallback)
    381       (uint16_t class_id, Handle<Value> wrapper);
    382 
    383   /** Returns the number of snapshots taken. */
    384   int GetSnapshotCount();
    385 
    386   /** Returns a snapshot by index. */
    387   const HeapSnapshot* GetHeapSnapshot(int index);
    388 
    389   /**
    390    * Returns SnapshotObjectId for a heap object referenced by |value| if
    391    * it has been seen by the heap profiler, kUnknownObjectId otherwise.
    392    */
    393   SnapshotObjectId GetObjectId(Handle<Value> value);
    394 
    395   /**
    396    * A constant for invalid SnapshotObjectId. GetSnapshotObjectId will return
    397    * it in case heap profiler cannot find id  for the object passed as
    398    * parameter. HeapSnapshot::GetNodeById will always return NULL for such id.
    399    */
    400   static const SnapshotObjectId kUnknownObjectId = 0;
    401 
    402   /**
    403    * Callback interface for retrieving user friendly names of global objects.
    404    */
    405   class ObjectNameResolver {
    406    public:
    407     /**
    408      * Returns name to be used in the heap snapshot for given node. Returned
    409      * string must stay alive until snapshot collection is completed.
    410      */
    411     virtual const char* GetName(Handle<Object> object) = 0;
    412    protected:
    413     virtual ~ObjectNameResolver() {}
    414   };
    415 
    416   /**
    417    * Takes a heap snapshot and returns it. Title may be an empty string.
    418    */
    419   const HeapSnapshot* TakeHeapSnapshot(
    420       Handle<String> title,
    421       ActivityControl* control = NULL,
    422       ObjectNameResolver* global_object_name_resolver = NULL);
    423 
    424   /**
    425    * Starts tracking of heap objects population statistics. After calling
    426    * this method, all heap objects relocations done by the garbage collector
    427    * are being registered.
    428    *
    429    * |track_allocations| parameter controls whether stack trace of each
    430    * allocation in the heap will be recorded and reported as part of
    431    * HeapSnapshot.
    432    */
    433   void StartTrackingHeapObjects(bool track_allocations = false);
    434 
    435   /**
    436    * Adds a new time interval entry to the aggregated statistics array. The
    437    * time interval entry contains information on the current heap objects
    438    * population size. The method also updates aggregated statistics and
    439    * reports updates for all previous time intervals via the OutputStream
    440    * object. Updates on each time interval are provided as a stream of the
    441    * HeapStatsUpdate structure instances.
    442    * The return value of the function is the last seen heap object Id.
    443    *
    444    * StartTrackingHeapObjects must be called before the first call to this
    445    * method.
    446    */
    447   SnapshotObjectId GetHeapStats(OutputStream* stream);
    448 
    449   /**
    450    * Stops tracking of heap objects population statistics, cleans up all
    451    * collected data. StartHeapObjectsTracking must be called again prior to
    452    * calling PushHeapObjectsStats next time.
    453    */
    454   void StopTrackingHeapObjects();
    455 
    456   /**
    457    * Deletes all snapshots taken. All previously returned pointers to
    458    * snapshots and their contents become invalid after this call.
    459    */
    460   void DeleteAllHeapSnapshots();
    461 
    462   /** Binds a callback to embedder's class ID. */
    463   void SetWrapperClassInfoProvider(
    464       uint16_t class_id,
    465       WrapperInfoCallback callback);
    466 
    467   /**
    468    * Default value of persistent handle class ID. Must not be used to
    469    * define a class. Can be used to reset a class of a persistent
    470    * handle.
    471    */
    472   static const uint16_t kPersistentHandleNoClassId = 0;
    473 
    474   /** Returns memory used for profiler internal data and snapshots. */
    475   size_t GetProfilerMemorySize();
    476 
    477   /**
    478    * Sets a RetainedObjectInfo for an object group (see V8::SetObjectGroupId).
    479    */
    480   void SetRetainedObjectInfo(UniqueId id, RetainedObjectInfo* info);
    481 
    482   /**
    483    * Starts recording JS allocations immediately as they arrive and tracking of
    484    * heap objects population statistics.
    485    */
    486   V8_DEPRECATED("Use StartTrackingHeapObjects instead",
    487                 void StartRecordingHeapAllocations());
    488 
    489   /**
    490    * Stops recording JS allocations and tracking of heap objects population
    491    * statistics, cleans all collected heap objects population statistics data.
    492    */
    493   V8_DEPRECATED("Use StopTrackingHeapObjects instead",
    494                 void StopRecordingHeapAllocations());
    495 
    496 
    497  private:
    498   HeapProfiler();
    499   ~HeapProfiler();
    500   HeapProfiler(const HeapProfiler&);
    501   HeapProfiler& operator=(const HeapProfiler&);
    502 };
    503 
    504 
    505 /**
    506  * Interface for providing information about embedder's objects
    507  * held by global handles. This information is reported in two ways:
    508  *
    509  *  1. When calling AddObjectGroup, an embedder may pass
    510  *     RetainedObjectInfo instance describing the group.  To collect
    511  *     this information while taking a heap snapshot, V8 calls GC
    512  *     prologue and epilogue callbacks.
    513  *
    514  *  2. When a heap snapshot is collected, V8 additionally
    515  *     requests RetainedObjectInfos for persistent handles that
    516  *     were not previously reported via AddObjectGroup.
    517  *
    518  * Thus, if an embedder wants to provide information about native
    519  * objects for heap snapshots, he can do it in a GC prologue
    520  * handler, and / or by assigning wrapper class ids in the following way:
    521  *
    522  *  1. Bind a callback to class id by calling SetWrapperClassInfoProvider.
    523  *  2. Call SetWrapperClassId on certain persistent handles.
    524  *
    525  * V8 takes ownership of RetainedObjectInfo instances passed to it and
    526  * keeps them alive only during snapshot collection. Afterwards, they
    527  * are freed by calling the Dispose class function.
    528  */
    529 class V8_EXPORT RetainedObjectInfo {  // NOLINT
    530  public:
    531   /** Called by V8 when it no longer needs an instance. */
    532   virtual void Dispose() = 0;
    533 
    534   /** Returns whether two instances are equivalent. */
    535   virtual bool IsEquivalent(RetainedObjectInfo* other) = 0;
    536 
    537   /**
    538    * Returns hash value for the instance. Equivalent instances
    539    * must have the same hash value.
    540    */
    541   virtual intptr_t GetHash() = 0;
    542 
    543   /**
    544    * Returns human-readable label. It must be a null-terminated UTF-8
    545    * encoded string. V8 copies its contents during a call to GetLabel.
    546    */
    547   virtual const char* GetLabel() = 0;
    548 
    549   /**
    550    * Returns human-readable group label. It must be a null-terminated UTF-8
    551    * encoded string. V8 copies its contents during a call to GetGroupLabel.
    552    * Heap snapshot generator will collect all the group names, create
    553    * top level entries with these names and attach the objects to the
    554    * corresponding top level group objects. There is a default
    555    * implementation which is required because embedders don't have their
    556    * own implementation yet.
    557    */
    558   virtual const char* GetGroupLabel() { return GetLabel(); }
    559 
    560   /**
    561    * Returns element count in case if a global handle retains
    562    * a subgraph by holding one of its nodes.
    563    */
    564   virtual intptr_t GetElementCount() { return -1; }
    565 
    566   /** Returns embedder's object size in bytes. */
    567   virtual intptr_t GetSizeInBytes() { return -1; }
    568 
    569  protected:
    570   RetainedObjectInfo() {}
    571   virtual ~RetainedObjectInfo() {}
    572 
    573  private:
    574   RetainedObjectInfo(const RetainedObjectInfo&);
    575   RetainedObjectInfo& operator=(const RetainedObjectInfo&);
    576 };
    577 
    578 
    579 /**
    580  * A struct for exporting HeapStats data from V8, using "push" model.
    581  * See HeapProfiler::GetHeapStats.
    582  */
    583 struct HeapStatsUpdate {
    584   HeapStatsUpdate(uint32_t index, uint32_t count, uint32_t size)
    585     : index(index), count(count), size(size) { }
    586   uint32_t index;  // Index of the time interval that was changed.
    587   uint32_t count;  // New value of count field for the interval with this index.
    588   uint32_t size;  // New value of size field for the interval with this index.
    589 };
    590 
    591 
    592 }  // namespace v8
    593 
    594 
    595 #endif  // V8_V8_PROFILER_H_
    596