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_; } cpu_profiler_metadata_size()204 size_t cpu_profiler_metadata_size() { return cpu_profiler_metadata_size_; } 205 206 private: 207 size_t code_and_metadata_size_; 208 size_t bytecode_and_metadata_size_; 209 size_t external_script_source_size_; 210 size_t cpu_profiler_metadata_size_; 211 212 friend class Isolate; 213 }; 214 215 } // namespace v8 216 217 #endif // INCLUDE_V8_STATISTICS_H_ 218