v8-profiler.h revision c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9
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#ifdef _WIN32 34// Setup for Windows DLL export/import. See v8.h in this directory for 35// information on how to build/use V8 as a DLL. 36#if defined(BUILDING_V8_SHARED) && defined(USING_V8_SHARED) 37#error both BUILDING_V8_SHARED and USING_V8_SHARED are set - please check the\ 38 build configuration to ensure that at most one of these is set 39#endif 40 41#ifdef BUILDING_V8_SHARED 42#define V8EXPORT __declspec(dllexport) 43#elif USING_V8_SHARED 44#define V8EXPORT __declspec(dllimport) 45#else 46#define V8EXPORT 47#endif 48 49#else // _WIN32 50 51// Setup for Linux shared library export. See v8.h in this directory for 52// information on how to build/use V8 as shared library. 53#if defined(__GNUC__) && (__GNUC__ >= 4) && defined(V8_SHARED) 54#define V8EXPORT __attribute__ ((visibility("default"))) 55#else // defined(__GNUC__) && (__GNUC__ >= 4) 56#define V8EXPORT 57#endif // defined(__GNUC__) && (__GNUC__ >= 4) 58 59#endif // _WIN32 60 61 62/** 63 * Profiler support for the V8 JavaScript engine. 64 */ 65namespace v8 { 66 67 68/** 69 * CpuProfileNode represents a node in a call graph. 70 */ 71class V8EXPORT CpuProfileNode { 72 public: 73 /** Returns function name (empty string for anonymous functions.) */ 74 Handle<String> GetFunctionName() const; 75 76 /** Returns resource name for script from where the function originates. */ 77 Handle<String> GetScriptResourceName() const; 78 79 /** 80 * Returns the number, 1-based, of the line where the function originates. 81 * kNoLineNumberInfo if no line number information is available. 82 */ 83 int GetLineNumber() const; 84 85 /** 86 * Returns total (self + children) execution time of the function, 87 * in milliseconds, estimated by samples count. 88 */ 89 double GetTotalTime() const; 90 91 /** 92 * Returns self execution time of the function, in milliseconds, 93 * estimated by samples count. 94 */ 95 double GetSelfTime() const; 96 97 /** Returns the count of samples where function exists. */ 98 double GetTotalSamplesCount() const; 99 100 /** Returns the count of samples where function was currently executing. */ 101 double GetSelfSamplesCount() const; 102 103 /** Returns function entry UID. */ 104 unsigned GetCallUid() const; 105 106 /** Returns child nodes count of the node. */ 107 int GetChildrenCount() const; 108 109 /** Retrieves a child node by index. */ 110 const CpuProfileNode* GetChild(int index) const; 111 112 static const int kNoLineNumberInfo = Message::kNoLineNumberInfo; 113}; 114 115 116/** 117 * CpuProfile contains a CPU profile in a form of two call trees: 118 * - top-down (from main() down to functions that do all the work); 119 * - bottom-up call graph (in backward direction). 120 */ 121class V8EXPORT CpuProfile { 122 public: 123 /** Returns CPU profile UID (assigned by the profiler.) */ 124 unsigned GetUid() const; 125 126 /** Returns CPU profile title. */ 127 Handle<String> GetTitle() const; 128 129 /** Returns the root node of the bottom up call tree. */ 130 const CpuProfileNode* GetBottomUpRoot() const; 131 132 /** Returns the root node of the top down call tree. */ 133 const CpuProfileNode* GetTopDownRoot() const; 134 135 /** 136 * Deletes the profile and removes it from CpuProfiler's list. 137 * All pointers to nodes previously returned become invalid. 138 * Profiles with the same uid but obtained using different 139 * security token are not deleted, but become inaccessible 140 * using FindProfile method. It is embedder's responsibility 141 * to call Delete on these profiles. 142 */ 143 void Delete(); 144}; 145 146 147/** 148 * Interface for controlling CPU profiling. 149 */ 150class V8EXPORT CpuProfiler { 151 public: 152 /** 153 * A note on security tokens usage. As scripts from different 154 * origins can run inside a single V8 instance, it is possible to 155 * have functions from different security contexts intermixed in a 156 * single CPU profile. To avoid exposing function names belonging to 157 * other contexts, filtering by security token is performed while 158 * obtaining profiling results. 159 */ 160 161 /** 162 * Returns the number of profiles collected (doesn't include 163 * profiles that are being collected at the moment of call.) 164 */ 165 static int GetProfilesCount(); 166 167 /** Returns a profile by index. */ 168 static const CpuProfile* GetProfile( 169 int index, 170 Handle<Value> security_token = Handle<Value>()); 171 172 /** Returns a profile by uid. */ 173 static const CpuProfile* FindProfile( 174 unsigned uid, 175 Handle<Value> security_token = Handle<Value>()); 176 177 /** 178 * Starts collecting CPU profile. Title may be an empty string. It 179 * is allowed to have several profiles being collected at 180 * once. Attempts to start collecting several profiles with the same 181 * title are silently ignored. While collecting a profile, functions 182 * from all security contexts are included in it. The token-based 183 * filtering is only performed when querying for a profile. 184 */ 185 static void StartProfiling(Handle<String> title); 186 187 /** 188 * Stops collecting CPU profile with a given title and returns it. 189 * If the title given is empty, finishes the last profile started. 190 */ 191 static const CpuProfile* StopProfiling( 192 Handle<String> title, 193 Handle<Value> security_token = Handle<Value>()); 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 static void DeleteAllProfiles(); 201}; 202 203 204class HeapGraphNode; 205 206 207/** 208 * HeapSnapshotEdge represents a directed connection between heap 209 * graph nodes: from retainers to retained nodes. 210 */ 211class V8EXPORT HeapGraphEdge { 212 public: 213 enum Type { 214 kContextVariable = 0, // A variable from a function context. 215 kElement = 1, // An element of an array. 216 kProperty = 2, // A named object property. 217 kInternal = 3, // A link that can't be accessed from JS, 218 // thus, its name isn't a real property name 219 // (e.g. parts of a ConsString). 220 kHidden = 4, // A link that is needed for proper sizes 221 // calculation, but may be hidden from user. 222 kShortcut = 5, // A link that must not be followed during 223 // sizes calculation. 224 kWeak = 6 // A weak reference (ignored by the GC). 225 }; 226 227 /** Returns edge type (see HeapGraphEdge::Type). */ 228 Type GetType() const; 229 230 /** 231 * Returns edge name. This can be a variable name, an element index, or 232 * a property name. 233 */ 234 Handle<Value> GetName() const; 235 236 /** Returns origin node. */ 237 const HeapGraphNode* GetFromNode() const; 238 239 /** Returns destination node. */ 240 const HeapGraphNode* GetToNode() const; 241}; 242 243 244/** 245 * HeapGraphNode represents a node in a heap graph. 246 */ 247class V8EXPORT HeapGraphNode { 248 public: 249 enum Type { 250 kHidden = 0, // Hidden node, may be filtered when shown to user. 251 kArray = 1, // An array of elements. 252 kString = 2, // A string. 253 kObject = 3, // A JS object (except for arrays and strings). 254 kCode = 4, // Compiled code. 255 kClosure = 5, // Function closure. 256 kRegExp = 6, // RegExp. 257 kHeapNumber = 7, // Number stored in the heap. 258 kNative = 8 // Native object (not from V8 heap). 259 }; 260 261 /** Returns node type (see HeapGraphNode::Type). */ 262 Type GetType() const; 263 264 /** 265 * Returns node name. Depending on node's type this can be the name 266 * of the constructor (for objects), the name of the function (for 267 * closures), string value, or an empty string (for compiled code). 268 */ 269 Handle<String> GetName() const; 270 271 /** 272 * Returns node id. For the same heap object, the id remains the same 273 * across all snapshots. 274 */ 275 uint64_t GetId() const; 276 277 /** Returns node's own size, in bytes. */ 278 int GetSelfSize() const; 279 280 /** 281 * Returns node's retained size, in bytes. That is, self + sizes of 282 * the objects that are reachable only from this object. In other 283 * words, the size of memory that will be reclaimed having this node 284 * collected. 285 * 286 * Exact retained size calculation has O(N) (number of nodes) 287 * computational complexity, while approximate has O(1). It is 288 * assumed that initially heap profiling tools provide approximate 289 * sizes for all nodes, and then exact sizes are calculated for the 290 * most 'interesting' nodes. 291 */ 292 int GetRetainedSize(bool exact) const; 293 294 /** Returns child nodes count of the node. */ 295 int GetChildrenCount() const; 296 297 /** Retrieves a child by index. */ 298 const HeapGraphEdge* GetChild(int index) const; 299 300 /** Returns retainer nodes count of the node. */ 301 int GetRetainersCount() const; 302 303 /** Returns a retainer by index. */ 304 const HeapGraphEdge* GetRetainer(int index) const; 305 306 /** 307 * Returns a dominator node. This is the node that participates in every 308 * path from the snapshot root to the current node. 309 */ 310 const HeapGraphNode* GetDominatorNode() const; 311 312 /** 313 * Finds and returns a value from the heap corresponding to this node, 314 * if the value is still reachable. 315 */ 316 Handle<Value> GetHeapValue() const; 317}; 318 319 320/** 321 * HeapSnapshots record the state of the JS heap at some moment. 322 */ 323class V8EXPORT HeapSnapshot { 324 public: 325 enum Type { 326 kFull = 0 // Heap snapshot with all instances and references. 327 }; 328 enum SerializationFormat { 329 kJSON = 0 // See format description near 'Serialize' method. 330 }; 331 332 /** Returns heap snapshot type. */ 333 Type GetType() const; 334 335 /** Returns heap snapshot UID (assigned by the profiler.) */ 336 unsigned GetUid() const; 337 338 /** Returns heap snapshot title. */ 339 Handle<String> GetTitle() const; 340 341 /** Returns the root node of the heap graph. */ 342 const HeapGraphNode* GetRoot() const; 343 344 /** Returns a node by its id. */ 345 const HeapGraphNode* GetNodeById(uint64_t id) const; 346 347 /** Returns total nodes count in the snapshot. */ 348 int GetNodesCount() const; 349 350 /** Returns a node by index. */ 351 const HeapGraphNode* GetNode(int index) const; 352 353 /** 354 * Deletes the snapshot and removes it from HeapProfiler's list. 355 * All pointers to nodes, edges and paths previously returned become 356 * invalid. 357 */ 358 void Delete(); 359 360 /** 361 * Prepare a serialized representation of the snapshot. The result 362 * is written into the stream provided in chunks of specified size. 363 * The total length of the serialized snapshot is unknown in 364 * advance, it can be roughly equal to JS heap size (that means, 365 * it can be really big - tens of megabytes). 366 * 367 * For the JSON format, heap contents are represented as an object 368 * with the following structure: 369 * 370 * { 371 * snapshot: {title: "...", uid: nnn}, 372 * nodes: [ 373 * meta-info (JSON string), 374 * nodes themselves 375 * ], 376 * strings: [strings] 377 * } 378 * 379 * Outgoing node links are stored after each node. Nodes reference strings 380 * and other nodes by their indexes in corresponding arrays. 381 */ 382 void Serialize(OutputStream* stream, SerializationFormat format) const; 383}; 384 385 386class RetainedObjectInfo; 387 388/** 389 * Interface for controlling heap profiling. 390 */ 391class V8EXPORT HeapProfiler { 392 public: 393 /** 394 * Callback function invoked for obtaining RetainedObjectInfo for 395 * the given JavaScript wrapper object. It is prohibited to enter V8 396 * while the callback is running: only getters on the handle and 397 * GetPointerFromInternalField on the objects are allowed. 398 */ 399 typedef RetainedObjectInfo* (*WrapperInfoCallback) 400 (uint16_t class_id, Handle<Value> wrapper); 401 402 /** Returns the number of snapshots taken. */ 403 static int GetSnapshotsCount(); 404 405 /** Returns a snapshot by index. */ 406 static const HeapSnapshot* GetSnapshot(int index); 407 408 /** Returns a profile by uid. */ 409 static const HeapSnapshot* FindSnapshot(unsigned uid); 410 411 /** 412 * Takes a heap snapshot and returns it. Title may be an empty string. 413 * See HeapSnapshot::Type for types description. 414 */ 415 static const HeapSnapshot* TakeSnapshot( 416 Handle<String> title, 417 HeapSnapshot::Type type = HeapSnapshot::kFull, 418 ActivityControl* control = NULL); 419 420 /** 421 * Deletes all snapshots taken. All previously returned pointers to 422 * snapshots and their contents become invalid after this call. 423 */ 424 static void DeleteAllSnapshots(); 425 426 /** Binds a callback to embedder's class ID. */ 427 static void DefineWrapperClass( 428 uint16_t class_id, 429 WrapperInfoCallback callback); 430 431 /** 432 * Default value of persistent handle class ID. Must not be used to 433 * define a class. Can be used to reset a class of a persistent 434 * handle. 435 */ 436 static const uint16_t kPersistentHandleNoClassId = 0; 437}; 438 439 440/** 441 * Interface for providing information about embedder's objects 442 * held by global handles. This information is reported in two ways: 443 * 444 * 1. When calling AddObjectGroup, an embedder may pass 445 * RetainedObjectInfo instance describing the group. To collect 446 * this information while taking a heap snapshot, V8 calls GC 447 * prologue and epilogue callbacks. 448 * 449 * 2. When a heap snapshot is collected, V8 additionally 450 * requests RetainedObjectInfos for persistent handles that 451 * were not previously reported via AddObjectGroup. 452 * 453 * Thus, if an embedder wants to provide information about native 454 * objects for heap snapshots, he can do it in a GC prologue 455 * handler, and / or by assigning wrapper class ids in the following way: 456 * 457 * 1. Bind a callback to class id by calling DefineWrapperClass. 458 * 2. Call SetWrapperClassId on certain persistent handles. 459 * 460 * V8 takes ownership of RetainedObjectInfo instances passed to it and 461 * keeps them alive only during snapshot collection. Afterwards, they 462 * are freed by calling the Dispose class function. 463 */ 464class V8EXPORT RetainedObjectInfo { // NOLINT 465 public: 466 /** Called by V8 when it no longer needs an instance. */ 467 virtual void Dispose() = 0; 468 469 /** Returns whether two instances are equivalent. */ 470 virtual bool IsEquivalent(RetainedObjectInfo* other) = 0; 471 472 /** 473 * Returns hash value for the instance. Equivalent instances 474 * must have the same hash value. 475 */ 476 virtual intptr_t GetHash() = 0; 477 478 /** 479 * Returns human-readable label. It must be a NUL-terminated UTF-8 480 * encoded string. V8 copies its contents during a call to GetLabel. 481 */ 482 virtual const char* GetLabel() = 0; 483 484 /** 485 * Returns element count in case if a global handle retains 486 * a subgraph by holding one of its nodes. 487 */ 488 virtual intptr_t GetElementCount() { return -1; } 489 490 /** Returns embedder's object size in bytes. */ 491 virtual intptr_t GetSizeInBytes() { return -1; } 492 493 protected: 494 RetainedObjectInfo() {} 495 virtual ~RetainedObjectInfo() {} 496 497 private: 498 RetainedObjectInfo(const RetainedObjectInfo&); 499 RetainedObjectInfo& operator=(const RetainedObjectInfo&); 500}; 501 502 503} // namespace v8 504 505 506#undef V8EXPORT 507 508 509#endif // V8_V8_PROFILER_H_ 510