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 */ 65 namespace v8 { 66 67 68 /** 69 * CpuProfileNode represents a node in a call graph. 70 */ 71 class 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 */ 121 class 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 */ 150 class 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 204 class HeapGraphNode; 205 206 207 /** 208 * HeapSnapshotEdge represents a directed connection between heap 209 * graph nodes: from retainers to retained nodes. 210 */ 211 class 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 */ 247 class 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 kSynthetic = 9 // Synthetic object, usualy used for grouping 260 // snapshot items together. 261 }; 262 263 /** Returns node type (see HeapGraphNode::Type). */ 264 Type GetType() const; 265 266 /** 267 * Returns node name. Depending on node's type this can be the name 268 * of the constructor (for objects), the name of the function (for 269 * closures), string value, or an empty string (for compiled code). 270 */ 271 Handle<String> GetName() const; 272 273 /** 274 * Returns node id. For the same heap object, the id remains the same 275 * across all snapshots. 276 */ 277 uint64_t GetId() const; 278 279 /** Returns node's own size, in bytes. */ 280 int GetSelfSize() const; 281 282 /** 283 * Returns node's retained size, in bytes. That is, self + sizes of 284 * the objects that are reachable only from this object. In other 285 * words, the size of memory that will be reclaimed having this node 286 * collected. 287 */ 288 int GetRetainedSize() const; 289 290 /** Returns child nodes count of the node. */ 291 int GetChildrenCount() const; 292 293 /** Retrieves a child by index. */ 294 const HeapGraphEdge* GetChild(int index) const; 295 296 /** Returns retainer nodes count of the node. */ 297 int GetRetainersCount() const; 298 299 /** Returns a retainer by index. */ 300 const HeapGraphEdge* GetRetainer(int index) const; 301 302 /** 303 * Returns a dominator node. This is the node that participates in every 304 * path from the snapshot root to the current node. 305 */ 306 const HeapGraphNode* GetDominatorNode() const; 307 308 /** 309 * Finds and returns a value from the heap corresponding to this node, 310 * if the value is still reachable. 311 */ 312 Handle<Value> GetHeapValue() const; 313 }; 314 315 316 /** 317 * HeapSnapshots record the state of the JS heap at some moment. 318 */ 319 class V8EXPORT HeapSnapshot { 320 public: 321 enum Type { 322 kFull = 0 // Heap snapshot with all instances and references. 323 }; 324 enum SerializationFormat { 325 kJSON = 0 // See format description near 'Serialize' method. 326 }; 327 328 /** Returns heap snapshot type. */ 329 Type GetType() const; 330 331 /** Returns heap snapshot UID (assigned by the profiler.) */ 332 unsigned GetUid() const; 333 334 /** Returns heap snapshot title. */ 335 Handle<String> GetTitle() const; 336 337 /** Returns the root node of the heap graph. */ 338 const HeapGraphNode* GetRoot() const; 339 340 /** Returns a node by its id. */ 341 const HeapGraphNode* GetNodeById(uint64_t id) const; 342 343 /** Returns total nodes count in the snapshot. */ 344 int GetNodesCount() const; 345 346 /** Returns a node by index. */ 347 const HeapGraphNode* GetNode(int index) const; 348 349 /** 350 * Deletes the snapshot and removes it from HeapProfiler's list. 351 * All pointers to nodes, edges and paths previously returned become 352 * invalid. 353 */ 354 void Delete(); 355 356 /** 357 * Prepare a serialized representation of the snapshot. The result 358 * is written into the stream provided in chunks of specified size. 359 * The total length of the serialized snapshot is unknown in 360 * advance, it can be roughly equal to JS heap size (that means, 361 * it can be really big - tens of megabytes). 362 * 363 * For the JSON format, heap contents are represented as an object 364 * with the following structure: 365 * 366 * { 367 * snapshot: {title: "...", uid: nnn}, 368 * nodes: [ 369 * meta-info (JSON string), 370 * nodes themselves 371 * ], 372 * strings: [strings] 373 * } 374 * 375 * Outgoing node links are stored after each node. Nodes reference strings 376 * and other nodes by their indexes in corresponding arrays. 377 */ 378 void Serialize(OutputStream* stream, SerializationFormat format) const; 379 }; 380 381 382 class RetainedObjectInfo; 383 384 /** 385 * Interface for controlling heap profiling. 386 */ 387 class V8EXPORT HeapProfiler { 388 public: 389 /** 390 * Callback function invoked for obtaining RetainedObjectInfo for 391 * the given JavaScript wrapper object. It is prohibited to enter V8 392 * while the callback is running: only getters on the handle and 393 * GetPointerFromInternalField on the objects are allowed. 394 */ 395 typedef RetainedObjectInfo* (*WrapperInfoCallback) 396 (uint16_t class_id, Handle<Value> wrapper); 397 398 /** Returns the number of snapshots taken. */ 399 static int GetSnapshotsCount(); 400 401 /** Returns a snapshot by index. */ 402 static const HeapSnapshot* GetSnapshot(int index); 403 404 /** Returns a profile by uid. */ 405 static const HeapSnapshot* FindSnapshot(unsigned uid); 406 407 /** 408 * Takes a heap snapshot and returns it. Title may be an empty string. 409 * See HeapSnapshot::Type for types description. 410 */ 411 static const HeapSnapshot* TakeSnapshot( 412 Handle<String> title, 413 HeapSnapshot::Type type = HeapSnapshot::kFull, 414 ActivityControl* control = NULL); 415 416 /** 417 * Deletes all snapshots taken. All previously returned pointers to 418 * snapshots and their contents become invalid after this call. 419 */ 420 static void DeleteAllSnapshots(); 421 422 /** Binds a callback to embedder's class ID. */ 423 static void DefineWrapperClass( 424 uint16_t class_id, 425 WrapperInfoCallback callback); 426 427 /** 428 * Default value of persistent handle class ID. Must not be used to 429 * define a class. Can be used to reset a class of a persistent 430 * handle. 431 */ 432 static const uint16_t kPersistentHandleNoClassId = 0; 433 434 /** Returns the number of currently existing persistent handles. */ 435 static int GetPersistentHandleCount(); 436 }; 437 438 439 /** 440 * Interface for providing information about embedder's objects 441 * held by global handles. This information is reported in two ways: 442 * 443 * 1. When calling AddObjectGroup, an embedder may pass 444 * RetainedObjectInfo instance describing the group. To collect 445 * this information while taking a heap snapshot, V8 calls GC 446 * prologue and epilogue callbacks. 447 * 448 * 2. When a heap snapshot is collected, V8 additionally 449 * requests RetainedObjectInfos for persistent handles that 450 * were not previously reported via AddObjectGroup. 451 * 452 * Thus, if an embedder wants to provide information about native 453 * objects for heap snapshots, he can do it in a GC prologue 454 * handler, and / or by assigning wrapper class ids in the following way: 455 * 456 * 1. Bind a callback to class id by calling DefineWrapperClass. 457 * 2. Call SetWrapperClassId on certain persistent handles. 458 * 459 * V8 takes ownership of RetainedObjectInfo instances passed to it and 460 * keeps them alive only during snapshot collection. Afterwards, they 461 * are freed by calling the Dispose class function. 462 */ 463 class V8EXPORT RetainedObjectInfo { // NOLINT 464 public: 465 /** Called by V8 when it no longer needs an instance. */ 466 virtual void Dispose() = 0; 467 468 /** Returns whether two instances are equivalent. */ 469 virtual bool IsEquivalent(RetainedObjectInfo* other) = 0; 470 471 /** 472 * Returns hash value for the instance. Equivalent instances 473 * must have the same hash value. 474 */ 475 virtual intptr_t GetHash() = 0; 476 477 /** 478 * Returns human-readable label. It must be a null-terminated UTF-8 479 * encoded string. V8 copies its contents during a call to GetLabel. 480 */ 481 virtual const char* GetLabel() = 0; 482 483 /** 484 * Returns human-readable group label. It must be a null-terminated UTF-8 485 * encoded string. V8 copies its contents during a call to GetGroupLabel. 486 * Heap snapshot generator will collect all the group names, create 487 * top level entries with these names and attach the objects to the 488 * corresponding top level group objects. There is a default 489 * implementation which is required because embedders don't have their 490 * own implementation yet. 491 */ GetGroupLabel()492 virtual const char* GetGroupLabel() { return GetLabel(); } 493 494 /** 495 * Returns element count in case if a global handle retains 496 * a subgraph by holding one of its nodes. 497 */ GetElementCount()498 virtual intptr_t GetElementCount() { return -1; } 499 500 /** Returns embedder's object size in bytes. */ GetSizeInBytes()501 virtual intptr_t GetSizeInBytes() { return -1; } 502 503 protected: RetainedObjectInfo()504 RetainedObjectInfo() {} ~RetainedObjectInfo()505 virtual ~RetainedObjectInfo() {} 506 507 private: 508 RetainedObjectInfo(const RetainedObjectInfo&); 509 RetainedObjectInfo& operator=(const RetainedObjectInfo&); 510 }; 511 512 513 } // namespace v8 514 515 516 #undef V8EXPORT 517 518 519 #endif // V8_V8_PROFILER_H_ 520