• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 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_GC_IDLE_TIME_HANDLER_H_
6 #define V8_HEAP_GC_IDLE_TIME_HANDLER_H_
7 
8 #include "src/globals.h"
9 
10 namespace v8 {
11 namespace internal {
12 
13 enum GCIdleTimeActionType {
14   DONE,
15   DO_NOTHING,
16   DO_INCREMENTAL_STEP,
17   DO_FULL_GC,
18 };
19 
20 
21 class GCIdleTimeAction {
22  public:
Done()23   static GCIdleTimeAction Done() {
24     GCIdleTimeAction result;
25     result.type = DONE;
26     result.additional_work = false;
27     return result;
28   }
29 
Nothing()30   static GCIdleTimeAction Nothing() {
31     GCIdleTimeAction result;
32     result.type = DO_NOTHING;
33     result.additional_work = false;
34     return result;
35   }
36 
IncrementalStep()37   static GCIdleTimeAction IncrementalStep() {
38     GCIdleTimeAction result;
39     result.type = DO_INCREMENTAL_STEP;
40     result.additional_work = false;
41     return result;
42   }
43 
FullGC()44   static GCIdleTimeAction FullGC() {
45     GCIdleTimeAction result;
46     result.type = DO_FULL_GC;
47     result.additional_work = false;
48     return result;
49   }
50 
51   void Print();
52 
53   GCIdleTimeActionType type;
54   bool additional_work;
55 };
56 
57 
58 class GCIdleTimeHeapState {
59  public:
60   void Print();
61 
62   int contexts_disposed;
63   double contexts_disposal_rate;
64   size_t size_of_objects;
65   bool incremental_marking_stopped;
66 };
67 
68 
69 // The idle time handler makes decisions about which garbage collection
70 // operations are executing during IdleNotification.
71 class V8_EXPORT_PRIVATE GCIdleTimeHandler {
72  public:
73   // If we haven't recorded any incremental marking events yet, we carefully
74   // mark with a conservative lower bound for the marking speed.
75   static const size_t kInitialConservativeMarkingSpeed = 100 * KB;
76 
77   // Maximum marking step size returned by EstimateMarkingStepSize.
78   static const size_t kMaximumMarkingStepSize = 700 * MB;
79 
80   // We have to make sure that we finish the IdleNotification before
81   // idle_time_in_ms. Hence, we conservatively prune our workload estimate.
82   static const double kConservativeTimeRatio;
83 
84   // If we haven't recorded any mark-compact events yet, we use
85   // conservative lower bound for the mark-compact speed.
86   static const size_t kInitialConservativeMarkCompactSpeed = 2 * MB;
87 
88   // If we haven't recorded any final incremental mark-compact events yet, we
89   // use conservative lower bound for the mark-compact speed.
90   static const size_t kInitialConservativeFinalIncrementalMarkCompactSpeed =
91       2 * MB;
92 
93   // Maximum final incremental mark-compact time returned by
94   // EstimateFinalIncrementalMarkCompactTime.
95   static const size_t kMaxFinalIncrementalMarkCompactTimeInMs;
96 
97   // This is the maximum scheduled idle time. Note that it can be more than
98   // 16.66 ms when there is currently no rendering going on.
99   static const size_t kMaxScheduledIdleTime = 50;
100 
101   // The maximum idle time when frames are rendered is 16.66ms.
102   static const size_t kMaxFrameRenderingIdleTime = 17;
103 
104   static const int kMinBackgroundIdleTime = 900;
105 
106   // An allocation throughput below kLowAllocationThroughput bytes/ms is
107   // considered low
108   static const size_t kLowAllocationThroughput = 1000;
109 
110   static const size_t kMaxHeapSizeForContextDisposalMarkCompact = 100 * MB;
111 
112   // If contexts are disposed at a higher rate a full gc is triggered.
113   static const double kHighContextDisposalRate;
114 
115   // Incremental marking step time.
116   static const size_t kIncrementalMarkingStepTimeInMs = 1;
117 
118   static const size_t kMinTimeForOverApproximatingWeakClosureInMs;
119 
120   // Number of times we will return a Nothing action in the current mode
121   // despite having idle time available before we returning a Done action to
122   // ensure we don't keep scheduling idle tasks and making no progress.
123   static const int kMaxNoProgressIdleTimes = 10;
124 
GCIdleTimeHandler()125   GCIdleTimeHandler() : idle_times_which_made_no_progress_(0) {}
126 
127   GCIdleTimeAction Compute(double idle_time_in_ms,
128                            GCIdleTimeHeapState heap_state);
129 
130   bool Enabled();
131 
ResetNoProgressCounter()132   void ResetNoProgressCounter() { idle_times_which_made_no_progress_ = 0; }
133 
134   static size_t EstimateMarkingStepSize(double idle_time_in_ms,
135                                         double marking_speed_in_bytes_per_ms);
136 
137   static double EstimateFinalIncrementalMarkCompactTime(
138       size_t size_of_objects, double mark_compact_speed_in_bytes_per_ms);
139 
140   static bool ShouldDoContextDisposalMarkCompact(int context_disposed,
141                                                  double contexts_disposal_rate,
142                                                  size_t size_of_objects);
143 
144   static bool ShouldDoFinalIncrementalMarkCompact(
145       double idle_time_in_ms, size_t size_of_objects,
146       double final_incremental_mark_compact_speed_in_bytes_per_ms);
147 
148   static bool ShouldDoOverApproximateWeakClosure(double idle_time_in_ms);
149 
150  private:
151   GCIdleTimeAction NothingOrDone(double idle_time_in_ms);
152 
153   // Idle notifications with no progress.
154   int idle_times_which_made_no_progress_;
155 
156   DISALLOW_COPY_AND_ASSIGN(GCIdleTimeHandler);
157 };
158 
159 }  // namespace internal
160 }  // namespace v8
161 
162 #endif  // V8_HEAP_GC_IDLE_TIME_HANDLER_H_
163