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:
parent
200095c3e7
commit
1373784d83
@ -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.
|
||||
|
@ -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) {
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user