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