[heap] Simplify and linearly scale ResourceConstraints::ConfigureDefaults.

Perf Sheriffs: This CL may change performance on various benchmarks.

BUG=chromium:716032

Review-Url: https://codereview.chromium.org/2895473003
Cr-Commit-Position: refs/heads/master@{#45495}
This commit is contained in:
hpayer 2017-05-23 10:00:57 -07:00 committed by Commit bot
parent 611ec69d85
commit d37dd4a66e
5 changed files with 66 additions and 50 deletions

View File

@ -874,38 +874,11 @@ ResourceConstraints::ResourceConstraints()
void ResourceConstraints::ConfigureDefaults(uint64_t physical_memory,
uint64_t virtual_memory_limit) {
#if V8_OS_ANDROID
// Android has higher physical memory requirements before raising the maximum
// heap size limits since it has no swap space.
const uint64_t low_limit = 512ul * i::MB;
const uint64_t medium_limit = 1ul * i::GB;
const uint64_t high_limit = 2ul * i::GB;
#else
const uint64_t low_limit = 512ul * i::MB;
const uint64_t medium_limit = 768ul * i::MB;
const uint64_t high_limit = 1ul * i::GB;
#endif
if (physical_memory <= low_limit) {
set_max_semi_space_size(i::Heap::kMaxSemiSpaceSizeLowMemoryDevice);
set_max_old_space_size(i::Heap::kMaxOldSpaceSizeLowMemoryDevice);
set_max_zone_pool_size(i::AccountingAllocator::kMaxPoolSizeLowMemoryDevice);
} else if (physical_memory <= medium_limit) {
set_max_semi_space_size(i::Heap::kMaxSemiSpaceSizeMediumMemoryDevice);
set_max_old_space_size(i::Heap::kMaxOldSpaceSizeMediumMemoryDevice);
set_max_zone_pool_size(
i::AccountingAllocator::kMaxPoolSizeMediumMemoryDevice);
} else if (physical_memory <= high_limit) {
set_max_semi_space_size(i::Heap::kMaxSemiSpaceSizeHighMemoryDevice);
set_max_old_space_size(i::Heap::kMaxOldSpaceSizeHighMemoryDevice);
set_max_zone_pool_size(
i::AccountingAllocator::kMaxPoolSizeHighMemoryDevice);
} else {
set_max_semi_space_size(i::Heap::kMaxSemiSpaceSizeHugeMemoryDevice);
set_max_old_space_size(i::Heap::kMaxOldSpaceSizeHugeMemoryDevice);
set_max_zone_pool_size(
i::AccountingAllocator::kMaxPoolSizeHugeMemoryDevice);
}
set_max_semi_space_size(
static_cast<int>(i::Heap::ComputeMaxSemiSpaceSize(physical_memory)));
set_max_old_space_size(
static_cast<int>(i::Heap::ComputeMaxOldGenerationSize(physical_memory)));
set_max_zone_pool_size(i::AccountingAllocator::kMaxPoolSize);
if (virtual_memory_limit > 0 && i::kRequiresCodeRange) {
// Reserve no more than 1/8 of the memory for the code range, but at most
@ -916,7 +889,6 @@ void ResourceConstraints::ConfigureDefaults(uint64_t physical_memory,
}
}
void SetResourceConstraints(i::Isolate* isolate,
const ResourceConstraints& constraints) {
int semi_space_size = constraints.max_semi_space_size();

View File

@ -620,18 +620,13 @@ class Heap {
#endif
// The new space size has to be a power of 2. Sizes are in MB.
static const int kMaxSemiSpaceSizeLowMemoryDevice = 1 * kPointerMultiplier;
static const int kMaxSemiSpaceSizeMediumMemoryDevice = 4 * kPointerMultiplier;
static const int kMaxSemiSpaceSizeHighMemoryDevice = 8 * kPointerMultiplier;
static const int kMaxSemiSpaceSizeHugeMemoryDevice = 8 * kPointerMultiplier;
static const int kMinSemiSpaceSize = 1 * kPointerMultiplier;
static const int kMaxSemiSpaceSize = 8 * kPointerMultiplier;
// The old space size has to be a multiple of Page::kPageSize.
// Sizes are in MB.
static const int kMaxOldSpaceSizeLowMemoryDevice = 128 * kPointerMultiplier;
static const int kMaxOldSpaceSizeMediumMemoryDevice =
256 * kPointerMultiplier;
static const int kMaxOldSpaceSizeHighMemoryDevice = 512 * kPointerMultiplier;
static const int kMaxOldSpaceSizeHugeMemoryDevice = 1024 * kPointerMultiplier;
static const int kMinOldSpaceSize = 128 * kPointerMultiplier;
static const int kMaxOldSpaceSize = 1024 * kPointerMultiplier;
static const int kTraceRingBufferSize = 512;
static const int kStacktraceBufferSize = 512;
@ -955,10 +950,12 @@ 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;
}
@ -1349,6 +1346,27 @@ class Heap {
size_t InitialSemiSpaceSize() { return initial_semispace_size_; }
size_t MaxOldGenerationSize() { return max_old_generation_size_; }
static size_t ComputeMaxOldGenerationSize(uint64_t physical_memory) {
const int old_space_physical_memory_factor = 4;
int computed_size =
static_cast<int>(physical_memory / i::MB /
old_space_physical_memory_factor * kPointerMultiplier);
return Max(Min(computed_size, kMaxOldSpaceSize), kMinOldSpaceSize);
}
static size_t ComputeMaxSemiSpaceSize(uint64_t physical_memory) {
const uint64_t min_physical_memory = 512 * MB;
const uint64_t max_physical_memory = 2 * static_cast<uint64_t>(GB);
uint64_t capped_physical_memory =
Max(Min(physical_memory, max_physical_memory), min_physical_memory);
// linearly scale max semi-space size: (X-A)/(B-A)*(D-C)+C
return static_cast<int>(((capped_physical_memory - min_physical_memory) *
(kMaxSemiSpaceSize - kMinSemiSpaceSize)) /
(max_physical_memory - min_physical_memory) +
kMinSemiSpaceSize);
}
// Returns the capacity of the heap in bytes w/o growing. Heap grows when
// more spaces are needed until it reaches the limit.
size_t Capacity();

View File

@ -20,10 +20,7 @@ namespace internal {
class V8_EXPORT_PRIVATE AccountingAllocator {
public:
static const size_t kMaxPoolSizeLowMemoryDevice = 8ul * KB;
static const size_t kMaxPoolSizeMediumMemoryDevice = 8ul * KB;
static const size_t kMaxPoolSizeHighMemoryDevice = 8ul * KB;
static const size_t kMaxPoolSizeHugeMemoryDevice = 8ul * KB;
static const size_t kMaxPoolSize = 8ul * KB;
AccountingAllocator();
virtual ~AccountingAllocator();

View File

@ -45,5 +45,37 @@ TEST(Heap, HeapGrowingFactor) {
Heap::HeapGrowingFactor(400, 1));
}
TEST(Heap, SemiSpaceSize) {
uint64_t configurations[][2] = {
{0, 1 * i::Heap::kPointerMultiplier},
{512 * i::MB, 1 * i::Heap::kPointerMultiplier},
{1 * i::GB, 3 * i::Heap::kPointerMultiplier},
{2 * static_cast<uint64_t>(i::GB), i::Heap::kMaxSemiSpaceSize},
{4 * static_cast<uint64_t>(i::GB), i::Heap::kMaxSemiSpaceSize},
{8 * static_cast<uint64_t>(i::GB), i::Heap::kMaxSemiSpaceSize}};
for (auto configuration : configurations) {
ASSERT_EQ(configuration[1],
static_cast<uint64_t>(
i::Heap::ComputeMaxSemiSpaceSize(configuration[0])));
}
}
TEST(Heap, OldGenerationSize) {
uint64_t configurations[][2] = {
{0, i::Heap::kMinOldSpaceSize},
{512, i::Heap::kMinOldSpaceSize},
{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}};
for (auto configuration : configurations) {
ASSERT_EQ(configuration[1],
static_cast<uint64_t>(
i::Heap::ComputeMaxOldGenerationSize(configuration[0])));
}
}
} // namespace internal
} // namespace v8

View File

@ -11,10 +11,7 @@ namespace internal {
TEST(Zone, SegmentPoolConstraints) {
size_t sizes[]{
0, // Corner case
AccountingAllocator::kMaxPoolSizeLowMemoryDevice,
AccountingAllocator::kMaxPoolSizeMediumMemoryDevice,
AccountingAllocator::kMaxPoolSizeHighMemoryDevice,
AccountingAllocator::kMaxPoolSizeHugeMemoryDevice,
AccountingAllocator::kMaxPoolSize,
GB // Something really large
};