1 // Copyright 2021 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 INCLUDE_V8_STATISTICS_H_
6 #define INCLUDE_V8_STATISTICS_H_
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 
11 #include <memory>
12 #include <utility>
13 #include <vector>
14 
15 #include "v8-local-handle.h"  // NOLINT(build/include_directory)
16 #include "v8-promise.h"       // NOLINT(build/include_directory)
17 #include "v8config.h"         // NOLINT(build/include_directory)
18 
19 namespace v8 {
20 
21 class Context;
22 class Isolate;
23 
24 namespace internal {
25 class ReadOnlyHeap;
26 }  // namespace internal
27 
28 /**
29  * Controls how the default MeasureMemoryDelegate reports the result of
30  * the memory measurement to JS. With kSummary only the total size is reported.
31  * With kDetailed the result includes the size of each native context.
32  */
33 enum class MeasureMemoryMode { kSummary, kDetailed };
34 
35 /**
36  * Controls how promptly a memory measurement request is executed.
37  * By default the measurement is folded with the next scheduled GC which may
38  * happen after a while and is forced after some timeout.
39  * The kEager mode starts incremental GC right away and is useful for testing.
40  * The kLazy mode does not force GC.
41  */
42 enum class MeasureMemoryExecution { kDefault, kEager, kLazy };
43 
44 /**
45  * The delegate is used in Isolate::MeasureMemory API.
46  *
47  * It specifies the contexts that need to be measured and gets called when
48  * the measurement is completed to report the results.
49  */
50 class V8_EXPORT MeasureMemoryDelegate {
51  public:
52   virtual ~MeasureMemoryDelegate() = default;
53 
54   /**
55    * Returns true if the size of the given context needs to be measured.
56    */
57   virtual bool ShouldMeasure(Local<Context> context) = 0;
58 
59   /**
60    * This function is called when memory measurement finishes.
61    *
62    * \param context_sizes_in_bytes a vector of (context, size) pairs that
63    *   includes each context for which ShouldMeasure returned true and that
64    *   was not garbage collected while the memory measurement was in progress.
65    *
66    * \param unattributed_size_in_bytes total size of objects that were not
67    *   attributed to any context (i.e. are likely shared objects).
68    */
69   virtual void MeasurementComplete(
70       const std::vector<std::pair<Local<Context>, size_t>>&
71           context_sizes_in_bytes,
72       size_t unattributed_size_in_bytes) = 0;
73 
74   /**
75    * Returns a default delegate that resolves the given promise when
76    * the memory measurement completes.
77    *
78    * \param isolate the current isolate
79    * \param context the current context
80    * \param promise_resolver the promise resolver that is given the
81    *   result of the memory measurement.
82    * \param mode the detail level of the result.
83    */
84   static std::unique_ptr<MeasureMemoryDelegate> Default(
85       Isolate* isolate, Local<Context> context,
86       Local<Promise::Resolver> promise_resolver, MeasureMemoryMode mode);
87 };
88 
89 /**
90  * Collection of shared per-process V8 memory information.
91  *
92  * Instances of this class can be passed to
93  * v8::V8::GetSharedMemoryStatistics to get shared memory statistics from V8.
94  */
95 class V8_EXPORT SharedMemoryStatistics {
96  public:
97   SharedMemoryStatistics();
read_only_space_size()98   size_t read_only_space_size() { return read_only_space_size_; }
read_only_space_used_size()99   size_t read_only_space_used_size() { return read_only_space_used_size_; }
read_only_space_physical_size()100   size_t read_only_space_physical_size() {
101     return read_only_space_physical_size_;
102   }
103 
104  private:
105   size_t read_only_space_size_;
106   size_t read_only_space_used_size_;
107   size_t read_only_space_physical_size_;
108 
109   friend class V8;
110   friend class internal::ReadOnlyHeap;
111 };
112 
113 /**
114  * Collection of V8 heap information.
115  *
116  * Instances of this class can be passed to v8::Isolate::GetHeapStatistics to
117  * get heap statistics from V8.
118  */
119 class V8_EXPORT HeapStatistics {
120  public:
121   HeapStatistics();
total_heap_size()122   size_t total_heap_size() { return total_heap_size_; }
total_heap_size_executable()123   size_t total_heap_size_executable() { return total_heap_size_executable_; }
total_physical_size()124   size_t total_physical_size() { return total_physical_size_; }
total_available_size()125   size_t total_available_size() { return total_available_size_; }
total_global_handles_size()126   size_t total_global_handles_size() { return total_global_handles_size_; }
used_global_handles_size()127   size_t used_global_handles_size() { return used_global_handles_size_; }
used_heap_size()128   size_t used_heap_size() { return used_heap_size_; }
heap_size_limit()129   size_t heap_size_limit() { return heap_size_limit_; }
malloced_memory()130   size_t malloced_memory() { return malloced_memory_; }
external_memory()131   size_t external_memory() { return external_memory_; }
peak_malloced_memory()132   size_t peak_malloced_memory() { return peak_malloced_memory_; }
number_of_native_contexts()133   size_t number_of_native_contexts() { return number_of_native_contexts_; }
number_of_detached_contexts()134   size_t number_of_detached_contexts() { return number_of_detached_contexts_; }
135 
136   /**
137    * Returns a 0/1 boolean, which signifies whether the V8 overwrite heap
138    * garbage with a bit pattern.
139    */
does_zap_garbage()140   size_t does_zap_garbage() { return does_zap_garbage_; }
141 
142  private:
143   size_t total_heap_size_;
144   size_t total_heap_size_executable_;
145   size_t total_physical_size_;
146   size_t total_available_size_;
147   size_t used_heap_size_;
148   size_t heap_size_limit_;
149   size_t malloced_memory_;
150   size_t external_memory_;
151   size_t peak_malloced_memory_;
152   bool does_zap_garbage_;
153   size_t number_of_native_contexts_;
154   size_t number_of_detached_contexts_;
155   size_t total_global_handles_size_;
156   size_t used_global_handles_size_;
157 
158   friend class V8;
159   friend class Isolate;
160 };
161 
162 class V8_EXPORT HeapSpaceStatistics {
163  public:
164   HeapSpaceStatistics();
space_name()165   const char* space_name() { return space_name_; }
space_size()166   size_t space_size() { return space_size_; }
space_used_size()167   size_t space_used_size() { return space_used_size_; }
space_available_size()168   size_t space_available_size() { return space_available_size_; }
physical_space_size()169   size_t physical_space_size() { return physical_space_size_; }
170 
171  private:
172   const char* space_name_;
173   size_t space_size_;
174   size_t space_used_size_;
175   size_t space_available_size_;
176   size_t physical_space_size_;
177 
178   friend class Isolate;
179 };
180 
181 class V8_EXPORT HeapObjectStatistics {
182  public:
183   HeapObjectStatistics();
object_type()184   const char* object_type() { return object_type_; }
object_sub_type()185   const char* object_sub_type() { return object_sub_type_; }
object_count()186   size_t object_count() { return object_count_; }
object_size()187   size_t object_size() { return object_size_; }
188 
189  private:
190   const char* object_type_;
191   const char* object_sub_type_;
192   size_t object_count_;
193   size_t object_size_;
194 
195   friend class Isolate;
196 };
197 
198 class V8_EXPORT HeapCodeStatistics {
199  public:
200   HeapCodeStatistics();
code_and_metadata_size()201   size_t code_and_metadata_size() { return code_and_metadata_size_; }
bytecode_and_metadata_size()202   size_t bytecode_and_metadata_size() { return bytecode_and_metadata_size_; }
external_script_source_size()203   size_t external_script_source_size() { return external_script_source_size_; }
204 
205  private:
206   size_t code_and_metadata_size_;
207   size_t bytecode_and_metadata_size_;
208   size_t external_script_source_size_;
209 
210   friend class Isolate;
211 };
212 
213 }  // namespace v8
214 
215 #endif  // INCLUDE_V8_STATISTICS_H_
216