Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(270)

Side by Side Diff: src/heap.cc

Issue 423303006: Make sure that there is enough time left before finishing incremental marking in idle notification. Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/heap.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/api.h" 8 #include "src/api.h"
9 #include "src/base/once.h" 9 #include "src/base/once.h"
10 #include "src/base/utils/random-number-generator.h" 10 #include "src/base/utils/random-number-generator.h"
(...skipping 4209 matching lines...) Expand 10 before | Expand all | Expand 10 after
4220 if (!IsHeapIterable()) { 4220 if (!IsHeapIterable()) {
4221 CollectAllGarbage(kMakeHeapIterableMask, "Heap::MakeHeapIterable"); 4221 CollectAllGarbage(kMakeHeapIterableMask, "Heap::MakeHeapIterable");
4222 } 4222 }
4223 if (mark_compact_collector()->sweeping_in_progress()) { 4223 if (mark_compact_collector()->sweeping_in_progress()) {
4224 mark_compact_collector()->EnsureSweepingCompleted(); 4224 mark_compact_collector()->EnsureSweepingCompleted();
4225 } 4225 }
4226 ASSERT(IsHeapIterable()); 4226 ASSERT(IsHeapIterable());
4227 } 4227 }
4228 4228
4229 4229
4230 void Heap::AdvanceIdleIncrementalMarking(intptr_t step_size) { 4230 int Heap::AdvanceIdleIncrementalMarking(intptr_t step_size) {
4231 double start = base::OS::TimeCurrentMillis();
4231 incremental_marking()->Step(step_size, 4232 incremental_marking()->Step(step_size,
4232 IncrementalMarking::NO_GC_VIA_STACK_GUARD); 4233 IncrementalMarking::NO_GC_VIA_STACK_GUARD);
4234 return static_cast<int>(base::OS::TimeCurrentMillis() - start);
4235 }
4233 4236
4237
4238 void Heap::FinalizeIdleIncrementalMarking() {
4234 if (incremental_marking()->IsComplete()) { 4239 if (incremental_marking()->IsComplete()) {
4235 bool uncommit = false; 4240 bool uncommit = false;
4236 if (gc_count_at_last_idle_gc_ == gc_count_) { 4241 if (gc_count_at_last_idle_gc_ == gc_count_) {
4237 // No GC since the last full GC, the mutator is probably not active. 4242 // No GC since the last full GC, the mutator is probably not active.
4238 isolate_->compilation_cache()->Clear(); 4243 isolate_->compilation_cache()->Clear();
4239 uncommit = true; 4244 uncommit = true;
4240 } 4245 }
4241 CollectAllGarbage(kReduceMemoryFootprintMask, 4246 CollectAllGarbage(kReduceMemoryFootprintMask,
4242 "idle notification: finalize incremental"); 4247 "idle notification: finalize incremental");
4243 mark_sweeps_since_idle_round_started_++; 4248 mark_sweeps_since_idle_round_started_++;
4244 gc_count_at_last_idle_gc_ = gc_count_; 4249 gc_count_at_last_idle_gc_ = gc_count_;
4245 if (uncommit) { 4250 if (uncommit) {
4246 new_space_.Shrink(); 4251 new_space_.Shrink();
4247 UncommitFromSpace(); 4252 UncommitFromSpace();
4248 } 4253 }
4249 } 4254 }
4250 } 4255 }
4251 4256
4252 4257
4253 bool Heap::IdleNotification(int hint) { 4258 bool Heap::IdleNotification(int idle_time_in_ms) {
4254 // If incremental marking is off, we do not perform idle notification. 4259 // If incremental marking is off, we do not perform idle notification.
4255 if (!FLAG_incremental_marking) return true; 4260 if (!FLAG_incremental_marking) return true;
4256 4261
4257 // Hints greater than this value indicate that 4262 // Hints greater than this value indicate that
4258 // the embedder is requesting a lot of GC work. 4263 // the embedder is requesting a lot of GC work.
4259 const int kMaxHint = 1000; 4264 const int kMaxHint = 1000;
4265 // TODO(hpayer): remove min hint
4260 const int kMinHintForIncrementalMarking = 10; 4266 const int kMinHintForIncrementalMarking = 10;
4261 // Minimal hint that allows to do full GC. 4267 // Minimal hint that allows to do full GC.
4262 const int kMinHintForFullGC = 100; 4268 const int kMinHintForFullGC = 100;
4263 intptr_t size_factor = Min(Max(hint, 20), kMaxHint) / 4; 4269 // TODO(hpayer, ernstm): use previous time measurements to calculate
4270 // proper size_factor
4271 intptr_t size_factor = Min(Max(idle_time_in_ms, 20), kMaxHint) / 4;
4264 // The size factor is in range [5..250]. The numbers here are chosen from 4272 // The size factor is in range [5..250]. The numbers here are chosen from
4265 // experiments. If you changes them, make sure to test with 4273 // experiments. If you changes them, make sure to test with
4266 // chrome/performance_ui_tests --gtest_filter="GeneralMixMemoryTest.* 4274 // chrome/performance_ui_tests --gtest_filter="GeneralMixMemoryTest.*
4267 intptr_t step_size = 4275 intptr_t step_size =
4268 size_factor * IncrementalMarking::kAllocatedThreshold; 4276 size_factor * IncrementalMarking::kAllocatedThreshold;
4269 4277
4270 isolate()->counters()->gc_idle_time_allotted_in_ms()->AddSample(hint); 4278 isolate()->counters()->gc_idle_time_allotted_in_ms()->AddSample(
4279 idle_time_in_ms);
4271 HistogramTimerScope idle_notification_scope( 4280 HistogramTimerScope idle_notification_scope(
4272 isolate_->counters()->gc_idle_notification()); 4281 isolate_->counters()->gc_idle_notification());
4273 4282
4274 if (contexts_disposed_ > 0) { 4283 if (contexts_disposed_ > 0) {
4275 contexts_disposed_ = 0; 4284 contexts_disposed_ = 0;
4276 int mark_sweep_time = Min(TimeMarkSweepWouldTakeInMs(), 1000); 4285 int mark_sweep_time = Min(TimeMarkSweepWouldTakeInMs(), 1000);
4277 if (hint >= mark_sweep_time && !FLAG_expose_gc && 4286 if (idle_time_in_ms >= mark_sweep_time && !FLAG_expose_gc &&
4278 incremental_marking()->IsStopped()) { 4287 incremental_marking()->IsStopped()) {
4279 HistogramTimerScope scope(isolate_->counters()->gc_context()); 4288 HistogramTimerScope scope(isolate_->counters()->gc_context());
4280 CollectAllGarbage(kReduceMemoryFootprintMask, 4289 CollectAllGarbage(kReduceMemoryFootprintMask,
4281 "idle notification: contexts disposed"); 4290 "idle notification: contexts disposed");
4282 } else { 4291 } else {
4283 AdvanceIdleIncrementalMarking(step_size); 4292 int remaining_time = AdvanceIdleIncrementalMarking(step_size);
ernstm 2014/07/30 10:33:26 Isn't the value returned by AdvanceIdleIncremental
Hannes Payer (out of office) 2014/07/30 11:48:52 yes, that makes sense. actually, we should use the
4293 if (idle_time_in_ms - remaining_time > kMinHintForIncrementalMarking) {
4294 FinalizeIdleIncrementalMarking();
4295 }
4284 } 4296 }
4285 4297
4286 // After context disposal there is likely a lot of garbage remaining, reset 4298 // After context disposal there is likely a lot of garbage remaining, reset
4287 // the idle notification counters in order to trigger more incremental GCs 4299 // the idle notification counters in order to trigger more incremental GCs
4288 // on subsequent idle notifications. 4300 // on subsequent idle notifications.
4289 StartIdleRound(); 4301 StartIdleRound();
4290 return false; 4302 return false;
4291 } 4303 }
4292 4304
4293 // By doing small chunks of GC work in each IdleNotification, 4305 // By doing small chunks of GC work in each IdleNotification,
(...skipping 14 matching lines...) Expand all
4308 4320
4309 int remaining_mark_sweeps = kMaxMarkSweepsInIdleRound - 4321 int remaining_mark_sweeps = kMaxMarkSweepsInIdleRound -
4310 mark_sweeps_since_idle_round_started_; 4322 mark_sweeps_since_idle_round_started_;
4311 4323
4312 if (incremental_marking()->IsStopped()) { 4324 if (incremental_marking()->IsStopped()) {
4313 // If there are no more than two GCs left in this idle round and we are 4325 // If there are no more than two GCs left in this idle round and we are
4314 // allowed to do a full GC, then make those GCs full in order to compact 4326 // allowed to do a full GC, then make those GCs full in order to compact
4315 // the code space. 4327 // the code space.
4316 // TODO(ulan): Once we enable code compaction for incremental marking, 4328 // TODO(ulan): Once we enable code compaction for incremental marking,
4317 // we can get rid of this special case and always start incremental marking. 4329 // we can get rid of this special case and always start incremental marking.
4318 if (remaining_mark_sweeps <= 2 && hint >= kMinHintForFullGC) { 4330 if (remaining_mark_sweeps <= 2 && idle_time_in_ms >= kMinHintForFullGC) {
4319 CollectAllGarbage(kReduceMemoryFootprintMask, 4331 CollectAllGarbage(kReduceMemoryFootprintMask,
4320 "idle notification: finalize idle round"); 4332 "idle notification: finalize idle round");
4321 mark_sweeps_since_idle_round_started_++; 4333 mark_sweeps_since_idle_round_started_++;
4322 } else if (hint > kMinHintForIncrementalMarking) { 4334 } else if (idle_time_in_ms > kMinHintForIncrementalMarking) {
4323 incremental_marking()->Start(); 4335 incremental_marking()->Start();
4324 } 4336 }
4325 } 4337 }
4326 if (!incremental_marking()->IsStopped() && 4338 if (!incremental_marking()->IsStopped() &&
4327 hint > kMinHintForIncrementalMarking) { 4339 idle_time_in_ms > kMinHintForIncrementalMarking) {
4328 AdvanceIdleIncrementalMarking(step_size); 4340 int remaining_time = AdvanceIdleIncrementalMarking(step_size);
ernstm 2014/07/30 10:33:26 remaining_time -> time_elapsed?
Hannes Payer (out of office) 2014/07/30 11:48:52 yes.
4341 if (idle_time_in_ms - remaining_time > kMinHintForIncrementalMarking) {
4342 FinalizeIdleIncrementalMarking();
4343 }
4329 } 4344 }
4330 4345
4331 if (mark_sweeps_since_idle_round_started_ >= kMaxMarkSweepsInIdleRound) { 4346 if (mark_sweeps_since_idle_round_started_ >= kMaxMarkSweepsInIdleRound) {
4332 FinishIdleRound(); 4347 FinishIdleRound();
4333 return true; 4348 return true;
4334 } 4349 }
4335 4350
4336 // If the IdleNotifcation is called with a large hint we will wait for 4351 // If the IdleNotifcation is called with a large idle_time_in_ms we will wait
4337 // the sweepter threads here. 4352 // for the sweepter threads here.
4338 if (hint >= kMinHintForFullGC && 4353 if (idle_time_in_ms >= kMinHintForFullGC &&
4339 mark_compact_collector()->sweeping_in_progress()) { 4354 mark_compact_collector()->sweeping_in_progress()) {
4340 mark_compact_collector()->EnsureSweepingCompleted(); 4355 mark_compact_collector()->EnsureSweepingCompleted();
4341 } 4356 }
4342 4357
4343 return false; 4358 return false;
4344 } 4359 }
4345 4360
4346 4361
4347 #ifdef DEBUG 4362 #ifdef DEBUG
4348 4363
(...skipping 1817 matching lines...) Expand 10 before | Expand all | Expand 10 after
6166 static_cast<int>(object_sizes_last_time_[index])); 6181 static_cast<int>(object_sizes_last_time_[index]));
6167 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT) 6182 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT)
6168 #undef ADJUST_LAST_TIME_OBJECT_COUNT 6183 #undef ADJUST_LAST_TIME_OBJECT_COUNT
6169 6184
6170 MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); 6185 MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_));
6171 MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); 6186 MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_));
6172 ClearObjectStats(); 6187 ClearObjectStats();
6173 } 6188 }
6174 6189
6175 } } // namespace v8::internal 6190 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/heap.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698