OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/heap/gc-idle-time-handler.h" | 5 #include "src/heap/gc-idle-time-handler.h" |
6 #include "src/heap/gc-tracer.h" | 6 #include "src/heap/gc-tracer.h" |
7 #include "src/utils.h" | 7 #include "src/utils.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
180 } | 180 } |
181 | 181 |
182 | 182 |
183 bool GCIdleTimeHandler::ShouldDoOverApproximateWeakClosure( | 183 bool GCIdleTimeHandler::ShouldDoOverApproximateWeakClosure( |
184 size_t idle_time_in_ms) { | 184 size_t idle_time_in_ms) { |
185 // TODO(jochen): Estimate the time it will take to build the object groups. | 185 // TODO(jochen): Estimate the time it will take to build the object groups. |
186 return idle_time_in_ms >= kMinTimeForOverApproximatingWeakClosureInMs; | 186 return idle_time_in_ms >= kMinTimeForOverApproximatingWeakClosureInMs; |
187 } | 187 } |
188 | 188 |
189 | 189 |
| 190 GCIdleTimeAction GCIdleTimeHandler::NothingOrDone() { |
| 191 if (idle_times_which_made_no_progress_since_last_idle_round_ >= |
| 192 kMaxNoProgressIdleTimesPerIdleRound) { |
| 193 return GCIdleTimeAction::Done(); |
| 194 } else { |
| 195 idle_times_which_made_no_progress_since_last_idle_round_++; |
| 196 return GCIdleTimeAction::Nothing(); |
| 197 } |
| 198 } |
| 199 |
| 200 |
190 // The following logic is implemented by the controller: | 201 // The following logic is implemented by the controller: |
191 // (1) If we don't have any idle time, do nothing, unless a context was | 202 // (1) If we don't have any idle time, do nothing, unless a context was |
192 // disposed, incremental marking is stopped, and the heap is small. Then do | 203 // disposed, incremental marking is stopped, and the heap is small. Then do |
193 // a full GC. | 204 // a full GC. |
194 // (2) If the new space is almost full and we can affort a Scavenge or if the | 205 // (2) If the new space is almost full and we can afford a Scavenge or if the |
195 // next Scavenge will very likely take long, then a Scavenge is performed. | 206 // next Scavenge will very likely take long, then a Scavenge is performed. |
196 // (3) If there is currently no MarkCompact idle round going on, we start a | 207 // (3) If there is currently no MarkCompact idle round going on, we start a |
197 // new idle round if enough garbage was created. Otherwise we do not perform | 208 // new idle round if enough garbage was created. Otherwise we do not perform |
198 // garbage collection to keep system utilization low. | 209 // garbage collection to keep system utilization low. |
199 // (4) If incremental marking is done, we perform a full garbage collection | 210 // (4) If incremental marking is done, we perform a full garbage collection |
200 // if we are allowed to still do full garbage collections during this idle | 211 // if we are allowed to still do full garbage collections during this idle |
201 // round or if we are not allowed to start incremental marking. Otherwise we | 212 // round or if we are not allowed to start incremental marking. Otherwise we |
202 // do not perform garbage collection to keep system utilization low. | 213 // do not perform garbage collection to keep system utilization low. |
203 // (5) If sweeping is in progress and we received a large enough idle time | 214 // (5) If sweeping is in progress and we received a large enough idle time |
204 // request, we finalize sweeping here. | 215 // request, we finalize sweeping here. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
236 } | 247 } |
237 } | 248 } |
238 | 249 |
239 if (heap_state.incremental_marking_stopped) { | 250 if (heap_state.incremental_marking_stopped) { |
240 if (ShouldDoMarkCompact(static_cast<size_t>(idle_time_in_ms), | 251 if (ShouldDoMarkCompact(static_cast<size_t>(idle_time_in_ms), |
241 heap_state.size_of_objects, | 252 heap_state.size_of_objects, |
242 heap_state.mark_compact_speed_in_bytes_per_ms)) { | 253 heap_state.mark_compact_speed_in_bytes_per_ms)) { |
243 return GCIdleTimeAction::FullGC(); | 254 return GCIdleTimeAction::FullGC(); |
244 } | 255 } |
245 } | 256 } |
246 | 257 if (heap_state.sweeping_in_progress) { |
247 if (heap_state.sweeping_in_progress && heap_state.sweeping_completed) { | 258 if (heap_state.sweeping_completed) { |
248 return GCIdleTimeAction::FinalizeSweeping(); | 259 return GCIdleTimeAction::FinalizeSweeping(); |
| 260 } else { |
| 261 return NothingOrDone(); |
| 262 } |
| 263 } |
| 264 if (heap_state.incremental_marking_stopped && |
| 265 !heap_state.can_start_incremental_marking) { |
| 266 return NothingOrDone(); |
249 } | 267 } |
250 | 268 |
251 if (heap_state.incremental_marking_stopped && | |
252 !heap_state.can_start_incremental_marking) { | |
253 return GCIdleTimeAction::Nothing(); | |
254 } | |
255 size_t step_size = EstimateMarkingStepSize( | 269 size_t step_size = EstimateMarkingStepSize( |
256 static_cast<size_t>(kIncrementalMarkingStepTimeInMs), | 270 static_cast<size_t>(kIncrementalMarkingStepTimeInMs), |
257 heap_state.incremental_marking_speed_in_bytes_per_ms); | 271 heap_state.incremental_marking_speed_in_bytes_per_ms); |
258 return GCIdleTimeAction::IncrementalMarking(step_size); | 272 return GCIdleTimeAction::IncrementalMarking(step_size); |
259 } | 273 } |
260 } | 274 } |
261 } | 275 } |
OLD | NEW |