deps: update v8 to 4.3.61.21
[platform/upstream/nodejs.git] / deps / v8 / src / heap / gc-idle-time-handler.h
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_MARKING,
17   DO_SCAVENGE,
18   DO_FULL_GC,
19   DO_FINALIZE_SWEEPING
20 };
21
22
23 class GCIdleTimeAction {
24  public:
25   static GCIdleTimeAction Done() {
26     GCIdleTimeAction result;
27     result.type = DONE;
28     result.parameter = 0;
29     result.additional_work = false;
30     return result;
31   }
32
33   static GCIdleTimeAction Nothing() {
34     GCIdleTimeAction result;
35     result.type = DO_NOTHING;
36     result.parameter = 0;
37     result.additional_work = false;
38     return result;
39   }
40
41   static GCIdleTimeAction IncrementalMarking(intptr_t step_size) {
42     GCIdleTimeAction result;
43     result.type = DO_INCREMENTAL_MARKING;
44     result.parameter = step_size;
45     result.additional_work = false;
46     return result;
47   }
48
49   static GCIdleTimeAction Scavenge() {
50     GCIdleTimeAction result;
51     result.type = DO_SCAVENGE;
52     result.parameter = 0;
53     result.additional_work = false;
54     return result;
55   }
56
57   static GCIdleTimeAction FullGC() {
58     GCIdleTimeAction result;
59     result.type = DO_FULL_GC;
60     result.parameter = 0;
61     result.additional_work = false;
62     return result;
63   }
64
65   static GCIdleTimeAction FinalizeSweeping() {
66     GCIdleTimeAction result;
67     result.type = DO_FINALIZE_SWEEPING;
68     result.parameter = 0;
69     result.additional_work = false;
70     return result;
71   }
72
73   void Print();
74
75   GCIdleTimeActionType type;
76   intptr_t parameter;
77   bool additional_work;
78 };
79
80
81 class GCTracer;
82
83 // The idle time handler makes decisions about which garbage collection
84 // operations are executing during IdleNotification.
85 class GCIdleTimeHandler {
86  public:
87   // If we haven't recorded any incremental marking events yet, we carefully
88   // mark with a conservative lower bound for the marking speed.
89   static const size_t kInitialConservativeMarkingSpeed = 100 * KB;
90
91   // Maximum marking step size returned by EstimateMarkingStepSize.
92   static const size_t kMaximumMarkingStepSize = 700 * MB;
93
94   // We have to make sure that we finish the IdleNotification before
95   // idle_time_in_ms. Hence, we conservatively prune our workload estimate.
96   static const double kConservativeTimeRatio;
97
98   // If we haven't recorded any mark-compact events yet, we use
99   // conservative lower bound for the mark-compact speed.
100   static const size_t kInitialConservativeMarkCompactSpeed = 2 * MB;
101
102   // If we haven't recorded any final incremental mark-compact events yet, we
103   // use conservative lower bound for the mark-compact speed.
104   static const size_t kInitialConservativeFinalIncrementalMarkCompactSpeed =
105       2 * MB;
106
107   // Maximum mark-compact time returned by EstimateMarkCompactTime.
108   static const size_t kMaxMarkCompactTimeInMs;
109
110   // Maximum final incremental mark-compact time returned by
111   // EstimateFinalIncrementalMarkCompactTime.
112   static const size_t kMaxFinalIncrementalMarkCompactTimeInMs;
113
114   // Minimum time to finalize sweeping phase. The main thread may wait for
115   // sweeper threads.
116   static const size_t kMinTimeForFinalizeSweeping;
117
118   // Number of idle mark-compact events, after which idle handler will finish
119   // idle round.
120   static const int kMaxMarkCompactsInIdleRound;
121
122   // Number of scavenges that will trigger start of new idle round.
123   static const int kIdleScavengeThreshold;
124
125   // This is the maximum scheduled idle time. Note that it can be more than
126   // 16.66 ms when there is currently no rendering going on.
127   static const size_t kMaxScheduledIdleTime = 50;
128
129   // The maximum idle time when frames are rendered is 16.66ms.
130   static const size_t kMaxFrameRenderingIdleTime = 17;
131
132   // lower bound for the scavenger speed.
133   static const size_t kInitialConservativeScavengeSpeed = 100 * KB;
134
135   // If contexts are disposed at a higher rate a full gc is triggered.
136   static const double kHighContextDisposalRate;
137
138   // Incremental marking step time.
139   static const size_t kIncrementalMarkingStepTimeInMs = 1;
140
141   static const size_t kMinTimeForOverApproximatingWeakClosureInMs;
142
143   // Number of times we will return a Nothing action per Idle round despite
144   // having idle time available before we returning a Done action to ensure we
145   // don't keep scheduling idle tasks and making no progress.
146   static const int kMaxNoProgressIdleTimesPerIdleRound = 10;
147
148   class HeapState {
149    public:
150     void Print();
151
152     int contexts_disposed;
153     double contexts_disposal_rate;
154     size_t size_of_objects;
155     bool incremental_marking_stopped;
156     bool can_start_incremental_marking;
157     bool sweeping_in_progress;
158     size_t mark_compact_speed_in_bytes_per_ms;
159     size_t incremental_marking_speed_in_bytes_per_ms;
160     size_t final_incremental_mark_compact_speed_in_bytes_per_ms;
161     size_t scavenge_speed_in_bytes_per_ms;
162     size_t used_new_space_size;
163     size_t new_space_capacity;
164     size_t new_space_allocation_throughput_in_bytes_per_ms;
165   };
166
167   GCIdleTimeHandler()
168       : mark_compacts_since_idle_round_started_(0),
169         scavenges_since_last_idle_round_(0),
170         idle_times_which_made_no_progress_since_last_idle_round_(0) {}
171
172   GCIdleTimeAction Compute(double idle_time_in_ms, HeapState heap_state);
173
174   void NotifyIdleMarkCompact() {
175     if (mark_compacts_since_idle_round_started_ < kMaxMarkCompactsInIdleRound) {
176       ++mark_compacts_since_idle_round_started_;
177       if (mark_compacts_since_idle_round_started_ ==
178           kMaxMarkCompactsInIdleRound) {
179         scavenges_since_last_idle_round_ = 0;
180       }
181     }
182   }
183
184   void NotifyScavenge() { ++scavenges_since_last_idle_round_; }
185
186   static size_t EstimateMarkingStepSize(size_t idle_time_in_ms,
187                                         size_t marking_speed_in_bytes_per_ms);
188
189   static size_t EstimateMarkCompactTime(
190       size_t size_of_objects, size_t mark_compact_speed_in_bytes_per_ms);
191
192   static size_t EstimateFinalIncrementalMarkCompactTime(
193       size_t size_of_objects, size_t mark_compact_speed_in_bytes_per_ms);
194
195   static bool ShouldDoMarkCompact(size_t idle_time_in_ms,
196                                   size_t size_of_objects,
197                                   size_t mark_compact_speed_in_bytes_per_ms);
198
199   static bool ShouldDoContextDisposalMarkCompact(int context_disposed,
200                                                  double contexts_disposal_rate);
201
202   static bool ShouldDoFinalIncrementalMarkCompact(
203       size_t idle_time_in_ms, size_t size_of_objects,
204       size_t final_incremental_mark_compact_speed_in_bytes_per_ms);
205
206   static bool ShouldDoOverApproximateWeakClosure(size_t idle_time_in_ms);
207
208   static bool ShouldDoScavenge(
209       size_t idle_time_in_ms, size_t new_space_size, size_t used_new_space_size,
210       size_t scavenger_speed_in_bytes_per_ms,
211       size_t new_space_allocation_throughput_in_bytes_per_ms);
212
213  private:
214   GCIdleTimeAction NothingOrDone();
215
216   void StartIdleRound() {
217     mark_compacts_since_idle_round_started_ = 0;
218     idle_times_which_made_no_progress_since_last_idle_round_ = 0;
219   }
220   bool IsMarkCompactIdleRoundFinished() {
221     return mark_compacts_since_idle_round_started_ ==
222            kMaxMarkCompactsInIdleRound;
223   }
224   bool EnoughGarbageSinceLastIdleRound() {
225     return scavenges_since_last_idle_round_ >= kIdleScavengeThreshold;
226   }
227
228   int mark_compacts_since_idle_round_started_;
229   int scavenges_since_last_idle_round_;
230   int idle_times_which_made_no_progress_since_last_idle_round_;
231
232   DISALLOW_COPY_AND_ASSIGN(GCIdleTimeHandler);
233 };
234
235 }  // namespace internal
236 }  // namespace v8
237
238 #endif  // V8_HEAP_GC_IDLE_TIME_HANDLER_H_