11cb0ef41Sopenharmony_ci// Copyright 2019 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#ifndef V8_HEAP_MEMORY_MEASUREMENT_H_
61cb0ef41Sopenharmony_ci#define V8_HEAP_MEMORY_MEASUREMENT_H_
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci#include <list>
91cb0ef41Sopenharmony_ci#include <unordered_map>
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_ci#include "include/v8-statistics.h"
121cb0ef41Sopenharmony_ci#include "src/base/platform/elapsed-timer.h"
131cb0ef41Sopenharmony_ci#include "src/base/utils/random-number-generator.h"
141cb0ef41Sopenharmony_ci#include "src/common/globals.h"
151cb0ef41Sopenharmony_ci#include "src/objects/contexts.h"
161cb0ef41Sopenharmony_ci#include "src/objects/map.h"
171cb0ef41Sopenharmony_ci#include "src/objects/objects.h"
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_cinamespace v8 {
201cb0ef41Sopenharmony_cinamespace internal {
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_ciclass Heap;
231cb0ef41Sopenharmony_ciclass NativeContextStats;
241cb0ef41Sopenharmony_ci
251cb0ef41Sopenharmony_ciclass MemoryMeasurement {
261cb0ef41Sopenharmony_ci public:
271cb0ef41Sopenharmony_ci  explicit MemoryMeasurement(Isolate* isolate);
281cb0ef41Sopenharmony_ci
291cb0ef41Sopenharmony_ci  bool EnqueueRequest(std::unique_ptr<v8::MeasureMemoryDelegate> delegate,
301cb0ef41Sopenharmony_ci                      v8::MeasureMemoryExecution execution,
311cb0ef41Sopenharmony_ci                      const std::vector<Handle<NativeContext>> contexts);
321cb0ef41Sopenharmony_ci  std::vector<Address> StartProcessing();
331cb0ef41Sopenharmony_ci  void FinishProcessing(const NativeContextStats& stats);
341cb0ef41Sopenharmony_ci
351cb0ef41Sopenharmony_ci  static std::unique_ptr<v8::MeasureMemoryDelegate> DefaultDelegate(
361cb0ef41Sopenharmony_ci      Isolate* isolate, Handle<NativeContext> context,
371cb0ef41Sopenharmony_ci      Handle<JSPromise> promise, v8::MeasureMemoryMode mode);
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_ci private:
401cb0ef41Sopenharmony_ci  static const int kGCTaskDelayInSeconds = 10;
411cb0ef41Sopenharmony_ci  struct Request {
421cb0ef41Sopenharmony_ci    std::unique_ptr<v8::MeasureMemoryDelegate> delegate;
431cb0ef41Sopenharmony_ci    Handle<WeakFixedArray> contexts;
441cb0ef41Sopenharmony_ci    std::vector<size_t> sizes;
451cb0ef41Sopenharmony_ci    size_t shared;
461cb0ef41Sopenharmony_ci    base::ElapsedTimer timer;
471cb0ef41Sopenharmony_ci  };
481cb0ef41Sopenharmony_ci  void ScheduleReportingTask();
491cb0ef41Sopenharmony_ci  void ReportResults();
501cb0ef41Sopenharmony_ci  void ScheduleGCTask(v8::MeasureMemoryExecution execution);
511cb0ef41Sopenharmony_ci  bool IsGCTaskPending(v8::MeasureMemoryExecution execution);
521cb0ef41Sopenharmony_ci  void SetGCTaskPending(v8::MeasureMemoryExecution execution);
531cb0ef41Sopenharmony_ci  void SetGCTaskDone(v8::MeasureMemoryExecution execution);
541cb0ef41Sopenharmony_ci  int NextGCTaskDelayInSeconds();
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_ci  std::list<Request> received_;
571cb0ef41Sopenharmony_ci  std::list<Request> processing_;
581cb0ef41Sopenharmony_ci  std::list<Request> done_;
591cb0ef41Sopenharmony_ci  Isolate* isolate_;
601cb0ef41Sopenharmony_ci  bool reporting_task_pending_ = false;
611cb0ef41Sopenharmony_ci  bool delayed_gc_task_pending_ = false;
621cb0ef41Sopenharmony_ci  bool eager_gc_task_pending_ = false;
631cb0ef41Sopenharmony_ci  base::RandomNumberGenerator random_number_generator_;
641cb0ef41Sopenharmony_ci};
651cb0ef41Sopenharmony_ci
661cb0ef41Sopenharmony_ci// Infers the native context for some of the heap objects.
671cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE NativeContextInferrer {
681cb0ef41Sopenharmony_ci public:
691cb0ef41Sopenharmony_ci  // The native_context parameter is both the input and output parameter.
701cb0ef41Sopenharmony_ci  // It should be initialized to the context that will be used for the object
711cb0ef41Sopenharmony_ci  // if the inference is not successful. The function performs more work if the
721cb0ef41Sopenharmony_ci  // context is the shared context.
731cb0ef41Sopenharmony_ci  V8_INLINE bool Infer(Isolate* isolate, Map map, HeapObject object,
741cb0ef41Sopenharmony_ci                       Address* native_context);
751cb0ef41Sopenharmony_ci
761cb0ef41Sopenharmony_ci private:
771cb0ef41Sopenharmony_ci  bool InferForContext(Isolate* isolate, Context context,
781cb0ef41Sopenharmony_ci                       Address* native_context);
791cb0ef41Sopenharmony_ci  bool InferForJSFunction(Isolate* isolate, JSFunction function,
801cb0ef41Sopenharmony_ci                          Address* native_context);
811cb0ef41Sopenharmony_ci  bool InferForJSObject(Isolate* isolate, Map map, JSObject object,
821cb0ef41Sopenharmony_ci                        Address* native_context);
831cb0ef41Sopenharmony_ci};
841cb0ef41Sopenharmony_ci
851cb0ef41Sopenharmony_ci// Maintains mapping from native contexts to their sizes.
861cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE NativeContextStats {
871cb0ef41Sopenharmony_ci public:
881cb0ef41Sopenharmony_ci  V8_INLINE void IncrementSize(Address context, Map map, HeapObject object,
891cb0ef41Sopenharmony_ci                               size_t size);
901cb0ef41Sopenharmony_ci
911cb0ef41Sopenharmony_ci  size_t Get(Address context) const {
921cb0ef41Sopenharmony_ci    const auto it = size_by_context_.find(context);
931cb0ef41Sopenharmony_ci    if (it == size_by_context_.end()) return 0;
941cb0ef41Sopenharmony_ci    return it->second;
951cb0ef41Sopenharmony_ci  }
961cb0ef41Sopenharmony_ci  void Clear();
971cb0ef41Sopenharmony_ci  void Merge(const NativeContextStats& other);
981cb0ef41Sopenharmony_ci
991cb0ef41Sopenharmony_ci private:
1001cb0ef41Sopenharmony_ci  V8_INLINE bool HasExternalBytes(Map map);
1011cb0ef41Sopenharmony_ci  void IncrementExternalSize(Address context, Map map, HeapObject object);
1021cb0ef41Sopenharmony_ci  std::unordered_map<Address, size_t> size_by_context_;
1031cb0ef41Sopenharmony_ci};
1041cb0ef41Sopenharmony_ci
1051cb0ef41Sopenharmony_ci}  // namespace internal
1061cb0ef41Sopenharmony_ci}  // namespace v8
1071cb0ef41Sopenharmony_ci
1081cb0ef41Sopenharmony_ci#endif  // V8_HEAP_MEMORY_MEASUREMENT_H_
109