Index: src/heap/mark-compact.cc |
diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc |
index 7e02afa3c9ebe65c982d8dffed41b3819e5574f5..be9938b4a1b5eb9ef06f597728a39a0f53dc5fbf 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<Address>(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<Address>(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"); |
} |