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