v8  7.0.276 (node 11.14.0)
V8 is Google's open source JavaScript engine
v8-profiler.h
Go to the documentation of this file.
1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_V8_PROFILER_H_
6 #define V8_V8_PROFILER_H_
7 
8 #include <unordered_set>
9 #include <vector>
10 #include "v8.h" // NOLINT(build/include)
11 
12 /**
13  * Profiler support for the V8 JavaScript engine.
14  */
15 namespace v8 {
16 
17 class HeapGraphNode;
18 struct HeapStatsUpdate;
19 
20 typedef uint32_t SnapshotObjectId;
21 
22 
24  int script_id;
25  size_t position;
26 };
27 
28 } // namespace v8
29 
30 #ifdef V8_OS_WIN
31 template class V8_EXPORT std::vector<v8::CpuProfileDeoptFrame>;
32 #endif
33 
34 namespace v8 {
35 
37  /** A pointer to a static string owned by v8. */
38  const char* deopt_reason;
40 };
41 
42 } // namespace v8
43 
44 #ifdef V8_OS_WIN
45 template class V8_EXPORT std::vector<v8::CpuProfileDeoptInfo>;
46 #endif
47 
48 namespace v8 {
49 
50 // TickSample captures the information collected for each sample.
51 struct TickSample {
52  // Internal profiling (with --prof + tools/$OS-tick-processor) wants to
53  // include the runtime function we're calling. Externally exposed tick
54  // samples don't care.
56 
58  : state(OTHER),
59  pc(nullptr),
60  external_callback_entry(nullptr),
61  frames_count(0),
62  has_external_callback(false),
63  update_stats(true) {}
64 
65  /**
66  * Initialize a tick sample from the isolate.
67  * \param isolate The isolate.
68  * \param state Execution state.
69  * \param record_c_entry_frame Include or skip the runtime function.
70  * \param update_stats Whether update the sample to the aggregated stats.
71  * \param use_simulator_reg_state When set to true and V8 is running under a
72  * simulator, the method will use the simulator
73  * register state rather than the one provided
74  * with |state| argument. Otherwise the method
75  * will use provided register |state| as is.
76  */
77  void Init(Isolate* isolate, const v8::RegisterState& state,
78  RecordCEntryFrame record_c_entry_frame, bool update_stats,
79  bool use_simulator_reg_state = true);
80  /**
81  * Get a call stack sample from the isolate.
82  * \param isolate The isolate.
83  * \param state Register state.
84  * \param record_c_entry_frame Include or skip the runtime function.
85  * \param frames Caller allocated buffer to store stack frames.
86  * \param frames_limit Maximum number of frames to capture. The buffer must
87  * be large enough to hold the number of frames.
88  * \param sample_info The sample info is filled up by the function
89  * provides number of actual captured stack frames and
90  * the current VM state.
91  * \param use_simulator_reg_state When set to true and V8 is running under a
92  * simulator, the method will use the simulator
93  * register state rather than the one provided
94  * with |state| argument. Otherwise the method
95  * will use provided register |state| as is.
96  * \note GetStackSample is thread and signal safe and should only be called
97  * when the JS thread is paused or interrupted.
98  * Otherwise the behavior is undefined.
99  */
100  static bool GetStackSample(Isolate* isolate, v8::RegisterState* state,
101  RecordCEntryFrame record_c_entry_frame,
102  void** frames, size_t frames_limit,
103  v8::SampleInfo* sample_info,
104  bool use_simulator_reg_state = true);
105  StateTag state; // The state of the VM.
106  void* pc; // Instruction pointer.
107  union {
108  void* tos; // Top stack value (*sp).
110  };
111  static const unsigned kMaxFramesCountLog2 = 8;
112  static const unsigned kMaxFramesCount = (1 << kMaxFramesCountLog2) - 1;
113  void* stack[kMaxFramesCount]; // Call stack.
114  unsigned frames_count : kMaxFramesCountLog2; // Number of captured frames.
116  bool update_stats : 1; // Whether the sample should update aggregated stats.
117 };
118 
119 /**
120  * CpuProfileNode represents a node in a call graph.
121  */
123  public:
124  struct LineTick {
125  /** The 1-based number of the source line where the function originates. */
126  int line;
127 
128  /** The count of samples associated with the source line. */
129  unsigned int hit_count;
130  };
131 
132  /** Returns function name (empty string for anonymous functions.) */
134 
135  /**
136  * Returns function name (empty string for anonymous functions.)
137  * The string ownership is *not* passed to the caller. It stays valid until
138  * profile is deleted. The function is thread safe.
139  */
140  const char* GetFunctionNameStr() const;
141 
142  /** Returns id of the script where function is located. */
143  int GetScriptId() const;
144 
145  /** Returns resource name for script from where the function originates. */
147 
148  /**
149  * Returns resource name for script from where the function originates.
150  * The string ownership is *not* passed to the caller. It stays valid until
151  * profile is deleted. The function is thread safe.
152  */
153  const char* GetScriptResourceNameStr() const;
154 
155  /**
156  * Returns the number, 1-based, of the line where the function originates.
157  * kNoLineNumberInfo if no line number information is available.
158  */
159  int GetLineNumber() const;
160 
161  /**
162  * Returns 1-based number of the column where the function originates.
163  * kNoColumnNumberInfo if no column number information is available.
164  */
165  int GetColumnNumber() const;
166 
167  /**
168  * Returns the number of the function's source lines that collect the samples.
169  */
170  unsigned int GetHitLineCount() const;
171 
172  /** Returns the set of source lines that collect the samples.
173  * The caller allocates buffer and responsible for releasing it.
174  * True if all available entries are copied, otherwise false.
175  * The function copies nothing if buffer is not large enough.
176  */
177  bool GetLineTicks(LineTick* entries, unsigned int length) const;
178 
179  /** Returns bailout reason for the function
180  * if the optimization was disabled for it.
181  */
182  const char* GetBailoutReason() const;
183 
184  /**
185  * Returns the count of samples where the function was currently executing.
186  */
187  unsigned GetHitCount() const;
188 
189  /** Returns function entry UID. */
191  "Use GetScriptId, GetLineNumber, and GetColumnNumber instead.",
192  unsigned GetCallUid() const);
193 
194  /** Returns id of the node. The id is unique within the tree */
195  unsigned GetNodeId() const;
196 
197  /** Returns child nodes count of the node. */
198  int GetChildrenCount() const;
199 
200  /** Retrieves a child node by index. */
201  const CpuProfileNode* GetChild(int index) const;
202 
203  /** Retrieves deopt infos for the node. */
204  const std::vector<CpuProfileDeoptInfo>& GetDeoptInfos() const;
205 
208 };
209 
210 
211 /**
212  * CpuProfile contains a CPU profile in a form of top-down call tree
213  * (from main() down to functions that do all the work).
214  */
216  public:
217  /** Returns CPU profile title. */
219 
220  /** Returns the root node of the top down call tree. */
222 
223  /**
224  * Returns number of samples recorded. The samples are not recorded unless
225  * |record_samples| parameter of CpuProfiler::StartCpuProfiling is true.
226  */
227  int GetSamplesCount() const;
228 
229  /**
230  * Returns profile node corresponding to the top frame the sample at
231  * the given index.
232  */
233  const CpuProfileNode* GetSample(int index) const;
234 
235  /**
236  * Returns the timestamp of the sample. The timestamp is the number of
237  * microseconds since some unspecified starting point.
238  * The point is equal to the starting point used by GetStartTime.
239  */
240  int64_t GetSampleTimestamp(int index) const;
241 
242  /**
243  * Returns time when the profile recording was started (in microseconds)
244  * since some unspecified starting point.
245  */
246  int64_t GetStartTime() const;
247 
248  /**
249  * Returns time when the profile recording was stopped (in microseconds)
250  * since some unspecified starting point.
251  * The point is equal to the starting point used by GetStartTime.
252  */
253  int64_t GetEndTime() const;
254 
255  /**
256  * Deletes the profile and removes it from CpuProfiler's list.
257  * All pointers to nodes previously returned become invalid.
258  */
259  void Delete();
260 };
261 
263  // In the resulting CpuProfile tree, intermediate nodes in a stack trace
264  // (from the root to a leaf) will have line numbers that point to the start
265  // line of the function, rather than the line of the callsite of the child.
267  // In the resulting CpuProfile tree, nodes are separated based on the line
268  // number of their callsite in their parent.
270 };
271 
272 /**
273  * Interface for controlling CPU profiling. Instance of the
274  * profiler can be created using v8::CpuProfiler::New method.
275  */
277  public:
278  /**
279  * Creates a new CPU profiler for the |isolate|. The isolate must be
280  * initialized. The profiler object must be disposed after use by calling
281  * |Dispose| method.
282  */
283  static CpuProfiler* New(Isolate* isolate);
284 
285  /**
286  * Synchronously collect current stack sample in all profilers attached to
287  * the |isolate|. The call does not affect number of ticks recorded for
288  * the current top node.
289  */
290  static void CollectSample(Isolate* isolate);
291 
292  /**
293  * Disposes the CPU profiler object.
294  */
295  void Dispose();
296 
297  /**
298  * Changes default CPU profiler sampling interval to the specified number
299  * of microseconds. Default interval is 1000us. This method must be called
300  * when there are no profiles being recorded.
301  */
302  void SetSamplingInterval(int us);
303 
304  /**
305  * Starts collecting CPU profile. Title may be an empty string. It
306  * is allowed to have several profiles being collected at
307  * once. Attempts to start collecting several profiles with the same
308  * title are silently ignored. While collecting a profile, functions
309  * from all security contexts are included in it. The token-based
310  * filtering is only performed when querying for a profile.
311  *
312  * |record_samples| parameter controls whether individual samples should
313  * be recorded in addition to the aggregated tree.
314  */
316  bool record_samples = false);
317  /**
318  * The same as StartProfiling above, but the CpuProfilingMode defaults to
319  * kLeafNodeLineNumbers mode, which was the previous default behavior of the
320  * profiler.
321  */
322  void StartProfiling(Local<String> title, bool record_samples = false);
323 
324  /**
325  * Stops collecting CPU profile with a given title and returns it.
326  * If the title given is empty, finishes the last profile started.
327  */
329 
330  /**
331  * Force collection of a sample. Must be called on the VM thread.
332  * Recording the forced sample does not contribute to the aggregated
333  * profile statistics.
334  */
335  V8_DEPRECATED("Use static CollectSample(Isolate*) instead.",
336  void CollectSample());
337 
338  /**
339  * Tells the profiler whether the embedder is idle.
340  */
341  V8_DEPRECATED("Use Isolate::SetIdle(bool) instead.",
342  void SetIdle(bool is_idle));
343 
344  private:
345  CpuProfiler();
346  ~CpuProfiler();
347  CpuProfiler(const CpuProfiler&);
348  CpuProfiler& operator=(const CpuProfiler&);
349 };
350 
351 
352 /**
353  * HeapSnapshotEdge represents a directed connection between heap
354  * graph nodes: from retainers to retained nodes.
355  */
357  public:
358  enum Type {
359  kContextVariable = 0, // A variable from a function context.
360  kElement = 1, // An element of an array.
361  kProperty = 2, // A named object property.
362  kInternal = 3, // A link that can't be accessed from JS,
363  // thus, its name isn't a real property name
364  // (e.g. parts of a ConsString).
365  kHidden = 4, // A link that is needed for proper sizes
366  // calculation, but may be hidden from user.
367  kShortcut = 5, // A link that must not be followed during
368  // sizes calculation.
369  kWeak = 6 // A weak reference (ignored by the GC).
370  };
371 
372  /** Returns edge type (see HeapGraphEdge::Type). */
373  Type GetType() const;
374 
375  /**
376  * Returns edge name. This can be a variable name, an element index, or
377  * a property name.
378  */
379  Local<Value> GetName() const;
380 
381  /** Returns origin node. */
382  const HeapGraphNode* GetFromNode() const;
383 
384  /** Returns destination node. */
385  const HeapGraphNode* GetToNode() const;
386 };
387 
388 
389 /**
390  * HeapGraphNode represents a node in a heap graph.
391  */
393  public:
394  enum Type {
395  kHidden = 0, // Hidden node, may be filtered when shown to user.
396  kArray = 1, // An array of elements.
397  kString = 2, // A string.
398  kObject = 3, // A JS object (except for arrays and strings).
399  kCode = 4, // Compiled code.
400  kClosure = 5, // Function closure.
401  kRegExp = 6, // RegExp.
402  kHeapNumber = 7, // Number stored in the heap.
403  kNative = 8, // Native object (not from V8 heap).
404  kSynthetic = 9, // Synthetic object, usually used for grouping
405  // snapshot items together.
406  kConsString = 10, // Concatenated string. A pair of pointers to strings.
407  kSlicedString = 11, // Sliced string. A fragment of another string.
408  kSymbol = 12, // A Symbol (ES6).
409  kBigInt = 13 // BigInt.
410  };
411 
412  /** Returns node type (see HeapGraphNode::Type). */
413  Type GetType() const;
414 
415  /**
416  * Returns node name. Depending on node's type this can be the name
417  * of the constructor (for objects), the name of the function (for
418  * closures), string value, or an empty string (for compiled code).
419  */
420  Local<String> GetName() const;
421 
422  /**
423  * Returns node id. For the same heap object, the id remains the same
424  * across all snapshots.
425  */
427 
428  /** Returns node's own size, in bytes. */
429  size_t GetShallowSize() const;
430 
431  /** Returns child nodes count of the node. */
432  int GetChildrenCount() const;
433 
434  /** Retrieves a child by index. */
435  const HeapGraphEdge* GetChild(int index) const;
436 };
437 
438 
439 /**
440  * An interface for exporting data from V8, using "push" model.
441  */
442 class V8_EXPORT OutputStream { // NOLINT
443  public:
444  enum WriteResult {
446  kAbort = 1
447  };
448  virtual ~OutputStream() {}
449  /** Notify about the end of stream. */
450  virtual void EndOfStream() = 0;
451  /** Get preferred output chunk size. Called only once. */
452  virtual int GetChunkSize() { return 1024; }
453  /**
454  * Writes the next chunk of snapshot data into the stream. Writing
455  * can be stopped by returning kAbort as function result. EndOfStream
456  * will not be called in case writing was aborted.
457  */
458  virtual WriteResult WriteAsciiChunk(char* data, int size) = 0;
459  /**
460  * Writes the next chunk of heap stats data into the stream. Writing
461  * can be stopped by returning kAbort as function result. EndOfStream
462  * will not be called in case writing was aborted.
463  */
464  virtual WriteResult WriteHeapStatsChunk(HeapStatsUpdate* data, int count) {
465  return kAbort;
466  }
467 };
468 
469 
470 /**
471  * HeapSnapshots record the state of the JS heap at some moment.
472  */
474  public:
476  kJSON = 0 // See format description near 'Serialize' method.
477  };
478 
479  /** Returns the root node of the heap graph. */
480  const HeapGraphNode* GetRoot() const;
481 
482  /** Returns a node by its id. */
484 
485  /** Returns total nodes count in the snapshot. */
486  int GetNodesCount() const;
487 
488  /** Returns a node by index. */
489  const HeapGraphNode* GetNode(int index) const;
490 
491  /** Returns a max seen JS object Id. */
493 
494  /**
495  * Deletes the snapshot and removes it from HeapProfiler's list.
496  * All pointers to nodes, edges and paths previously returned become
497  * invalid.
498  */
499  void Delete();
500 
501  /**
502  * Prepare a serialized representation of the snapshot. The result
503  * is written into the stream provided in chunks of specified size.
504  * The total length of the serialized snapshot is unknown in
505  * advance, it can be roughly equal to JS heap size (that means,
506  * it can be really big - tens of megabytes).
507  *
508  * For the JSON format, heap contents are represented as an object
509  * with the following structure:
510  *
511  * {
512  * snapshot: {
513  * title: "...",
514  * uid: nnn,
515  * meta: { meta-info },
516  * node_count: nnn,
517  * edge_count: nnn
518  * },
519  * nodes: [nodes array],
520  * edges: [edges array],
521  * strings: [strings array]
522  * }
523  *
524  * Nodes reference strings, other nodes, and edges by their indexes
525  * in corresponding arrays.
526  */
527  void Serialize(OutputStream* stream,
528  SerializationFormat format = kJSON) const;
529 };
530 
531 
532 /**
533  * An interface for reporting progress and controlling long-running
534  * activities.
535  */
536 class V8_EXPORT ActivityControl { // NOLINT
537  public:
540  kAbort = 1
541  };
542  virtual ~ActivityControl() {}
543  /**
544  * Notify about current progress. The activity can be stopped by
545  * returning kAbort as the callback result.
546  */
547  virtual ControlOption ReportProgressValue(int done, int total) = 0;
548 };
549 
550 
551 /**
552  * AllocationProfile is a sampled profile of allocations done by the program.
553  * This is structured as a call-graph.
554  */
556  public:
557  struct Allocation {
558  /**
559  * Size of the sampled allocation object.
560  */
561  size_t size;
562 
563  /**
564  * The number of objects of such size that were sampled.
565  */
566  unsigned int count;
567  };
568 
569  /**
570  * Represents a node in the call-graph.
571  */
572  struct Node {
573  /**
574  * Name of the function. May be empty for anonymous functions or if the
575  * script corresponding to this function has been unloaded.
576  */
578 
579  /**
580  * Name of the script containing the function. May be empty if the script
581  * name is not available, or if the script has been unloaded.
582  */
584 
585  /**
586  * id of the script where the function is located. May be equal to
587  * v8::UnboundScript::kNoScriptId in cases where the script doesn't exist.
588  */
590 
591  /**
592  * Start position of the function in the script.
593  */
595 
596  /**
597  * 1-indexed line number where the function starts. May be
598  * kNoLineNumberInfo if no line number information is available.
599  */
601 
602  /**
603  * 1-indexed column number where the function starts. May be
604  * kNoColumnNumberInfo if no line number information is available.
605  */
607 
608  /**
609  * List of callees called from this node for which we have sampled
610  * allocations. The lifetime of the children is scoped to the containing
611  * AllocationProfile.
612  */
613  std::vector<Node*> children;
614 
615  /**
616  * List of self allocations done by this node in the call-graph.
617  */
618  std::vector<Allocation> allocations;
619  };
620 
621  /**
622  * Returns the root node of the call-graph. The root node corresponds to an
623  * empty JS call-stack. The lifetime of the returned Node* is scoped to the
624  * containing AllocationProfile.
625  */
626  virtual Node* GetRootNode() = 0;
627 
628  virtual ~AllocationProfile() {}
629 
632 };
633 
634 /**
635  * An object graph consisting of embedder objects and V8 objects.
636  * Edges of the graph are strong references between the objects.
637  * The embedder can build this graph during heap snapshot generation
638  * to include the embedder objects in the heap snapshot.
639  * Usage:
640  * 1) Define derived class of EmbedderGraph::Node for embedder objects.
641  * 2) Set the build embedder graph callback on the heap profiler using
642  * HeapProfiler::AddBuildEmbedderGraphCallback.
643  * 3) In the callback use graph->AddEdge(node1, node2) to add an edge from
644  * node1 to node2.
645  * 4) To represent references from/to V8 object, construct V8 nodes using
646  * graph->V8Node(value).
647  */
649  public:
650  class Node {
651  public:
652  Node() = default;
653  virtual ~Node() = default;
654  virtual const char* Name() = 0;
655  virtual size_t SizeInBytes() = 0;
656  /**
657  * The corresponding V8 wrapper node if not null.
658  * During heap snapshot generation the embedder node and the V8 wrapper
659  * node will be merged into one node to simplify retaining paths.
660  */
661  virtual Node* WrapperNode() { return nullptr; }
662  virtual bool IsRootNode() { return false; }
663  /** Must return true for non-V8 nodes. */
664  virtual bool IsEmbedderNode() { return true; }
665  /**
666  * Optional name prefix. It is used in Chrome for tagging detached nodes.
667  */
668  virtual const char* NamePrefix() { return nullptr; }
669 
670  private:
671  Node(const Node&) = delete;
672  Node& operator=(const Node&) = delete;
673  };
674 
675  /**
676  * Returns a node corresponding to the given V8 value. Ownership is not
677  * transferred. The result pointer is valid while the graph is alive.
678  */
679  virtual Node* V8Node(const v8::Local<v8::Value>& value) = 0;
680 
681  /**
682  * Adds the given node to the graph and takes ownership of the node.
683  * Returns a raw pointer to the node that is valid while the graph is alive.
684  */
685  virtual Node* AddNode(std::unique_ptr<Node> node) = 0;
686 
687  /**
688  * Adds an edge that represents a strong reference from the given
689  * node |from| to the given node |to|. The nodes must be added to the graph
690  * before calling this function.
691  *
692  * If name is nullptr, the edge will have auto-increment indexes, otherwise
693  * it will be named accordingly.
694  */
695  virtual void AddEdge(Node* from, Node* to, const char* name = nullptr) = 0;
696 
697  virtual ~EmbedderGraph() = default;
698 };
699 
700 /**
701  * Interface for controlling heap profiling. Instance of the
702  * profiler can be retrieved using v8::Isolate::GetHeapProfiler.
703  */
705  public:
709  };
710 
711  typedef std::unordered_set<const v8::PersistentBase<v8::Value>*>
713  typedef std::vector<std::pair<v8::RetainedObjectInfo*, RetainerChildren>>
715  typedef std::vector<std::pair<const v8::PersistentBase<v8::Value>*,
716  const v8::PersistentBase<v8::Value>*>>
718 
719  struct RetainerInfos {
722  };
723 
724  /**
725  * Callback function invoked to retrieve all RetainerInfos from the embedder.
726  */
727  typedef RetainerInfos (*GetRetainerInfosCallback)(v8::Isolate* isolate);
728 
729  /**
730  * Callback function invoked for obtaining RetainedObjectInfo for
731  * the given JavaScript wrapper object. It is prohibited to enter V8
732  * while the callback is running: only getters on the handle and
733  * GetPointerFromInternalField on the objects are allowed.
734  */
735  typedef RetainedObjectInfo* (*WrapperInfoCallback)(uint16_t class_id,
736  Local<Value> wrapper);
737 
738  /**
739  * Callback function invoked during heap snapshot generation to retrieve
740  * the embedder object graph. The callback should use graph->AddEdge(..) to
741  * add references between the objects.
742  * The callback must not trigger garbage collection in V8.
743  */
744  typedef void (*BuildEmbedderGraphCallback)(v8::Isolate* isolate,
745  v8::EmbedderGraph* graph,
746  void* data);
747 
748  /** TODO(addaleax): Remove */
749  typedef void (*LegacyBuildEmbedderGraphCallback)(v8::Isolate* isolate,
750  v8::EmbedderGraph* graph);
751 
752  /** Returns the number of snapshots taken. */
754 
755  /** Returns a snapshot by index. */
756  const HeapSnapshot* GetHeapSnapshot(int index);
757 
758  /**
759  * Returns SnapshotObjectId for a heap object referenced by |value| if
760  * it has been seen by the heap profiler, kUnknownObjectId otherwise.
761  */
763 
764  /**
765  * Returns heap object with given SnapshotObjectId if the object is alive,
766  * otherwise empty handle is returned.
767  */
769 
770  /**
771  * Clears internal map from SnapshotObjectId to heap object. The new objects
772  * will not be added into it unless a heap snapshot is taken or heap object
773  * tracking is kicked off.
774  */
776 
777  /**
778  * A constant for invalid SnapshotObjectId. GetSnapshotObjectId will return
779  * it in case heap profiler cannot find id for the object passed as
780  * parameter. HeapSnapshot::GetNodeById will always return NULL for such id.
781  */
783 
784  /**
785  * Callback interface for retrieving user friendly names of global objects.
786  */
788  public:
789  /**
790  * Returns name to be used in the heap snapshot for given node. Returned
791  * string must stay alive until snapshot collection is completed.
792  */
793  virtual const char* GetName(Local<Object> object) = 0;
794 
795  protected:
796  virtual ~ObjectNameResolver() {}
797  };
798 
799  /**
800  * Takes a heap snapshot and returns it.
801  */
803  ActivityControl* control = NULL,
804  ObjectNameResolver* global_object_name_resolver = NULL);
805 
806  /**
807  * Starts tracking of heap objects population statistics. After calling
808  * this method, all heap objects relocations done by the garbage collector
809  * are being registered.
810  *
811  * |track_allocations| parameter controls whether stack trace of each
812  * allocation in the heap will be recorded and reported as part of
813  * HeapSnapshot.
814  */
815  void StartTrackingHeapObjects(bool track_allocations = false);
816 
817  /**
818  * Adds a new time interval entry to the aggregated statistics array. The
819  * time interval entry contains information on the current heap objects
820  * population size. The method also updates aggregated statistics and
821  * reports updates for all previous time intervals via the OutputStream
822  * object. Updates on each time interval are provided as a stream of the
823  * HeapStatsUpdate structure instances.
824  * If |timestamp_us| is supplied, timestamp of the new entry will be written
825  * into it. The return value of the function is the last seen heap object Id.
826  *
827  * StartTrackingHeapObjects must be called before the first call to this
828  * method.
829  */
831  int64_t* timestamp_us = NULL);
832 
833  /**
834  * Stops tracking of heap objects population statistics, cleans up all
835  * collected data. StartHeapObjectsTracking must be called again prior to
836  * calling GetHeapStats next time.
837  */
839 
840  /**
841  * Starts gathering a sampling heap profile. A sampling heap profile is
842  * similar to tcmalloc's heap profiler and Go's mprof. It samples object
843  * allocations and builds an online 'sampling' heap profile. At any point in
844  * time, this profile is expected to be a representative sample of objects
845  * currently live in the system. Each sampled allocation includes the stack
846  * trace at the time of allocation, which makes this really useful for memory
847  * leak detection.
848  *
849  * This mechanism is intended to be cheap enough that it can be used in
850  * production with minimal performance overhead.
851  *
852  * Allocations are sampled using a randomized Poisson process. On average, one
853  * allocation will be sampled every |sample_interval| bytes allocated. The
854  * |stack_depth| parameter controls the maximum number of stack frames to be
855  * captured on each allocation.
856  *
857  * NOTE: This is a proof-of-concept at this point. Right now we only sample
858  * newspace allocations. Support for paged space allocation (e.g. pre-tenured
859  * objects, large objects, code objects, etc.) and native allocations
860  * doesn't exist yet, but is anticipated in the future.
861  *
862  * Objects allocated before the sampling is started will not be included in
863  * the profile.
864  *
865  * Returns false if a sampling heap profiler is already running.
866  */
867  bool StartSamplingHeapProfiler(uint64_t sample_interval = 512 * 1024,
868  int stack_depth = 16,
870 
871  /**
872  * Stops the sampling heap profile and discards the current profile.
873  */
875 
876  /**
877  * Returns the sampled profile of allocations allocated (and still live) since
878  * StartSamplingHeapProfiler was called. The ownership of the pointer is
879  * transferred to the caller. Returns nullptr if sampling heap profiler is not
880  * active.
881  */
883 
884  /**
885  * Deletes all snapshots taken. All previously returned pointers to
886  * snapshots and their contents become invalid after this call.
887  */
889 
890  /** Binds a callback to embedder's class ID. */
892  "Use AddBuildEmbedderGraphCallback to provide info about embedder nodes",
893  void SetWrapperClassInfoProvider(uint16_t class_id,
894  WrapperInfoCallback callback));
895 
897  "Use AddBuildEmbedderGraphCallback to provide info about embedder nodes",
898  void SetGetRetainerInfosCallback(GetRetainerInfosCallback callback));
899 
901  "Use AddBuildEmbedderGraphCallback to provide info about embedder nodes",
902  void SetBuildEmbedderGraphCallback(
905  void* data);
907  void* data);
908 
909  /**
910  * Default value of persistent handle class ID. Must not be used to
911  * define a class. Can be used to reset a class of a persistent
912  * handle.
913  */
914  static const uint16_t kPersistentHandleNoClassId = 0;
915 
916  private:
917  HeapProfiler();
918  ~HeapProfiler();
919  HeapProfiler(const HeapProfiler&);
920  HeapProfiler& operator=(const HeapProfiler&);
921 };
922 
923 /**
924  * Interface for providing information about embedder's objects
925  * held by global handles. This information is reported in two ways:
926  *
927  * 1. When calling AddObjectGroup, an embedder may pass
928  * RetainedObjectInfo instance describing the group. To collect
929  * this information while taking a heap snapshot, V8 calls GC
930  * prologue and epilogue callbacks.
931  *
932  * 2. When a heap snapshot is collected, V8 additionally
933  * requests RetainedObjectInfos for persistent handles that
934  * were not previously reported via AddObjectGroup.
935  *
936  * Thus, if an embedder wants to provide information about native
937  * objects for heap snapshots, it can do it in a GC prologue
938  * handler, and / or by assigning wrapper class ids in the following way:
939  *
940  * 1. Bind a callback to class id by calling SetWrapperClassInfoProvider.
941  * 2. Call SetWrapperClassId on certain persistent handles.
942  *
943  * V8 takes ownership of RetainedObjectInfo instances passed to it and
944  * keeps them alive only during snapshot collection. Afterwards, they
945  * are freed by calling the Dispose class function.
946  */
947 class V8_EXPORT RetainedObjectInfo { // NOLINT
948  public:
949  /** Called by V8 when it no longer needs an instance. */
950  virtual void Dispose() = 0;
951 
952  /** Returns whether two instances are equivalent. */
953  virtual bool IsEquivalent(RetainedObjectInfo* other) = 0;
954 
955  /**
956  * Returns hash value for the instance. Equivalent instances
957  * must have the same hash value.
958  */
959  virtual intptr_t GetHash() = 0;
960 
961  /**
962  * Returns human-readable label. It must be a null-terminated UTF-8
963  * encoded string. V8 copies its contents during a call to GetLabel.
964  */
965  virtual const char* GetLabel() = 0;
966 
967  /**
968  * Returns human-readable group label. It must be a null-terminated UTF-8
969  * encoded string. V8 copies its contents during a call to GetGroupLabel.
970  * Heap snapshot generator will collect all the group names, create
971  * top level entries with these names and attach the objects to the
972  * corresponding top level group objects. There is a default
973  * implementation which is required because embedders don't have their
974  * own implementation yet.
975  */
976  virtual const char* GetGroupLabel() { return GetLabel(); }
977 
978  /**
979  * Returns element count in case if a global handle retains
980  * a subgraph by holding one of its nodes.
981  */
982  virtual intptr_t GetElementCount() { return -1; }
983 
984  /** Returns embedder's object size in bytes. */
985  virtual intptr_t GetSizeInBytes() { return -1; }
986 
987  protected:
989  virtual ~RetainedObjectInfo() {}
990 
991  private:
992  RetainedObjectInfo(const RetainedObjectInfo&);
993  RetainedObjectInfo& operator=(const RetainedObjectInfo&);
994 };
995 
996 
997 /**
998  * A struct for exporting HeapStats data from V8, using "push" model.
999  * See HeapProfiler::GetHeapStats.
1000  */
1002  HeapStatsUpdate(uint32_t index, uint32_t count, uint32_t size)
1003  : index(index), count(count), size(size) { }
1004  uint32_t index; // Index of the time interval that was changed.
1005  uint32_t count; // New value of count field for the interval with this index.
1006  uint32_t size; // New value of size field for the interval with this index.
1007 };
1008 
1009 #define CODE_EVENTS_LIST(V)
1010  V(Builtin)
1011  V(Callback)
1012  V(Eval)
1013  V(Function)
1014  V(InterpretedFunction)
1015  V(Handler)
1016  V(BytecodeHandler)
1017  V(LazyCompile)
1018  V(RegExp)
1019  V(Script)
1020  V(Stub)
1021 
1022 /**
1023  * Note that this enum may be extended in the future. Please include a default
1024  * case if this enum is used in a switch statement.
1025  */
1027  kUnknownType = 0
1028 #define V(Name) , k##Name##Type
1030 #undef V
1031 };
1032 
1033 /**
1034  * Representation of a code creation event
1035  */
1037  public:
1038  uintptr_t GetCodeStartAddress();
1039  size_t GetCodeSize();
1044  /**
1045  * NOTE (mmarchini): We can't allocate objects in the heap when we collect
1046  * existing code, and both the code type and the comment are not stored in the
1047  * heap, so we return those as const char*.
1048  */
1050  const char* GetComment();
1051 
1052  static const char* GetCodeEventTypeName(CodeEventType code_event_type);
1053 };
1054 
1055 /**
1056  * Interface to listen to code creation events.
1057  */
1059  public:
1060  /**
1061  * Creates a new listener for the |isolate|. The isolate must be initialized.
1062  * The listener object must be disposed after use by calling |Dispose| method.
1063  * Multiple listeners can be created for the same isolate.
1064  */
1065  explicit CodeEventHandler(Isolate* isolate);
1066  virtual ~CodeEventHandler();
1067 
1068  virtual void Handle(CodeEvent* code_event) = 0;
1069 
1070  void Enable();
1071  void Disable();
1072 
1073  private:
1074  CodeEventHandler();
1075  CodeEventHandler(const CodeEventHandler&);
1076  CodeEventHandler& operator=(const CodeEventHandler&);
1077  void* internal_listener_;
1078 };
1079 
1080 } // namespace v8
1081 
1082 
1083 #endif // V8_V8_PROFILER_H_