From 723e120bd04aeb4da5b6b5e348cb5eaf28de5c48 Mon Sep 17 00:00:00 2001 From: mlippautz Date: Fri, 15 Apr 2016 06:02:15 -0700 Subject: [PATCH] [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} --- src/heap/heap-inl.h | 8 ++++++++ src/heap/heap.h | 9 ++------ src/heap/spaces-inl.h | 19 +++++++++++++++++ src/heap/spaces.cc | 1 + src/heap/spaces.h | 48 ++++++++++--------------------------------- 5 files changed, 41 insertions(+), 44 deletions(-) diff --git a/src/heap/heap-inl.h b/src/heap/heap-inl.h index bcc82beb6a..da6a481c4b 100644 --- a/src/heap/heap-inl.h +++ b/src/heap/heap-inl.h @@ -460,6 +460,14 @@ void Heap::CopyBlock(Address dst, Address src, int byte_size) { static_cast(byte_size / kPointerSize)); } +void Heap::UpdateNewSpaceAllocationCounter() { + new_space_allocation_counter_ = NewSpaceAllocationCounter(); +} + +size_t Heap::NewSpaceAllocationCounter() { + return new_space_allocation_counter_ + new_space()->AllocatedSinceLastGC(); +} + template AllocationMemento* Heap::FindAllocationMemento(HeapObject* object) { // Check if there is potentially a memento behind the object. If diff --git a/src/heap/heap.h b/src/heap/heap.h index 24eba0fe8d..c9503d3e4d 100644 --- a/src/heap/heap.h +++ b/src/heap/heap.h @@ -1257,13 +1257,8 @@ class Heap { return static_cast(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) { diff --git a/src/heap/spaces-inl.h b/src/heap/spaces-inl.h index 1593ed87ae..db01d0eed9 100644 --- a/src/heap/spaces-inl.h +++ b/src/heap/spaces-inl.h @@ -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(allocated_since_last_gc_ + top_delta - + age_mark_delta); +} + // -------------------------------------------------------------------------- // AllocationResult diff --git a/src/heap/spaces.cc b/src/heap/spaces.cc index 54b7696835..3f42527461 100644 --- a/src/heap/spaces.cc +++ b/src/heap/spaces.cc @@ -1482,6 +1482,7 @@ bool NewSpace::AddFreshPage() { int remaining_in_page = static_cast(limit - top); heap()->CreateFillerObjectAt(top, remaining_in_page, ClearRecordedSlots::kNo); pages_used_++; + allocated_since_last_gc_ += NewSpacePage::kAllocatableMemory; UpdateAllocationInfo(); return true; diff --git a/src/heap/spaces.h b/src/heap/spaces.h index 6832458a16..c7866b64fb 100644 --- a/src/heap/spaces.h +++ b/src/heap/spaces.h @@ -542,6 +542,10 @@ class MemoryChunk { return reinterpret_cast(OffsetFrom(a) & ~kAlignmentMask); } + static intptr_t OffsetInPage(Address a) { + return reinterpret_cast(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(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.