| Index: src/spaces.cc
|
| ===================================================================
|
| --- src/spaces.cc (revision 2737)
|
| +++ src/spaces.cc (working copy)
|
| @@ -951,18 +951,46 @@
|
| }
|
|
|
|
|
| -bool NewSpace::Grow() {
|
| +void NewSpace::Grow() {
|
| ASSERT(Capacity() < MaximumCapacity());
|
| - // TODO(1240712): Failure to double the from space can result in
|
| - // semispaces of different sizes. In the event of that failure, the
|
| - // to space doubling should be rolled back before returning false.
|
| - if (!to_space_.Grow() || !from_space_.Grow()) return false;
|
| + if (to_space_.Grow()) {
|
| + // Only grow from space if we managed to grow to space.
|
| + if (!from_space_.Grow()) {
|
| + // If we managed to grow to space but couldn't grow from space,
|
| + // attempt to shrink to space.
|
| + if (!to_space_.ShrinkTo(from_space_.Capacity())) {
|
| + // We are in an inconsistent state because we could not
|
| + // commit/uncommit memory from new space.
|
| + V8::FatalProcessOutOfMemory("Failed to grow new space.");
|
| + }
|
| + }
|
| + }
|
| allocation_info_.limit = to_space_.high();
|
| ASSERT_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_);
|
| - return true;
|
| }
|
|
|
|
|
| +void NewSpace::Shrink() {
|
| + int new_capacity = Max(InitialCapacity(), 2 * Size());
|
| + int rounded_new_capacity = RoundUp(new_capacity, OS::AllocateAlignment());
|
| + if (rounded_new_capacity < Capacity() &&
|
| + to_space_.ShrinkTo(rounded_new_capacity)) {
|
| + // Only shrink from space if we managed to shrink to space.
|
| + if (!from_space_.ShrinkTo(rounded_new_capacity)) {
|
| + // If we managed to shrink to space but couldn't shrink from
|
| + // space, attempt to grow to space again.
|
| + if (!to_space_.GrowTo(from_space_.Capacity())) {
|
| + // We are in an inconsistent state because we could not
|
| + // commit/uncommit memory from new space.
|
| + V8::FatalProcessOutOfMemory("Failed to shrink new space.");
|
| + }
|
| + }
|
| + }
|
| + allocation_info_.limit = to_space_.high();
|
| + ASSERT_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_);
|
| +}
|
| +
|
| +
|
| void NewSpace::ResetAllocationInfo() {
|
| allocation_info_.top = to_space_.low();
|
| allocation_info_.limit = to_space_.high();
|
| @@ -1058,6 +1086,7 @@
|
| // otherwise. In the mark-compact collector, the memory region of the from
|
| // space is used as the marking stack. It requires contiguous memory
|
| // addresses.
|
| + initial_capacity_ = initial_capacity;
|
| capacity_ = initial_capacity;
|
| maximum_capacity_ = maximum_capacity;
|
| committed_ = false;
|
| @@ -1091,6 +1120,30 @@
|
| }
|
|
|
|
|
| +bool SemiSpace::GrowTo(int new_capacity) {
|
| + ASSERT(new_capacity <= maximum_capacity_);
|
| + ASSERT(new_capacity > capacity_);
|
| + int delta = new_capacity - capacity_;
|
| + if (!MemoryAllocator::CommitBlock(high(), delta, executable())) {
|
| + return false;
|
| + }
|
| + capacity_ = new_capacity;
|
| + return true;
|
| +}
|
| +
|
| +
|
| +bool SemiSpace::ShrinkTo(int new_capacity) {
|
| + ASSERT(new_capacity >= initial_capacity_);
|
| + ASSERT(new_capacity < capacity_);
|
| + int delta = capacity_ - new_capacity;
|
| + if (!MemoryAllocator::UncommitBlock(high() - delta, delta)) {
|
| + return false;
|
| + }
|
| + capacity_ = new_capacity;
|
| + return true;
|
| +}
|
| +
|
| +
|
| #ifdef DEBUG
|
| void SemiSpace::Print() { }
|
|
|
|
|