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 21 matching lines...) Expand all Loading... |
32 if (additional_work) { | 32 if (additional_work) { |
33 PrintF("; finalized marking"); | 33 PrintF("; finalized marking"); |
34 } | 34 } |
35 break; | 35 break; |
36 case DO_SCAVENGE: | 36 case DO_SCAVENGE: |
37 PrintF("scavenge"); | 37 PrintF("scavenge"); |
38 break; | 38 break; |
39 case DO_FULL_GC: | 39 case DO_FULL_GC: |
40 PrintF("full GC"); | 40 PrintF("full GC"); |
41 break; | 41 break; |
42 case DO_FULL_GC_COMPACT: | |
43 PrintF("full GC compact"); | |
44 break; | |
45 case DO_FINALIZE_SWEEPING: | 42 case DO_FINALIZE_SWEEPING: |
46 PrintF("finalize sweeping"); | 43 PrintF("finalize sweeping"); |
47 break; | 44 break; |
48 } | 45 } |
49 } | 46 } |
50 | 47 |
51 | 48 |
52 void GCIdleTimeHandler::HeapState::Print() { | 49 void GCIdleTimeHandler::HeapState::Print() { |
53 PrintF("contexts_disposed=%d ", contexts_disposed); | 50 PrintF("contexts_disposed=%d ", contexts_disposed); |
54 PrintF("contexts_disposal_rate=%f ", contexts_disposal_rate); | 51 PrintF("contexts_disposal_rate=%f ", contexts_disposal_rate); |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 return true; | 149 return true; |
153 } | 150 } |
154 } | 151 } |
155 return false; | 152 return false; |
156 } | 153 } |
157 | 154 |
158 | 155 |
159 bool GCIdleTimeHandler::ShouldDoMarkCompact( | 156 bool GCIdleTimeHandler::ShouldDoMarkCompact( |
160 size_t idle_time_in_ms, size_t size_of_objects, | 157 size_t idle_time_in_ms, size_t size_of_objects, |
161 size_t mark_compact_speed_in_bytes_per_ms) { | 158 size_t mark_compact_speed_in_bytes_per_ms) { |
162 return idle_time_in_ms >= | 159 return idle_time_in_ms >= kMaxScheduledIdleTime && |
163 EstimateMarkCompactTime(size_of_objects, | 160 idle_time_in_ms >= |
164 mark_compact_speed_in_bytes_per_ms); | 161 EstimateMarkCompactTime(size_of_objects, |
| 162 mark_compact_speed_in_bytes_per_ms); |
165 } | 163 } |
166 | 164 |
167 | 165 |
168 bool GCIdleTimeHandler::ShouldDoReduceMemoryMarkCompact( | |
169 size_t idle_time_in_ms) { | |
170 return idle_time_in_ms >= kMinTimeForReduceMemory; | |
171 } | |
172 | |
173 | |
174 bool GCIdleTimeHandler::ShouldDoContextDisposalMarkCompact( | 166 bool GCIdleTimeHandler::ShouldDoContextDisposalMarkCompact( |
175 int contexts_disposed, double contexts_disposal_rate) { | 167 int contexts_disposed, double contexts_disposal_rate) { |
176 return contexts_disposed > 0 && contexts_disposal_rate > 0 && | 168 return contexts_disposed > 0 && contexts_disposal_rate > 0 && |
177 contexts_disposal_rate < kHighContextDisposalRate; | 169 contexts_disposal_rate < kHighContextDisposalRate; |
178 } | 170 } |
179 | 171 |
180 | 172 |
181 bool GCIdleTimeHandler::ShouldDoFinalIncrementalMarkCompact( | 173 bool GCIdleTimeHandler::ShouldDoFinalIncrementalMarkCompact( |
182 size_t idle_time_in_ms, size_t size_of_objects, | 174 size_t idle_time_in_ms, size_t size_of_objects, |
183 size_t final_incremental_mark_compact_speed_in_bytes_per_ms) { | 175 size_t final_incremental_mark_compact_speed_in_bytes_per_ms) { |
(...skipping 24 matching lines...) Expand all Loading... |
208 | 200 |
209 // The following logic is implemented by the controller: | 201 // The following logic is implemented by the controller: |
210 // (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 |
211 // 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 |
212 // a full GC. | 204 // a full GC. |
213 // (2) If the new space is almost full and we can afford a Scavenge or if the | 205 // (2) If the new space is almost full and we can afford a Scavenge or if the |
214 // 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. |
215 // (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 |
216 // 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 |
217 // garbage collection to keep system utilization low. | 209 // garbage collection to keep system utilization low. |
218 // (4) If we have long idle time, we try to reduce the memory footprint. | 210 // (4) If incremental marking is done, we perform a full garbage collection |
219 // (5) If incremental marking is done, we perform a full garbage collection | 211 // if we are allowed to still do full garbage collections during this idle |
220 // if we are allowed to still do full garbage collections during this idle | |
221 // 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 |
222 // do not perform garbage collection to keep system utilization low. | 213 // do not perform garbage collection to keep system utilization low. |
223 // (6) 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 |
224 // request, we finalize sweeping here. | 215 // request, we finalize sweeping here. |
225 // (7) If incremental marking is in progress, we perform a marking step. Note, | 216 // (6) If incremental marking is in progress, we perform a marking step. Note, |
226 // that this currently may trigger a full garbage collection. | 217 // that this currently may trigger a full garbage collection. |
227 GCIdleTimeAction GCIdleTimeHandler::Compute(double idle_time_in_ms, | 218 GCIdleTimeAction GCIdleTimeHandler::Compute(double idle_time_in_ms, |
228 HeapState heap_state) { | 219 HeapState heap_state) { |
229 if (static_cast<int>(idle_time_in_ms) <= 0) { | 220 if (static_cast<int>(idle_time_in_ms) <= 0) { |
230 if (heap_state.contexts_disposed > 0) { | 221 if (heap_state.contexts_disposed > 0) { |
231 StartIdleRound(); | 222 StartIdleRound(); |
232 } | 223 } |
233 if (heap_state.incremental_marking_stopped) { | 224 if (heap_state.incremental_marking_stopped) { |
234 if (ShouldDoContextDisposalMarkCompact( | 225 if (ShouldDoContextDisposalMarkCompact( |
235 heap_state.contexts_disposed, | 226 heap_state.contexts_disposed, |
(...skipping 13 matching lines...) Expand all Loading... |
249 } | 240 } |
250 | 241 |
251 if (IsMarkCompactIdleRoundFinished()) { | 242 if (IsMarkCompactIdleRoundFinished()) { |
252 if (EnoughGarbageSinceLastIdleRound()) { | 243 if (EnoughGarbageSinceLastIdleRound()) { |
253 StartIdleRound(); | 244 StartIdleRound(); |
254 } else { | 245 } else { |
255 return GCIdleTimeAction::Done(); | 246 return GCIdleTimeAction::Done(); |
256 } | 247 } |
257 } | 248 } |
258 | 249 |
259 if (ShouldDoReduceMemoryMarkCompact(static_cast<size_t>(idle_time_in_ms))) { | |
260 return GCIdleTimeAction::FullGCCompact(); | |
261 } | |
262 | |
263 if (heap_state.incremental_marking_stopped) { | 250 if (heap_state.incremental_marking_stopped) { |
264 if (ShouldDoMarkCompact(static_cast<size_t>(idle_time_in_ms), | 251 if (ShouldDoMarkCompact(static_cast<size_t>(idle_time_in_ms), |
265 heap_state.size_of_objects, | 252 heap_state.size_of_objects, |
266 heap_state.mark_compact_speed_in_bytes_per_ms)) { | 253 heap_state.mark_compact_speed_in_bytes_per_ms)) { |
267 return GCIdleTimeAction::FullGC(); | 254 return GCIdleTimeAction::FullGC(); |
268 } | 255 } |
269 } | 256 } |
270 if (heap_state.sweeping_in_progress) { | 257 if (heap_state.sweeping_in_progress) { |
271 if (heap_state.sweeping_completed) { | 258 if (heap_state.sweeping_completed) { |
272 return GCIdleTimeAction::FinalizeSweeping(); | 259 return GCIdleTimeAction::FinalizeSweeping(); |
273 } else { | 260 } else { |
274 return NothingOrDone(); | 261 return NothingOrDone(); |
275 } | 262 } |
276 } | 263 } |
277 if (heap_state.incremental_marking_stopped && | 264 if (heap_state.incremental_marking_stopped && |
278 !heap_state.can_start_incremental_marking) { | 265 !heap_state.can_start_incremental_marking) { |
279 return NothingOrDone(); | 266 return NothingOrDone(); |
280 } | 267 } |
281 | 268 |
282 size_t step_size = EstimateMarkingStepSize( | 269 size_t step_size = EstimateMarkingStepSize( |
283 static_cast<size_t>(kIncrementalMarkingStepTimeInMs), | 270 static_cast<size_t>(kIncrementalMarkingStepTimeInMs), |
284 heap_state.incremental_marking_speed_in_bytes_per_ms); | 271 heap_state.incremental_marking_speed_in_bytes_per_ms); |
285 return GCIdleTimeAction::IncrementalMarking(step_size); | 272 return GCIdleTimeAction::IncrementalMarking(step_size); |
286 } | 273 } |
287 } | 274 } |
288 } | 275 } |
OLD | NEW |