Make store buffer more robust to OOM.

R=hpayer@chromium.org
BUG=

Review URL: https://codereview.chromium.org/1086263002

Cr-Commit-Position: refs/heads/master@{#27876}
This commit is contained in:
erikcorry 2015-04-16 03:39:48 -07:00 committed by Commit bot
parent 5729299752
commit a3f5e04c99

View File

@ -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;