Chromium Code Reviews| Index: src/heap/heap.cc |
| diff --git a/src/heap/heap.cc b/src/heap/heap.cc |
| index 8431b26089543ed410238bc0b1b8d33f3e73fc37..e9d1d89fd6a92520a3fffceb967f818448ce15c3 100644 |
| --- a/src/heap/heap.cc |
| +++ b/src/heap/heap.cc |
| @@ -267,13 +267,6 @@ GarbageCollector Heap::SelectGarbageCollector(AllocationSpace space, |
| return MARK_COMPACTOR; |
| } |
| - // Is enough data promoted to justify a global GC? |
| - if (OldGenerationAllocationLimitReached()) { |
| - isolate_->counters()->gc_compactor_caused_by_promoted_data()->Increment(); |
| - *reason = "promotion limit reached"; |
| - return MARK_COMPACTOR; |
| - } |
| - |
| // Is there enough space left in OLD to guarantee that a scavenge can |
| // succeed? |
| // |
| @@ -1064,10 +1057,15 @@ void Heap::StartIncrementalMarking(int gc_flags, |
| void Heap::StartIncrementalMarkingIfAllocationLimitIsReached( |
| int gc_flags, const GCCallbackFlags gc_callback_flags) { |
| - if (incremental_marking()->IsStopped() && |
| - incremental_marking()->ShouldActivateEvenWithoutIdleNotification()) { |
| - StartIncrementalMarking(gc_flags, GarbageCollectionReason::kAllocationLimit, |
| - gc_callback_flags); |
| + if (incremental_marking()->IsStopped()) { |
| + IncrementalMarkingLimit reached_limit = ReachedIncrementalMarkingLimit(); |
| + if (reached_limit == IncrementalMarkingLimit::kSoftLimit) { |
| + incremental_marking()->incremental_marking_job()->ScheduleTask(this); |
| + } else if (reached_limit == IncrementalMarkingLimit::kHardLimit) { |
| + StartIncrementalMarking(gc_flags, |
| + GarbageCollectionReason::kAllocationLimit, |
| + gc_callback_flags); |
| + } |
| } |
| } |
| @@ -5318,7 +5316,6 @@ void Heap::SetOldGenerationAllocationLimit(intptr_t old_gen_size, |
| } |
| } |
| - |
| void Heap::DampenOldGenerationAllocationLimit(intptr_t old_gen_size, |
| double gc_speed, |
| double mutator_speed) { |
| @@ -5337,6 +5334,53 @@ void Heap::DampenOldGenerationAllocationLimit(intptr_t old_gen_size, |
| } |
| } |
| +// This predicate is called when an old generation space cannot allocated from |
| +// the free list and is about to add a new page. Returning false will cause a |
| +// major GC. It happens when the old generation allocation limit is reached and |
| +// - either we need to optimize for memory usage, |
| +// - or the incremental marking is not in progress and we cannot start it. |
| +bool Heap::ShouldExpandOldGenerationOnAllocationFailure() { |
| + if (always_allocate() || OldGenerationSpaceAvailable() > 0) return true; |
| + // We reached the old generation allocation limit. |
| + |
| + if (ShouldOptimizeForMemoryUsage()) return false; |
| + |
| + if (incremental_marking()->IsStopped() && |
| + ReachedIncrementalMarkingLimit() == IncrementalMarkingLimit::kNoLimit) { |
| + // We cannot start incremental marking. |
| + return false; |
| + } |
| + return true; |
| +} |
| + |
| +// This function returns either kNoLimit, kSoftLimit, or kHardLimit. |
| +// The kNoLimit means that either incremental marking is disabled or it is too |
| +// early to start incremental marking. |
| +// The kSoftLimit means that incremental marking should be started soon. |
| +// The kHardLimit means that incremental marking should be started immediately. |
| +Heap::IncrementalMarkingLimit Heap::ReachedIncrementalMarkingLimit() { |
|
Hannes Payer (out of office)
2016/09/27 09:16:53
nit: maybe rename to IncrementalMarkingLimitReache
ulan
2016/09/27 17:06:41
Renamed the function.
|
| + if (!incremental_marking()->CanBeActivated() || |
| + PromotedSpaceSizeOfObjects() < IncrementalMarking::kActivationThreshold) { |
| + // Incremental marking is disabled or it is too early to start. |
| + return IncrementalMarkingLimit::kNoLimit; |
| + } |
| + if ((FLAG_stress_compaction && (gc_count_ & 1) != 0) || |
| + HighMemoryPressure()) { |
| + // If there is high memory pressure or stress testing is enabled, then |
| + // start marking immediately. |
| + return IncrementalMarkingLimit::kHardLimit; |
| + } |
| + intptr_t old_generation_space_available = OldGenerationSpaceAvailable(); |
| + if (old_generation_space_available > new_space_->Capacity()) { |
| + return IncrementalMarkingLimit::kNoLimit; |
| + } |
| + // We are close to the allocation limit. |
| + // Choose between the hard and the soft limits. |
| + if (old_generation_space_available <= 0 || ShouldOptimizeForMemoryUsage()) { |
| + return IncrementalMarkingLimit::kHardLimit; |
| + } |
| + return IncrementalMarkingLimit::kSoftLimit; |
| +} |
| void Heap::EnableInlineAllocation() { |
| if (!inline_allocation_disabled_) return; |