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.
5 #ifndef V8_HEAP_GC_IDLE_TIME_HANDLER_H_
6 #define V8_HEAP_GC_IDLE_TIME_HANDLER_H_
8 #include "src/globals.h"
13 enum GCIdleTimeActionType {
16 DO_INCREMENTAL_MARKING,
23 class GCIdleTimeAction {
25 static GCIdleTimeAction Done() {
26 GCIdleTimeAction result;
29 result.additional_work = false;
33 static GCIdleTimeAction Nothing() {
34 GCIdleTimeAction result;
35 result.type = DO_NOTHING;
37 result.additional_work = false;
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;
49 static GCIdleTimeAction Scavenge() {
50 GCIdleTimeAction result;
51 result.type = DO_SCAVENGE;
53 result.additional_work = false;
57 static GCIdleTimeAction FullGC() {
58 GCIdleTimeAction result;
59 result.type = DO_FULL_GC;
61 result.additional_work = false;
65 static GCIdleTimeAction FinalizeSweeping() {
66 GCIdleTimeAction result;
67 result.type = DO_FINALIZE_SWEEPING;
69 result.additional_work = false;
75 GCIdleTimeActionType type;
83 // The idle time handler makes decisions about which garbage collection
84 // operations are executing during IdleNotification.
85 class GCIdleTimeHandler {
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;
91 // Maximum marking step size returned by EstimateMarkingStepSize.
92 static const size_t kMaximumMarkingStepSize = 700 * MB;
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;
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;
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 =
107 // Maximum mark-compact time returned by EstimateMarkCompactTime.
108 static const size_t kMaxMarkCompactTimeInMs;
110 // Maximum final incremental mark-compact time returned by
111 // EstimateFinalIncrementalMarkCompactTime.
112 static const size_t kMaxFinalIncrementalMarkCompactTimeInMs;
114 // Minimum time to finalize sweeping phase. The main thread may wait for
116 static const size_t kMinTimeForFinalizeSweeping;
118 // Number of idle mark-compact events, after which idle handler will finish
120 static const int kMaxMarkCompactsInIdleRound;
122 // Number of scavenges that will trigger start of new idle round.
123 static const int kIdleScavengeThreshold;
125 // That is the maximum idle time we will have during frame rendering.
126 static const size_t kMaxFrameRenderingIdleTime = 16;
128 // Minimum idle time to start incremental marking.
129 static const size_t kMinIdleTimeToStartIncrementalMarking = 10;
131 // If we haven't recorded any scavenger events yet, we use a conservative
132 // lower bound for the scavenger speed.
133 static const size_t kInitialConservativeScavengeSpeed = 100 * KB;
135 // If contexts are disposed at a higher rate a full gc is triggered.
136 static const double kHighContextDisposalRate;
138 // Incremental marking step time.
139 static const size_t kIncrementalMarkingStepTimeInMs = 1;
145 int contexts_disposed;
146 double contexts_disposal_rate;
147 size_t size_of_objects;
148 bool incremental_marking_stopped;
149 bool can_start_incremental_marking;
150 bool sweeping_in_progress;
151 size_t mark_compact_speed_in_bytes_per_ms;
152 size_t incremental_marking_speed_in_bytes_per_ms;
153 size_t final_incremental_mark_compact_speed_in_bytes_per_ms;
154 size_t scavenge_speed_in_bytes_per_ms;
155 size_t used_new_space_size;
156 size_t new_space_capacity;
157 size_t new_space_allocation_throughput_in_bytes_per_ms;
161 : mark_compacts_since_idle_round_started_(0),
162 scavenges_since_last_idle_round_(0) {}
164 GCIdleTimeAction Compute(double idle_time_in_ms, HeapState heap_state);
166 void NotifyIdleMarkCompact() {
167 if (mark_compacts_since_idle_round_started_ < kMaxMarkCompactsInIdleRound) {
168 ++mark_compacts_since_idle_round_started_;
169 if (mark_compacts_since_idle_round_started_ ==
170 kMaxMarkCompactsInIdleRound) {
171 scavenges_since_last_idle_round_ = 0;
176 void NotifyScavenge() { ++scavenges_since_last_idle_round_; }
178 static size_t EstimateMarkingStepSize(size_t idle_time_in_ms,
179 size_t marking_speed_in_bytes_per_ms);
181 static size_t EstimateMarkCompactTime(
182 size_t size_of_objects, size_t mark_compact_speed_in_bytes_per_ms);
184 static size_t EstimateFinalIncrementalMarkCompactTime(
185 size_t size_of_objects, size_t mark_compact_speed_in_bytes_per_ms);
187 static bool ShouldDoMarkCompact(size_t idle_time_in_ms,
188 size_t size_of_objects,
189 size_t mark_compact_speed_in_bytes_per_ms);
191 static bool ShouldDoContextDisposalMarkCompact(int context_disposed,
192 double contexts_disposal_rate);
194 static bool ShouldDoFinalIncrementalMarkCompact(
195 size_t idle_time_in_ms, size_t size_of_objects,
196 size_t final_incremental_mark_compact_speed_in_bytes_per_ms);
198 static bool ShouldDoScavenge(
199 size_t idle_time_in_ms, size_t new_space_size, size_t used_new_space_size,
200 size_t scavenger_speed_in_bytes_per_ms,
201 size_t new_space_allocation_throughput_in_bytes_per_ms);
204 void StartIdleRound() { mark_compacts_since_idle_round_started_ = 0; }
205 bool IsMarkCompactIdleRoundFinished() {
206 return mark_compacts_since_idle_round_started_ ==
207 kMaxMarkCompactsInIdleRound;
209 bool EnoughGarbageSinceLastIdleRound() {
210 return scavenges_since_last_idle_round_ >= kIdleScavengeThreshold;
213 int mark_compacts_since_idle_round_started_;
214 int scavenges_since_last_idle_round_;
216 DISALLOW_COPY_AND_ASSIGN(GCIdleTimeHandler);
219 } // namespace internal
222 #endif // V8_HEAP_GC_IDLE_TIME_HANDLER_H_