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() {
size_t Heap::OldGenerationCapacity() {
if (!HasBeenSetUp()) return 0;
return old_space_->Capacity() + code_space_->Capacity() +
map_space_->Capacity() + lo_space_->SizeOfObjects();
}
......@@ -301,6 +300,14 @@ size_t Heap::Available() {
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() {
return old_space_ != nullptr && code_space_ != nullptr &&
......@@ -328,16 +335,8 @@ GarbageCollector Heap::SelectGarbageCollector(AllocationSpace space,
return MARK_COMPACTOR;
}
// Is there enough space left in OLD to guarantee that a scavenge can
// succeed?
//
// 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()) {
// Over-estimate the new space size using capacity to allow some slack.
if (!CanExpandOldGeneration(new_space_->TotalCapacity())) {
isolate_->counters()
->gc_compactor_caused_by_oldspace_exhaustion()
->Increment();
......
......@@ -1978,10 +1978,7 @@ class Heap {
bool always_allocate() { return always_allocate_scope_count_.Value() != 0; }
bool CanExpandOldGeneration(size_t size) {
if (force_oom_) return false;
return (OldGenerationCapacity() + size) < MaxOldGenerationSize();
}
bool CanExpandOldGeneration(size_t size);
bool IsCloseToOutOfMemory(size_t slack) {
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