| 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 |