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

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') | test/heap-unittests/heap-unittest.cc » ('j') | 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"
11 #include "src/bootstrapper.h" 11 #include "src/bootstrapper.h"
12 #include "src/codegen.h" 12 #include "src/codegen.h"
13 #include "src/compilation-cache.h" 13 #include "src/compilation-cache.h"
14 #include "src/conversions.h" 14 #include "src/conversions.h"
15 #include "src/cpu-profiler.h" 15 #include "src/cpu-profiler.h"
16 #include "src/debug.h" 16 #include "src/debug.h"
17 #include "src/deoptimizer.h" 17 #include "src/deoptimizer.h"
18 #include "src/global-handles.h" 18 #include "src/global-handles.h"
19 #include "src/heap/gc-idle-time-handler.h"
19 #include "src/heap/incremental-marking.h" 20 #include "src/heap/incremental-marking.h"
20 #include "src/heap/mark-compact.h" 21 #include "src/heap/mark-compact.h"
21 #include "src/heap/objects-visiting-inl.h" 22 #include "src/heap/objects-visiting-inl.h"
22 #include "src/heap/objects-visiting.h" 23 #include "src/heap/objects-visiting.h"
23 #include "src/heap/store-buffer.h" 24 #include "src/heap/store-buffer.h"
24 #include "src/heap-profiler.h" 25 #include "src/heap-profiler.h"
25 #include "src/isolate-inl.h" 26 #include "src/isolate-inl.h"
26 #include "src/natives.h" 27 #include "src/natives.h"
27 #include "src/runtime-profiler.h" 28 #include "src/runtime-profiler.h"
28 #include "src/scopeinfo.h" 29 #include "src/scopeinfo.h"
(...skipping 4227 matching lines...) Expand 10 before | Expand all | Expand 10 after
4256 if (!IsHeapIterable()) { 4257 if (!IsHeapIterable()) {
4257 CollectAllGarbage(kMakeHeapIterableMask, "Heap::MakeHeapIterable"); 4258 CollectAllGarbage(kMakeHeapIterableMask, "Heap::MakeHeapIterable");
4258 } 4259 }
4259 if (mark_compact_collector()->sweeping_in_progress()) { 4260 if (mark_compact_collector()->sweeping_in_progress()) {
4260 mark_compact_collector()->EnsureSweepingCompleted(); 4261 mark_compact_collector()->EnsureSweepingCompleted();
4261 } 4262 }
4262 DCHECK(IsHeapIterable()); 4263 DCHECK(IsHeapIterable());
4263 } 4264 }
4264 4265
4265 4266
4266 void Heap::AdvanceIdleIncrementalMarking(intptr_t step_size) { 4267 void Heap::AdvanceIdleIncrementalMarking(int idle_time_in_ms) {
4268 intptr_t step_size = GCIdleTimeHandler::EstimateMarkingStepSize(
4269 idle_time_in_ms, tracer_.IncrementalMarkingSpeedInBytesPerMillisecond());
4270
4267 incremental_marking()->Step(step_size, 4271 incremental_marking()->Step(step_size,
4268 IncrementalMarking::NO_GC_VIA_STACK_GUARD, true); 4272 IncrementalMarking::NO_GC_VIA_STACK_GUARD, true);
4269 4273
4270 if (incremental_marking()->IsComplete()) { 4274 if (incremental_marking()->IsComplete()) {
4271 bool uncommit = false; 4275 bool uncommit = false;
4272 if (gc_count_at_last_idle_gc_ == gc_count_) { 4276 if (gc_count_at_last_idle_gc_ == gc_count_) {
4273 // No GC since the last full GC, the mutator is probably not active. 4277 // No GC since the last full GC, the mutator is probably not active.
4274 isolate_->compilation_cache()->Clear(); 4278 isolate_->compilation_cache()->Clear();
4275 uncommit = true; 4279 uncommit = true;
4276 } 4280 }
4277 CollectAllGarbage(kReduceMemoryFootprintMask, 4281 CollectAllGarbage(kReduceMemoryFootprintMask,
4278 "idle notification: finalize incremental"); 4282 "idle notification: finalize incremental");
4279 mark_sweeps_since_idle_round_started_++; 4283 mark_sweeps_since_idle_round_started_++;
4280 gc_count_at_last_idle_gc_ = gc_count_; 4284 gc_count_at_last_idle_gc_ = gc_count_;
4281 if (uncommit) { 4285 if (uncommit) {
4282 new_space_.Shrink(); 4286 new_space_.Shrink();
4283 UncommitFromSpace(); 4287 UncommitFromSpace();
4284 } 4288 }
4285 } 4289 }
4286 } 4290 }
4287 4291
4288 4292
4289 bool Heap::IdleNotification(int hint) { 4293 bool Heap::IdleNotification(int idle_time_in_ms) {
4290 // If incremental marking is off, we do not perform idle notification. 4294 // If incremental marking is off, we do not perform idle notification.
4291 if (!FLAG_incremental_marking) return true; 4295 if (!FLAG_incremental_marking) return true;
4292 4296
4293 // Hints greater than this value indicate that
4294 // the embedder is requesting a lot of GC work.
4295 const int kMaxHint = 1000;
4296 const int kMinHintForIncrementalMarking = 10;
4297 // Minimal hint that allows to do full GC. 4297 // Minimal hint that allows to do full GC.
4298 const int kMinHintForFullGC = 100; 4298 const int kMinHintForFullGC = 100;
4299 intptr_t size_factor = Min(Max(hint, 20), kMaxHint) / 4; 4299 isolate()->counters()->gc_idle_time_allotted_in_ms()->AddSample(
4300 // The size factor is in range [5..250]. The numbers here are chosen from 4300 idle_time_in_ms);
4301 // experiments. If you changes them, make sure to test with
4302 // chrome/performance_ui_tests --gtest_filter="GeneralMixMemoryTest.*
4303 intptr_t step_size = size_factor * IncrementalMarking::kAllocatedThreshold;
4304
4305 isolate()->counters()->gc_idle_time_allotted_in_ms()->AddSample(hint);
4306 HistogramTimerScope idle_notification_scope( 4301 HistogramTimerScope idle_notification_scope(
4307 isolate_->counters()->gc_idle_notification()); 4302 isolate_->counters()->gc_idle_notification());
4308 4303
4309 if (contexts_disposed_ > 0) { 4304 if (contexts_disposed_ > 0) {
4310 contexts_disposed_ = 0; 4305 contexts_disposed_ = 0;
4311 int mark_sweep_time = Min(TimeMarkSweepWouldTakeInMs(), 1000); 4306 int mark_sweep_time = Min(TimeMarkSweepWouldTakeInMs(), 1000);
4312 if (hint >= mark_sweep_time && !FLAG_expose_gc && 4307 if (idle_time_in_ms >= mark_sweep_time && !FLAG_expose_gc &&
4313 incremental_marking()->IsStopped()) { 4308 incremental_marking()->IsStopped()) {
4314 HistogramTimerScope scope(isolate_->counters()->gc_context()); 4309 HistogramTimerScope scope(isolate_->counters()->gc_context());
4315 CollectAllGarbage(kReduceMemoryFootprintMask, 4310 CollectAllGarbage(kReduceMemoryFootprintMask,
4316 "idle notification: contexts disposed"); 4311 "idle notification: contexts disposed");
4317 } else { 4312 } else {
4318 AdvanceIdleIncrementalMarking(step_size); 4313 AdvanceIdleIncrementalMarking(idle_time_in_ms);
4319 } 4314 }
4320 4315
4321 // After context disposal there is likely a lot of garbage remaining, reset 4316 // After context disposal there is likely a lot of garbage remaining, reset
4322 // the idle notification counters in order to trigger more incremental GCs 4317 // the idle notification counters in order to trigger more incremental GCs
4323 // on subsequent idle notifications. 4318 // on subsequent idle notifications.
4324 StartIdleRound(); 4319 StartIdleRound();
4325 return false; 4320 return false;
4326 } 4321 }
4327 4322
4328 // By doing small chunks of GC work in each IdleNotification, 4323 // By doing small chunks of GC work in each IdleNotification,
(...skipping 14 matching lines...) Expand all
4343 4338
4344 int remaining_mark_sweeps = 4339 int remaining_mark_sweeps =
4345 kMaxMarkSweepsInIdleRound - mark_sweeps_since_idle_round_started_; 4340 kMaxMarkSweepsInIdleRound - mark_sweeps_since_idle_round_started_;
4346 4341
4347 if (incremental_marking()->IsStopped()) { 4342 if (incremental_marking()->IsStopped()) {
4348 // If there are no more than two GCs left in this idle round and we are 4343 // If there are no more than two GCs left in this idle round and we are
4349 // allowed to do a full GC, then make those GCs full in order to compact 4344 // allowed to do a full GC, then make those GCs full in order to compact
4350 // the code space. 4345 // the code space.
4351 // TODO(ulan): Once we enable code compaction for incremental marking, 4346 // TODO(ulan): Once we enable code compaction for incremental marking,
4352 // we can get rid of this special case and always start incremental marking. 4347 // we can get rid of this special case and always start incremental marking.
4353 if (remaining_mark_sweeps <= 2 && hint >= kMinHintForFullGC) { 4348 if (remaining_mark_sweeps <= 2 && idle_time_in_ms >= kMinHintForFullGC) {
4354 CollectAllGarbage(kReduceMemoryFootprintMask, 4349 CollectAllGarbage(kReduceMemoryFootprintMask,
4355 "idle notification: finalize idle round"); 4350 "idle notification: finalize idle round");
4356 mark_sweeps_since_idle_round_started_++; 4351 mark_sweeps_since_idle_round_started_++;
4357 } else if (hint > kMinHintForIncrementalMarking) { 4352 } else {
4358 incremental_marking()->Start(); 4353 incremental_marking()->Start();
4359 } 4354 }
4360 } 4355 }
4361 if (!incremental_marking()->IsStopped() && 4356 if (!incremental_marking()->IsStopped()) {
4362 hint > kMinHintForIncrementalMarking) { 4357 AdvanceIdleIncrementalMarking(idle_time_in_ms);
4363 AdvanceIdleIncrementalMarking(step_size);
4364 } 4358 }
4365 4359
4366 if (mark_sweeps_since_idle_round_started_ >= kMaxMarkSweepsInIdleRound) { 4360 if (mark_sweeps_since_idle_round_started_ >= kMaxMarkSweepsInIdleRound) {
4367 FinishIdleRound(); 4361 FinishIdleRound();
4368 return true; 4362 return true;
4369 } 4363 }
4370 4364
4371 // If the IdleNotifcation is called with a large hint we will wait for 4365 // If the IdleNotifcation is called with a large hint we will wait for
4372 // the sweepter threads here. 4366 // the sweepter threads here.
4373 if (hint >= kMinHintForFullGC && 4367 if (idle_time_in_ms >= kMinHintForFullGC &&
4374 mark_compact_collector()->sweeping_in_progress()) { 4368 mark_compact_collector()->sweeping_in_progress()) {
4375 mark_compact_collector()->EnsureSweepingCompleted(); 4369 mark_compact_collector()->EnsureSweepingCompleted();
4376 } 4370 }
4377 4371
4378 return false; 4372 return false;
4379 } 4373 }
4380 4374
4381 4375
4382 #ifdef DEBUG 4376 #ifdef DEBUG
4383 4377
(...skipping 1763 matching lines...) Expand 10 before | Expand all | Expand 10 after
6147 static_cast<int>(object_sizes_last_time_[index])); 6141 static_cast<int>(object_sizes_last_time_[index]));
6148 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT) 6142 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT)
6149 #undef ADJUST_LAST_TIME_OBJECT_COUNT 6143 #undef ADJUST_LAST_TIME_OBJECT_COUNT
6150 6144
6151 MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); 6145 MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_));
6152 MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); 6146 MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_));
6153 ClearObjectStats(); 6147 ClearObjectStats();
6154 } 6148 }
6155 } 6149 }
6156 } // namespace v8::internal 6150 } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/heap/heap.h ('k') | test/heap-unittests/heap-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698