diff --git a/src/heap.cc b/src/heap.cc index b5a0bc5cb1..3b5dc826b7 100644 --- a/src/heap.cc +++ b/src/heap.cc @@ -695,12 +695,18 @@ void Heap::UpdateSurvivalRateTrend(int start_new_space_size) { (static_cast(young_survivors_after_last_gc_) * 100) / start_new_space_size; - if (survival_rate > kYoungSurvivalRateThreshold) { + if (survival_rate > kYoungSurvivalRateHighThreshold) { high_survival_rate_period_length_++; } else { high_survival_rate_period_length_ = 0; } + if (survival_rate < kYoungSurvivalRateLowThreshold) { + low_survival_rate_period_length_++; + } else { + low_survival_rate_period_length_ = 0; + } + double survival_rate_diff = survival_rate_ - survival_rate; if (survival_rate_diff > kYoungSurvivalRateAllowedDeviation) { @@ -760,32 +766,6 @@ bool Heap::PerformGarbageCollection(GarbageCollector collector, UpdateSurvivalRateTrend(start_new_space_size); - if (!new_space_high_promotion_mode_active_ && - new_space_.Capacity() == new_space_.MaximumCapacity() && - IsStableOrIncreasingSurvivalTrend() && - IsHighSurvivalRate()) { - // Stable high survival rates even though young generation is at - // maximum capacity indicates that most objects will be promoted. - // To decrease scavenger pauses and final mark-sweep pauses, we - // have to limit maximal capacity of the young generation. - new_space_high_promotion_mode_active_ = true; - if (FLAG_trace_gc) { - PrintF("Limited new space size due to high promotion rate: %d MB\n", - new_space_.InitialCapacity() / MB); - } - } else if (new_space_high_promotion_mode_active_ && - IsDecreasingSurvivalTrend() && - !IsHighSurvivalRate()) { - // Decreasing low survival rates might indicate that the above high - // promotion mode is over and we should allow the young generation - // to grow again. - new_space_high_promotion_mode_active_ = false; - if (FLAG_trace_gc) { - PrintF("Unlimited new space size due to low promotion rate: %d MB\n", - new_space_.MaximumCapacity() / MB); - } - } - size_of_old_gen_at_last_old_space_gc_ = PromotedSpaceSize(); if (high_survival_rate_during_scavenges && @@ -815,6 +795,32 @@ bool Heap::PerformGarbageCollection(GarbageCollector collector, UpdateSurvivalRateTrend(start_new_space_size); } + if (!new_space_high_promotion_mode_active_ && + new_space_.Capacity() == new_space_.MaximumCapacity() && + IsStableOrIncreasingSurvivalTrend() && + IsHighSurvivalRate()) { + // Stable high survival rates even though young generation is at + // maximum capacity indicates that most objects will be promoted. + // To decrease scavenger pauses and final mark-sweep pauses, we + // have to limit maximal capacity of the young generation. + new_space_high_promotion_mode_active_ = true; + if (FLAG_trace_gc) { + PrintF("Limited new space size due to high promotion rate: %d MB\n", + new_space_.InitialCapacity() / MB); + } + } else if (new_space_high_promotion_mode_active_ && + IsStableOrDecreasingSurvivalTrend() && + IsLowSurvivalRate()) { + // Decreasing low survival rates might indicate that the above high + // promotion mode is over and we should allow the young generation + // to grow again. + new_space_high_promotion_mode_active_ = false; + if (FLAG_trace_gc) { + PrintF("Unlimited new space size due to low promotion rate: %d MB\n", + new_space_.MaximumCapacity() / MB); + } + } + if (new_space_high_promotion_mode_active_ && new_space_.Capacity() > new_space_.InitialCapacity()) { new_space_.Shrink(); @@ -1099,7 +1105,7 @@ void Heap::Scavenge() { isolate_->descriptor_lookup_cache()->Clear(); // Used for updating survived_since_last_expansion_ at function end. - intptr_t survived_watermark = PromotedSpaceSize(); + intptr_t survived_watermark = PromotedSpaceSizeOfObjects(); CheckNewSpaceExpansionCriteria(); @@ -1191,7 +1197,7 @@ void Heap::Scavenge() { // Update how much has survived scavenge. IncrementYoungSurvivorsCounter(static_cast( - (PromotedSpaceSize() - survived_watermark) + new_space_.Size())); + (PromotedSpaceSizeOfObjects() - survived_watermark) + new_space_.Size())); LOG(isolate_, ResourceEvent("scavenge", "end")); @@ -5422,6 +5428,16 @@ intptr_t Heap::PromotedSpaceSize() { } +intptr_t Heap::PromotedSpaceSizeOfObjects() { + return old_pointer_space_->SizeOfObjects() + + old_data_space_->SizeOfObjects() + + code_space_->SizeOfObjects() + + map_space_->SizeOfObjects() + + cell_space_->SizeOfObjects() + + lo_space_->SizeOfObjects(); +} + + int Heap::PromotedExternalMemorySize() { if (amount_of_external_allocated_memory_ <= amount_of_external_allocated_memory_at_last_global_gc_) return 0; diff --git a/src/heap.h b/src/heap.h index a5ddac3f2c..c8ac927cd2 100644 --- a/src/heap.h +++ b/src/heap.h @@ -1382,6 +1382,7 @@ class Heap { void CheckNewSpaceExpansionCriteria(); inline void IncrementYoungSurvivorsCounter(int survived) { + ASSERT(survived >= 0); young_survivors_after_last_gc_ = survived; survived_since_last_expansion_ += survived; } @@ -1431,6 +1432,7 @@ class Heap { // Returns the size of objects residing in non new spaces. intptr_t PromotedSpaceSize(); + intptr_t PromotedSpaceSizeOfObjects(); double total_regexp_code_generated() { return total_regexp_code_generated_; } void IncreaseTotalRegexpCodeGenerated(int size) { @@ -1805,11 +1807,13 @@ class Heap { enum SurvivalRateTrend { INCREASING, STABLE, DECREASING, FLUCTUATING }; - static const int kYoungSurvivalRateThreshold = 90; + static const int kYoungSurvivalRateHighThreshold = 90; + static const int kYoungSurvivalRateLowThreshold = 10; static const int kYoungSurvivalRateAllowedDeviation = 15; int young_survivors_after_last_gc_; int high_survival_rate_period_length_; + int low_survival_rate_period_length_; double survival_rate_; SurvivalRateTrend previous_survival_rate_trend_; SurvivalRateTrend survival_rate_trend_; @@ -1842,18 +1846,28 @@ class Heap { } } + bool IsStableOrDecreasingSurvivalTrend() { + switch (survival_rate_trend()) { + case STABLE: + case DECREASING: + return true; + default: + return false; + } + } + bool IsIncreasingSurvivalTrend() { return survival_rate_trend() == INCREASING; } - bool IsDecreasingSurvivalTrend() { - return survival_rate_trend() == DECREASING; - } - bool IsHighSurvivalRate() { return high_survival_rate_period_length_ > 0; } + bool IsLowSurvivalRate() { + return low_survival_rate_period_length_ > 0; + } + void SelectScavengingVisitorsTable(); void StartIdleRound() {