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

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

Issue 2364923002: [heap] New heuristics for starting of incremental marking. (Closed)
Patch Set: rebase Created 4 years, 2 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
« no previous file with comments | « src/heap/heap.h ('k') | src/heap/heap-inl.h » ('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/heap/heap.h" 5 #include "src/heap/heap.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/ast/context-slot-cache.h" 9 #include "src/ast/context-slot-cache.h"
10 #include "src/base/bits.h" 10 #include "src/base/bits.h"
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 isolate_->counters()->gc_compactor_caused_by_request()->Increment(); 260 isolate_->counters()->gc_compactor_caused_by_request()->Increment();
261 *reason = "GC in old space requested"; 261 *reason = "GC in old space requested";
262 return MARK_COMPACTOR; 262 return MARK_COMPACTOR;
263 } 263 }
264 264
265 if (FLAG_gc_global || (FLAG_stress_compaction && (gc_count_ & 1) != 0)) { 265 if (FLAG_gc_global || (FLAG_stress_compaction && (gc_count_ & 1) != 0)) {
266 *reason = "GC in old space forced by flags"; 266 *reason = "GC in old space forced by flags";
267 return MARK_COMPACTOR; 267 return MARK_COMPACTOR;
268 } 268 }
269 269
270 // Is enough data promoted to justify a global GC?
271 if (OldGenerationAllocationLimitReached()) {
272 isolate_->counters()->gc_compactor_caused_by_promoted_data()->Increment();
273 *reason = "promotion limit reached";
274 return MARK_COMPACTOR;
275 }
276
277 // Is there enough space left in OLD to guarantee that a scavenge can 270 // Is there enough space left in OLD to guarantee that a scavenge can
278 // succeed? 271 // succeed?
279 // 272 //
280 // Note that MemoryAllocator->MaxAvailable() undercounts the memory available 273 // Note that MemoryAllocator->MaxAvailable() undercounts the memory available
281 // for object promotion. It counts only the bytes that the memory 274 // for object promotion. It counts only the bytes that the memory
282 // allocator has not yet allocated from the OS and assigned to any space, 275 // allocator has not yet allocated from the OS and assigned to any space,
283 // and does not count available bytes already in the old space or code 276 // and does not count available bytes already in the old space or code
284 // space. Undercounting is safe---we may get an unrequested full GC when 277 // space. Undercounting is safe---we may get an unrequested full GC when
285 // a scavenge would have succeeded. 278 // a scavenge would have succeeded.
286 if (memory_allocator()->MaxAvailable() <= new_space_->Size()) { 279 if (memory_allocator()->MaxAvailable() <= new_space_->Size()) {
(...skipping 674 matching lines...) Expand 10 before | Expand all | Expand 10 after
961 if (collector == SCAVENGER && !incremental_marking()->IsStopped()) { 954 if (collector == SCAVENGER && !incremental_marking()->IsStopped()) {
962 if (FLAG_trace_incremental_marking) { 955 if (FLAG_trace_incremental_marking) {
963 isolate()->PrintWithTimestamp( 956 isolate()->PrintWithTimestamp(
964 "[IncrementalMarking] Scavenge during marking.\n"); 957 "[IncrementalMarking] Scavenge during marking.\n");
965 } 958 }
966 } 959 }
967 960
968 if (collector == MARK_COMPACTOR && !ShouldFinalizeIncrementalMarking() && 961 if (collector == MARK_COMPACTOR && !ShouldFinalizeIncrementalMarking() &&
969 !ShouldAbortIncrementalMarking() && !incremental_marking()->IsStopped() && 962 !ShouldAbortIncrementalMarking() && !incremental_marking()->IsStopped() &&
970 !incremental_marking()->should_hurry() && FLAG_incremental_marking && 963 !incremental_marking()->should_hurry() && FLAG_incremental_marking &&
971 OldGenerationAllocationLimitReached()) { 964 OldGenerationSpaceAvailable() <= 0) {
972 if (!incremental_marking()->IsComplete() && 965 if (!incremental_marking()->IsComplete() &&
973 !mark_compact_collector()->marking_deque_.IsEmpty() && 966 !mark_compact_collector()->marking_deque_.IsEmpty() &&
974 !FLAG_gc_global) { 967 !FLAG_gc_global) {
975 if (FLAG_trace_incremental_marking) { 968 if (FLAG_trace_incremental_marking) {
976 isolate()->PrintWithTimestamp( 969 isolate()->PrintWithTimestamp(
977 "[IncrementalMarking] Delaying MarkSweep.\n"); 970 "[IncrementalMarking] Delaying MarkSweep.\n");
978 } 971 }
979 collector = SCAVENGER; 972 collector = SCAVENGER;
980 collector_reason = "incremental marking delaying mark-sweep"; 973 collector_reason = "incremental marking delaying mark-sweep";
981 } 974 }
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1073 GarbageCollectionReason gc_reason, 1066 GarbageCollectionReason gc_reason,
1074 GCCallbackFlags gc_callback_flags) { 1067 GCCallbackFlags gc_callback_flags) {
1075 DCHECK(incremental_marking()->IsStopped()); 1068 DCHECK(incremental_marking()->IsStopped());
1076 set_current_gc_flags(gc_flags); 1069 set_current_gc_flags(gc_flags);
1077 current_gc_callback_flags_ = gc_callback_flags; 1070 current_gc_callback_flags_ = gc_callback_flags;
1078 incremental_marking()->Start(gc_reason); 1071 incremental_marking()->Start(gc_reason);
1079 } 1072 }
1080 1073
1081 void Heap::StartIncrementalMarkingIfAllocationLimitIsReached( 1074 void Heap::StartIncrementalMarkingIfAllocationLimitIsReached(
1082 int gc_flags, const GCCallbackFlags gc_callback_flags) { 1075 int gc_flags, const GCCallbackFlags gc_callback_flags) {
1083 if (incremental_marking()->IsStopped() && 1076 if (incremental_marking()->IsStopped()) {
1084 incremental_marking()->ShouldActivateEvenWithoutIdleNotification()) { 1077 IncrementalMarkingLimit reached_limit = IncrementalMarkingLimitReached();
1085 StartIncrementalMarking(gc_flags, GarbageCollectionReason::kAllocationLimit, 1078 if (reached_limit == IncrementalMarkingLimit::kSoftLimit) {
1086 gc_callback_flags); 1079 incremental_marking()->incremental_marking_job()->ScheduleTask(this);
1080 } else if (reached_limit == IncrementalMarkingLimit::kHardLimit) {
1081 StartIncrementalMarking(gc_flags,
1082 GarbageCollectionReason::kAllocationLimit,
1083 gc_callback_flags);
1084 }
1087 } 1085 }
1088 } 1086 }
1089 1087
1090 void Heap::StartIdleIncrementalMarking(GarbageCollectionReason gc_reason) { 1088 void Heap::StartIdleIncrementalMarking(GarbageCollectionReason gc_reason) {
1091 gc_idle_time_handler_->ResetNoProgressCounter(); 1089 gc_idle_time_handler_->ResetNoProgressCounter();
1092 StartIncrementalMarking(kReduceMemoryFootprintMask, gc_reason, 1090 StartIncrementalMarking(kReduceMemoryFootprintMask, gc_reason,
1093 kNoGCCallbackFlags); 1091 kNoGCCallbackFlags);
1094 } 1092 }
1095 1093
1096 1094
(...skipping 4228 matching lines...) Expand 10 before | Expand all | Expand 10 after
5325 CalculateOldGenerationAllocationLimit(factor, old_gen_size); 5323 CalculateOldGenerationAllocationLimit(factor, old_gen_size);
5326 5324
5327 if (FLAG_trace_gc_verbose) { 5325 if (FLAG_trace_gc_verbose) {
5328 isolate_->PrintWithTimestamp("Grow: old size: %" V8PRIdPTR 5326 isolate_->PrintWithTimestamp("Grow: old size: %" V8PRIdPTR
5329 " KB, new limit: %" V8PRIdPTR " KB (%.1f)\n", 5327 " KB, new limit: %" V8PRIdPTR " KB (%.1f)\n",
5330 old_gen_size / KB, 5328 old_gen_size / KB,
5331 old_generation_allocation_limit_ / KB, factor); 5329 old_generation_allocation_limit_ / KB, factor);
5332 } 5330 }
5333 } 5331 }
5334 5332
5335
5336 void Heap::DampenOldGenerationAllocationLimit(intptr_t old_gen_size, 5333 void Heap::DampenOldGenerationAllocationLimit(intptr_t old_gen_size,
5337 double gc_speed, 5334 double gc_speed,
5338 double mutator_speed) { 5335 double mutator_speed) {
5339 double factor = HeapGrowingFactor(gc_speed, mutator_speed); 5336 double factor = HeapGrowingFactor(gc_speed, mutator_speed);
5340 intptr_t limit = CalculateOldGenerationAllocationLimit(factor, old_gen_size); 5337 intptr_t limit = CalculateOldGenerationAllocationLimit(factor, old_gen_size);
5341 if (limit < old_generation_allocation_limit_) { 5338 if (limit < old_generation_allocation_limit_) {
5342 if (FLAG_trace_gc_verbose) { 5339 if (FLAG_trace_gc_verbose) {
5343 isolate_->PrintWithTimestamp( 5340 isolate_->PrintWithTimestamp(
5344 "Dampen: old size: %" V8PRIdPTR " KB, old limit: %" V8PRIdPTR 5341 "Dampen: old size: %" V8PRIdPTR " KB, old limit: %" V8PRIdPTR
5345 " KB, " 5342 " KB, "
5346 "new limit: %" V8PRIdPTR " KB (%.1f)\n", 5343 "new limit: %" V8PRIdPTR " KB (%.1f)\n",
5347 old_gen_size / KB, old_generation_allocation_limit_ / KB, limit / KB, 5344 old_gen_size / KB, old_generation_allocation_limit_ / KB, limit / KB,
5348 factor); 5345 factor);
5349 } 5346 }
5350 old_generation_allocation_limit_ = limit; 5347 old_generation_allocation_limit_ = limit;
5351 } 5348 }
5352 } 5349 }
5353 5350
5351 // This predicate is called when an old generation space cannot allocated from
5352 // the free list and is about to add a new page. Returning false will cause a
5353 // major GC. It happens when the old generation allocation limit is reached and
5354 // - either we need to optimize for memory usage,
5355 // - or the incremental marking is not in progress and we cannot start it.
5356 bool Heap::ShouldExpandOldGenerationOnAllocationFailure() {
5357 if (always_allocate() || OldGenerationSpaceAvailable() > 0) return true;
5358 // We reached the old generation allocation limit.
5359
5360 if (ShouldOptimizeForMemoryUsage()) return false;
5361
5362 if (incremental_marking()->IsStopped() &&
5363 IncrementalMarkingLimitReached() == IncrementalMarkingLimit::kNoLimit) {
5364 // We cannot start incremental marking.
5365 return false;
5366 }
5367 return true;
5368 }
5369
5370 // This function returns either kNoLimit, kSoftLimit, or kHardLimit.
5371 // The kNoLimit means that either incremental marking is disabled or it is too
5372 // early to start incremental marking.
5373 // The kSoftLimit means that incremental marking should be started soon.
5374 // The kHardLimit means that incremental marking should be started immediately.
5375 Heap::IncrementalMarkingLimit Heap::IncrementalMarkingLimitReached() {
5376 if (!incremental_marking()->CanBeActivated() ||
5377 PromotedSpaceSizeOfObjects() < IncrementalMarking::kActivationThreshold) {
5378 // Incremental marking is disabled or it is too early to start.
5379 return IncrementalMarkingLimit::kNoLimit;
5380 }
5381 if ((FLAG_stress_compaction && (gc_count_ & 1) != 0) ||
5382 HighMemoryPressure()) {
5383 // If there is high memory pressure or stress testing is enabled, then
5384 // start marking immediately.
5385 return IncrementalMarkingLimit::kHardLimit;
5386 }
5387 intptr_t old_generation_space_available = OldGenerationSpaceAvailable();
5388 if (old_generation_space_available > new_space_->Capacity()) {
5389 return IncrementalMarkingLimit::kNoLimit;
5390 }
5391 // We are close to the allocation limit.
5392 // Choose between the hard and the soft limits.
5393 if (old_generation_space_available <= 0 || ShouldOptimizeForMemoryUsage()) {
5394 return IncrementalMarkingLimit::kHardLimit;
5395 }
5396 return IncrementalMarkingLimit::kSoftLimit;
5397 }
5354 5398
5355 void Heap::EnableInlineAllocation() { 5399 void Heap::EnableInlineAllocation() {
5356 if (!inline_allocation_disabled_) return; 5400 if (!inline_allocation_disabled_) return;
5357 inline_allocation_disabled_ = false; 5401 inline_allocation_disabled_ = false;
5358 5402
5359 // Update inline allocation limit for new space. 5403 // Update inline allocation limit for new space.
5360 new_space()->UpdateInlineAllocationLimit(0); 5404 new_space()->UpdateInlineAllocationLimit(0);
5361 } 5405 }
5362 5406
5363 5407
(...skipping 1107 matching lines...) Expand 10 before | Expand all | Expand 10 after
6471 } 6515 }
6472 6516
6473 6517
6474 // static 6518 // static
6475 int Heap::GetStaticVisitorIdForMap(Map* map) { 6519 int Heap::GetStaticVisitorIdForMap(Map* map) {
6476 return StaticVisitorBase::GetVisitorId(map); 6520 return StaticVisitorBase::GetVisitorId(map);
6477 } 6521 }
6478 6522
6479 } // namespace internal 6523 } // namespace internal
6480 } // namespace v8 6524 } // namespace v8
OLDNEW
« no previous file with comments | « src/heap/heap.h ('k') | src/heap/heap-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698