[heap] Optimize NewSpace::AllocatedSinceLastGC

Replace page link walking with arithmetic computation.

BUG=chromium:603460
LOG=N

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

Cr-Commit-Position: refs/heads/master@{#35529}
This commit is contained in:
mlippautz 2016-04-15 06:02:15 -07:00 committed by Commit bot
parent 00a589d9ff
commit 723e120bd0
5 changed files with 41 additions and 44 deletions

View File

@ -460,6 +460,14 @@ void Heap::CopyBlock(Address dst, Address src, int byte_size) {
static_cast<size_t>(byte_size / kPointerSize));
}
void Heap::UpdateNewSpaceAllocationCounter() {
new_space_allocation_counter_ = NewSpaceAllocationCounter();
}
size_t Heap::NewSpaceAllocationCounter() {
return new_space_allocation_counter_ + new_space()->AllocatedSinceLastGC();
}
template <Heap::FindMementoMode mode>
AllocationMemento* Heap::FindAllocationMemento(HeapObject* object) {
// Check if there is potentially a memento behind the object. If

View File

@ -1257,13 +1257,8 @@ class Heap {
return static_cast<intptr_t>(total);
}
void UpdateNewSpaceAllocationCounter() {
new_space_allocation_counter_ = NewSpaceAllocationCounter();
}
size_t NewSpaceAllocationCounter() {
return new_space_allocation_counter_ + new_space()->AllocatedSinceLastGC();
}
inline void UpdateNewSpaceAllocationCounter();
inline size_t NewSpaceAllocationCounter();
// This should be used only for testing.
void set_new_space_allocation_counter(size_t new_value) {

View File

@ -243,6 +243,25 @@ bool NewSpace::FromSpaceContainsSlow(Address a) {
bool NewSpace::ToSpaceContains(Object* o) { return to_space_.Contains(o); }
bool NewSpace::FromSpaceContains(Object* o) { return from_space_.Contains(o); }
size_t NewSpace::AllocatedSinceLastGC() {
const intptr_t age_mark_offset =
NewSpacePage::OffsetInPage(to_space_.age_mark());
const intptr_t top_offset =
NewSpacePage::OffsetInPage(allocation_info_.top());
const intptr_t age_mark_delta =
age_mark_offset >= NewSpacePage::kObjectStartOffset
? age_mark_offset - NewSpacePage::kObjectStartOffset
: NewSpacePage::kAllocatableMemory;
const intptr_t top_delta = top_offset >= NewSpacePage::kObjectStartOffset
? top_offset - NewSpacePage::kObjectStartOffset
: NewSpacePage::kAllocatableMemory;
DCHECK((allocated_since_last_gc_ > 0) ||
(NewSpacePage::FromLimit(allocation_info_.top()) ==
NewSpacePage::FromLimit(to_space_.age_mark())));
return static_cast<size_t>(allocated_since_last_gc_ + top_delta -
age_mark_delta);
}
// --------------------------------------------------------------------------
// AllocationResult

View File

@ -1482,6 +1482,7 @@ bool NewSpace::AddFreshPage() {
int remaining_in_page = static_cast<int>(limit - top);
heap()->CreateFillerObjectAt(top, remaining_in_page, ClearRecordedSlots::kNo);
pages_used_++;
allocated_since_last_gc_ += NewSpacePage::kAllocatableMemory;
UpdateAllocationInfo();
return true;

View File

@ -542,6 +542,10 @@ class MemoryChunk {
return reinterpret_cast<MemoryChunk*>(OffsetFrom(a) & ~kAlignmentMask);
}
static intptr_t OffsetInPage(Address a) {
return reinterpret_cast<intptr_t>(a) & kPageAlignmentMask;
}
static inline MemoryChunk* FromAnyPointerAddress(Heap* heap, Address addr);
static inline void UpdateHighWaterMark(Address mark) {
@ -2582,6 +2586,7 @@ class NewSpace : public Space {
from_space_(heap, kFromSpace),
reservation_(),
pages_used_(0),
allocated_since_last_gc_(0),
top_on_previous_step_(0),
allocated_histogram_(nullptr),
promoted_histogram_(nullptr) {}
@ -2653,42 +2658,7 @@ class NewSpace : public Space {
// Return the available bytes without growing.
intptr_t Available() override { return Capacity() - Size(); }
size_t AllocatedSinceLastGC() {
bool seen_age_mark = false;
Address age_mark = to_space_.age_mark();
NewSpacePage* current_page = to_space_.first_page();
NewSpacePage* age_mark_page = NewSpacePage::FromAddress(age_mark);
NewSpacePage* last_page = NewSpacePage::FromAddress(top() - kPointerSize);
if (age_mark_page == last_page) {
if (top() - age_mark >= 0) {
return top() - age_mark;
}
// Top was reset at some point, invalidating this metric.
return 0;
}
while (current_page != last_page) {
if (current_page == age_mark_page) {
seen_age_mark = true;
break;
}
current_page = current_page->next_page();
}
if (!seen_age_mark) {
// Top was reset at some point, invalidating this metric.
return 0;
}
intptr_t allocated = age_mark_page->area_end() - age_mark;
DCHECK_EQ(current_page, age_mark_page);
current_page = age_mark_page->next_page();
while (current_page != last_page) {
allocated += NewSpacePage::kAllocatableMemory;
current_page = current_page->next_page();
}
allocated += top() - current_page->area_start();
DCHECK_LE(0, allocated);
DCHECK_LE(allocated, Size());
return static_cast<size_t>(allocated);
}
inline size_t AllocatedSinceLastGC();
// Return the maximum capacity of a semispace.
int MaximumCapacity() {
@ -2722,7 +2692,10 @@ class NewSpace : public Space {
// Get the age mark of the inactive semispace.
Address age_mark() { return from_space_.age_mark(); }
// Set the age mark in the active semispace.
void set_age_mark(Address mark) { to_space_.set_age_mark(mark); }
void set_age_mark(Address mark) {
to_space_.set_age_mark(mark);
allocated_since_last_gc_ = 0;
}
// The allocation top and limit address.
Address* allocation_top_address() { return allocation_info_.top_address(); }
@ -2843,6 +2816,7 @@ class NewSpace : public Space {
SemiSpace from_space_;
base::VirtualMemory reservation_;
int pages_used_;
intptr_t allocated_since_last_gc_;
// Allocation pointer and limit for normal allocation and allocation during
// mark-compact collection.