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

Reland "[heap] Attempt to incorporate backing store counters into heap sizing...

Reland "[heap] Attempt to incorporate backing store counters into heap sizing and GC trigger stragery."

This is a reland of ba735dde

Original change's description:
> [heap] Attempt to incorporate backing store counters into heap sizing and GC trigger stragery.
> 
> Bug: chromium:845409
> Cq-Include-Trybots: luci.chromium.try:linux_chromium_rel_ng
> Change-Id: Ic62a4339110e3dd2a6b1961a246e2bee0c07c03b
> Reviewed-on: https://chromium-review.googlesource.com/1160162
> Commit-Queue: Rodrigo Bruno <rfbpb@google.com>
> Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
> Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#55128}

Bug: chromium:845409
Change-Id: Iaff177f7bebbc073460fab0ae4e5cd9e632e1921
Cq-Include-Trybots: luci.chromium.try:linux_chromium_rel_ng
Reviewed-on: https://chromium-review.googlesource.com/1177301Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Commit-Queue: Rodrigo Bruno <rfbpb@google.com>
Cr-Commit-Position: refs/heads/master@{#55454}
parent dd732b4f
......@@ -9381,7 +9381,7 @@ class Internals {
kExternalMemoryLimitOffset + kApiInt64Size;
static const int kIsolateRootsOffset = kExternalMemoryLimitOffset +
kApiInt64Size + kApiInt64Size +
kApiPointerSize + kApiPointerSize;
kApiInt64Size + kApiPointerSize;
static const int kUndefinedValueRootIndex = 4;
static const int kTheHoleValueRootIndex = 5;
static const int kNullValueRootIndex = 6;
......
......@@ -8359,7 +8359,8 @@ void Isolate::GetHeapStatistics(HeapStatistics* heap_statistics) {
heap_statistics->malloced_memory_ =
isolate->allocator()->GetCurrentMemoryUsage() +
isolate->wasm_engine()->allocator()->GetCurrentMemoryUsage();
heap_statistics->external_memory_ = isolate->heap()->external_memory();
heap_statistics->external_memory_ = isolate->heap()->external_memory() +
isolate->heap()->backing_story_bytes();
heap_statistics->peak_malloced_memory_ =
isolate->allocator()->GetMaxMemoryUsage() +
isolate->wasm_engine()->allocator()->GetMaxMemoryUsage();
......
......@@ -135,6 +135,7 @@ class ShellArrayBufferAllocator : public ArrayBufferAllocatorBase {
// ArrayBuffer allocator that never allocates over 10MB.
class MockArrayBufferAllocator : public ArrayBufferAllocatorBase {
protected:
void* Allocate(size_t length) override {
return ArrayBufferAllocatorBase::Allocate(Adjust(length));
}
......@@ -154,6 +155,37 @@ class MockArrayBufferAllocator : public ArrayBufferAllocatorBase {
}
};
class MockArrayBufferAllocatiorWithLimit : public MockArrayBufferAllocator {
public:
explicit MockArrayBufferAllocatiorWithLimit(size_t allocation_limit)
: space_left_(allocation_limit) {}
protected:
void* Allocate(size_t length) override {
if (length > space_left_) {
return nullptr;
}
space_left_ -= length;
return MockArrayBufferAllocator::Allocate(length);
}
void* AllocateUninitialized(size_t length) override {
if (length > space_left_) {
return nullptr;
}
space_left_ -= length;
return MockArrayBufferAllocator::AllocateUninitialized(length);
}
void Free(void* data, size_t length) override {
space_left_ += length;
return MockArrayBufferAllocator::Free(data, length);
}
private:
std::atomic<size_t> space_left_;
};
// Predictable v8::Platform implementation. Worker threads are disabled, idle
// tasks are disallowed, and the time reported by {MonotonicallyIncreasingTime}
// is deterministic.
......@@ -2789,6 +2821,11 @@ bool Shell::SetOptions(int argc, char* argv[]) {
strcmp(argv[i], "--no-stress-background-compile") == 0) {
options.stress_background_compile = false;
argv[i] = nullptr;
} else if (strncmp(argv[i], "--mock-arraybuffer-allocator-limit=", 35) ==
0) {
options.mock_arraybuffer_allocator = true;
options.mock_arraybuffer_allocator_limit = atoi(argv[i] + 35);
argv[i] = nullptr;
} else if (strcmp(argv[i], "--noalways-opt") == 0 ||
strcmp(argv[i], "--no-always-opt") == 0) {
// No support for stressing if we can't use --always-opt.
......@@ -3362,7 +3399,11 @@ int Shell::Main(int argc, char* argv[]) {
Isolate::CreateParams create_params;
ShellArrayBufferAllocator shell_array_buffer_allocator;
MockArrayBufferAllocator mock_arraybuffer_allocator;
if (options.mock_arraybuffer_allocator) {
MockArrayBufferAllocatiorWithLimit mock_arraybuffer_allocator_limit(
options.mock_arraybuffer_allocator_limit);
if (options.mock_arraybuffer_allocator_limit > 0) {
Shell::array_buffer_allocator = &mock_arraybuffer_allocator_limit;
} else if (options.mock_arraybuffer_allocator) {
Shell::array_buffer_allocator = &mock_arraybuffer_allocator;
} else {
Shell::array_buffer_allocator = &shell_array_buffer_allocator;
......
......@@ -369,6 +369,7 @@ class ShellOptions {
bool test_shell;
bool expected_to_throw;
bool mock_arraybuffer_allocator;
int mock_arraybuffer_allocator_limit = 0;
bool enable_inspector;
int num_isolates;
v8::ScriptCompiler::CompileOptions compile_options;
......
......@@ -48,8 +48,6 @@ class ArrayBufferCollector::FreeingTask final : public CancelableTask {
};
void ArrayBufferCollector::FreeAllocationsOnBackgroundThread() {
// TODO(wez): Remove backing-store from external memory accounting.
heap_->account_external_memory_concurrently_freed();
if (!heap_->IsTearingDown() && FLAG_concurrent_array_buffer_freeing) {
V8::GetCurrentPlatform()->CallOnWorkerThread(
base::make_unique<FreeingTask>(heap_));
......
......@@ -30,12 +30,6 @@ void ArrayBufferTracker::RegisterNew(Heap* heap, JSArrayBuffer* buffer) {
DCHECK_NOT_NULL(tracker);
tracker->Add(buffer, length);
}
// TODO(wez): Remove backing-store from external memory accounting.
// We may go over the limit of externally allocated memory here. We call the
// api function to trigger a GC in this case.
reinterpret_cast<v8::Isolate*>(heap->isolate())
->AdjustAmountOfExternalAllocatedMemory(length);
}
void ArrayBufferTracker::Unregister(Heap* heap, JSArrayBuffer* buffer) {
......@@ -49,9 +43,6 @@ void ArrayBufferTracker::Unregister(Heap* heap, JSArrayBuffer* buffer) {
DCHECK_NOT_NULL(tracker);
tracker->Remove(buffer, length);
}
// TODO(wez): Remove backing-store from external memory accounting.
heap->update_external_memory(-static_cast<intptr_t>(length));
}
Space* LocalArrayBufferTracker::space() { return page_->owner(); }
......@@ -76,10 +67,6 @@ void LocalArrayBufferTracker::Free(Callback should_free) {
if (freed_memory > 0) {
page_->DecrementExternalBackingStoreBytes(
ExternalBackingStoreType::kArrayBuffer, freed_memory);
// TODO(wez): Remove backing-store from external memory accounting.
page_->heap()->update_external_memory_concurrently_freed(
static_cast<intptr_t>(freed_memory));
}
}
......@@ -99,7 +86,6 @@ void ArrayBufferTracker::FreeDead(Page* page, MarkingState* marking_state) {
void LocalArrayBufferTracker::Add(JSArrayBuffer* buffer, size_t length) {
page_->IncrementExternalBackingStoreBytes(
ExternalBackingStoreType::kArrayBuffer, length);
auto ret = array_buffers_.insert(
{buffer,
{buffer->backing_store(), length, buffer->backing_store(),
......@@ -113,7 +99,6 @@ void LocalArrayBufferTracker::Add(JSArrayBuffer* buffer, size_t length) {
void LocalArrayBufferTracker::Remove(JSArrayBuffer* buffer, size_t length) {
page_->DecrementExternalBackingStoreBytes(
ExternalBackingStoreType::kArrayBuffer, length);
TrackingData::iterator it = array_buffers_.find(buffer);
// Check that we indeed find a key to remove.
DCHECK(it != array_buffers_.end());
......
......@@ -54,7 +54,6 @@ void LocalArrayBufferTracker::Process(Callback callback) {
tracker->Add(new_buffer, length);
}
moved_memory += it->second.length;
} else if (result == kRemoveEntry) {
const size_t length = it->second.length;
freed_memory += length;
......@@ -68,11 +67,6 @@ void LocalArrayBufferTracker::Process(Callback callback) {
UNREACHABLE();
}
}
if (moved_memory || freed_memory) {
// TODO(wez): Remove backing-store from external memory accounting.
page_->heap()->update_external_memory_concurrently_freed(
static_cast<intptr_t>(freed_memory));
}
array_buffers_.swap(kept_array_buffers);
......
......@@ -66,35 +66,10 @@ double MemoryController::GrowingFactor(double gc_speed, double mutator_speed,
return factor;
}
double MemoryController::MaxGrowingFactor(size_t curr_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_size_in_mb = curr_max_size / MB;
max_size_in_mb = Max(max_size_in_mb, kMinSize);
// If we are on a device with lots of memory, we allow a high heap
// growing factor.
if (max_size_in_mb >= kMaxSize) {
return high_factor;
}
DCHECK_GE(max_size_in_mb, kMinSize);
DCHECK_LT(max_size_in_mb, kMaxSize);
// On smaller devices we linearly scale the factor: (X-A)/(B-A)*(D-C)+C
double factor = (max_size_in_mb - kMinSize) *
(max_small_factor - min_small_factor) /
(kMaxSize - kMinSize) +
min_small_factor;
return factor;
}
size_t MemoryController::CalculateAllocationLimit(
size_t curr_size, size_t max_size, double gc_speed, double mutator_speed,
size_t new_space_capacity, Heap::HeapGrowingMode growing_mode) {
double max_factor = MaxGrowingFactor(max_size);
size_t curr_size, size_t max_size, double max_factor, double gc_speed,
double mutator_speed, size_t new_space_capacity,
Heap::HeapGrowingMode growing_mode) {
double factor = GrowingFactor(gc_speed, mutator_speed, max_factor);
if (FLAG_trace_gc_verbose) {
......@@ -125,7 +100,7 @@ size_t MemoryController::CalculateAllocationLimit(
MinimumAllocationLimitGrowingStep(growing_mode));
limit += new_space_capacity;
uint64_t halfway_to_the_max =
(static_cast<uint64_t>(curr_size) + max_size) / 2;
(static_cast<uint64_t>(curr_size) + static_cast<uint64_t>(max_size)) / 2;
size_t result = static_cast<size_t>(Min(limit, halfway_to_the_max));
if (FLAG_trace_gc_verbose) {
......@@ -147,5 +122,30 @@ size_t MemoryController::MinimumAllocationLimitGrowingStep(
: kRegularAllocationLimitGrowingStep);
}
double HeapController::MaxGrowingFactor(size_t curr_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_size_in_mb = curr_max_size / MB;
max_size_in_mb = Max(max_size_in_mb, kMinSize);
// If we are on a device with lots of memory, we allow a high heap
// growing factor.
if (max_size_in_mb >= kMaxSize) {
return high_factor;
}
DCHECK_GE(max_size_in_mb, kMinSize);
DCHECK_LT(max_size_in_mb, kMaxSize);
// On smaller devices we linearly scale the factor: (X-A)/(B-A)*(D-C)+C
double factor = (max_size_in_mb - kMinSize) *
(max_small_factor - min_small_factor) /
(kMaxSize - kMinSize) +
min_small_factor;
return factor;
}
} // namespace internal
} // namespace v8
......@@ -13,35 +13,51 @@
namespace v8 {
namespace internal {
enum AvailableAllocationSpace {
kAboveAllocationLimit,
kCloseToAllocationLimit,
kBelowAllocationLimit,
};
class V8_EXPORT_PRIVATE MemoryController {
public:
MemoryController(Heap* heap, double min_growing_factor,
double max_growing_factor,
double conservative_growing_factor,
double target_mutator_utilization, size_t min_size,
size_t max_size)
double target_mutator_utilization,
double close_to_allocation_limit_factor)
: heap_(heap),
kMinGrowingFactor(min_growing_factor),
kMaxGrowingFactor(max_growing_factor),
kConservativeGrowingFactor(conservative_growing_factor),
kTargetMutatorUtilization(target_mutator_utilization),
kMinSize(min_size),
kMaxSize(max_size) {}
kCloseToAllocationLimitFactor(close_to_allocation_limit_factor) {}
virtual ~MemoryController() {}
// Computes the allocation limit to trigger the next garbage collection.
size_t CalculateAllocationLimit(size_t curr_size, size_t max_size,
double gc_speed, double mutator_speed,
double max_factor, double gc_speed,
double mutator_speed,
size_t new_space_capacity,
Heap::HeapGrowingMode growing_mode);
// Computes the growing step when the limit increases.
size_t MinimumAllocationLimitGrowingStep(Heap::HeapGrowingMode growing_mode);
AvailableAllocationSpace CheckAllocationLimit(size_t used_memory,
size_t allocation_limit) {
if (used_memory > allocation_limit) {
return AvailableAllocationSpace::kAboveAllocationLimit;
} else if (used_memory >
(kCloseToAllocationLimitFactor * allocation_limit)) {
return AvailableAllocationSpace::kCloseToAllocationLimit;
}
return AvailableAllocationSpace::kBelowAllocationLimit;
}
protected:
double GrowingFactor(double gc_speed, double mutator_speed,
double max_factor);
double MaxGrowingFactor(size_t curr_max_size);
virtual const char* ControllerName() = 0;
Heap* const heap_;
......@@ -50,9 +66,7 @@ class V8_EXPORT_PRIVATE MemoryController {
const double kMaxGrowingFactor;
const double kConservativeGrowingFactor;
const double kTargetMutatorUtilization;
// Sizes are in MB.
const size_t kMinSize;
const size_t kMaxSize;
const double kCloseToAllocationLimitFactor;
FRIEND_TEST(HeapControllerTest, HeapGrowingFactor);
FRIEND_TEST(HeapControllerTest, MaxHeapGrowingFactor);
......@@ -60,20 +74,29 @@ class V8_EXPORT_PRIVATE MemoryController {
FRIEND_TEST(HeapControllerTest, OldGenerationAllocationLimit);
};
class HeapController : public MemoryController {
class V8_EXPORT_PRIVATE HeapController : public MemoryController {
public:
explicit HeapController(Heap* heap)
: MemoryController(heap, 1.1, 4.0, 1.3, 0.97, kMinHeapSize,
kMaxHeapSize) {}
// Sizes are in MB.
static const size_t kMinHeapSize = 128 * Heap::kPointerMultiplier;
static const size_t kMaxHeapSize = 1024 * Heap::kPointerMultiplier;
static const size_t kMinSize = 128 * Heap::kPointerMultiplier;
static const size_t kMaxSize = 1024 * Heap::kPointerMultiplier;
explicit HeapController(Heap* heap)
: MemoryController(heap, 1.1, 4.0, 1.3, 0.97, 0.75) {}
double MaxGrowingFactor(size_t curr_max_size);
protected:
const char* ControllerName() { return "HeapController"; }
};
class GlobalMemoryController : public MemoryController {
public:
explicit GlobalMemoryController(Heap* heap)
: MemoryController(heap, 1.1, 4.0, 1.3, 0.97, 0.75) {}
protected:
const char* ControllerName() { return "GlobalMemoryController"; }
};
} // namespace internal
} // namespace v8
......
This diff is collapsed.
......@@ -172,6 +172,7 @@ class GCIdleTimeAction;
class GCIdleTimeHandler;
class GCIdleTimeHeapState;
class GCTracer;
class GlobalMemoryController;
class HeapController;
class HeapObjectAllocationTracker;
class HeapObjectsFilter;
......@@ -180,6 +181,7 @@ class HistogramTimer;
class Isolate;
class LocalEmbedderHeapTracer;
class MemoryAllocator;
class MemoryController;
class MemoryReducer;
class MinorMarkCompactCollector;
class ObjectIterator;
......@@ -235,7 +237,8 @@ enum class GarbageCollectionReason {
kSamplingProfiler = 19,
kSnapshotCreator = 20,
kTesting = 21,
kExternalFinalize = 22
kExternalFinalize = 22,
kGlobalAllocationLimit = 23
// If you add new items here, then update the incremental_marking_reason,
// mark_compact_reason, and scavenge_reason counters in counters.h.
// Also update src/tools/metrics/histograms/histograms.xml in chromium.
......@@ -677,16 +680,9 @@ class Heap {
int64_t external_memory_hard_limit() { return MaxOldGenerationSize() / 2; }
int64_t external_memory() { return external_memory_; }
void update_external_memory(int64_t delta) { external_memory_ += delta; }
int64_t backing_story_bytes() const { return backing_store_bytes_; }
void update_external_memory_concurrently_freed(intptr_t freed) {
external_memory_concurrently_freed_ += freed;
}
void account_external_memory_concurrently_freed() {
external_memory_ -= external_memory_concurrently_freed_;
external_memory_concurrently_freed_ = 0;
}
void update_backing_store_bytes(int64_t amount);
void ProcessMovedExternalString(Page* old_page, Page* new_page,
ExternalString* string);
......@@ -1329,6 +1325,14 @@ class Heap {
// Excludes external memory held by those objects.
size_t OldGenerationSizeOfObjects();
// Returns the size of JS and external objects
size_t GlobalSizeOfObjects() {
size_t global_size = OldGenerationSizeOfObjects() +
static_cast<size_t>(backing_store_bytes_);
CHECK_GE(global_size, static_cast<size_t>(backing_store_bytes_));
return global_size;
}
// ===========================================================================
// Prologue/epilogue callback methods.========================================
// ===========================================================================
......@@ -1697,7 +1701,9 @@ class Heap {
// Flush the number to string cache.
void FlushNumberStringCache();
void ConfigureInitialOldGenerationSize();
size_t ConfigureInitialControllerSize(MemoryController* controller,
size_t curr_limit);
void ConfigureInitialAllocationLimits();
bool HasLowYoungGenerationAllocationRate();
bool HasLowOldGenerationAllocationRate();
......@@ -1846,6 +1852,7 @@ class Heap {
// ===========================================================================
HeapController* heap_controller() { return heap_controller_; }
GlobalMemoryController* global_controller() { return global_controller_; }
MemoryReducer* memory_reducer() { return memory_reducer_; }
// For some webpages RAIL mode does not switch from PERFORMANCE_LOAD.
......@@ -1856,6 +1863,12 @@ class Heap {
bool ShouldOptimizeForLoadTime();
void set_allocation_limits(size_t old_generation_allocation_limit,
size_t global_memory_allocation_limit) {
old_generation_allocation_limit_ = old_generation_allocation_limit;
global_memory_allocation_limit_ = global_memory_allocation_limit;
}
size_t old_generation_allocation_limit() const {
return old_generation_allocation_limit_;
}
......@@ -1970,8 +1983,8 @@ class Heap {
// Caches the amount of external memory registered at the last MC.
int64_t external_memory_at_last_mark_compact_;
// The amount of memory that has been freed concurrently.
std::atomic<intptr_t> external_memory_concurrently_freed_;
// Backing store bytes (array buffers and external strings).
std::atomic<int64_t> backing_store_bytes_;
// This can be calculated directly from a pointer to the heap; however, it is
// more expedient to get at the isolate directly from within Heap methods.
......@@ -2004,6 +2017,7 @@ class Heap {
size_t max_semi_space_size_;
size_t initial_semispace_size_;
size_t max_old_generation_size_;
size_t max_global_memory_size_;
size_t initial_max_old_generation_size_;
size_t initial_old_generation_size_;
bool old_generation_size_configured_;
......@@ -2104,6 +2118,10 @@ class Heap {
// generation and on every allocation in large object space.
size_t old_generation_allocation_limit_;
// The limit when to trigger memory pressure. This limit accounts for JS
// memory and external memory (array buffers and external strings).
size_t global_memory_allocation_limit_;
// Indicates that inline bump-pointer allocation has been globally disabled
// for all spaces. This is used to disable allocations in generated code.
bool inline_allocation_disabled_;
......@@ -2157,6 +2175,7 @@ class Heap {
StoreBuffer* store_buffer_;
HeapController* heap_controller_;
GlobalMemoryController* global_controller_;
IncrementalMarking* incremental_marking_;
ConcurrentMarking* concurrent_marking_;
......
......@@ -803,7 +803,6 @@ void MarkCompactCollector::Prepare() {
space = spaces.next()) {
space->PrepareForMarkCompact();
}
heap()->account_external_memory_concurrently_freed();
#ifdef VERIFY_HEAP
if (!was_marked_incrementally_ && FLAG_verify_heap) {
......@@ -3848,8 +3847,6 @@ void MinorMarkCompactCollector::CollectGarbage() {
RememberedSet<OLD_TO_NEW>::PreFreeEmptyBuckets(chunk);
}
});
heap()->account_external_memory_concurrently_freed();
}
void MinorMarkCompactCollector::MakeIterable(
......
......@@ -1018,11 +1018,13 @@ class Space : public Malloced {
void IncrementExternalBackingStoreBytes(ExternalBackingStoreType type,
size_t amount) {
external_backing_store_bytes_[type] += amount;
heap()->update_backing_store_bytes(static_cast<int64_t>(amount));
}
void DecrementExternalBackingStoreBytes(ExternalBackingStoreType type,
size_t amount) {
DCHECK_GE(external_backing_store_bytes_[type], amount);
external_backing_store_bytes_[type] -= amount;
heap()->update_backing_store_bytes(-static_cast<int64_t>(amount));
}
V8_EXPORT_PRIVATE void* GetRandomMmapAddr();
......
......@@ -1588,6 +1588,7 @@ HEAP_TEST(TestSizeOfObjects) {
Isolate* isolate = CcTest::i_isolate();
Heap* heap = CcTest::heap();
MarkCompactCollector* collector = heap->mark_compact_collector();
ManualGCScope manual_gc_scope;
// Get initial heap size after several full GCs, which will stabilize
// the heap size and return with sweeping finished completely.
......
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --mock-arraybuffer-allocator-limit=800000000
for (var i = 0; i < 1024; i++) {
let garbage = new ArrayBuffer(1024*1024);
}
......@@ -51,15 +51,14 @@ TEST_F(HeapControllerTest, HeapGrowingFactor) {
TEST_F(HeapControllerTest, MaxHeapGrowingFactor) {
HeapController heap_controller(i_isolate()->heap());
CheckEqualRounded(
1.3, heap_controller.MaxGrowingFactor(heap_controller.kMinSize * MB));
1.3, heap_controller.MaxGrowingFactor(HeapController::kMinSize * MB));
CheckEqualRounded(1.600, heap_controller.MaxGrowingFactor(
heap_controller.kMaxSize / 2 * MB));
HeapController::kMaxSize / 2 * MB));
CheckEqualRounded(
1.999, heap_controller.MaxGrowingFactor(
(heap_controller.kMaxSize - Heap::kPointerMultiplier) * MB));
CheckEqualRounded(4.0,
heap_controller.MaxGrowingFactor(
static_cast<size_t>(heap_controller.kMaxSize) * MB));
(HeapController::kMaxSize - Heap::kPointerMultiplier) * MB));
CheckEqualRounded(
4.0, heap_controller.MaxGrowingFactor(HeapController::kMaxSize * MB));
}
TEST_F(HeapControllerTest, OldGenerationAllocationLimit) {
......@@ -75,39 +74,43 @@ TEST_F(HeapControllerTest, OldGenerationAllocationLimit) {
double factor =
heap_controller.GrowingFactor(gc_speed, mutator_speed, max_factor);
EXPECT_EQ(static_cast<size_t>(old_gen_size * factor + new_space_capacity),
heap->heap_controller()->CalculateAllocationLimit(
old_gen_size, max_old_generation_size, gc_speed, mutator_speed,
new_space_capacity, Heap::HeapGrowingMode::kDefault));
EXPECT_EQ(
static_cast<size_t>(old_gen_size * factor + new_space_capacity),
heap->heap_controller()->CalculateAllocationLimit(
old_gen_size, max_old_generation_size, max_factor, gc_speed,
mutator_speed, new_space_capacity, Heap::HeapGrowingMode::kDefault));
factor = Min(factor, heap_controller.kConservativeGrowingFactor);
EXPECT_EQ(static_cast<size_t>(old_gen_size * factor + new_space_capacity),
heap->heap_controller()->CalculateAllocationLimit(
old_gen_size, max_old_generation_size, gc_speed, mutator_speed,
new_space_capacity, Heap::HeapGrowingMode::kSlow));
EXPECT_EQ(
static_cast<size_t>(old_gen_size * factor + new_space_capacity),
heap->heap_controller()->CalculateAllocationLimit(
old_gen_size, max_old_generation_size, max_factor, gc_speed,
mutator_speed, new_space_capacity, Heap::HeapGrowingMode::kSlow));
factor = Min(factor, heap_controller.kConservativeGrowingFactor);
EXPECT_EQ(static_cast<size_t>(old_gen_size * factor + new_space_capacity),
heap->heap_controller()->CalculateAllocationLimit(
old_gen_size, max_old_generation_size, gc_speed, mutator_speed,
new_space_capacity, Heap::HeapGrowingMode::kConservative));
old_gen_size, max_old_generation_size, max_factor, gc_speed,
mutator_speed, new_space_capacity,
Heap::HeapGrowingMode::kConservative));
factor = heap_controller.kMinGrowingFactor;
EXPECT_EQ(static_cast<size_t>(old_gen_size * factor + new_space_capacity),
heap->heap_controller()->CalculateAllocationLimit(
old_gen_size, max_old_generation_size, gc_speed, mutator_speed,
new_space_capacity, Heap::HeapGrowingMode::kMinimal));
EXPECT_EQ(
static_cast<size_t>(old_gen_size * factor + new_space_capacity),
heap->heap_controller()->CalculateAllocationLimit(
old_gen_size, max_old_generation_size, max_factor, gc_speed,
mutator_speed, new_space_capacity, Heap::HeapGrowingMode::kMinimal));
}
TEST_F(HeapControllerTest, MaxOldGenerationSize) {
HeapController heap_controller(i_isolate()->heap());
uint64_t configurations[][2] = {
{0, heap_controller.kMinSize},
{512, heap_controller.kMinSize},
{0, HeapController::kMinSize},
{512, HeapController::kMinSize},
{1 * GB, 256 * Heap::kPointerMultiplier},
{2 * static_cast<uint64_t>(GB), 512 * Heap::kPointerMultiplier},
{4 * static_cast<uint64_t>(GB), heap_controller.kMaxSize},
{8 * static_cast<uint64_t>(GB), heap_controller.kMaxSize}};
{4 * static_cast<uint64_t>(GB), HeapController::kMaxSize},
{8 * static_cast<uint64_t>(GB), HeapController::kMaxSize}};
for (auto configuration : configurations) {
ASSERT_EQ(configuration[1],
......
......@@ -294,7 +294,10 @@ local WHITELIST = {
"StateTag",
-- Ignore printing of elements transition.
"PrintElementsTransition"
"PrintElementsTransition",
-- Ignore GC reason method that returns a string (not GC trigger).
"GarbageCollectionReasonToString"
};
local function AddCause(name, cause)
......
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