Commit ed05df00 authored by ager@chromium.org's avatar ager@chromium.org

Shrink new space on compacting collections.

Review URL: http://codereview.chromium.org/174219

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2740 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent cba1ae7d
......@@ -465,8 +465,9 @@ void Heap::PerformGarbageCollection(AllocationSpace space,
old_gen_allocation_limit_ =
old_gen_size + Max(kMinimumAllocationLimit, old_gen_size / 2);
old_gen_exhausted_ = false;
} else {
Scavenge();
}
Scavenge();
Counters::objs_since_last_young.Set(0);
PostGarbageCollectionProcessing();
......@@ -520,6 +521,12 @@ void Heap::MarkCompact(GCTracer* tracer) {
Counters::objs_since_last_full.Set(0);
context_disposed_pending_ = false;
Scavenge();
// Shrink new space as much as possible after compacting full
// garbage collections.
if (is_compacting) new_space_.Shrink();
}
......@@ -668,8 +675,6 @@ void Heap::Scavenge() {
survived_since_last_expansion_ > new_space_.Capacity()) {
// Grow the size of new space if there is room to grow and enough
// data has survived scavenge since the last expansion.
// TODO(1240712): NewSpace::Grow has a return value which is
// ignored here.
new_space_.Grow();
survived_since_last_expansion_ = 0;
}
......
......@@ -951,15 +951,43 @@ void NewSpace::Flip() {
}
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_);
}
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_);
return true;
}
......@@ -1058,6 +1086,7 @@ bool SemiSpace::Setup(Address start,
// 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,32 @@ bool SemiSpace::Grow() {
}
bool SemiSpace::GrowTo(int new_capacity) {
ASSERT(new_capacity <= maximum_capacity_);
ASSERT(new_capacity > capacity_);
size_t delta = new_capacity - capacity_;
ASSERT(IsAligned(delta, OS::AllocateAlignment()));
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_);
size_t delta = capacity_ - new_capacity;
ASSERT(IsAligned(delta, OS::AllocateAlignment()));
if (!MemoryAllocator::UncommitBlock(high() - delta, delta)) {
return false;
}
capacity_ = new_capacity;
return true;
}
#ifdef DEBUG
void SemiSpace::Print() { }
......
......@@ -1010,6 +1010,15 @@ class SemiSpace : public Space {
// address range to grow).
bool Grow();
// Grow the semispace to the new capacity. The new capacity
// requested must be larger than the current capacity.
bool GrowTo(int new_capacity);
// Shrinks the semispace to the new capacity. The new capacity
// requested must be more than the amount of used memory in the
// semispace and less than the current capacity.
bool ShrinkTo(int new_capacity);
// Returns the start address of the space.
Address low() { return start_; }
// Returns one past the end address of the space.
......@@ -1057,11 +1066,14 @@ class SemiSpace : public Space {
// Returns the maximum capacity of the semi space.
int MaximumCapacity() { return maximum_capacity_; }
// Returns the initial capacity of the semi space.
int InitialCapacity() { return initial_capacity_; }
private:
// The current and maximum capacity of the space.
int capacity_;
int maximum_capacity_;
int initial_capacity_;
// The start address of the space.
Address start_;
......@@ -1152,8 +1164,11 @@ class NewSpace : public Space {
void Flip();
// Grow the capacity of the semispaces. Assumes that they are not at
// their maximum capacity. Returns a flag indicating success or failure.
bool Grow();
// their maximum capacity.
void Grow();
// Shrink the capacity of the semispaces.
void Shrink();
// True if the address or object lies in the address range of either
// semispace (not necessarily below the allocation pointer).
......@@ -1181,6 +1196,12 @@ class NewSpace : public Space {
return to_space_.MaximumCapacity();
}
// Returns the initial capacity of a semispace.
int InitialCapacity() {
ASSERT(to_space_.InitialCapacity() == from_space_.InitialCapacity());
return to_space_.InitialCapacity();
}
// Return the address of the allocation pointer in the active semispace.
Address top() { return allocation_info_.top; }
// Return the address of the first object in the active semispace.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment