Commit 4cc5520a authored by Ulan Degenbaev's avatar Ulan Degenbaev Committed by Commit Bot

[heap] Fix the guard for expanding the heap during evacuation.

Currently the size of compaction spaces is not taken into account in
the Heap::CanExpandOldGeneration predicate. This can push the heap size
over the hard limit in some cases.

This patch makes Heap::CanExpandOldGeneration stricter and also fixes
the SelectGarbageCollector to prefer Mark-Compact near the hard limit.

Bug: chromium:784077
Change-Id: I00c7295eba8794a342dd6277a45f995529054b64
Reviewed-on: https://chromium-review.googlesource.com/779265Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Commit-Queue: Ulan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49519}
parent 7d77d3d6
...@@ -245,7 +245,6 @@ size_t Heap::Capacity() { ...@@ -245,7 +245,6 @@ size_t Heap::Capacity() {
size_t Heap::OldGenerationCapacity() { size_t Heap::OldGenerationCapacity() {
if (!HasBeenSetUp()) return 0; if (!HasBeenSetUp()) return 0;
return old_space_->Capacity() + code_space_->Capacity() + return old_space_->Capacity() + code_space_->Capacity() +
map_space_->Capacity() + lo_space_->SizeOfObjects(); map_space_->Capacity() + lo_space_->SizeOfObjects();
} }
...@@ -301,6 +300,14 @@ size_t Heap::Available() { ...@@ -301,6 +300,14 @@ size_t Heap::Available() {
return total; return total;
} }
bool Heap::CanExpandOldGeneration(size_t size) {
if (force_oom_) return false;
if (OldGenerationCapacity() + size > MaxOldGenerationSize()) return false;
// The OldGenerationCapacity does not account compaction spaces used
// during evacuation. Ensure that expanding the old generation does push
// the total allocated memory size over the maximum heap size.
return memory_allocator()->Size() + size <= MaxReserved();
}
bool Heap::HasBeenSetUp() { bool Heap::HasBeenSetUp() {
return old_space_ != nullptr && code_space_ != nullptr && return old_space_ != nullptr && code_space_ != nullptr &&
...@@ -328,16 +335,8 @@ GarbageCollector Heap::SelectGarbageCollector(AllocationSpace space, ...@@ -328,16 +335,8 @@ GarbageCollector Heap::SelectGarbageCollector(AllocationSpace space,
return MARK_COMPACTOR; return MARK_COMPACTOR;
} }
// Is there enough space left in OLD to guarantee that a scavenge can // Over-estimate the new space size using capacity to allow some slack.
// succeed? if (!CanExpandOldGeneration(new_space_->TotalCapacity())) {
//
// Note that MemoryAllocator->MaxAvailable() undercounts the memory available
// for object promotion. It counts only the bytes that the memory
// allocator has not yet allocated from the OS and assigned to any space,
// and does not count available bytes already in the old space or code
// space. Undercounting is safe---we may get an unrequested full GC when
// a scavenge would have succeeded.
if (memory_allocator()->MaxAvailable() <= new_space_->Size()) {
isolate_->counters() isolate_->counters()
->gc_compactor_caused_by_oldspace_exhaustion() ->gc_compactor_caused_by_oldspace_exhaustion()
->Increment(); ->Increment();
......
...@@ -1978,10 +1978,7 @@ class Heap { ...@@ -1978,10 +1978,7 @@ class Heap {
bool always_allocate() { return always_allocate_scope_count_.Value() != 0; } bool always_allocate() { return always_allocate_scope_count_.Value() != 0; }
bool CanExpandOldGeneration(size_t size) { bool CanExpandOldGeneration(size_t size);
if (force_oom_) return false;
return (OldGenerationCapacity() + size) < MaxOldGenerationSize();
}
bool IsCloseToOutOfMemory(size_t slack) { bool IsCloseToOutOfMemory(size_t slack) {
return OldGenerationCapacity() + slack >= MaxOldGenerationSize(); return OldGenerationCapacity() + slack >= MaxOldGenerationSize();
......
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