| Index: src/heap/heap.cc
|
| diff --git a/src/heap/heap.cc b/src/heap/heap.cc
|
| index 9686e0dac2129bd784305be2032200965f616d95..a4d28792caf009f2df3fc0c723624829a4a4589b 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?
|
| //
|
| @@ -968,7 +961,7 @@ bool Heap::CollectGarbage(GarbageCollector collector,
|
| if (collector == MARK_COMPACTOR && !ShouldFinalizeIncrementalMarking() &&
|
| !ShouldAbortIncrementalMarking() && !incremental_marking()->IsStopped() &&
|
| !incremental_marking()->should_hurry() && FLAG_incremental_marking &&
|
| - OldGenerationAllocationLimitReached()) {
|
| + OldGenerationSpaceAvailable() <= 0) {
|
| if (!incremental_marking()->IsComplete() &&
|
| !mark_compact_collector()->marking_deque_.IsEmpty() &&
|
| !FLAG_gc_global) {
|
| @@ -1080,10 +1073,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 = IncrementalMarkingLimitReached();
|
| + 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);
|
| + }
|
| }
|
| }
|
|
|
| @@ -5332,7 +5330,6 @@ void Heap::SetOldGenerationAllocationLimit(intptr_t old_gen_size,
|
| }
|
| }
|
|
|
| -
|
| void Heap::DampenOldGenerationAllocationLimit(intptr_t old_gen_size,
|
| double gc_speed,
|
| double mutator_speed) {
|
| @@ -5351,6 +5348,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() &&
|
| + IncrementalMarkingLimitReached() == 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::IncrementalMarkingLimitReached() {
|
| + 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;
|
|
|