Commit d623c25a authored by Rodrigo Bruno's avatar Rodrigo Bruno Committed by Commit Bot

[heap] Refactoring HeapController. Created new ExternalMemoryController.

This CL introduces a new MemoryController that will be used to control
the size of external memory (array buffers and external string for now).

Bug: chromium:845409
Change-Id: I119506ce0243ac33cec2b783b888b53ee11225a9
Reviewed-on: https://chromium-review.googlesource.com/1156393
Commit-Queue: Rodrigo Bruno <rfbpb@google.com>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54854}
parent cc67e696
......@@ -52,48 +52,49 @@ const double HeapController::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 HeapController::HeapGrowingFactor(double gc_speed, double mutator_speed,
double max_factor) {
DCHECK_LE(kMinHeapGrowingFactor, max_factor);
DCHECK_GE(kMaxHeapGrowingFactor, max_factor);
double MemoryController::GrowingFactor(double min_growing_factor,
double max_growing_factor,
double target_mutator_utilization,
double gc_speed, double mutator_speed,
double max_factor) {
DCHECK_LE(min_growing_factor, max_factor);
DCHECK_GE(max_growing_factor, max_factor);
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;
const double a = speed_ratio * (1 - target_mutator_utilization);
const double b = speed_ratio * (1 - target_mutator_utilization) -
target_mutator_utilization;
// 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);
factor = Max(factor, min_growing_factor);
return factor;
}
double HeapController::MaxHeapGrowingFactor(size_t max_old_generation_size) {
double MemoryController::MaxGrowingFactor(size_t curr_max_size, size_t min_size,
size_t max_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));
size_t max_size_in_mb = curr_max_size / MB;
max_size_in_mb = Max(max_size_in_mb, static_cast<size_t>(min_size));
// 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) {
if (max_size_in_mb >= max_size) {
return high_factor;
}
DCHECK_GE(max_old_generation_size_in_mb, kMinOldGenerationSize);
DCHECK_LT(max_old_generation_size_in_mb, kMaxOldGenerationSize);
DCHECK_GE(max_size_in_mb, min_size);
DCHECK_LT(max_size_in_mb, max_size);
// On smaller devices we linearly scale the factor: (X-A)/(B-A)*(D-C)+C
double factor = (max_old_generation_size_in_mb - kMinOldGenerationSize) *
double factor = (max_size_in_mb - min_size) *
(max_small_factor - min_small_factor) /
(kMaxOldGenerationSize - kMinOldGenerationSize) +
(max_size - min_size) +
min_small_factor;
return factor;
}
......@@ -102,8 +103,11 @@ size_t HeapController::CalculateOldGenerationAllocationLimit(
size_t old_gen_size, size_t max_old_generation_size, double gc_speed,
double mutator_speed, size_t new_space_capacity,
Heap::HeapGrowingMode growing_mode) {
double max_factor = MaxHeapGrowingFactor(max_old_generation_size);
double factor = HeapGrowingFactor(gc_speed, mutator_speed, max_factor);
double max_factor = MaxGrowingFactor(
max_old_generation_size, kMinOldGenerationSize, kMaxOldGenerationSize);
double factor = GrowingFactor(kMinHeapGrowingFactor, kMaxHeapGrowingFactor,
kTargetMutatorUtilization, gc_speed,
mutator_speed, max_factor);
if (FLAG_trace_gc_verbose) {
heap_->isolate()->PrintWithTimestamp(
......
......@@ -13,7 +13,22 @@
namespace v8 {
namespace internal {
class HeapController {
class MemoryController {
protected:
V8_EXPORT_PRIVATE static double GrowingFactor(
double min_growing_factor, double max_growing_factor,
double target_mutator_utilization, double gc_speed, double mutator_speed,
double max_factor);
V8_EXPORT_PRIVATE static double MaxGrowingFactor(size_t curr_max_size,
size_t min_size,
size_t max_size);
FRIEND_TEST(HeapController, HeapGrowingFactor);
FRIEND_TEST(HeapController, MaxHeapGrowingFactor);
FRIEND_TEST(HeapControllerTest, OldGenerationAllocationLimit);
};
class HeapController : public MemoryController {
public:
explicit HeapController(Heap* heap) : heap_(heap) {}
......@@ -38,13 +53,7 @@ class HeapController {
V8_EXPORT_PRIVATE static const double kMinHeapGrowingFactor;
V8_EXPORT_PRIVATE static const double kMaxHeapGrowingFactor;
V8_EXPORT_PRIVATE static const double kConservativeHeapGrowingFactor;
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 max_factor);
static const double kTargetMutatorUtilization;
V8_EXPORT_PRIVATE static const double kTargetMutatorUtilization;
Heap* heap_;
};
......
......@@ -33,32 +33,52 @@ void CheckEqualRounded(double expected, double actual) {
}
TEST(HeapController, HeapGrowingFactor) {
CheckEqualRounded(HeapController::kMaxHeapGrowingFactor,
HeapController::HeapGrowingFactor(34, 1, 4.0));
CheckEqualRounded(3.553, HeapController::HeapGrowingFactor(45, 1, 4.0));
CheckEqualRounded(2.830, HeapController::HeapGrowingFactor(50, 1, 4.0));
CheckEqualRounded(1.478, HeapController::HeapGrowingFactor(100, 1, 4.0));
CheckEqualRounded(1.193, HeapController::HeapGrowingFactor(200, 1, 4.0));
CheckEqualRounded(1.121, HeapController::HeapGrowingFactor(300, 1, 4.0));
CheckEqualRounded(HeapController::HeapGrowingFactor(300, 1, 4.0),
HeapController::HeapGrowingFactor(600, 2, 4.0));
CheckEqualRounded(HeapController::kMinHeapGrowingFactor,
HeapController::HeapGrowingFactor(400, 1, 4.0));
double min_factor = HeapController::kMinHeapGrowingFactor;
double max_factor = HeapController::kMaxHeapGrowingFactor;
double target_mu = HeapController::kTargetMutatorUtilization;
CheckEqualRounded(max_factor,
MemoryController::GrowingFactor(min_factor, max_factor,
target_mu, 34, 1, 4.0));
CheckEqualRounded(3.553, MemoryController::GrowingFactor(
min_factor, max_factor, target_mu, 45, 1, 4.0));
CheckEqualRounded(2.830, MemoryController::GrowingFactor(
min_factor, max_factor, target_mu, 50, 1, 4.0));
CheckEqualRounded(1.478, MemoryController::GrowingFactor(
min_factor, max_factor, target_mu, 100, 1, 4.0));
CheckEqualRounded(1.193, MemoryController::GrowingFactor(
min_factor, max_factor, target_mu, 200, 1, 4.0));
CheckEqualRounded(1.121, MemoryController::GrowingFactor(
min_factor, max_factor, target_mu, 300, 1, 4.0));
CheckEqualRounded(MemoryController::GrowingFactor(min_factor, max_factor,
target_mu, 300, 1, 4.0),
MemoryController::GrowingFactor(min_factor, max_factor,
target_mu, 600, 2, 4.0));
CheckEqualRounded(min_factor,
MemoryController::GrowingFactor(min_factor, max_factor,
target_mu, 400, 1, 4.0));
}
TEST(HeapController, MaxHeapGrowingFactor) {
CheckEqualRounded(1.3, HeapController::MaxHeapGrowingFactor(
HeapController::kMinOldGenerationSize * MB));
CheckEqualRounded(1.600, HeapController::MaxHeapGrowingFactor(
HeapController::kMaxOldGenerationSize / 2 * MB));
CheckEqualRounded(1.999, HeapController::MaxHeapGrowingFactor(
CheckEqualRounded(1.3, MemoryController::MaxGrowingFactor(
HeapController::kMinOldGenerationSize * MB,
HeapController::kMinOldGenerationSize,
HeapController::kMaxOldGenerationSize));
CheckEqualRounded(1.600, MemoryController::MaxGrowingFactor(
HeapController::kMaxOldGenerationSize / 2 * MB,
HeapController::kMinOldGenerationSize,
HeapController::kMaxOldGenerationSize));
CheckEqualRounded(1.999, MemoryController::MaxGrowingFactor(
(HeapController::kMaxOldGenerationSize -
Heap::kPointerMultiplier) *
MB));
MB,
HeapController::kMinOldGenerationSize,
HeapController::kMaxOldGenerationSize));
CheckEqualRounded(
4.0,
HeapController::MaxHeapGrowingFactor(
static_cast<size_t>(HeapController::kMaxOldGenerationSize) * MB));
4.0, MemoryController::MaxGrowingFactor(
static_cast<size_t>(HeapController::kMaxOldGenerationSize) * MB,
HeapController::kMinOldGenerationSize,
HeapController::kMaxOldGenerationSize));
}
TEST_F(HeapControllerTest, OldGenerationAllocationLimit) {
......@@ -69,10 +89,14 @@ TEST_F(HeapControllerTest, OldGenerationAllocationLimit) {
double mutator_speed = 1;
size_t new_space_capacity = 16 * MB;
double max_factor =
HeapController::MaxHeapGrowingFactor(max_old_generation_size);
double max_factor = MemoryController::MaxGrowingFactor(
max_old_generation_size, HeapController::kMinOldGenerationSize,
HeapController::kMaxOldGenerationSize);
double factor =
HeapController::HeapGrowingFactor(gc_speed, mutator_speed, max_factor);
MemoryController::GrowingFactor(HeapController::kMinHeapGrowingFactor,
HeapController::kMaxHeapGrowingFactor,
HeapController::kTargetMutatorUtilization,
gc_speed, mutator_speed, max_factor);
EXPECT_EQ(static_cast<size_t>(old_gen_size * factor + new_space_capacity),
heap->heap_controller()->CalculateOldGenerationAllocationLimit(
......
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