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
19namespace v8 {
20
21class Context;
22class Isolate;
23
24namespace internal {
25class 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 */
33enum 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 */
42enum 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 */
50class 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 */
95class V8_EXPORT SharedMemoryStatistics {
96 public:
97  SharedMemoryStatistics();
98  size_t read_only_space_size() { return read_only_space_size_; }
99  size_t read_only_space_used_size() { return read_only_space_used_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 */
119class V8_EXPORT HeapStatistics {
120 public:
121  HeapStatistics();
122  size_t total_heap_size() { return total_heap_size_; }
123  size_t total_heap_size_executable() { return total_heap_size_executable_; }
124  size_t total_physical_size() { return total_physical_size_; }
125  size_t total_available_size() { return total_available_size_; }
126  size_t total_global_handles_size() { return total_global_handles_size_; }
127  size_t used_global_handles_size() { return used_global_handles_size_; }
128  size_t used_heap_size() { return used_heap_size_; }
129  size_t heap_size_limit() { return heap_size_limit_; }
130  size_t malloced_memory() { return malloced_memory_; }
131  size_t external_memory() { return external_memory_; }
132  size_t peak_malloced_memory() { return peak_malloced_memory_; }
133  size_t number_of_native_contexts() { return number_of_native_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   */
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
162class V8_EXPORT HeapSpaceStatistics {
163 public:
164  HeapSpaceStatistics();
165  const char* space_name() { return space_name_; }
166  size_t space_size() { return space_size_; }
167  size_t space_used_size() { return space_used_size_; }
168  size_t space_available_size() { return space_available_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
181class V8_EXPORT HeapObjectStatistics {
182 public:
183  HeapObjectStatistics();
184  const char* object_type() { return object_type_; }
185  const char* object_sub_type() { return object_sub_type_; }
186  size_t object_count() { return object_count_; }
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
198class V8_EXPORT HeapCodeStatistics {
199 public:
200  HeapCodeStatistics();
201  size_t code_and_metadata_size() { return code_and_metadata_size_; }
202  size_t bytecode_and_metadata_size() { return bytecode_and_metadata_size_; }
203  size_t external_script_source_size() { return external_script_source_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