Chromium Code Reviews| Index: src/heap/heap.cc |
| diff --git a/src/heap/heap.cc b/src/heap/heap.cc |
| index f2783cf48297e0c26e35cb2169153e008e02e301..01d05e3857be5467987ce81781bbb97c857ebc38 100644 |
| --- a/src/heap/heap.cc |
| +++ b/src/heap/heap.cc |
| @@ -1219,7 +1219,9 @@ bool Heap::PerformGarbageCollection( |
| old_gen_exhausted_ = false; |
| old_generation_size_configured_ = true; |
| // This should be updated before PostGarbageCollectionProcessing, which can |
| - // cause another GC. |
| + // cause another GC. Take into account the objects promoted during GC. |
| + old_generation_allocation_counter_ += |
| + static_cast<size_t>(promoted_objects_size_); |
| old_generation_size_at_last_gc_ = PromotedSpaceSizeOfObjects(); |
| } else { |
| Scavenge(); |
| @@ -1261,9 +1263,12 @@ bool Heap::PerformGarbageCollection( |
| // Register the amount of external allocated memory. |
| amount_of_external_allocated_memory_at_last_global_gc_ = |
| amount_of_external_allocated_memory_; |
| - SetOldGenerationAllocationLimit( |
| - PromotedSpaceSizeOfObjects(), |
| - tracer()->CurrentAllocationThroughputInBytesPerMillisecond()); |
| + double gc_speed = tracer()->CombinedMarkCompactSpeedInBytesPerMillisecond(); |
| + double mutator_speed = static_cast<double>( |
| + tracer() |
| + ->CurrentOldGenerationAllocationThroughputInBytesPerMillisecond()); |
| + intptr_t old_gen_size = PromotedSpaceSizeOfObjects(); |
| + SetOldGenerationAllocationLimit(old_gen_size, gc_speed, mutator_speed); |
| } |
| { |
| @@ -5286,6 +5291,48 @@ int64_t Heap::PromotedExternalMemorySize() { |
| } |
| +const double Heap::kMinHeapGrowingFactor = 1.1; |
| +const double Heap::kMaxHeapGrowingFactor = 4.0; |
| +const double Heap::kMaxHeapGrowingFactorMemoryConstrained = 2.0; |
| +const double Heap::kMaxHeapGrowingFactorIdle = 1.5; |
| +const double Heap::kTargetMutatorUtilization = 0.97; |
| + |
| + |
| +// Given GC speed in bytes per ms, the allocation throughput in bytes per ms |
| +// (mutator speed), this functions returns the heap growing factor that will |
| +// achive the kTargetMutatorUtilisation if the GC speed and the mutator speed |
| +// remain the same until the next GC. For details and explanation see |
| +// https://goo.gl/LLGvBs. |
|
Hannes Payer (out of office)
2015/06/11 01:33:57
Instead of posting a link, can we add the necessar
ulan
2015/06/11 08:49:37
Done.
|
| +double Heap::HeapGrowingFactor(double gc_speed, double mutator_speed) { |
| + double max_factor = kMaxHeapGrowingFactor; |
| + // We set the old generation growing factor to 2 to grow the heap slower on |
| + // memory-constrained devices. |
| + if (max_old_generation_size_ <= kMaxOldSpaceSizeMediumMemoryDevice) { |
|
Hannes Payer (out of office)
2015/06/11 01:33:57
If we would not access max_old_generation_size_, t
ulan
2015/06/11 08:49:37
Done. The first function to be unit-tested in Heap
|
| + max_factor = kMaxHeapGrowingFactorMemoryConstrained; |
| + } |
| + |
| + if (gc_speed == 0 || mutator_speed == 0) return max_factor; |
| + |
| + const double speed_ratio = gc_speed / mutator_speed; |
| + const double mu = kTargetMutatorUtilization; |
| + |
| + const double a = speed_ratio * (1 - mu); |
| + const double b = speed_ratio * (1 - mu) - mu; |
| + |
| + // The factor is a / b, but we need to check for small b first. |
| + double factor = (a < b * max_factor) ? a / b : max_factor; |
| + factor = Min(factor, max_factor); |
| + factor = Max(factor, kMinHeapGrowingFactor); |
| + if (FLAG_trace_gc_verbose) { |
| + PrintIsolate(isolate_, |
| + "Heap growing factor %.1f based on mu=%.3f, speed_ratio=%.f " |
| + "(gc=%.f, mutator=%.f)\n", |
| + factor, mu, speed_ratio, gc_speed, mutator_speed); |
| + } |
| + return factor; |
| +} |
| + |
| + |
| intptr_t Heap::CalculateOldGenerationAllocationLimit(double factor, |
| intptr_t old_gen_size) { |
| CHECK(factor > 1.0); |
| @@ -5298,52 +5345,20 @@ intptr_t Heap::CalculateOldGenerationAllocationLimit(double factor, |
| } |
| -void Heap::SetOldGenerationAllocationLimit( |
| - intptr_t old_gen_size, size_t current_allocation_throughput) { |
| -// Allocation throughput on Android devices is typically lower than on |
| -// non-mobile devices. |
| -#if V8_OS_ANDROID |
| - const size_t kHighThroughput = 2500; |
| - const size_t kLowThroughput = 250; |
| -#else |
| - const size_t kHighThroughput = 10000; |
| - const size_t kLowThroughput = 1000; |
| -#endif |
| - const double min_scaling_factor = 1.1; |
| - const double max_scaling_factor = 1.5; |
| - double max_factor = 4; |
| - const double idle_max_factor = 1.5; |
| - // We set the old generation growing factor to 2 to grow the heap slower on |
| - // memory-constrained devices. |
| - if (max_old_generation_size_ <= kMaxOldSpaceSizeMediumMemoryDevice) { |
| - max_factor = 2; |
| - } |
| - |
| - double factor; |
| - double idle_factor; |
| - if (current_allocation_throughput == 0 || |
| - current_allocation_throughput >= kHighThroughput) { |
| - factor = max_factor; |
| - } else if (current_allocation_throughput <= kLowThroughput) { |
| - factor = min_scaling_factor; |
| - } else { |
| - // Compute factor using linear interpolation between points |
| - // (kHighThroughput, max_scaling_factor) and (kLowThroughput, min_factor). |
| - factor = min_scaling_factor + |
| - (current_allocation_throughput - kLowThroughput) * |
| - (max_scaling_factor - min_scaling_factor) / |
| - (kHighThroughput - kLowThroughput); |
| - } |
| +void Heap::SetOldGenerationAllocationLimit(intptr_t old_gen_size, |
| + double gc_speed, |
| + double mutator_speed) { |
| + double factor = HeapGrowingFactor(gc_speed, mutator_speed); |
| if (FLAG_stress_compaction || |
| mark_compact_collector()->reduce_memory_footprint_) { |
| - factor = min_scaling_factor; |
| + factor = kMinHeapGrowingFactor; |
| } |
| // TODO(hpayer): Investigate if idle_old_generation_allocation_limit_ is still |
| // needed after taking the allocation rate for the old generation limit into |
| // account. |
| - idle_factor = Min(factor, idle_max_factor); |
| + double idle_factor = Min(factor, kMaxHeapGrowingFactorIdle); |
| old_generation_allocation_limit_ = |
| CalculateOldGenerationAllocationLimit(factor, old_gen_size); |