• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 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 V8_HEAP_MEMORY_MEASUREMENT_H_
6 #define V8_HEAP_MEMORY_MEASUREMENT_H_
7 
8 #include <list>
9 #include <unordered_map>
10 
11 #include "src/base/platform/elapsed-timer.h"
12 #include "src/base/utils/random-number-generator.h"
13 #include "src/common/globals.h"
14 #include "src/objects/contexts.h"
15 #include "src/objects/map.h"
16 #include "src/objects/objects.h"
17 
18 namespace v8 {
19 namespace internal {
20 
21 class Heap;
22 class NativeContextStats;
23 
24 class MemoryMeasurement {
25  public:
26   explicit MemoryMeasurement(Isolate* isolate);
27 
28   bool EnqueueRequest(std::unique_ptr<v8::MeasureMemoryDelegate> delegate,
29                       v8::MeasureMemoryExecution execution,
30                       const std::vector<Handle<NativeContext>> contexts);
31   std::vector<Address> StartProcessing();
32   void FinishProcessing(const NativeContextStats& stats);
33 
34   static std::unique_ptr<v8::MeasureMemoryDelegate> DefaultDelegate(
35       Isolate* isolate, Handle<NativeContext> context,
36       Handle<JSPromise> promise, v8::MeasureMemoryMode mode);
37 
38  private:
39   static const int kGCTaskDelayInSeconds = 10;
40   struct Request {
41     std::unique_ptr<v8::MeasureMemoryDelegate> delegate;
42     Handle<WeakFixedArray> contexts;
43     std::vector<size_t> sizes;
44     size_t shared;
45     base::ElapsedTimer timer;
46   };
47   void ScheduleReportingTask();
48   void ReportResults();
49   void ScheduleGCTask(v8::MeasureMemoryExecution execution);
50   bool IsGCTaskPending(v8::MeasureMemoryExecution execution);
51   void SetGCTaskPending(v8::MeasureMemoryExecution execution);
52   void SetGCTaskDone(v8::MeasureMemoryExecution execution);
53   int NextGCTaskDelayInSeconds();
54 
55   std::list<Request> received_;
56   std::list<Request> processing_;
57   std::list<Request> done_;
58   Isolate* isolate_;
59   bool reporting_task_pending_ = false;
60   bool delayed_gc_task_pending_ = false;
61   bool eager_gc_task_pending_ = false;
62   base::RandomNumberGenerator random_number_generator_;
63 };
64 
65 // Infers the native context for some of the heap objects.
66 class V8_EXPORT_PRIVATE NativeContextInferrer {
67  public:
68   // The native_context parameter is both the input and output parameter.
69   // It should be initialized to the context that will be used for the object
70   // if the inference is not successful. The function performs more work if the
71   // context is the shared context.
72   V8_INLINE bool Infer(Isolate* isolate, Map map, HeapObject object,
73                        Address* native_context);
74 
75  private:
76   bool InferForContext(Isolate* isolate, Context context,
77                        Address* native_context);
78   bool InferForJSFunction(Isolate* isolate, JSFunction function,
79                           Address* native_context);
80   bool InferForJSObject(Isolate* isolate, Map map, JSObject object,
81                         Address* native_context);
82 };
83 
84 // Maintains mapping from native contexts to their sizes.
85 class V8_EXPORT_PRIVATE NativeContextStats {
86  public:
87   V8_INLINE void IncrementSize(Address context, Map map, HeapObject object,
88                                size_t size);
89 
Get(Address context)90   size_t Get(Address context) const {
91     const auto it = size_by_context_.find(context);
92     if (it == size_by_context_.end()) return 0;
93     return it->second;
94   }
95   void Clear();
96   void Merge(const NativeContextStats& other);
97 
98  private:
99   V8_INLINE bool HasExternalBytes(Map map);
100   void IncrementExternalSize(Address context, Map map, HeapObject object);
101   std::unordered_map<Address, size_t> size_by_context_;
102 };
103 
104 }  // namespace internal
105 }  // namespace v8
106 
107 #endif  // V8_HEAP_MEMORY_MEASUREMENT_H_
108