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

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

Issue 492763002: Move idle notification handling to GCIdleTimeHandler. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Undo more changes 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
« src/heap/gc-idle-time-handler.cc ('K') | « 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 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 max_gc_pause_(0.0), 113 max_gc_pause_(0.0),
114 total_gc_time_ms_(0.0), 114 total_gc_time_ms_(0.0),
115 max_alive_after_gc_(0), 115 max_alive_after_gc_(0),
116 min_in_mutator_(kMaxInt), 116 min_in_mutator_(kMaxInt),
117 marking_time_(0.0), 117 marking_time_(0.0),
118 sweeping_time_(0.0), 118 sweeping_time_(0.0),
119 mark_compact_collector_(this), 119 mark_compact_collector_(this),
120 store_buffer_(this), 120 store_buffer_(this),
121 marking_(this), 121 marking_(this),
122 incremental_marking_(this), 122 incremental_marking_(this),
123 number_idle_notifications_(0),
124 last_idle_notification_gc_count_(0),
125 last_idle_notification_gc_count_init_(false),
126 mark_sweeps_since_idle_round_started_(0),
127 gc_count_at_last_idle_gc_(0), 123 gc_count_at_last_idle_gc_(0),
128 scavenges_since_last_idle_round_(kIdleScavengeThreshold),
129 full_codegen_bytes_generated_(0), 124 full_codegen_bytes_generated_(0),
130 crankshaft_codegen_bytes_generated_(0), 125 crankshaft_codegen_bytes_generated_(0),
131 gcs_since_last_deopt_(0), 126 gcs_since_last_deopt_(0),
132 #ifdef VERIFY_HEAP 127 #ifdef VERIFY_HEAP
133 no_weak_object_verification_scope_depth_(0), 128 no_weak_object_verification_scope_depth_(0),
134 #endif 129 #endif
135 allocation_sites_scratchpad_length_(0), 130 allocation_sites_scratchpad_length_(0),
136 promotion_queue_(this), 131 promotion_queue_(this),
137 configured_(false), 132 configured_(false),
138 external_string_table_(this), 133 external_string_table_(this),
(...skipping 1413 matching lines...) Expand 10 before | Expand all | Expand 10 after
1552 new_space_.inline_allocation_limit_step()); 1547 new_space_.inline_allocation_limit_step());
1553 1548
1554 // Update how much has survived scavenge. 1549 // Update how much has survived scavenge.
1555 IncrementYoungSurvivorsCounter(static_cast<int>( 1550 IncrementYoungSurvivorsCounter(static_cast<int>(
1556 (PromotedSpaceSizeOfObjects() - survived_watermark) + new_space_.Size())); 1551 (PromotedSpaceSizeOfObjects() - survived_watermark) + new_space_.Size()));
1557 1552
1558 LOG(isolate_, ResourceEvent("scavenge", "end")); 1553 LOG(isolate_, ResourceEvent("scavenge", "end"));
1559 1554
1560 gc_state_ = NOT_IN_GC; 1555 gc_state_ = NOT_IN_GC;
1561 1556
1562 scavenges_since_last_idle_round_++; 1557 gc_idle_time_handler_.NotifyScavenge();
1563 } 1558 }
1564 1559
1565 1560
1566 String* Heap::UpdateNewSpaceReferenceInExternalStringTableEntry(Heap* heap, 1561 String* Heap::UpdateNewSpaceReferenceInExternalStringTableEntry(Heap* heap,
1567 Object** p) { 1562 Object** p) {
1568 MapWord first_word = HeapObject::cast(*p)->map_word(); 1563 MapWord first_word = HeapObject::cast(*p)->map_word();
1569 1564
1570 if (!first_word.IsForwardingAddress()) { 1565 if (!first_word.IsForwardingAddress()) {
1571 // Unreachable external string can be finalized. 1566 // Unreachable external string can be finalized.
1572 heap->FinalizeExternalString(String::cast(*p)); 1567 heap->FinalizeExternalString(String::cast(*p));
(...skipping 2684 matching lines...) Expand 10 before | Expand all | Expand 10 after
4257 if (!IsHeapIterable()) { 4252 if (!IsHeapIterable()) {
4258 CollectAllGarbage(kMakeHeapIterableMask, "Heap::MakeHeapIterable"); 4253 CollectAllGarbage(kMakeHeapIterableMask, "Heap::MakeHeapIterable");
4259 } 4254 }
4260 if (mark_compact_collector()->sweeping_in_progress()) { 4255 if (mark_compact_collector()->sweeping_in_progress()) {
4261 mark_compact_collector()->EnsureSweepingCompleted(); 4256 mark_compact_collector()->EnsureSweepingCompleted();
4262 } 4257 }
4263 DCHECK(IsHeapIterable()); 4258 DCHECK(IsHeapIterable());
4264 } 4259 }
4265 4260
4266 4261
4267 void Heap::AdvanceIdleIncrementalMarking(int idle_time_in_ms) { 4262 void Heap::AdvanceIdleIncrementalMarking(intptr_t step_size) {
4268 intptr_t step_size = GCIdleTimeHandler::EstimateMarkingStepSize(
4269 idle_time_in_ms, tracer_.IncrementalMarkingSpeedInBytesPerMillisecond());
4270
4271 incremental_marking()->Step(step_size, 4263 incremental_marking()->Step(step_size,
4272 IncrementalMarking::NO_GC_VIA_STACK_GUARD, true); 4264 IncrementalMarking::NO_GC_VIA_STACK_GUARD, true);
4273 4265
4274 if (incremental_marking()->IsComplete()) { 4266 if (incremental_marking()->IsComplete()) {
4275 bool uncommit = false; 4267 bool uncommit = false;
4276 if (gc_count_at_last_idle_gc_ == gc_count_) { 4268 if (gc_count_at_last_idle_gc_ == gc_count_) {
4277 // No GC since the last full GC, the mutator is probably not active. 4269 // No GC since the last full GC, the mutator is probably not active.
4278 isolate_->compilation_cache()->Clear(); 4270 isolate_->compilation_cache()->Clear();
4279 uncommit = true; 4271 uncommit = true;
4280 } 4272 }
4281 CollectAllGarbage(kReduceMemoryFootprintMask, 4273 CollectAllGarbage(kReduceMemoryFootprintMask,
4282 "idle notification: finalize incremental"); 4274 "idle notification: finalize incremental");
4283 mark_sweeps_since_idle_round_started_++; 4275 gc_idle_time_handler_.NotifyIdleFullGC();
4284 gc_count_at_last_idle_gc_ = gc_count_; 4276 gc_count_at_last_idle_gc_ = gc_count_;
4285 if (uncommit) { 4277 if (uncommit) {
4286 new_space_.Shrink(); 4278 new_space_.Shrink();
4287 UncommitFromSpace(); 4279 UncommitFromSpace();
4288 } 4280 }
4289 } 4281 }
4290 } 4282 }
4291 4283
4292 4284
4293 bool Heap::IdleNotification(int idle_time_in_ms) { 4285 bool Heap::IdleNotification(int idle_time_in_ms) {
4294 // If incremental marking is off, we do not perform idle notification. 4286 // If incremental marking is off, we do not perform idle notification.
4295 if (!FLAG_incremental_marking) return true; 4287 if (!FLAG_incremental_marking) return true;
4296
4297 // Minimal hint that allows to do full GC.
4298 const int kMinHintForFullGC = 100;
4299 isolate()->counters()->gc_idle_time_allotted_in_ms()->AddSample( 4288 isolate()->counters()->gc_idle_time_allotted_in_ms()->AddSample(
4300 idle_time_in_ms); 4289 idle_time_in_ms);
4301 HistogramTimerScope idle_notification_scope( 4290 HistogramTimerScope idle_notification_scope(
4302 isolate_->counters()->gc_idle_notification()); 4291 isolate_->counters()->gc_idle_notification());
4303 4292
4304 if (contexts_disposed_ > 0) { 4293 GCIdleTimeAction action = gc_idle_time_handler_.Compute(
4305 contexts_disposed_ = 0; 4294 idle_time_in_ms, contexts_disposed_, SizeOfObjects(),
4306 int mark_sweep_time = Min(TimeMarkSweepWouldTakeInMs(), 1000); 4295 incremental_marking()->IsStopped(), tracer());
4307 if (idle_time_in_ms >= mark_sweep_time && !FLAG_expose_gc && 4296 contexts_disposed_ = 0;
4308 incremental_marking()->IsStopped()) { 4297 bool result = false;
4298 switch (action.type) {
4299 case DO_INCREMENTAL_MARKING:
4300 if (incremental_marking()->IsStopped()) {
Hannes Payer (out of office) 2014/08/20 18:24:11 I think this check should be in the Compute functi
ulan 2014/08/21 08:45:19 Acknowledged.
4301 incremental_marking()->Start();
4302 }
4303 AdvanceIdleIncrementalMarking(action.parameter);
4304 break;
4305 case DO_FULL_GC: {
4309 HistogramTimerScope scope(isolate_->counters()->gc_context()); 4306 HistogramTimerScope scope(isolate_->counters()->gc_context());
4310 CollectAllGarbage(kReduceMemoryFootprintMask, 4307 const char* message = contexts_disposed_
4311 "idle notification: contexts disposed"); 4308 ? "idle notification: contexts disposed"
4312 } else { 4309 : "idle notification: finalize idle round";
4313 AdvanceIdleIncrementalMarking(idle_time_in_ms); 4310 CollectAllGarbage(kReduceMemoryFootprintMask, message);
4311 gc_idle_time_handler_.NotifyIdleFullGC();
4312 break;
4314 } 4313 }
4315 4314 case DO_SCAVENGE:
4316 // After context disposal there is likely a lot of garbage remaining, reset 4315 CollectGarbage(NEW_SPACE, "idle notification: scavenge");
4317 // the idle notification counters in order to trigger more incremental GCs 4316 break;
4318 // on subsequent idle notifications. 4317 case DO_NOTHING:
4319 StartIdleRound(); 4318 result = true;
4320 return false; 4319 break;
4321 } 4320 }
4322
4323 // By doing small chunks of GC work in each IdleNotification,
4324 // perform a round of incremental GCs and after that wait until
4325 // the mutator creates enough garbage to justify a new round.
4326 // An incremental GC progresses as follows:
4327 // 1. many incremental marking steps,
4328 // 2. one old space mark-sweep-compact,
4329 // Use mark-sweep-compact events to count incremental GCs in a round.
4330
4331 if (mark_sweeps_since_idle_round_started_ >= kMaxMarkSweepsInIdleRound) {
4332 if (EnoughGarbageSinceLastIdleRound()) {
4333 StartIdleRound();
4334 } else {
4335 return true;
4336 }
4337 }
4338
4339 int remaining_mark_sweeps =
4340 kMaxMarkSweepsInIdleRound - mark_sweeps_since_idle_round_started_;
4341
4342 if (incremental_marking()->IsStopped()) {
4343 // If there are no more than two GCs left in this idle round and we are
4344 // allowed to do a full GC, then make those GCs full in order to compact
4345 // the code space.
4346 // TODO(ulan): Once we enable code compaction for incremental marking,
4347 // we can get rid of this special case and always start incremental marking.
4348 if (remaining_mark_sweeps <= 2 && idle_time_in_ms >= kMinHintForFullGC) {
4349 CollectAllGarbage(kReduceMemoryFootprintMask,
4350 "idle notification: finalize idle round");
4351 mark_sweeps_since_idle_round_started_++;
4352 } else {
4353 incremental_marking()->Start();
4354 }
4355 }
4356 if (!incremental_marking()->IsStopped()) {
4357 AdvanceIdleIncrementalMarking(idle_time_in_ms);
4358 }
4359
4360 if (mark_sweeps_since_idle_round_started_ >= kMaxMarkSweepsInIdleRound) {
4361 FinishIdleRound();
4362 return true;
4363 }
4364
4365 // If the IdleNotifcation is called with a large hint we will wait for 4321 // If the IdleNotifcation is called with a large hint we will wait for
4366 // the sweepter threads here. 4322 // the sweepter threads here.
4323 const int kMinHintForFullGC = 100;
4367 if (idle_time_in_ms >= kMinHintForFullGC && 4324 if (idle_time_in_ms >= kMinHintForFullGC &&
4368 mark_compact_collector()->sweeping_in_progress()) { 4325 mark_compact_collector()->sweeping_in_progress()) {
Hannes Payer (out of office) 2014/08/20 18:24:11 Should we do a SWEEP action., which is selected wh
ulan 2014/08/21 08:45:19 Agreed, but let's do this in a separate CL to redu
4369 mark_compact_collector()->EnsureSweepingCompleted(); 4326 mark_compact_collector()->EnsureSweepingCompleted();
4370 } 4327 }
4371 4328
4372 return false; 4329 return result;
4373 } 4330 }
4374 4331
4375 4332
4376 #ifdef DEBUG 4333 #ifdef DEBUG
4377 4334
4378 void Heap::Print() { 4335 void Heap::Print() {
4379 if (!HasBeenSetUp()) return; 4336 if (!HasBeenSetUp()) return;
4380 isolate()->PrintStack(stdout); 4337 isolate()->PrintStack(stdout);
4381 AllSpaces spaces(this); 4338 AllSpaces spaces(this);
4382 for (Space* space = spaces.next(); space != NULL; space = spaces.next()) { 4339 for (Space* space = spaces.next(); space != NULL; space = spaces.next()) {
(...skipping 1758 matching lines...) Expand 10 before | Expand all | Expand 10 after
6141 static_cast<int>(object_sizes_last_time_[index])); 6098 static_cast<int>(object_sizes_last_time_[index]));
6142 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT) 6099 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT)
6143 #undef ADJUST_LAST_TIME_OBJECT_COUNT 6100 #undef ADJUST_LAST_TIME_OBJECT_COUNT
6144 6101
6145 MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); 6102 MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_));
6146 MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); 6103 MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_));
6147 ClearObjectStats(); 6104 ClearObjectStats();
6148 } 6105 }
6149 } 6106 }
6150 } // namespace v8::internal 6107 } // namespace v8::internal
OLDNEW
« src/heap/gc-idle-time-handler.cc ('K') | « src/heap/heap.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698