Commit 465caac8 authored by mlippautz's avatar mlippautz Committed by Commit bot

[heap] Unify accounting committed memory across all spaces.

Untangles committed memory from capacity in a given space and unifies accounting
for all spaces.

Pre-work for parallel compaction.

R=hpayer@chromium.org
BUG=chromium:524425
LOG=N

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

Cr-Commit-Position: refs/heads/master@{#31149}
parent e16dd13d
...@@ -1016,6 +1016,8 @@ void PagedSpace::MergeCompactionSpace(CompactionSpace* other) { ...@@ -1016,6 +1016,8 @@ void PagedSpace::MergeCompactionSpace(CompactionSpace* other) {
accounting_stats_.Merge(other->accounting_stats_); accounting_stats_.Merge(other->accounting_stats_);
other->accounting_stats_.Reset(); other->accounting_stats_.Reset();
AccountCommitted(other->CommittedMemory());
// Move over pages. // Move over pages.
PageIterator it(other); PageIterator it(other);
Page* p = nullptr; Page* p = nullptr;
...@@ -1094,6 +1096,8 @@ bool PagedSpace::Expand() { ...@@ -1094,6 +1096,8 @@ bool PagedSpace::Expand() {
executable()); executable());
if (p == NULL) return false; if (p == NULL) return false;
AccountCommitted(static_cast<intptr_t>(p->size()));
// Pages created during bootstrapping may contain immortal immovable objects. // Pages created during bootstrapping may contain immortal immovable objects.
if (!heap()->deserialization_complete()) p->MarkNeverEvacuate(); if (!heap()->deserialization_complete()) p->MarkNeverEvacuate();
...@@ -1160,6 +1164,7 @@ void PagedSpace::ReleasePage(Page* page) { ...@@ -1160,6 +1164,7 @@ void PagedSpace::ReleasePage(Page* page) {
page->Unlink(); page->Unlink();
} }
AccountUncommitted(static_cast<intptr_t>(page->size()));
heap()->QueueMemoryChunkForFree(page); heap()->QueueMemoryChunkForFree(page);
DCHECK(Capacity() > 0); DCHECK(Capacity() > 0);
...@@ -1586,7 +1591,6 @@ void SemiSpace::SetUp(Address start, int initial_capacity, int target_capacity, ...@@ -1586,7 +1591,6 @@ void SemiSpace::SetUp(Address start, int initial_capacity, int target_capacity,
total_capacity_ = initial_capacity; total_capacity_ = initial_capacity;
target_capacity_ = RoundDown(target_capacity, Page::kPageSize); target_capacity_ = RoundDown(target_capacity, Page::kPageSize);
maximum_total_capacity_ = RoundDown(maximum_capacity, Page::kPageSize); maximum_total_capacity_ = RoundDown(maximum_capacity, Page::kPageSize);
maximum_committed_ = 0;
committed_ = false; committed_ = false;
start_ = start; start_ = start;
address_mask_ = ~(maximum_capacity - 1); address_mask_ = ~(maximum_capacity - 1);
...@@ -1609,6 +1613,7 @@ bool SemiSpace::Commit() { ...@@ -1609,6 +1613,7 @@ bool SemiSpace::Commit() {
start_, total_capacity_, executable())) { start_, total_capacity_, executable())) {
return false; return false;
} }
AccountCommitted(total_capacity_);
NewSpacePage* current = anchor(); NewSpacePage* current = anchor();
for (int i = 0; i < pages; i++) { for (int i = 0; i < pages; i++) {
...@@ -1632,6 +1637,8 @@ bool SemiSpace::Uncommit() { ...@@ -1632,6 +1637,8 @@ bool SemiSpace::Uncommit() {
total_capacity_)) { total_capacity_)) {
return false; return false;
} }
AccountUncommitted(total_capacity_);
anchor()->set_next_page(anchor()); anchor()->set_next_page(anchor());
anchor()->set_prev_page(anchor()); anchor()->set_prev_page(anchor());
...@@ -1668,6 +1675,7 @@ bool SemiSpace::GrowTo(int new_capacity) { ...@@ -1668,6 +1675,7 @@ bool SemiSpace::GrowTo(int new_capacity) {
start_ + total_capacity_, delta, executable())) { start_ + total_capacity_, delta, executable())) {
return false; return false;
} }
AccountCommitted(static_cast<intptr_t>(delta));
SetCapacity(new_capacity); SetCapacity(new_capacity);
NewSpacePage* last_page = anchor()->prev_page(); NewSpacePage* last_page = anchor()->prev_page();
DCHECK(last_page != anchor()); DCHECK(last_page != anchor());
...@@ -1698,6 +1706,7 @@ bool SemiSpace::ShrinkTo(int new_capacity) { ...@@ -1698,6 +1706,7 @@ bool SemiSpace::ShrinkTo(int new_capacity) {
if (!allocator->UncommitBlock(start_ + new_capacity, delta)) { if (!allocator->UncommitBlock(start_ + new_capacity, delta)) {
return false; return false;
} }
AccountUncommitted(static_cast<intptr_t>(delta));
int pages_after = new_capacity / Page::kPageSize; int pages_after = new_capacity / Page::kPageSize;
NewSpacePage* new_last_page = NewSpacePage* new_last_page =
...@@ -1783,9 +1792,6 @@ void SemiSpace::Swap(SemiSpace* from, SemiSpace* to) { ...@@ -1783,9 +1792,6 @@ void SemiSpace::Swap(SemiSpace* from, SemiSpace* to) {
void SemiSpace::SetCapacity(int new_capacity) { void SemiSpace::SetCapacity(int new_capacity) {
total_capacity_ = new_capacity; total_capacity_ = new_capacity;
if (total_capacity_ > maximum_committed_) {
maximum_committed_ = total_capacity_;
}
} }
...@@ -2863,7 +2869,6 @@ LargeObjectSpace::~LargeObjectSpace() {} ...@@ -2863,7 +2869,6 @@ LargeObjectSpace::~LargeObjectSpace() {}
bool LargeObjectSpace::SetUp() { bool LargeObjectSpace::SetUp() {
first_page_ = NULL; first_page_ = NULL;
size_ = 0; size_ = 0;
maximum_committed_ = 0;
page_count_ = 0; page_count_ = 0;
objects_size_ = 0; objects_size_ = 0;
chunk_map_.Clear(); chunk_map_.Clear();
...@@ -2901,15 +2906,12 @@ AllocationResult LargeObjectSpace::AllocateRaw(int object_size, ...@@ -2901,15 +2906,12 @@ AllocationResult LargeObjectSpace::AllocateRaw(int object_size,
DCHECK(page->area_size() >= object_size); DCHECK(page->area_size() >= object_size);
size_ += static_cast<int>(page->size()); size_ += static_cast<int>(page->size());
AccountCommitted(static_cast<intptr_t>(page->size()));
objects_size_ += object_size; objects_size_ += object_size;
page_count_++; page_count_++;
page->set_next_page(first_page_); page->set_next_page(first_page_);
first_page_ = page; first_page_ = page;
if (size_ > maximum_committed_) {
maximum_committed_ = size_;
}
// Register all MemoryChunk::kAlignment-aligned chunks covered by // Register all MemoryChunk::kAlignment-aligned chunks covered by
// this large page in the chunk map. // this large page in the chunk map.
uintptr_t base = reinterpret_cast<uintptr_t>(page) / MemoryChunk::kAlignment; uintptr_t base = reinterpret_cast<uintptr_t>(page) / MemoryChunk::kAlignment;
...@@ -3013,6 +3015,7 @@ void LargeObjectSpace::FreeUnmarkedObjects() { ...@@ -3013,6 +3015,7 @@ void LargeObjectSpace::FreeUnmarkedObjects() {
heap()->mark_compact_collector()->ReportDeleteIfNeeded(object, heap()->mark_compact_collector()->ReportDeleteIfNeeded(object,
heap()->isolate()); heap()->isolate());
size_ -= static_cast<int>(page->size()); size_ -= static_cast<int>(page->size());
AccountUncommitted(static_cast<intptr_t>(page->size()));
objects_size_ -= object->Size(); objects_size_ -= object->Size();
page_count_--; page_count_--;
......
...@@ -908,7 +908,11 @@ class LargePage : public MemoryChunk { ...@@ -908,7 +908,11 @@ class LargePage : public MemoryChunk {
class Space : public Malloced { class Space : public Malloced {
public: public:
Space(Heap* heap, AllocationSpace id, Executability executable) Space(Heap* heap, AllocationSpace id, Executability executable)
: heap_(heap), id_(id), executable_(executable) {} : heap_(heap),
id_(id),
executable_(executable),
committed_(0),
max_committed_(0) {}
virtual ~Space() {} virtual ~Space() {}
...@@ -920,6 +924,12 @@ class Space : public Malloced { ...@@ -920,6 +924,12 @@ class Space : public Malloced {
// Identity used in error reporting. // Identity used in error reporting.
AllocationSpace identity() { return id_; } AllocationSpace identity() { return id_; }
// Return the total amount committed memory for this space, i.e., allocatable
// memory and page headers.
virtual intptr_t CommittedMemory() { return committed_; }
virtual intptr_t MaximumCommittedMemory() { return max_committed_; }
// Returns allocated size. // Returns allocated size.
virtual intptr_t Size() = 0; virtual intptr_t Size() = 0;
...@@ -927,9 +937,6 @@ class Space : public Malloced { ...@@ -927,9 +937,6 @@ class Space : public Malloced {
// (e.g. see LargeObjectSpace). // (e.g. see LargeObjectSpace).
virtual intptr_t SizeOfObjects() { return Size(); } virtual intptr_t SizeOfObjects() { return Size(); }
// Return the total amount of memory committed for new space.
virtual intptr_t CommittedMemory() = 0;
// Approximate amount of physical memory committed for this space. // Approximate amount of physical memory committed for this space.
virtual size_t CommittedPhysicalMemory() = 0; virtual size_t CommittedPhysicalMemory() = 0;
...@@ -948,10 +955,29 @@ class Space : public Malloced { ...@@ -948,10 +955,29 @@ class Space : public Malloced {
virtual void Print() = 0; virtual void Print() = 0;
#endif #endif
protected:
void AccountCommitted(intptr_t bytes) {
DCHECK_GE(bytes, 0);
committed_ += bytes;
if (committed_ > max_committed_) {
max_committed_ = committed_;
}
}
void AccountUncommitted(intptr_t bytes) {
DCHECK_GE(bytes, 0);
committed_ -= bytes;
DCHECK_GE(committed_, 0);
}
private: private:
Heap* heap_; Heap* heap_;
AllocationSpace id_; AllocationSpace id_;
Executability executable_; Executability executable_;
// Keeps track of committed memory in a space.
intptr_t committed_;
intptr_t max_committed_;
}; };
...@@ -1811,13 +1837,6 @@ class PagedSpace : public Space { ...@@ -1811,13 +1837,6 @@ class PagedSpace : public Space {
// Current capacity without growing (Size() + Available()). // Current capacity without growing (Size() + Available()).
intptr_t Capacity() { return accounting_stats_.Capacity(); } intptr_t Capacity() { return accounting_stats_.Capacity(); }
// Total amount of memory committed for this space. For paged
// spaces this equals the capacity.
intptr_t CommittedMemory() override { return Capacity(); }
// The maximum amount of memory ever committed for this space.
intptr_t MaximumCommittedMemory() { return accounting_stats_.MaxCapacity(); }
// Approximate amount of physical memory committed for this space. // Approximate amount of physical memory committed for this space.
size_t CommittedPhysicalMemory() override; size_t CommittedPhysicalMemory() override;
...@@ -2285,11 +2304,6 @@ class SemiSpace : public Space { ...@@ -2285,11 +2304,6 @@ class SemiSpace : public Space {
intptr_t SizeOfObjects() override { return Size(); } intptr_t SizeOfObjects() override { return Size(); }
intptr_t CommittedMemory() override {
UNREACHABLE();
return 0;
}
intptr_t Available() override { intptr_t Available() override {
UNREACHABLE(); UNREACHABLE();
return 0; return 0;
...@@ -2334,9 +2348,6 @@ class SemiSpace : public Space { ...@@ -2334,9 +2348,6 @@ class SemiSpace : public Space {
static void Swap(SemiSpace* from, SemiSpace* to); static void Swap(SemiSpace* from, SemiSpace* to);
// Returns the maximum amount of memory ever committed by the semi space.
size_t MaximumCommittedMemory() { return maximum_committed_; }
// Approximate amount of physical memory committed for this space. // Approximate amount of physical memory committed for this space.
size_t CommittedPhysicalMemory() override; size_t CommittedPhysicalMemory() override;
...@@ -2356,8 +2367,6 @@ class SemiSpace : public Space { ...@@ -2356,8 +2367,6 @@ class SemiSpace : public Space {
int maximum_total_capacity_; int maximum_total_capacity_;
int initial_total_capacity_; int initial_total_capacity_;
intptr_t maximum_committed_;
// The start address of the space. // The start address of the space.
Address start_; Address start_;
// Used to govern object promotion during mark-compact collection. // Used to govern object promotion during mark-compact collection.
...@@ -2511,16 +2520,15 @@ class NewSpace : public Space { ...@@ -2511,16 +2520,15 @@ class NewSpace : public Space {
return to_space_.TotalCapacity(); return to_space_.TotalCapacity();
} }
// Return the total amount of memory committed for new space. // Committed memory for NewSpace is the committed memory of both semi-spaces
// combined.
intptr_t CommittedMemory() override { intptr_t CommittedMemory() override {
if (from_space_.is_committed()) return 2 * Capacity(); return from_space_.CommittedMemory() + to_space_.CommittedMemory();
return TotalCapacity();
} }
// Return the total amount of memory committed for new space. intptr_t MaximumCommittedMemory() override {
intptr_t MaximumCommittedMemory() { return from_space_.MaximumCommittedMemory() +
return to_space_.MaximumCommittedMemory() + to_space_.MaximumCommittedMemory();
from_space_.MaximumCommittedMemory();
} }
// Approximate amount of physical memory committed for this space. // Approximate amount of physical memory committed for this space.
...@@ -2888,10 +2896,6 @@ class LargeObjectSpace : public Space { ...@@ -2888,10 +2896,6 @@ class LargeObjectSpace : public Space {
intptr_t SizeOfObjects() override { return objects_size_; } intptr_t SizeOfObjects() override { return objects_size_; }
intptr_t MaximumCommittedMemory() { return maximum_committed_; }
intptr_t CommittedMemory() override { return Size(); }
// Approximate amount of physical memory committed for this space. // Approximate amount of physical memory committed for this space.
size_t CommittedPhysicalMemory() override; size_t CommittedPhysicalMemory() override;
...@@ -2934,7 +2938,6 @@ class LargeObjectSpace : public Space { ...@@ -2934,7 +2938,6 @@ class LargeObjectSpace : public Space {
bool SlowContains(Address addr) { return FindObject(addr)->IsHeapObject(); } bool SlowContains(Address addr) { return FindObject(addr)->IsHeapObject(); }
private: private:
intptr_t maximum_committed_;
// The head of the linked list of large object chunks. // The head of the linked list of large object chunks.
LargePage* first_page_; LargePage* first_page_;
intptr_t size_; // allocated bytes intptr_t size_; // allocated bytes
......
...@@ -620,7 +620,7 @@ UNINITIALIZED_TEST(NewSpaceGrowsToTargetCapacity) { ...@@ -620,7 +620,7 @@ UNINITIALIZED_TEST(NewSpaceGrowsToTargetCapacity) {
// This test doesn't work if we start with a non-default new space // This test doesn't work if we start with a non-default new space
// configuration. // configuration.
if (new_space->InitialTotalCapacity() == Page::kPageSize) { if (new_space->InitialTotalCapacity() == Page::kPageSize) {
CHECK(new_space->CommittedMemory() == new_space->InitialTotalCapacity()); CHECK_EQ(new_space->CommittedMemory(), new_space->InitialTotalCapacity());
// Fill up the first (and only) page of the semi space. // Fill up the first (and only) page of the semi space.
FillCurrentPage(new_space); FillCurrentPage(new_space);
...@@ -631,7 +631,7 @@ UNINITIALIZED_TEST(NewSpaceGrowsToTargetCapacity) { ...@@ -631,7 +631,7 @@ UNINITIALIZED_TEST(NewSpaceGrowsToTargetCapacity) {
v8::internal::AllocationResult allocation = v8::internal::AllocationResult allocation =
new_space->AllocateRawUnaligned(80); new_space->AllocateRawUnaligned(80);
CHECK(!allocation.IsRetry()); CHECK(!allocation.IsRetry());
CHECK(new_space->CommittedMemory() == 2 * Page::kPageSize); CHECK_EQ(new_space->CommittedMemory(), 2 * Page::kPageSize);
// Turn the allocation into a proper object so isolate teardown won't // Turn the allocation into a proper object so isolate teardown won't
// crash. // crash.
......
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