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; |