Capacity returns allocatable memory and TotalCapacity returns allocatable plus non-allocatable memory for the new space.

BUG=
R=ulan@chromium.org

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

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24040 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
hpayer@chromium.org 2014-09-18 12:52:12 +00:00
parent 200095c3e7
commit 1373784d83
4 changed files with 78 additions and 72 deletions

View File

@ -1282,8 +1282,8 @@ static void VerifyNonPointerSpacePointers(Heap* heap) {
void Heap::CheckNewSpaceExpansionCriteria() {
if (new_space_.Capacity() < new_space_.MaximumCapacity() &&
survived_since_last_expansion_ > new_space_.Capacity()) {
if (new_space_.TotalCapacity() < new_space_.MaximumCapacity() &&
survived_since_last_expansion_ > new_space_.TotalCapacity()) {
// Grow the size of new space if there is room to grow, enough data
// has survived scavenge since the last expansion and we are not in
// high promotion mode.

View File

@ -1259,14 +1259,15 @@ void NewSpace::Flip() { SemiSpace::Swap(&from_space_, &to_space_); }
void NewSpace::Grow() {
// Double the semispace size but only up to maximum capacity.
DCHECK(Capacity() < MaximumCapacity());
int new_capacity = Min(MaximumCapacity(), 2 * static_cast<int>(Capacity()));
DCHECK(TotalCapacity() < MaximumCapacity());
int new_capacity =
Min(MaximumCapacity(), 2 * static_cast<int>(TotalCapacity()));
if (to_space_.GrowTo(new_capacity)) {
// Only grow from space if we managed to grow to-space.
if (!from_space_.GrowTo(new_capacity)) {
// 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())) {
if (!to_space_.ShrinkTo(from_space_.TotalCapacity())) {
// We are in an inconsistent state because we could not
// commit/uncommit memory from new space.
V8::FatalProcessOutOfMemory("Failed to grow new space.");
@ -1278,16 +1279,16 @@ void NewSpace::Grow() {
void NewSpace::Shrink() {
int new_capacity = Max(InitialCapacity(), 2 * SizeAsInt());
int new_capacity = Max(InitialTotalCapacity(), 2 * SizeAsInt());
int rounded_new_capacity = RoundUp(new_capacity, Page::kPageSize);
if (rounded_new_capacity < Capacity() &&
if (rounded_new_capacity < TotalCapacity() &&
to_space_.ShrinkTo(rounded_new_capacity)) {
// Only shrink from-space if we managed to shrink to-space.
from_space_.Reset();
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())) {
if (!to_space_.GrowTo(from_space_.TotalCapacity())) {
// We are in an inconsistent state because we could not
// commit/uncommit memory from new space.
V8::FatalProcessOutOfMemory("Failed to shrink new space.");
@ -1465,9 +1466,9 @@ void SemiSpace::SetUp(Address start, int initial_capacity,
// space is used as the marking stack. It requires contiguous memory
// addresses.
DCHECK(maximum_capacity >= Page::kPageSize);
initial_capacity_ = RoundDown(initial_capacity, Page::kPageSize);
capacity_ = initial_capacity;
maximum_capacity_ = RoundDown(maximum_capacity, Page::kPageSize);
initial_total_capacity_ = RoundDown(initial_capacity, Page::kPageSize);
total_capacity_ = initial_capacity;
maximum_total_capacity_ = RoundDown(maximum_capacity, Page::kPageSize);
maximum_committed_ = 0;
committed_ = false;
start_ = start;
@ -1480,15 +1481,15 @@ void SemiSpace::SetUp(Address start, int initial_capacity,
void SemiSpace::TearDown() {
start_ = NULL;
capacity_ = 0;
total_capacity_ = 0;
}
bool SemiSpace::Commit() {
DCHECK(!is_committed());
int pages = capacity_ / Page::kPageSize;
if (!heap()->isolate()->memory_allocator()->CommitBlock(start_, capacity_,
executable())) {
int pages = total_capacity_ / Page::kPageSize;
if (!heap()->isolate()->memory_allocator()->CommitBlock(
start_, total_capacity_, executable())) {
return false;
}
@ -1500,7 +1501,7 @@ bool SemiSpace::Commit() {
current = new_page;
}
SetCapacity(capacity_);
SetCapacity(total_capacity_);
committed_ = true;
Reset();
return true;
@ -1509,8 +1510,9 @@ bool SemiSpace::Commit() {
bool SemiSpace::Uncommit() {
DCHECK(is_committed());
Address start = start_ + maximum_capacity_ - capacity_;
if (!heap()->isolate()->memory_allocator()->UncommitBlock(start, capacity_)) {
Address start = start_ + maximum_total_capacity_ - total_capacity_;
if (!heap()->isolate()->memory_allocator()->UncommitBlock(start,
total_capacity_)) {
return false;
}
anchor()->set_next_page(anchor());
@ -1537,16 +1539,16 @@ bool SemiSpace::GrowTo(int new_capacity) {
if (!Commit()) return false;
}
DCHECK((new_capacity & Page::kPageAlignmentMask) == 0);
DCHECK(new_capacity <= maximum_capacity_);
DCHECK(new_capacity > capacity_);
int pages_before = capacity_ / Page::kPageSize;
DCHECK(new_capacity <= maximum_total_capacity_);
DCHECK(new_capacity > total_capacity_);
int pages_before = total_capacity_ / Page::kPageSize;
int pages_after = new_capacity / Page::kPageSize;
size_t delta = new_capacity - capacity_;
size_t delta = new_capacity - total_capacity_;
DCHECK(IsAligned(delta, base::OS::AllocateAlignment()));
if (!heap()->isolate()->memory_allocator()->CommitBlock(
start_ + capacity_, delta, executable())) {
start_ + total_capacity_, delta, executable())) {
return false;
}
SetCapacity(new_capacity);
@ -1569,10 +1571,10 @@ bool SemiSpace::GrowTo(int new_capacity) {
bool SemiSpace::ShrinkTo(int new_capacity) {
DCHECK((new_capacity & Page::kPageAlignmentMask) == 0);
DCHECK(new_capacity >= initial_capacity_);
DCHECK(new_capacity < capacity_);
DCHECK(new_capacity >= initial_total_capacity_);
DCHECK(new_capacity < total_capacity_);
if (is_committed()) {
size_t delta = capacity_ - new_capacity;
size_t delta = total_capacity_ - new_capacity;
DCHECK(IsAligned(delta, base::OS::AllocateAlignment()));
MemoryAllocator* allocator = heap()->isolate()->memory_allocator();
@ -1652,9 +1654,9 @@ void SemiSpace::Swap(SemiSpace* from, SemiSpace* to) {
void SemiSpace::SetCapacity(int new_capacity) {
capacity_ = new_capacity;
if (capacity_ > maximum_committed_) {
maximum_committed_ = capacity_;
total_capacity_ = new_capacity;
if (total_capacity_ > maximum_committed_) {
maximum_committed_ = total_capacity_;
}
}
@ -1895,11 +1897,11 @@ static void DoReportStatistics(Isolate* isolate, HistogramInfo* info,
void NewSpace::ReportStatistics() {
#ifdef DEBUG
if (FLAG_heap_stats) {
float pct = static_cast<float>(Available()) / Capacity();
float pct = static_cast<float>(Available()) / TotalCapacity();
PrintF(" capacity: %" V8_PTR_PREFIX
"d"
", available: %" V8_PTR_PREFIX "d, %%%d\n",
Capacity(), Available(), static_cast<int>(pct * 100));
TotalCapacity(), Available(), static_cast<int>(pct * 100));
PrintF("\n Object Histogram:\n");
for (int i = 0; i <= LAST_TYPE; i++) {
if (allocated_histogram_[i].number() > 0) {

View File

@ -2161,14 +2161,14 @@ class SemiSpace : public Space {
inline static void AssertValidRange(Address from, Address to) {}
#endif
// Returns the current capacity of the semi space.
int Capacity() { return capacity_; }
// Returns the current total capacity of the semispace.
int TotalCapacity() { return total_capacity_; }
// Returns the maximum capacity of the semi space.
int MaximumCapacity() { return maximum_capacity_; }
// Returns the maximum total capacity of the semispace.
int MaximumTotalCapacity() { return maximum_total_capacity_; }
// Returns the initial capacity of the semi space.
int InitialCapacity() { return initial_capacity_; }
// Returns the initial capacity of the semispace.
int InitialTotalCapacity() { return initial_total_capacity_; }
SemiSpaceId id() { return id_; }
@ -2190,10 +2190,10 @@ class SemiSpace : public Space {
NewSpacePage* anchor() { return &anchor_; }
// The current and maximum capacity of the space.
int capacity_;
int maximum_capacity_;
int initial_capacity_;
// The current and maximum total capacity of the space.
int total_capacity_;
int maximum_total_capacity_;
int initial_total_capacity_;
intptr_t maximum_committed_;
@ -2363,22 +2363,24 @@ class NewSpace : public Space {
// new space, which can't get as big as the other spaces then this is useful:
int SizeAsInt() { return static_cast<int>(Size()); }
// Return the current capacity of a semispace.
intptr_t EffectiveCapacity() {
SLOW_DCHECK(to_space_.Capacity() == from_space_.Capacity());
return (to_space_.Capacity() / Page::kPageSize) * NewSpacePage::kAreaSize;
// Return the allocatable capacity of a semispace.
intptr_t Capacity() {
SLOW_DCHECK(to_space_.TotalCapacity() == from_space_.TotalCapacity());
return (to_space_.TotalCapacity() / Page::kPageSize) *
NewSpacePage::kAreaSize;
}
// Return the current capacity of a semispace.
intptr_t Capacity() {
DCHECK(to_space_.Capacity() == from_space_.Capacity());
return to_space_.Capacity();
// Return the current size of a semispace, allocatable and non-allocatable
// memory.
intptr_t TotalCapacity() {
DCHECK(to_space_.TotalCapacity() == from_space_.TotalCapacity());
return to_space_.TotalCapacity();
}
// Return the total amount of memory committed for new space.
intptr_t CommittedMemory() {
if (from_space_.is_committed()) return 2 * Capacity();
return Capacity();
return TotalCapacity();
}
// Return the total amount of memory committed for new space.
@ -2395,16 +2397,18 @@ class NewSpace : public Space {
// Return the maximum capacity of a semispace.
int MaximumCapacity() {
DCHECK(to_space_.MaximumCapacity() == from_space_.MaximumCapacity());
return to_space_.MaximumCapacity();
DCHECK(to_space_.MaximumTotalCapacity() ==
from_space_.MaximumTotalCapacity());
return to_space_.MaximumTotalCapacity();
}
bool IsAtMaximumCapacity() { return Capacity() == MaximumCapacity(); }
bool IsAtMaximumCapacity() { return TotalCapacity() == MaximumCapacity(); }
// Returns the initial capacity of a semispace.
int InitialCapacity() {
DCHECK(to_space_.InitialCapacity() == from_space_.InitialCapacity());
return to_space_.InitialCapacity();
int InitialTotalCapacity() {
DCHECK(to_space_.InitialTotalCapacity() ==
from_space_.InitialTotalCapacity());
return to_space_.InitialTotalCapacity();
}
// Return the address of the allocation pointer in the active semispace.

View File

@ -1684,7 +1684,7 @@ static void FillUpNewSpace(NewSpace* new_space) {
Factory* factory = isolate->factory();
HandleScope scope(isolate);
AlwaysAllocateScope always_allocate(isolate);
intptr_t available = new_space->EffectiveCapacity() - new_space->Size();
intptr_t available = new_space->Capacity() - new_space->Size();
intptr_t number_of_fillers = (available / FixedArray::SizeFor(32)) - 1;
for (intptr_t i = 0; i < number_of_fillers; i++) {
CHECK(heap->InNewSpace(*factory->NewFixedArray(32, NOT_TENURED)));
@ -1707,20 +1707,20 @@ TEST(GrowAndShrinkNewSpace) {
// Explicitly growing should double the space capacity.
intptr_t old_capacity, new_capacity;
old_capacity = new_space->Capacity();
old_capacity = new_space->TotalCapacity();
new_space->Grow();
new_capacity = new_space->Capacity();
new_capacity = new_space->TotalCapacity();
CHECK(2 * old_capacity == new_capacity);
old_capacity = new_space->Capacity();
old_capacity = new_space->TotalCapacity();
FillUpNewSpace(new_space);
new_capacity = new_space->Capacity();
new_capacity = new_space->TotalCapacity();
CHECK(old_capacity == new_capacity);
// Explicitly shrinking should not affect space capacity.
old_capacity = new_space->Capacity();
old_capacity = new_space->TotalCapacity();
new_space->Shrink();
new_capacity = new_space->Capacity();
new_capacity = new_space->TotalCapacity();
CHECK(old_capacity == new_capacity);
// Let the scavenger empty the new space.
@ -1728,17 +1728,17 @@ TEST(GrowAndShrinkNewSpace) {
CHECK_LE(new_space->Size(), old_capacity);
// Explicitly shrinking should halve the space capacity.
old_capacity = new_space->Capacity();
old_capacity = new_space->TotalCapacity();
new_space->Shrink();
new_capacity = new_space->Capacity();
new_capacity = new_space->TotalCapacity();
CHECK(old_capacity == 2 * new_capacity);
// Consecutive shrinking should not affect space capacity.
old_capacity = new_space->Capacity();
old_capacity = new_space->TotalCapacity();
new_space->Shrink();
new_space->Shrink();
new_space->Shrink();
new_capacity = new_space->Capacity();
new_capacity = new_space->TotalCapacity();
CHECK(old_capacity == new_capacity);
}
@ -1757,13 +1757,13 @@ TEST(CollectingAllAvailableGarbageShrinksNewSpace) {
v8::HandleScope scope(CcTest::isolate());
NewSpace* new_space = heap->new_space();
intptr_t old_capacity, new_capacity;
old_capacity = new_space->Capacity();
old_capacity = new_space->TotalCapacity();
new_space->Grow();
new_capacity = new_space->Capacity();
new_capacity = new_space->TotalCapacity();
CHECK(2 * old_capacity == new_capacity);
FillUpNewSpace(new_space);
heap->CollectAllAvailableGarbage();
new_capacity = new_space->Capacity();
new_capacity = new_space->TotalCapacity();
CHECK(old_capacity == new_capacity);
}
@ -4379,10 +4379,10 @@ TEST(PromotionQueue) {
// Grow the semi-space to two pages to make semi-space copy overwrite the
// promotion queue, which will be at the end of the second page.
intptr_t old_capacity = new_space->Capacity();
intptr_t old_capacity = new_space->TotalCapacity();
new_space->Grow();
CHECK(new_space->IsAtMaximumCapacity());
CHECK(2 * old_capacity == new_space->Capacity());
CHECK(2 * old_capacity == new_space->TotalCapacity());
// Call the scavenger two times to get an empty new space
heap->CollectGarbage(NEW_SPACE);