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

Side by Side Diff: src/heap/heap.cc

Issue 465473002: Use actual incremental marking throughput in IdleNotification to estimate marking step size. (Closed) 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/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 4241 matching lines...) Expand 10 before | Expand all | Expand 10 after
4252 if (!IsHeapIterable()) { 4252 if (!IsHeapIterable()) {
4253 CollectAllGarbage(kMakeHeapIterableMask, "Heap::MakeHeapIterable"); 4253 CollectAllGarbage(kMakeHeapIterableMask, "Heap::MakeHeapIterable");
4254 } 4254 }
4255 if (mark_compact_collector()->sweeping_in_progress()) { 4255 if (mark_compact_collector()->sweeping_in_progress()) {
4256 mark_compact_collector()->EnsureSweepingCompleted(); 4256 mark_compact_collector()->EnsureSweepingCompleted();
4257 } 4257 }
4258 DCHECK(IsHeapIterable()); 4258 DCHECK(IsHeapIterable());
4259 } 4259 }
4260 4260
4261 4261
4262 void Heap::AdvanceIdleIncrementalMarking(intptr_t step_size) { 4262 intptr_t Heap::EstimateMarkingStepSize(int idle_time_in_ms) {
4263 // We have to make sure that we finish the IdleNotification before
4264 // idle_time_in_ms. Hence, we conservatively prune our workload estimate.
4265 const double kConservativeTimeRatio = 0.9;
4266 // If we haven't recorded any incremental marking events yet, we carefully
4267 // mark with a conservative lower bound for the marking speed.
4268 const intptr_t kMarkingSpeedInBytesLowerBound = 100 * KB;
4269 intptr_t marking_speed_in_bytes_per_millisecond =
4270 tracer_.IncrementalMarkingSpeedInBytesPerMillisecond();
4271 if (marking_speed_in_bytes_per_millisecond == 0) {
4272 marking_speed_in_bytes_per_millisecond = kMarkingSpeedInBytesLowerBound;
4273 }
4274 return static_cast<intptr_t>(marking_speed_in_bytes_per_millisecond *
ulan 2014/08/18 12:32:13 Potential integer overflow here, maybe use marking
Hannes Payer (out of office) 2014/08/19 15:24:04 Good catch.
4275 kConservativeTimeRatio * idle_time_in_ms);
4276 }
4277
4278
4279 void Heap::AdvanceIdleIncrementalMarking(int idle_time_in_ms) {
4280 intptr_t step_size = EstimateMarkingStepSize(idle_time_in_ms);
4281
4263 incremental_marking()->Step(step_size, 4282 incremental_marking()->Step(step_size,
4264 IncrementalMarking::NO_GC_VIA_STACK_GUARD, true); 4283 IncrementalMarking::NO_GC_VIA_STACK_GUARD, true);
4265 4284
4266 if (incremental_marking()->IsComplete()) { 4285 if (incremental_marking()->IsComplete()) {
4267 bool uncommit = false; 4286 bool uncommit = false;
4268 if (gc_count_at_last_idle_gc_ == gc_count_) { 4287 if (gc_count_at_last_idle_gc_ == gc_count_) {
4269 // No GC since the last full GC, the mutator is probably not active. 4288 // No GC since the last full GC, the mutator is probably not active.
4270 isolate_->compilation_cache()->Clear(); 4289 isolate_->compilation_cache()->Clear();
4271 uncommit = true; 4290 uncommit = true;
4272 } 4291 }
4273 CollectAllGarbage(kReduceMemoryFootprintMask, 4292 CollectAllGarbage(kReduceMemoryFootprintMask,
4274 "idle notification: finalize incremental"); 4293 "idle notification: finalize incremental");
4275 mark_sweeps_since_idle_round_started_++; 4294 mark_sweeps_since_idle_round_started_++;
4276 gc_count_at_last_idle_gc_ = gc_count_; 4295 gc_count_at_last_idle_gc_ = gc_count_;
4277 if (uncommit) { 4296 if (uncommit) {
4278 new_space_.Shrink(); 4297 new_space_.Shrink();
4279 UncommitFromSpace(); 4298 UncommitFromSpace();
4280 } 4299 }
4281 } 4300 }
4282 } 4301 }
4283 4302
4284 4303
4285 bool Heap::IdleNotification(int hint) { 4304 bool Heap::IdleNotification(int idle_time_in_ms) {
4286 // If incremental marking is off, we do not perform idle notification. 4305 // If incremental marking is off, we do not perform idle notification.
4287 if (!FLAG_incremental_marking) return true; 4306 if (!FLAG_incremental_marking) return true;
4288 4307
4289 // Hints greater than this value indicate that
4290 // the embedder is requesting a lot of GC work.
4291 const int kMaxHint = 1000;
4292 const int kMinHintForIncrementalMarking = 10;
4293 // Minimal hint that allows to do full GC. 4308 // Minimal hint that allows to do full GC.
4294 const int kMinHintForFullGC = 100; 4309 const int kMinHintForFullGC = 100;
4295 intptr_t size_factor = Min(Max(hint, 20), kMaxHint) / 4; 4310 isolate()->counters()->gc_idle_time_allotted_in_ms()->AddSample(
4296 // The size factor is in range [5..250]. The numbers here are chosen from 4311 idle_time_in_ms);
4297 // experiments. If you changes them, make sure to test with
4298 // chrome/performance_ui_tests --gtest_filter="GeneralMixMemoryTest.*
4299 intptr_t step_size = size_factor * IncrementalMarking::kAllocatedThreshold;
4300
4301 isolate()->counters()->gc_idle_time_allotted_in_ms()->AddSample(hint);
4302 HistogramTimerScope idle_notification_scope( 4312 HistogramTimerScope idle_notification_scope(
4303 isolate_->counters()->gc_idle_notification()); 4313 isolate_->counters()->gc_idle_notification());
4304 4314
4305 if (contexts_disposed_ > 0) { 4315 if (contexts_disposed_ > 0) {
4306 contexts_disposed_ = 0; 4316 contexts_disposed_ = 0;
4307 int mark_sweep_time = Min(TimeMarkSweepWouldTakeInMs(), 1000); 4317 int mark_sweep_time = Min(TimeMarkSweepWouldTakeInMs(), 1000);
4308 if (hint >= mark_sweep_time && !FLAG_expose_gc && 4318 if (idle_time_in_ms >= mark_sweep_time && !FLAG_expose_gc &&
4309 incremental_marking()->IsStopped()) { 4319 incremental_marking()->IsStopped()) {
4310 HistogramTimerScope scope(isolate_->counters()->gc_context()); 4320 HistogramTimerScope scope(isolate_->counters()->gc_context());
4311 CollectAllGarbage(kReduceMemoryFootprintMask, 4321 CollectAllGarbage(kReduceMemoryFootprintMask,
4312 "idle notification: contexts disposed"); 4322 "idle notification: contexts disposed");
4313 } else { 4323 } else {
4314 AdvanceIdleIncrementalMarking(step_size); 4324 AdvanceIdleIncrementalMarking(idle_time_in_ms);
4315 } 4325 }
4316 4326
4317 // After context disposal there is likely a lot of garbage remaining, reset 4327 // After context disposal there is likely a lot of garbage remaining, reset
4318 // the idle notification counters in order to trigger more incremental GCs 4328 // the idle notification counters in order to trigger more incremental GCs
4319 // on subsequent idle notifications. 4329 // on subsequent idle notifications.
4320 StartIdleRound(); 4330 StartIdleRound();
4321 return false; 4331 return false;
4322 } 4332 }
4323 4333
4324 // By doing small chunks of GC work in each IdleNotification, 4334 // By doing small chunks of GC work in each IdleNotification,
(...skipping 14 matching lines...) Expand all
4339 4349
4340 int remaining_mark_sweeps = 4350 int remaining_mark_sweeps =
4341 kMaxMarkSweepsInIdleRound - mark_sweeps_since_idle_round_started_; 4351 kMaxMarkSweepsInIdleRound - mark_sweeps_since_idle_round_started_;
4342 4352
4343 if (incremental_marking()->IsStopped()) { 4353 if (incremental_marking()->IsStopped()) {
4344 // If there are no more than two GCs left in this idle round and we are 4354 // If there are no more than two GCs left in this idle round and we are
4345 // allowed to do a full GC, then make those GCs full in order to compact 4355 // allowed to do a full GC, then make those GCs full in order to compact
4346 // the code space. 4356 // the code space.
4347 // TODO(ulan): Once we enable code compaction for incremental marking, 4357 // TODO(ulan): Once we enable code compaction for incremental marking,
4348 // we can get rid of this special case and always start incremental marking. 4358 // we can get rid of this special case and always start incremental marking.
4349 if (remaining_mark_sweeps <= 2 && hint >= kMinHintForFullGC) { 4359 if (remaining_mark_sweeps <= 2 && idle_time_in_ms >= kMinHintForFullGC) {
4350 CollectAllGarbage(kReduceMemoryFootprintMask, 4360 CollectAllGarbage(kReduceMemoryFootprintMask,
4351 "idle notification: finalize idle round"); 4361 "idle notification: finalize idle round");
4352 mark_sweeps_since_idle_round_started_++; 4362 mark_sweeps_since_idle_round_started_++;
4353 } else if (hint > kMinHintForIncrementalMarking) { 4363 } else {
4354 incremental_marking()->Start(); 4364 incremental_marking()->Start();
4355 } 4365 }
4356 } 4366 }
4357 if (!incremental_marking()->IsStopped() && 4367 if (!incremental_marking()->IsStopped()) {
4358 hint > kMinHintForIncrementalMarking) { 4368 AdvanceIdleIncrementalMarking(idle_time_in_ms);
4359 AdvanceIdleIncrementalMarking(step_size);
4360 } 4369 }
4361 4370
4362 if (mark_sweeps_since_idle_round_started_ >= kMaxMarkSweepsInIdleRound) { 4371 if (mark_sweeps_since_idle_round_started_ >= kMaxMarkSweepsInIdleRound) {
4363 FinishIdleRound(); 4372 FinishIdleRound();
4364 return true; 4373 return true;
4365 } 4374 }
4366 4375
4367 // If the IdleNotifcation is called with a large hint we will wait for 4376 // If the IdleNotifcation is called with a large hint we will wait for
4368 // the sweepter threads here. 4377 // the sweepter threads here.
4369 if (hint >= kMinHintForFullGC && 4378 if (idle_time_in_ms >= kMinHintForFullGC &&
4370 mark_compact_collector()->sweeping_in_progress()) { 4379 mark_compact_collector()->sweeping_in_progress()) {
4371 mark_compact_collector()->EnsureSweepingCompleted(); 4380 mark_compact_collector()->EnsureSweepingCompleted();
4372 } 4381 }
4373 4382
4374 return false; 4383 return false;
4375 } 4384 }
4376 4385
4377 4386
4378 #ifdef DEBUG 4387 #ifdef DEBUG
4379 4388
(...skipping 1763 matching lines...) Expand 10 before | Expand all | Expand 10 after
6143 static_cast<int>(object_sizes_last_time_[index])); 6152 static_cast<int>(object_sizes_last_time_[index]));
6144 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT) 6153 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT)
6145 #undef ADJUST_LAST_TIME_OBJECT_COUNT 6154 #undef ADJUST_LAST_TIME_OBJECT_COUNT
6146 6155
6147 MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); 6156 MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_));
6148 MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); 6157 MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_));
6149 ClearObjectStats(); 6158 ClearObjectStats();
6150 } 6159 }
6151 } 6160 }
6152 } // namespace v8::internal 6161 } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/heap/heap.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698