19#if V8_ENABLE_WEBASSEMBLY
32class MemoryMeasurementResultBuilder final {
34 explicit MemoryMeasurementResultBuilder(
v8::Isolate* isolate)
35 :
isolate_(reinterpret_cast<Isolate*>(isolate)),
39 void AddTotal(
size_t estimate,
size_t lower_bound,
size_t upper_bound) {
40 AddProperty(result_,
factory_->total_string(),
41 NewResult(estimate, lower_bound, upper_bound));
43 void AddCurrent(
size_t estimate,
size_t lower_bound,
size_t upper_bound) {
45 AddProperty(result_,
factory_->current_string(),
46 NewResult(estimate, lower_bound, upper_bound));
48 void AddOther(
size_t estimate,
size_t lower_bound,
size_t upper_bound) {
50 other_.push_back(NewResult(estimate, lower_bound, upper_bound));
52 void AddWasm(
size_t code,
size_t metadata) {
53 DirectHandle<JSObject>
wasm = NewJSObject();
54 AddProperty(
wasm,
factory_->NewStringFromAsciiChecked(
"code"),
56 AddProperty(
wasm,
factory_->NewStringFromAsciiChecked(
"metadata"),
58 AddProperty(result_,
factory_->NewStringFromAsciiChecked(
"WebAssembly"),
61 DirectHandle<JSObject> Build() {
63 int length =
static_cast<int>(
other_.size());
64 DirectHandle<FixedArray> other =
factory_->NewFixedArray(length);
66 other->set(
i, *other_[
i]);
68 AddProperty(result_,
factory_->other_string(),
69 factory_->NewJSArrayWithElements(other));
78 DirectHandle<Object> estimate_obj = NewNumber(estimate);
79 AddProperty(
result,
factory_->jsMemoryEstimate_string(), estimate_obj);
80 DirectHandle<Object> range = NewRange(lower_bound, upper_bound);
84 DirectHandle<Object> NewNumber(
size_t value) {
85 return factory_->NewNumberFromSize(value);
90 DirectHandle<JSArray> NewRange(
size_t lower_bound,
size_t upper_bound) {
91 DirectHandle<Object> lower = NewNumber(lower_bound);
92 DirectHandle<Object> upper = NewNumber(upper_bound);
93 DirectHandle<FixedArray> elements =
factory_->NewFixedArray(2);
94 elements->set(0, *lower);
95 elements->set(1, *upper);
96 return factory_->NewJSArrayWithElements(elements);
98 void AddProperty(DirectHandle<JSObject>
object, DirectHandle<String> name,
99 DirectHandle<Object> value) {
140 other_context->GetSecurityToken();
144 size_t shared_size =
result.unattributed_size_in_bytes;
145 size_t wasm_code =
result.wasm_code_size_in_bytes;
146 size_t wasm_metadata =
result.wasm_metadata_size_in_bytes;
149 size_t total_size = 0;
150 size_t current_size = 0;
153 total_size +=
result.sizes_in_bytes[
i];
155 current_size =
result.sizes_in_bytes[
i];
158 MemoryMeasurementResultBuilder result_builder(
isolate_);
159 result_builder.AddTotal(total_size, total_size, total_size + shared_size);
160 if (wasm_code > 0 || wasm_metadata > 0) {
161 result_builder.AddWasm(wasm_code, wasm_metadata);
165 result_builder.AddCurrent(current_size, current_size,
166 current_size + shared_size);
169 size_t other_size =
result.sizes_in_bytes[
i];
170 result_builder.AddOther(other_size, other_size,
171 other_size + shared_size);
178 if (v8_promise->Resolve(v8_context, v8_result).IsNothing()) {
185 task_runner_(isolate->
heap()->GetForegroundTaskRunner()),
186 random_number_generator_() {
188 random_number_generator_.SetSeed(v8_flags.random_seed);
193 std::unique_ptr<v8::MeasureMemoryDelegate> delegate,
196 int length =
static_cast<int>(contexts.size());
200 weak_contexts->set(
i,
MakeWeak(*contexts[
i]));
204 Request request = {std::move(delegate),
205 global_weak_contexts,
206 std::vector<size_t>(length),
219 std::unordered_set<Address> unique_contexts;
224 for (
int i = 0;
i < contexts->
length();
i++) {
226 if (contexts->get(
i).GetHeapObject(&context)) {
227 unique_contexts.insert(context.ptr());
231 return std::vector<Address>(unique_contexts.begin(), unique_contexts.end());
238#if V8_ENABLE_WEBASSEMBLY
240 size_t wasm_metadata =
248 for (
int i = 0; i < static_cast<int>(request.
sizes.size());
i++) {
250 if (!request.
contexts->get(
i).GetHeapObject(&context)) {
253 request.
sizes[
i] = stats.Get(context.ptr());
256#if V8_ENABLE_WEBASSEMBLY
260 done_.push_back(std::move(request));
311 if (
heap->incremental_marking()->IsStopped()) {
316 heap->FinalizeIncrementalMarkingAtomically(
344 std::vector<size_t> size_in_bytes;
346 static_cast<size_t>(request.
contexts->length()));
347 for (
int i = 0;
i < request.
contexts->length();
i++) {
354 contexts.push_back(context);
355 size_in_bytes.push_back(request.
sizes[
i]);
358 {{contexts.begin(), contexts.end()},
359 {size_in_bytes.begin(), size_in_bytes.end()},
371 return std::make_unique<MeasureMemoryDelegate>(isolate, context, promise,
378 for (
const auto& it : other.size_by_context_) {
386 size_t external_size = 0;
387 if (instance_type == JS_ARRAY_BUFFER_TYPE) {
virtual void MeasurementComplete(Result result)
void PostDelayedTask(std::unique_ptr< Task > task, double delay_in_seconds, const SourceLocation &location=SourceLocation::Current())
void PostTask(std::unique_ptr< Task > task, const SourceLocation &location=SourceLocation::Current())
static Local< To > Convert(v8::internal::DirectHandle< From > obj)
TimeDelta Elapsed() const
V8_INLINE int NextInt() V8_WARN_UNUSED_RESULT
int64_t InMilliseconds() const
Handle< WeakFixedArray > NewWeakFixedArray(int length, AllocationType allocation=AllocationType::kYoung)
IndirectHandle< Object > Create(Tagged< Object > value)
GlobalHandles * global_handles() const
bool is_execution_terminating()
v8::internal::Factory * factory()
static V8_EXPORT_PRIVATE void AddProperty(Isolate *isolate, DirectHandle< JSObject > object, DirectHandle< Name > name, DirectHandle< Object > value, PropertyAttributes attributes)
static constexpr Address kSharedContext
const v8::Global< v8::Context > context_
void MeasurementComplete(Result result) override
const v8::MeasureMemoryMode mode_
bool ShouldMeasure(v8::Local< v8::Context > context) override
MeasureMemoryDelegate(v8::Isolate *isolate, v8::Local< v8::Context > context, v8::Local< v8::Promise::Resolver > promise, v8::MeasureMemoryMode mode)
const v8::Global< v8::Promise::Resolver > promise_
~MeasureMemoryDelegate() override=default
bool eager_gc_task_pending_
std::vector< Address > StartProcessing()
bool EnqueueRequest(std::unique_ptr< v8::MeasureMemoryDelegate > delegate, v8::MeasureMemoryExecution execution, const std::vector< Handle< NativeContext > > contexts)
bool reporting_task_pending_
bool IsGCTaskPending(v8::MeasureMemoryExecution execution)
base::RandomNumberGenerator random_number_generator_
MemoryMeasurement(Isolate *isolate)
void FinishProcessing(const NativeContextStats &stats)
int NextGCTaskDelayInSeconds()
std::list< Request > received_
bool delayed_gc_task_pending_
static std::unique_ptr< v8::MeasureMemoryDelegate > DefaultDelegate(v8::Isolate *isolate, v8::Local< v8::Context > context, v8::Local< v8::Promise::Resolver > promise, v8::MeasureMemoryMode mode)
std::shared_ptr< v8::TaskRunner > task_runner_
std::list< Request > done_
void SetGCTaskPending(v8::MeasureMemoryExecution execution)
void ScheduleReportingTask()
void ScheduleGCTask(v8::MeasureMemoryExecution execution)
std::list< Request > processing_
static const int kGCTaskDelayInSeconds
void SetGCTaskDone(v8::MeasureMemoryExecution execution)
std::unordered_map< Address, size_t > size_by_context_
void IncrementExternalSize(Address context, Tagged< Map > map, Tagged< HeapObject > object)
void Merge(const NativeContextStats &other)
size_t committed_code_space() const
size_t EstimateCurrentMemoryConsumption() const
size_t EstimateCurrentMemoryConsumption() const
RecordWriteMode const mode_
Handle< Context > context_
SharedFunctionInfoRef shared
ZoneVector< RpoNumber > & result
std::vector< Handle< JSObject > > other_
V8_INLINE constexpr bool IsExternalString(InstanceType instance_type)
WasmImportWrapperCache * GetWasmImportWrapperCache()
WasmCodeManager * GetWasmCodeManager()
WasmEngine * GetWasmEngine()
V8_INLINE DirectHandle< T > direct_handle(Tagged< T > object, Isolate *isolate)
Tagged< MaybeWeak< T > > MakeWeak(Tagged< T > value)
V8_EXPORT_PRIVATE FlagValues v8_flags
std::unique_ptr< CancelableTask > MakeCancelableTask(Isolate *isolate, std::function< void()> func)
tsan_relaxed_store_8_bits tsan_relaxed_store_32_bits tsan_seq_cst_store_8_bits tsan_seq_cst_store_32_bits tsan_relaxed_load_32_bits Address raw_context
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
v8::Local< T > ToApiHandle(v8::internal::DirectHandle< v8::internal::Object > obj)
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
#define V8_EXPORT_PRIVATE
std::unique_ptr< v8::MeasureMemoryDelegate > delegate
std::vector< size_t > sizes
Handle< WeakFixedArray > contexts