From f3219552b60a924844f6f5ae2d219222309d93ad Mon Sep 17 00:00:00 2001 From: erikcorry Date: Fri, 8 May 2015 08:12:44 -0700 Subject: [PATCH] If marking deque allocation fails, try to make do with a smaller one R=hpayer@chromium.org BUG= Review URL: https://codereview.chromium.org/1134743002 Cr-Commit-Position: refs/heads/master@{#28322} --- src/heap/mark-compact.cc | 49 ++++++++++++++++++++++++++++++++++++------------ src/heap/mark-compact.h | 2 +- 2 files changed, 38 insertions(+), 13 deletions(-) diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc index 7e02afa..be9938b 100644 --- a/src/heap/mark-compact.cc +++ b/src/heap/mark-compact.cc @@ -226,6 +226,7 @@ static void VerifyEvacuation(Heap* heap) { void MarkCompactCollector::SetUp() { free_list_old_space_.Reset(new FreeList(heap_->old_space())); + EnsureMarkingDequeIsCommittedAndInitialize(256 * KB); } @@ -2257,20 +2258,44 @@ void MarkCompactCollector::RetainMaps() { } -void MarkCompactCollector::EnsureMarkingDequeIsCommittedAndInitialize() { - if (marking_deque_memory_ == NULL) { - marking_deque_memory_ = new base::VirtualMemory(4 * MB); - } - if (!marking_deque_memory_committed_) { - if (!marking_deque_memory_->Commit( - reinterpret_cast
(marking_deque_memory_->address()), - marking_deque_memory_->size(), - false)) { // Not executable. - V8::FatalProcessOutOfMemory("EnsureMarkingDequeIsCommitted"); +void MarkCompactCollector::EnsureMarkingDequeIsCommittedAndInitialize( + size_t max_size) { + // If the marking deque is too small, we try to allocate a bigger one. + // If that fails, make do with a smaller one. + for (size_t size = max_size; size >= 256 * KB; size >>= 1) { + base::VirtualMemory* memory = marking_deque_memory_; + bool is_committed = marking_deque_memory_committed_; + + if (memory == NULL || memory->size() < size) { + // If we don't have memory or we only have small memory, then + // try to reserve a new one. + memory = new base::VirtualMemory(size); + is_committed = false; + } + if (is_committed) return; + if (memory->IsReserved() && + memory->Commit(reinterpret_cast
(memory->address()), + memory->size(), + false)) { // Not executable. + if (marking_deque_memory_ != NULL && marking_deque_memory_ != memory) { + delete marking_deque_memory_; + } + marking_deque_memory_ = memory; + marking_deque_memory_committed_ = true; + InitializeMarkingDeque(); + return; + } else { + // Commit failed, so we are under memory pressure. If this was the + // previously reserved area we tried to commit, then remove references + // to it before deleting it and unreserving it. + if (marking_deque_memory_ == memory) { + marking_deque_memory_ = NULL; + marking_deque_memory_committed_ = false; + } + delete memory; // Will also unreserve the virtual allocation. } - marking_deque_memory_committed_ = true; - InitializeMarkingDeque(); } + V8::FatalProcessOutOfMemory("EnsureMarkingDequeIsCommitted"); } diff --git a/src/heap/mark-compact.h b/src/heap/mark-compact.h index 03fd45a..322965d 100644 --- a/src/heap/mark-compact.h +++ b/src/heap/mark-compact.h @@ -704,7 +704,7 @@ class MarkCompactCollector { MarkingDeque* marking_deque() { return &marking_deque_; } - void EnsureMarkingDequeIsCommittedAndInitialize(); + void EnsureMarkingDequeIsCommittedAndInitialize(size_t max_size = 4 * MB); void InitializeMarkingDeque(); -- 2.7.4