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 retaners 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 }; 225 226 /** Returns edge type (see HeapGraphEdge::Type). */ 227 Type GetType() const; 228 229 /** 230 * Returns edge name. This can be a variable name, an element index, or 231 * a property name. 232 */ 233 Handle<Value> GetName() const; 234 235 /** Returns origin node. */ 236 const HeapGraphNode* GetFromNode() const; 237 238 /** Returns destination node. */ 239 const HeapGraphNode* GetToNode() const; 240 }; 241 242 243 /** 244 * HeapGraphNode represents a node in a heap graph. 245 */ 246 class V8EXPORT HeapGraphNode { 247 public: 248 enum Type { 249 kHidden = 0, // Hidden node, may be filtered when shown to user. 250 kArray = 1, // An array of elements. 251 kString = 2, // A string. 252 kObject = 3, // A JS object (except for arrays and strings). 253 kCode = 4, // Compiled code. 254 kClosure = 5, // Function closure. 255 kRegExp = 6, // RegExp. 256 kHeapNumber = 7, // Number stored in the heap. 257 kNative = 8 // Native object (not from V8 heap). 258 }; 259 260 /** Returns node type (see HeapGraphNode::Type). */ 261 Type GetType() const; 262 263 /** 264 * Returns node name. Depending on node's type this can be the name 265 * of the constructor (for objects), the name of the function (for 266 * closures), string value, or an empty string (for compiled code). 267 */ 268 Handle<String> GetName() const; 269 270 /** 271 * Returns node id. For the same heap object, the id remains the same 272 * across all snapshots. Not applicable to aggregated heap snapshots 273 * as they only contain aggregated instances. 274 */ 275 uint64_t GetId() const; 276 277 /** 278 * Returns the number of instances. Only applicable to aggregated 279 * heap snapshots. 280 */ 281 int GetInstancesCount() const; 282 283 /** Returns node's own size, in bytes. */ 284 int GetSelfSize() const; 285 286 /** 287 * Returns node's retained size, in bytes. That is, self + sizes of 288 * the objects that are reachable only from this object. In other 289 * words, the size of memory that will be reclaimed having this node 290 * collected. 291 * 292 * Exact retained size calculation has O(N) (number of nodes) 293 * computational complexity, while approximate has O(1). It is 294 * assumed that initially heap profiling tools provide approximate 295 * sizes for all nodes, and then exact sizes are calculated for the 296 * most 'interesting' nodes. 297 */ 298 int GetRetainedSize(bool exact) const; 299 300 /** Returns child nodes count of the node. */ 301 int GetChildrenCount() const; 302 303 /** Retrieves a child by index. */ 304 const HeapGraphEdge* GetChild(int index) const; 305 306 /** Returns retainer nodes count of the node. */ 307 int GetRetainersCount() const; 308 309 /** Returns a retainer by index. */ 310 const HeapGraphEdge* GetRetainer(int index) const; 311 312 /** 313 * Returns a dominator node. This is the node that participates in every 314 * path from the snapshot root to the current node. 315 */ 316 const HeapGraphNode* GetDominatorNode() const; 317 }; 318 319 320 /** 321 * HeapSnapshots record the state of the JS heap at some moment. 322 */ 323 class V8EXPORT HeapSnapshot { 324 public: 325 enum Type { 326 kFull = 0, // Heap snapshot with all instances and references. 327 kAggregated = 1 // Snapshot doesn't contain individual heap entries, 328 // instead they are grouped by constructor name. 329 }; 330 enum SerializationFormat { 331 kJSON = 0 // See format description near 'Serialize' method. 332 }; 333 334 /** Returns heap snapshot type. */ 335 Type GetType() const; 336 337 /** Returns heap snapshot UID (assigned by the profiler.) */ 338 unsigned GetUid() const; 339 340 /** Returns heap snapshot title. */ 341 Handle<String> GetTitle() const; 342 343 /** Returns the root node of the heap graph. */ 344 const HeapGraphNode* GetRoot() const; 345 346 /** Returns a node by its id. */ 347 const HeapGraphNode* GetNodeById(uint64_t id) 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 is 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 435 436 /** 437 * Interface for providing information about embedder's objects 438 * held by global handles. This information is reported in two ways: 439 * 440 * 1. When calling AddObjectGroup, an embedder may pass 441 * RetainedObjectInfo instance describing the group. To collect 442 * this information while taking a heap snapshot, V8 calls GC 443 * prologue and epilogue callbacks. 444 * 445 * 2. When a heap snapshot is collected, V8 additionally 446 * requests RetainedObjectInfos for persistent handles that 447 * were not previously reported via AddObjectGroup. 448 * 449 * Thus, if an embedder wants to provide information about native 450 * objects for heap snapshots, he can do it in a GC prologue 451 * handler, and / or by assigning wrapper class ids in the following way: 452 * 453 * 1. Bind a callback to class id by calling DefineWrapperClass. 454 * 2. Call SetWrapperClassId on certain persistent handles. 455 * 456 * V8 takes ownership of RetainedObjectInfo instances passed to it and 457 * keeps them alive only during snapshot collection. Afterwards, they 458 * are freed by calling the Dispose class function. 459 */ 460 class V8EXPORT RetainedObjectInfo { // NOLINT 461 public: 462 /** Called by V8 when it no longer needs an instance. */ 463 virtual void Dispose() = 0; 464 465 /** Returns whether two instances are equivalent. */ 466 virtual bool IsEquivalent(RetainedObjectInfo* other) = 0; 467 468 /** 469 * Returns hash value for the instance. Equivalent instances 470 * must have the same hash value. 471 */ 472 virtual intptr_t GetHash() = 0; 473 474 /** 475 * Returns human-readable label. It must be a NUL-terminated UTF-8 476 * encoded string. V8 copies its contents during a call to GetLabel. 477 */ 478 virtual const char* GetLabel() = 0; 479 480 /** 481 * Returns element count in case if a global handle retains 482 * a subgraph by holding one of its nodes. 483 */ 484 virtual intptr_t GetElementCount() { return -1; } 485 486 /** Returns embedder's object size in bytes. */ 487 virtual intptr_t GetSizeInBytes() { return -1; } 488 489 protected: 490 RetainedObjectInfo() {} 491 virtual ~RetainedObjectInfo() {} 492 493 private: 494 RetainedObjectInfo(const RetainedObjectInfo&); 495 RetainedObjectInfo& operator=(const RetainedObjectInfo&); 496 }; 497 498 499 } // namespace v8 500 501 502 #undef V8EXPORT 503 504 505 #endif // V8_V8_PROFILER_H_ 506