Fix responsiveness of high promotion mode heuristics.

This changes the heuristics for the high promotion mode to be checked
on all GCs (including scavenges), so that changes in the applications
behavior are recognized earlier. It also fixes miscalculations in the
survival counter and rate which caused heuristics to fail completely.

R=vegorov@chromium.org
BUG=v8:1899

Review URL: https://chromiumcodereview.appspot.com/9196003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10500 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 09ff5c4c
...@@ -695,12 +695,18 @@ void Heap::UpdateSurvivalRateTrend(int start_new_space_size) { ...@@ -695,12 +695,18 @@ void Heap::UpdateSurvivalRateTrend(int start_new_space_size) {
(static_cast<double>(young_survivors_after_last_gc_) * 100) / (static_cast<double>(young_survivors_after_last_gc_) * 100) /
start_new_space_size; start_new_space_size;
if (survival_rate > kYoungSurvivalRateThreshold) { if (survival_rate > kYoungSurvivalRateHighThreshold) {
high_survival_rate_period_length_++; high_survival_rate_period_length_++;
} else { } else {
high_survival_rate_period_length_ = 0; 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; double survival_rate_diff = survival_rate_ - survival_rate;
if (survival_rate_diff > kYoungSurvivalRateAllowedDeviation) { if (survival_rate_diff > kYoungSurvivalRateAllowedDeviation) {
...@@ -760,32 +766,6 @@ bool Heap::PerformGarbageCollection(GarbageCollector collector, ...@@ -760,32 +766,6 @@ bool Heap::PerformGarbageCollection(GarbageCollector collector,
UpdateSurvivalRateTrend(start_new_space_size); 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(); size_of_old_gen_at_last_old_space_gc_ = PromotedSpaceSize();
if (high_survival_rate_during_scavenges && if (high_survival_rate_during_scavenges &&
...@@ -815,6 +795,32 @@ bool Heap::PerformGarbageCollection(GarbageCollector collector, ...@@ -815,6 +795,32 @@ bool Heap::PerformGarbageCollection(GarbageCollector collector,
UpdateSurvivalRateTrend(start_new_space_size); 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_ && if (new_space_high_promotion_mode_active_ &&
new_space_.Capacity() > new_space_.InitialCapacity()) { new_space_.Capacity() > new_space_.InitialCapacity()) {
new_space_.Shrink(); new_space_.Shrink();
...@@ -1099,7 +1105,7 @@ void Heap::Scavenge() { ...@@ -1099,7 +1105,7 @@ void Heap::Scavenge() {
isolate_->descriptor_lookup_cache()->Clear(); isolate_->descriptor_lookup_cache()->Clear();
// Used for updating survived_since_last_expansion_ at function end. // Used for updating survived_since_last_expansion_ at function end.
intptr_t survived_watermark = PromotedSpaceSize(); intptr_t survived_watermark = PromotedSpaceSizeOfObjects();
CheckNewSpaceExpansionCriteria(); CheckNewSpaceExpansionCriteria();
...@@ -1191,7 +1197,7 @@ void Heap::Scavenge() { ...@@ -1191,7 +1197,7 @@ void Heap::Scavenge() {
// Update how much has survived scavenge. // Update how much has survived scavenge.
IncrementYoungSurvivorsCounter(static_cast<int>( IncrementYoungSurvivorsCounter(static_cast<int>(
(PromotedSpaceSize() - survived_watermark) + new_space_.Size())); (PromotedSpaceSizeOfObjects() - survived_watermark) + new_space_.Size()));
LOG(isolate_, ResourceEvent("scavenge", "end")); LOG(isolate_, ResourceEvent("scavenge", "end"));
...@@ -5422,6 +5428,16 @@ intptr_t Heap::PromotedSpaceSize() { ...@@ -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() { int Heap::PromotedExternalMemorySize() {
if (amount_of_external_allocated_memory_ if (amount_of_external_allocated_memory_
<= amount_of_external_allocated_memory_at_last_global_gc_) return 0; <= amount_of_external_allocated_memory_at_last_global_gc_) return 0;
......
...@@ -1382,6 +1382,7 @@ class Heap { ...@@ -1382,6 +1382,7 @@ class Heap {
void CheckNewSpaceExpansionCriteria(); void CheckNewSpaceExpansionCriteria();
inline void IncrementYoungSurvivorsCounter(int survived) { inline void IncrementYoungSurvivorsCounter(int survived) {
ASSERT(survived >= 0);
young_survivors_after_last_gc_ = survived; young_survivors_after_last_gc_ = survived;
survived_since_last_expansion_ += survived; survived_since_last_expansion_ += survived;
} }
...@@ -1431,6 +1432,7 @@ class Heap { ...@@ -1431,6 +1432,7 @@ class Heap {
// Returns the size of objects residing in non new spaces. // Returns the size of objects residing in non new spaces.
intptr_t PromotedSpaceSize(); intptr_t PromotedSpaceSize();
intptr_t PromotedSpaceSizeOfObjects();
double total_regexp_code_generated() { return total_regexp_code_generated_; } double total_regexp_code_generated() { return total_regexp_code_generated_; }
void IncreaseTotalRegexpCodeGenerated(int size) { void IncreaseTotalRegexpCodeGenerated(int size) {
...@@ -1805,11 +1807,13 @@ class Heap { ...@@ -1805,11 +1807,13 @@ class Heap {
enum SurvivalRateTrend { INCREASING, STABLE, DECREASING, FLUCTUATING }; 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; static const int kYoungSurvivalRateAllowedDeviation = 15;
int young_survivors_after_last_gc_; int young_survivors_after_last_gc_;
int high_survival_rate_period_length_; int high_survival_rate_period_length_;
int low_survival_rate_period_length_;
double survival_rate_; double survival_rate_;
SurvivalRateTrend previous_survival_rate_trend_; SurvivalRateTrend previous_survival_rate_trend_;
SurvivalRateTrend survival_rate_trend_; SurvivalRateTrend survival_rate_trend_;
...@@ -1842,18 +1846,28 @@ class Heap { ...@@ -1842,18 +1846,28 @@ class Heap {
} }
} }
bool IsIncreasingSurvivalTrend() { bool IsStableOrDecreasingSurvivalTrend() {
return survival_rate_trend() == INCREASING; switch (survival_rate_trend()) {
case STABLE:
case DECREASING:
return true;
default:
return false;
}
} }
bool IsDecreasingSurvivalTrend() { bool IsIncreasingSurvivalTrend() {
return survival_rate_trend() == DECREASING; return survival_rate_trend() == INCREASING;
} }
bool IsHighSurvivalRate() { bool IsHighSurvivalRate() {
return high_survival_rate_period_length_ > 0; return high_survival_rate_period_length_ > 0;
} }
bool IsLowSurvivalRate() {
return low_survival_rate_period_length_ > 0;
}
void SelectScavengingVisitorsTable(); void SelectScavengingVisitorsTable();
void StartIdleRound() { void StartIdleRound() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment