Commit a8cb171b authored by Hannes Payer's avatar Hannes Payer Committed by Commit Bot

[heap] Use target and current capacity counters to grow NewSpace.

Bug: chromium:1054771
Change-Id: I64d0d2a4f07add4adef78136b303881a900474a7
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2560198Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Commit-Queue: Hannes Payer <hpayer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#71427}
parent d4c885de
......@@ -39,7 +39,7 @@ Page* SemiSpace::InitializePage(MemoryChunk* chunk) {
bool SemiSpace::EnsureCurrentCapacity() {
if (is_committed()) {
const int expected_pages =
static_cast<int>(current_capacity_ / Page::kPageSize);
static_cast<int>(target_capacity_ / Page::kPageSize);
MemoryChunk* current_page = first_page();
int actual_pages = 0;
......@@ -91,7 +91,7 @@ bool SemiSpace::EnsureCurrentCapacity() {
void SemiSpace::SetUp(size_t initial_capacity, size_t maximum_capacity) {
DCHECK_GE(maximum_capacity, static_cast<size_t>(Page::kPageSize));
minimum_capacity_ = RoundDown(initial_capacity, Page::kPageSize);
current_capacity_ = minimum_capacity_;
target_capacity_ = minimum_capacity_;
maximum_capacity_ = RoundDown(maximum_capacity, Page::kPageSize);
committed_ = false;
}
......@@ -101,12 +101,12 @@ void SemiSpace::TearDown() {
if (is_committed()) {
Uncommit();
}
current_capacity_ = maximum_capacity_ = 0;
target_capacity_ = maximum_capacity_ = 0;
}
bool SemiSpace::Commit() {
DCHECK(!is_committed());
const int num_pages = static_cast<int>(current_capacity_ / Page::kPageSize);
const int num_pages = static_cast<int>(target_capacity_ / Page::kPageSize);
for (int pages_added = 0; pages_added < num_pages; pages_added++) {
// Pages in the new spaces can be moved to the old space by the full
// collector. Therefore, they must be initialized with the same FreeList as
......@@ -122,7 +122,7 @@ bool SemiSpace::Commit() {
memory_chunk_list_.PushBack(new_page);
}
Reset();
AccountCommitted(current_capacity_);
AccountCommitted(target_capacity_);
if (age_mark_ == kNullAddress) {
age_mark_ = first_page()->area_start();
}
......@@ -138,7 +138,7 @@ bool SemiSpace::Uncommit() {
heap()->memory_allocator()->Free<MemoryAllocator::kPooledAndQueue>(chunk);
}
current_page_ = nullptr;
AccountUncommitted(current_capacity_);
AccountUncommitted(target_capacity_);
committed_ = false;
heap()->memory_allocator()->unmapper()->FreeQueuedChunks();
return true;
......@@ -159,8 +159,8 @@ bool SemiSpace::GrowTo(size_t new_capacity) {
}
DCHECK_EQ(new_capacity & kPageAlignmentMask, 0u);
DCHECK_LE(new_capacity, maximum_capacity_);
DCHECK_GT(new_capacity, current_capacity_);
const size_t delta = new_capacity - current_capacity_;
DCHECK_GT(new_capacity, target_capacity_);
const size_t delta = new_capacity - target_capacity_;
DCHECK(IsAligned(delta, AllocatePageSize()));
const int delta_pages = static_cast<int>(delta / Page::kPageSize);
DCHECK(last_page());
......@@ -181,7 +181,7 @@ bool SemiSpace::GrowTo(size_t new_capacity) {
new_page->SetFlags(last_page()->GetFlags(), Page::kCopyOnFlipFlagsMask);
}
AccountCommitted(delta);
current_capacity_ = new_capacity;
target_capacity_ = new_capacity;
return true;
}
......@@ -199,16 +199,16 @@ void SemiSpace::RewindPages(int num_pages) {
bool SemiSpace::ShrinkTo(size_t new_capacity) {
DCHECK_EQ(new_capacity & kPageAlignmentMask, 0u);
DCHECK_GE(new_capacity, minimum_capacity_);
DCHECK_LT(new_capacity, current_capacity_);
DCHECK_LT(new_capacity, target_capacity_);
if (is_committed()) {
const size_t delta = current_capacity_ - new_capacity;
const size_t delta = target_capacity_ - new_capacity;
DCHECK(IsAligned(delta, Page::kPageSize));
int delta_pages = static_cast<int>(delta / Page::kPageSize);
RewindPages(delta_pages);
AccountUncommitted(delta);
heap()->memory_allocator()->unmapper()->FreeQueuedChunks();
}
current_capacity_ = new_capacity;
target_capacity_ = new_capacity;
return true;
}
......@@ -234,7 +234,7 @@ void SemiSpace::Reset() {
DCHECK(first_page());
DCHECK(last_page());
current_page_ = first_page();
pages_used_ = 0;
current_capacity_ = Page::kPageSize;
}
void SemiSpace::RemovePage(Page* page) {
......@@ -255,7 +255,7 @@ void SemiSpace::PrependPage(Page* page) {
static_cast<uintptr_t>(Page::kCopyAllFlags));
page->set_owner(this);
memory_chunk_list_.PushFront(page);
pages_used_++;
current_capacity_ += Page::kPageSize;
for (size_t i = 0; i < ExternalBackingStoreType::kNumTypes; i++) {
ExternalBackingStoreType t = static_cast<ExternalBackingStoreType>(i);
IncrementExternalBackingStoreBytes(t, page->ExternalBackingStoreBytes(t));
......@@ -277,7 +277,7 @@ void SemiSpace::Swap(SemiSpace* from, SemiSpace* to) {
intptr_t saved_to_space_flags = to->current_page()->GetFlags();
// We swap all properties but id_.
std::swap(from->current_capacity_, to->current_capacity_);
std::swap(from->target_capacity_, to->target_capacity_);
std::swap(from->maximum_capacity_, to->maximum_capacity_);
std::swap(from->minimum_capacity_, to->minimum_capacity_);
std::swap(from->age_mark_, to->age_mark_);
......@@ -440,7 +440,7 @@ void NewSpace::Grow() {
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_.current_capacity())) {
if (!to_space_.ShrinkTo(from_space_.target_capacity())) {
// We are in an inconsistent state because we could not
// commit/uncommit memory from new space.
FATAL("inconsistent state");
......@@ -460,7 +460,7 @@ void NewSpace::Shrink() {
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_.current_capacity())) {
if (!to_space_.GrowTo(from_space_.target_capacity())) {
// We are in an inconsistent state because we could not
// commit/uncommit memory from new space.
FATAL("inconsistent state");
......
......@@ -44,13 +44,13 @@ class SemiSpace : public Space {
SemiSpace(Heap* heap, SemiSpaceId semispace)
: Space(heap, NEW_SPACE, new NoFreeList()),
current_capacity_(0),
target_capacity_(0),
maximum_capacity_(0),
minimum_capacity_(0),
age_mark_(kNullAddress),
committed_(false),
id_(semispace),
current_page_(nullptr),
pages_used_(0) {}
current_page_(nullptr) {}
inline bool Contains(HeapObject o) const;
inline bool Contains(Object o) const;
......@@ -81,7 +81,6 @@ class SemiSpace : public Space {
}
Page* current_page() { return current_page_; }
int pages_used() { return pages_used_; }
// Returns the start address of the current page of the space.
Address page_low() { return current_page_->area_start(); }
......@@ -91,15 +90,14 @@ class SemiSpace : public Space {
bool AdvancePage() {
Page* next_page = current_page_->next_page();
// We cannot expand if we reached the maximum number of pages already. Note
// We cannot expand if we reached the target capcity. Note
// that we need to account for the next page already for this check as we
// could potentially fill the whole page after advancing.
const bool reached_max_pages = (pages_used_ + 1) == max_pages();
if (next_page == nullptr || reached_max_pages) {
if (next_page == nullptr || (current_capacity_ == target_capacity_)) {
return false;
}
current_page_ = next_page;
pages_used_++;
current_capacity_ += Page::kPageSize;
return true;
}
......@@ -119,6 +117,9 @@ class SemiSpace : public Space {
// Returns the current capacity of the semispace.
size_t current_capacity() { return current_capacity_; }
// Returns the target capacity of the semispace.
size_t target_capacity() { return target_capacity_; }
// Returns the maximum capacity of the semispace.
size_t maximum_capacity() { return maximum_capacity_; }
......@@ -172,16 +173,15 @@ class SemiSpace : public Space {
private:
void RewindPages(int num_pages);
inline int max_pages() {
return static_cast<int>(current_capacity_ / Page::kPageSize);
}
// Copies the flags into the masked positions on all pages in the space.
void FixPagesFlags(intptr_t flags, intptr_t flag_mask);
// The currently committed space capacity.
size_t current_capacity_;
// The targetted committed space capacity.
size_t target_capacity_;
// The maximum capacity that can be used by this space. A space cannot grow
// beyond that size.
size_t maximum_capacity_;
......@@ -197,8 +197,6 @@ class SemiSpace : public Space {
Page* current_page_;
int pages_used_;
friend class NewSpace;
friend class SemiSpaceObjectIterator;
};
......@@ -264,7 +262,7 @@ class V8_EXPORT_PRIVATE NewSpace
// Return the allocated bytes in the active semispace.
size_t Size() final {
DCHECK_GE(top(), to_space_.page_low());
return to_space_.pages_used() *
return (to_space_.current_capacity() - Page::kPageSize) / Page::kPageSize *
MemoryChunkLayout::AllocatableMemoryInDataPage() +
static_cast<size_t>(top() - to_space_.page_low());
}
......@@ -273,16 +271,16 @@ class V8_EXPORT_PRIVATE NewSpace
// Return the allocatable capacity of a semispace.
size_t Capacity() {
SLOW_DCHECK(to_space_.current_capacity() == from_space_.current_capacity());
return (to_space_.current_capacity() / Page::kPageSize) *
SLOW_DCHECK(to_space_.target_capacity() == from_space_.target_capacity());
return (to_space_.target_capacity() / Page::kPageSize) *
MemoryChunkLayout::AllocatableMemoryInDataPage();
}
// Return the current size of a semispace, allocatable and non-allocatable
// memory.
size_t TotalCapacity() {
DCHECK(to_space_.current_capacity() == from_space_.current_capacity());
return to_space_.current_capacity();
DCHECK(to_space_.target_capacity() == from_space_.target_capacity());
return to_space_.target_capacity();
}
// Committed memory for NewSpace is the committed memory of both semi-spaces
......
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