Index: src/heap/store-buffer.cc |
diff --git a/src/heap/store-buffer.cc b/src/heap/store-buffer.cc |
index a73e0fa57772f387a9c25be16136b87563e1df9c..f6df80e0dab84235ce58f2ba8f2edb1ccd37d11c 100644 |
--- a/src/heap/store-buffer.cc |
+++ b/src/heap/store-buffer.cc |
@@ -33,6 +33,9 @@ StoreBuffer::StoreBuffer(Heap* heap) |
void StoreBuffer::SetUp() { |
+ // Allocate 3x the buffer size, so that we can start the new store buffer |
+ // aligned to 2x the size. This lets us use a bit test to detect the end of |
+ // the area. |
virtual_memory_ = new base::VirtualMemory(kStoreBufferSize * 3); |
uintptr_t start_as_int = |
reinterpret_cast<uintptr_t>(virtual_memory_->address()); |
@@ -40,17 +43,22 @@ void StoreBuffer::SetUp() { |
reinterpret_cast<Address*>(RoundUp(start_as_int, kStoreBufferSize * 2)); |
limit_ = start_ + (kStoreBufferSize / kPointerSize); |
+ // Reserve space for the larger old buffer. |
old_virtual_memory_ = |
new base::VirtualMemory(kOldStoreBufferLength * kPointerSize); |
old_top_ = old_start_ = |
reinterpret_cast<Address*>(old_virtual_memory_->address()); |
// Don't know the alignment requirements of the OS, but it is certainly not |
// less than 0xfff. |
- DCHECK((reinterpret_cast<uintptr_t>(old_start_) & 0xfff) == 0); |
- int initial_length = |
- static_cast<int>(base::OS::CommitPageSize() / kPointerSize); |
- DCHECK(initial_length > 0); |
- DCHECK(initial_length <= kOldStoreBufferLength); |
+ CHECK((reinterpret_cast<uintptr_t>(old_start_) & 0xfff) == 0); |
+ CHECK(kStoreBufferSize >= base::OS::CommitPageSize()); |
+ // Initial size of the old buffer is as big as the buffer for new pointers. |
+ // This means even if we later fail to enlarge the old buffer due to OOM from |
+ // the OS, we will still be able to empty the new pointer buffer into the old |
+ // buffer. |
+ int initial_length = static_cast<int>(kStoreBufferSize / kPointerSize); |
+ CHECK(initial_length > 0); |
+ CHECK(initial_length <= kOldStoreBufferLength); |
old_limit_ = old_start_ + initial_length; |
old_reserved_limit_ = old_start_ + kOldStoreBufferLength; |
@@ -116,11 +124,12 @@ void StoreBuffer::EnsureSpace(intptr_t space_needed) { |
while (old_limit_ - old_top_ < space_needed && |
old_limit_ < old_reserved_limit_) { |
size_t grow = old_limit_ - old_start_; // Double size. |
- if (!old_virtual_memory_->Commit(reinterpret_cast<void*>(old_limit_), |
- grow * kPointerSize, false)) { |
- V8::FatalProcessOutOfMemory("StoreBuffer::EnsureSpace"); |
+ if (old_virtual_memory_->Commit(reinterpret_cast<void*>(old_limit_), |
+ grow * kPointerSize, false)) { |
+ old_limit_ += grow; |
+ } else { |
+ break; |
} |
- old_limit_ += grow; |
} |
if (SpaceAvailable(space_needed)) return; |