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/flags.h" | 5 #include "src/flags.h" |
6 #include "src/heap/gc-idle-time-handler.h" | 6 #include "src/heap/gc-idle-time-handler.h" |
7 #include "src/heap/gc-tracer.h" | 7 #include "src/heap/gc-tracer.h" |
8 #include "src/utils.h" | 8 #include "src/utils.h" |
9 | 9 |
10 namespace v8 { | 10 namespace v8 { |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
107 size_t result = | 107 size_t result = |
108 size_of_objects / final_incremental_mark_compact_speed_in_bytes_per_ms; | 108 size_of_objects / final_incremental_mark_compact_speed_in_bytes_per_ms; |
109 return Min(result, kMaxFinalIncrementalMarkCompactTimeInMs); | 109 return Min(result, kMaxFinalIncrementalMarkCompactTimeInMs); |
110 } | 110 } |
111 | 111 |
112 | 112 |
113 bool GCIdleTimeHandler::ShouldDoScavenge( | 113 bool GCIdleTimeHandler::ShouldDoScavenge( |
114 size_t idle_time_in_ms, size_t new_space_size, size_t used_new_space_size, | 114 size_t idle_time_in_ms, size_t new_space_size, size_t used_new_space_size, |
115 size_t scavenge_speed_in_bytes_per_ms, | 115 size_t scavenge_speed_in_bytes_per_ms, |
116 size_t new_space_allocation_throughput_in_bytes_per_ms) { | 116 size_t new_space_allocation_throughput_in_bytes_per_ms) { |
117 if (idle_time_in_ms >= kMinBackgroundIdleTime) { | |
118 // It is better to do full GC for the background tab. | |
119 return false; | |
120 } | |
117 size_t new_space_allocation_limit = | 121 size_t new_space_allocation_limit = |
118 kMaxScheduledIdleTime * scavenge_speed_in_bytes_per_ms; | 122 kMaxScheduledIdleTime * scavenge_speed_in_bytes_per_ms; |
119 | 123 |
120 // If the limit is larger than the new space size, then scavenging used to be | 124 // If the limit is larger than the new space size, then scavenging used to be |
121 // really fast. We can take advantage of the whole new space. | 125 // really fast. We can take advantage of the whole new space. |
122 if (new_space_allocation_limit > new_space_size) { | 126 if (new_space_allocation_limit > new_space_size) { |
123 new_space_allocation_limit = new_space_size; | 127 new_space_allocation_limit = new_space_size; |
124 } | 128 } |
125 | 129 |
126 // We do not know the allocation throughput before the first scavenge. | 130 // We do not know the allocation throughput before the first scavenge. |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
186 } | 190 } |
187 | 191 |
188 | 192 |
189 bool GCIdleTimeHandler::ShouldDoOverApproximateWeakClosure( | 193 bool GCIdleTimeHandler::ShouldDoOverApproximateWeakClosure( |
190 size_t idle_time_in_ms) { | 194 size_t idle_time_in_ms) { |
191 // TODO(jochen): Estimate the time it will take to build the object groups. | 195 // TODO(jochen): Estimate the time it will take to build the object groups. |
192 return idle_time_in_ms >= kMinTimeForOverApproximatingWeakClosureInMs; | 196 return idle_time_in_ms >= kMinTimeForOverApproximatingWeakClosureInMs; |
193 } | 197 } |
194 | 198 |
195 | 199 |
196 GCIdleTimeAction GCIdleTimeHandler::NothingOrDone() { | 200 GCIdleTimeAction GCIdleTimeHandler::NothingOrDone(double idle_time_in_ms) { |
197 if (idle_times_which_made_no_progress_ >= kMaxNoProgressIdleTimes) { | 201 if (idle_times_which_made_no_progress_ >= kMaxNoProgressIdleTimes && |
202 idle_time_in_ms < kMinBackgroundIdleTime) { | |
198 return GCIdleTimeAction::Done(); | 203 return GCIdleTimeAction::Done(); |
199 } else { | 204 } else { |
200 idle_times_which_made_no_progress_++; | 205 idle_times_which_made_no_progress_++; |
rmcilroy
2015/07/29 18:11:04
Could this cause wrapping of idle_times_which_made
ulan
2015/07/29 18:21:30
Thanks, rewrote to clap the counter.
Interval betw
rmcilroy
2015/07/30 07:14:07
Better safe than sorry ;). Thanks.
| |
201 return GCIdleTimeAction::Nothing(); | 206 return GCIdleTimeAction::Nothing(); |
202 } | 207 } |
203 } | 208 } |
204 | 209 |
205 | 210 |
206 // The following logic is implemented by the controller: | 211 // The following logic is implemented by the controller: |
207 // (1) If we don't have any idle time, do nothing, unless a context was | 212 // (1) If we don't have any idle time, do nothing, unless a context was |
208 // disposed, incremental marking is stopped, and the heap is small. Then do | 213 // disposed, incremental marking is stopped, and the heap is small. Then do |
209 // a full GC. | 214 // a full GC. |
210 // (2) If the context disposal rate is high and we cannot perform a full GC, | 215 // (2) If the context disposal rate is high and we cannot perform a full GC, |
(...skipping 14 matching lines...) Expand all Loading... | |
225 return GCIdleTimeAction::FullGC(); | 230 return GCIdleTimeAction::FullGC(); |
226 } | 231 } |
227 } | 232 } |
228 return GCIdleTimeAction::Nothing(); | 233 return GCIdleTimeAction::Nothing(); |
229 } | 234 } |
230 | 235 |
231 // We are in a context disposal GC scenario. Don't do anything if we do not | 236 // We are in a context disposal GC scenario. Don't do anything if we do not |
232 // get the right idle signal. | 237 // get the right idle signal. |
233 if (ShouldDoContextDisposalMarkCompact(heap_state.contexts_disposed, | 238 if (ShouldDoContextDisposalMarkCompact(heap_state.contexts_disposed, |
234 heap_state.contexts_disposal_rate)) { | 239 heap_state.contexts_disposal_rate)) { |
235 return NothingOrDone(); | 240 return NothingOrDone(idle_time_in_ms); |
236 } | 241 } |
237 | 242 |
238 if (ShouldDoScavenge( | 243 if (ShouldDoScavenge( |
239 static_cast<size_t>(idle_time_in_ms), heap_state.new_space_capacity, | 244 static_cast<size_t>(idle_time_in_ms), heap_state.new_space_capacity, |
240 heap_state.used_new_space_size, | 245 heap_state.used_new_space_size, |
241 heap_state.scavenge_speed_in_bytes_per_ms, | 246 heap_state.scavenge_speed_in_bytes_per_ms, |
242 heap_state.new_space_allocation_throughput_in_bytes_per_ms)) { | 247 heap_state.new_space_allocation_throughput_in_bytes_per_ms)) { |
243 return GCIdleTimeAction::Scavenge(); | 248 return GCIdleTimeAction::Scavenge(); |
244 } | 249 } |
245 | 250 |
246 if (heap_state.sweeping_in_progress) { | 251 if (heap_state.sweeping_in_progress) { |
247 if (heap_state.sweeping_completed) { | 252 if (heap_state.sweeping_completed) { |
248 return GCIdleTimeAction::FinalizeSweeping(); | 253 return GCIdleTimeAction::FinalizeSweeping(); |
249 } else { | 254 } else { |
250 return NothingOrDone(); | 255 return NothingOrDone(idle_time_in_ms); |
251 } | 256 } |
252 } | 257 } |
253 | 258 |
254 if (!FLAG_incremental_marking || heap_state.incremental_marking_stopped) { | 259 if (!FLAG_incremental_marking || heap_state.incremental_marking_stopped) { |
255 return GCIdleTimeAction::Done(); | 260 return GCIdleTimeAction::Done(); |
256 } | 261 } |
257 | 262 |
258 size_t step_size = EstimateMarkingStepSize( | 263 size_t step_size = EstimateMarkingStepSize( |
259 static_cast<size_t>(kIncrementalMarkingStepTimeInMs), | 264 static_cast<size_t>(kIncrementalMarkingStepTimeInMs), |
260 heap_state.incremental_marking_speed_in_bytes_per_ms); | 265 heap_state.incremental_marking_speed_in_bytes_per_ms); |
261 return GCIdleTimeAction::IncrementalMarking(step_size); | 266 return GCIdleTimeAction::IncrementalMarking(step_size); |
262 } | 267 } |
263 | 268 |
264 | 269 |
265 } | 270 } |
266 } | 271 } |
OLD | NEW |