Commit 07b7d720 authored by hpayer's avatar hpayer Committed by Commit Bot

[heap] Scale max heap growing factor.

BUG=chromium:716032

Review-Url: https://codereview.chromium.org/2919023003
Cr-Commit-Position: refs/heads/master@{#45850}
parent f555a692
......@@ -4182,7 +4182,7 @@ bool Heap::HasHighFragmentation(size_t used, size_t committed) {
bool Heap::ShouldOptimizeForMemoryUsage() {
return FLAG_optimize_for_size || isolate()->IsIsolateInBackground() ||
HighMemoryPressure() || IsLowMemoryDevice();
HighMemoryPressure();
}
void Heap::ActivateMemoryReducerIfNeeded() {
......@@ -5422,8 +5422,11 @@ const double Heap::kTargetMutatorUtilization = 0.97;
// F * (1 - MU / (R * (1 - MU))) = 1
// F * (R * (1 - MU) - MU) / (R * (1 - MU)) = 1
// F = R * (1 - MU) / (R * (1 - MU) - MU)
double Heap::HeapGrowingFactor(double gc_speed, double mutator_speed) {
if (gc_speed == 0 || mutator_speed == 0) return kMaxHeapGrowingFactor;
double Heap::HeapGrowingFactor(double gc_speed, double mutator_speed,
double max_factor) {
DCHECK(max_factor >= kMinHeapGrowingFactor);
DCHECK(max_factor <= kMaxHeapGrowingFactor);
if (gc_speed == 0 || mutator_speed == 0) return max_factor;
const double speed_ratio = gc_speed / mutator_speed;
const double mu = kTargetMutatorUtilization;
......@@ -5432,13 +5435,39 @@ double Heap::HeapGrowingFactor(double gc_speed, double mutator_speed) {
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 * kMaxHeapGrowingFactor) ? a / b : kMaxHeapGrowingFactor;
factor = Min(factor, kMaxHeapGrowingFactor);
double factor = (a < b * max_factor) ? a / b : max_factor;
factor = Min(factor, max_factor);
factor = Max(factor, kMinHeapGrowingFactor);
return factor;
}
double Heap::MaxHeapGrowingFactor(size_t max_old_generation_size) {
const double min_small_factor = 1.3;
const double max_small_factor = 2.0;
const double high_factor = 4.0;
size_t max_old_generation_size_in_mb = max_old_generation_size / MB;
max_old_generation_size_in_mb =
Max(max_old_generation_size_in_mb,
static_cast<size_t>(kMinOldGenerationSize));
// If we are on a device with lots of memory, we allow a high heap
// growing factor.
if (max_old_generation_size_in_mb >= kMaxOldGenerationSize) {
return high_factor;
}
DCHECK_GE(max_old_generation_size_in_mb, kMinOldGenerationSize);
DCHECK_LT(max_old_generation_size_in_mb, kMaxOldGenerationSize);
// On smaller devices we linearly scale the factor: (X-A)/(B-A)*(D-C)+C
double factor = (max_old_generation_size_in_mb - kMinOldGenerationSize) *
(max_small_factor - min_small_factor) /
(kMaxOldGenerationSize - kMinOldGenerationSize) +
min_small_factor;
return factor;
}
size_t Heap::CalculateOldGenerationAllocationLimit(double factor,
size_t old_gen_size) {
CHECK(factor > 1.0);
......@@ -5463,7 +5492,8 @@ size_t Heap::MinimumAllocationLimitGrowingStep() {
void Heap::SetOldGenerationAllocationLimit(size_t old_gen_size, double gc_speed,
double mutator_speed) {
double factor = HeapGrowingFactor(gc_speed, mutator_speed);
double max_factor = MaxHeapGrowingFactor(max_old_generation_size_);
double factor = HeapGrowingFactor(gc_speed, mutator_speed, max_factor);
if (FLAG_trace_gc_verbose) {
isolate_->PrintWithTimestamp(
......@@ -5473,10 +5503,6 @@ void Heap::SetOldGenerationAllocationLimit(size_t old_gen_size, double gc_speed,
mutator_speed);
}
if (IsMemoryConstrainedDevice()) {
factor = Min(factor, kMaxHeapGrowingFactorMemoryConstrained);
}
if (memory_reducer_->ShouldGrowHeapSlowly() ||
ShouldOptimizeForMemoryUsage()) {
factor = Min(factor, kConservativeHeapGrowingFactor);
......@@ -5503,7 +5529,8 @@ void Heap::SetOldGenerationAllocationLimit(size_t old_gen_size, double gc_speed,
void Heap::DampenOldGenerationAllocationLimit(size_t old_gen_size,
double gc_speed,
double mutator_speed) {
double factor = HeapGrowingFactor(gc_speed, mutator_speed);
double max_factor = MaxHeapGrowingFactor(max_old_generation_size_);
double factor = HeapGrowingFactor(gc_speed, mutator_speed, max_factor);
size_t limit = CalculateOldGenerationAllocationLimit(factor, old_gen_size);
if (limit < old_generation_allocation_limit_) {
if (FLAG_trace_gc_verbose) {
......
......@@ -624,8 +624,8 @@ class Heap {
// The old space size has to be a multiple of Page::kPageSize.
// Sizes are in MB.
static const int kMinOldSpaceSize = 128 * kPointerMultiplier;
static const int kMaxOldSpaceSize = 1024 * kPointerMultiplier;
static const int kMinOldGenerationSize = 128 * kPointerMultiplier;
static const int kMaxOldGenerationSize = 1024 * kPointerMultiplier;
static const int kTraceRingBufferSize = 512;
static const int kStacktraceBufferSize = 512;
......@@ -716,8 +716,11 @@ class Heap {
return "Unknown collector";
}
V8_EXPORT_PRIVATE static double MaxHeapGrowingFactor(
size_t max_old_generation_size);
V8_EXPORT_PRIVATE static double HeapGrowingFactor(double gc_speed,
double mutator_speed);
double mutator_speed,
double max_factor);
// Copy block of memory from src to dst. Size of block should be aligned
// by pointer size.
......@@ -939,16 +942,6 @@ class Heap {
bool ShouldOptimizeForMemoryUsage();
bool IsLowMemoryDevice() {
const int kMaxOldSpaceSizeLowMemoryDevice = 128 * kPointerMultiplier;
return max_old_generation_size_ <= kMaxOldSpaceSizeLowMemoryDevice;
}
bool IsMemoryConstrainedDevice() {
const int kMaxOldSpaceSizeMediumMemoryDevice = 256 * kPointerMultiplier;
return max_old_generation_size_ <= kMaxOldSpaceSizeMediumMemoryDevice;
}
bool HighMemoryPressure() {
return memory_pressure_level_.Value() != MemoryPressureLevel::kNone;
}
......@@ -1349,7 +1342,8 @@ class Heap {
int computed_size =
static_cast<int>(physical_memory / i::MB /
old_space_physical_memory_factor * kPointerMultiplier);
return Max(Min(computed_size, kMaxOldSpaceSize), kMinOldSpaceSize);
return Max(Min(computed_size, kMaxOldGenerationSize),
kMinOldGenerationSize);
}
static size_t ComputeMaxSemiSpaceSize(uint64_t physical_memory) {
......
......@@ -33,16 +33,30 @@ void CheckEqualRounded(double expected, double actual) {
TEST(Heap, HeapGrowingFactor) {
CheckEqualRounded(Heap::kMaxHeapGrowingFactor,
Heap::HeapGrowingFactor(34, 1));
CheckEqualRounded(3.553, Heap::HeapGrowingFactor(45, 1));
CheckEqualRounded(2.830, Heap::HeapGrowingFactor(50, 1));
CheckEqualRounded(1.478, Heap::HeapGrowingFactor(100, 1));
CheckEqualRounded(1.193, Heap::HeapGrowingFactor(200, 1));
CheckEqualRounded(1.121, Heap::HeapGrowingFactor(300, 1));
CheckEqualRounded(Heap::HeapGrowingFactor(300, 1),
Heap::HeapGrowingFactor(600, 2));
Heap::HeapGrowingFactor(34, 1, 4.0));
CheckEqualRounded(3.553, Heap::HeapGrowingFactor(45, 1, 4.0));
CheckEqualRounded(2.830, Heap::HeapGrowingFactor(50, 1, 4.0));
CheckEqualRounded(1.478, Heap::HeapGrowingFactor(100, 1, 4.0));
CheckEqualRounded(1.193, Heap::HeapGrowingFactor(200, 1, 4.0));
CheckEqualRounded(1.121, Heap::HeapGrowingFactor(300, 1, 4.0));
CheckEqualRounded(Heap::HeapGrowingFactor(300, 1, 4.0),
Heap::HeapGrowingFactor(600, 2, 4.0));
CheckEqualRounded(Heap::kMinHeapGrowingFactor,
Heap::HeapGrowingFactor(400, 1));
Heap::HeapGrowingFactor(400, 1, 4.0));
}
TEST(Heap, MaxHeapGrowingFactor) {
CheckEqualRounded(
1.3, Heap::MaxHeapGrowingFactor(Heap::kMinOldGenerationSize * MB));
CheckEqualRounded(
1.600, Heap::MaxHeapGrowingFactor(Heap::kMaxOldGenerationSize / 2 * MB));
CheckEqualRounded(
1.999,
Heap::MaxHeapGrowingFactor(
(Heap::kMaxOldGenerationSize - Heap::kPointerMultiplier) * MB));
CheckEqualRounded(4.0,
Heap::MaxHeapGrowingFactor(
static_cast<size_t>(Heap::kMaxOldGenerationSize) * MB));
}
TEST(Heap, SemiSpaceSize) {
......@@ -63,12 +77,12 @@ TEST(Heap, SemiSpaceSize) {
TEST(Heap, OldGenerationSize) {
uint64_t configurations[][2] = {
{0, i::Heap::kMinOldSpaceSize},
{512, i::Heap::kMinOldSpaceSize},
{0, i::Heap::kMinOldGenerationSize},
{512, i::Heap::kMinOldGenerationSize},
{1 * i::GB, 256 * i::Heap::kPointerMultiplier},
{2 * static_cast<uint64_t>(i::GB), 512 * i::Heap::kPointerMultiplier},
{4 * static_cast<uint64_t>(i::GB), i::Heap::kMaxOldSpaceSize},
{8 * static_cast<uint64_t>(i::GB), i::Heap::kMaxOldSpaceSize}};
{4 * static_cast<uint64_t>(i::GB), i::Heap::kMaxOldGenerationSize},
{8 * static_cast<uint64_t>(i::GB), i::Heap::kMaxOldGenerationSize}};
for (auto configuration : configurations) {
ASSERT_EQ(configuration[1],
......
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