Commit 9c8a7f84 authored by Leszek Swirski's avatar Leszek Swirski Committed by Commit Bot

[heap] Make Heap::Contains const

Add const Page iterators to Spaces, and add whichever const methods are
necessary for this to work. This and a couple more const methods allows
us to make Heap::Contains const.

Change-Id: I1b63a10575ccdb8a3979aef4fa63a97b288ff836
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2198975
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Commit-Queue: Ulan Degenbaev <ulan@chromium.org>
Auto-Submit: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67776}
parent 0062d759
...@@ -415,7 +415,7 @@ bool Heap::CanExpandOldGeneration(size_t size) { ...@@ -415,7 +415,7 @@ bool Heap::CanExpandOldGeneration(size_t size) {
return memory_allocator()->Size() + size <= MaxReserved(); return memory_allocator()->Size() + size <= MaxReserved();
} }
bool Heap::HasBeenSetUp() { bool Heap::HasBeenSetUp() const {
// We will always have a new space when the heap is set up. // We will always have a new space when the heap is set up.
return new_space_ != nullptr; return new_space_ != nullptr;
} }
...@@ -4079,7 +4079,7 @@ const char* Heap::GarbageCollectionReasonToString( ...@@ -4079,7 +4079,7 @@ const char* Heap::GarbageCollectionReasonToString(
UNREACHABLE(); UNREACHABLE();
} }
bool Heap::Contains(HeapObject value) { bool Heap::Contains(HeapObject value) const {
if (V8_ENABLE_THIRD_PARTY_HEAP_BOOL) { if (V8_ENABLE_THIRD_PARTY_HEAP_BOOL) {
return true; return true;
} }
...@@ -4096,7 +4096,7 @@ bool Heap::Contains(HeapObject value) { ...@@ -4096,7 +4096,7 @@ bool Heap::Contains(HeapObject value) {
new_lo_space_->Contains(value)); new_lo_space_->Contains(value));
} }
bool Heap::InSpace(HeapObject value, AllocationSpace space) { bool Heap::InSpace(HeapObject value, AllocationSpace space) const {
if (memory_allocator()->IsOutsideAllocatedSpace(value.address())) { if (memory_allocator()->IsOutsideAllocatedSpace(value.address())) {
return false; return false;
} }
...@@ -4123,7 +4123,7 @@ bool Heap::InSpace(HeapObject value, AllocationSpace space) { ...@@ -4123,7 +4123,7 @@ bool Heap::InSpace(HeapObject value, AllocationSpace space) {
UNREACHABLE(); UNREACHABLE();
} }
bool Heap::InSpaceSlow(Address addr, AllocationSpace space) { bool Heap::InSpaceSlow(Address addr, AllocationSpace space) const {
if (memory_allocator()->IsOutsideAllocatedSpace(addr)) { if (memory_allocator()->IsOutsideAllocatedSpace(addr)) {
return false; return false;
} }
......
...@@ -749,7 +749,7 @@ class Heap { ...@@ -749,7 +749,7 @@ class Heap {
void TearDown(); void TearDown();
// Returns whether SetUp has been called. // Returns whether SetUp has been called.
bool HasBeenSetUp(); bool HasBeenSetUp() const;
// =========================================================================== // ===========================================================================
// Getters for spaces. ======================================================= // Getters for spaces. =======================================================
...@@ -779,6 +779,9 @@ class Heap { ...@@ -779,6 +779,9 @@ class Heap {
GCTracer* tracer() { return tracer_.get(); } GCTracer* tracer() { return tracer_.get(); }
MemoryAllocator* memory_allocator() { return memory_allocator_.get(); } MemoryAllocator* memory_allocator() { return memory_allocator_.get(); }
const MemoryAllocator* memory_allocator() const {
return memory_allocator_.get();
}
inline Isolate* isolate(); inline Isolate* isolate();
...@@ -1107,15 +1110,15 @@ class Heap { ...@@ -1107,15 +1110,15 @@ class Heap {
// Checks whether an address/object is in the non-read-only heap (including // Checks whether an address/object is in the non-read-only heap (including
// auxiliary area and unused area). Use IsValidHeapObject if checking both // auxiliary area and unused area). Use IsValidHeapObject if checking both
// heaps is required. // heaps is required.
V8_EXPORT_PRIVATE bool Contains(HeapObject value); V8_EXPORT_PRIVATE bool Contains(HeapObject value) const;
// Checks whether an address/object in a space. // Checks whether an address/object in a space.
// Currently used by tests, serialization and heap verification only. // Currently used by tests, serialization and heap verification only.
V8_EXPORT_PRIVATE bool InSpace(HeapObject value, AllocationSpace space); V8_EXPORT_PRIVATE bool InSpace(HeapObject value, AllocationSpace space) const;
// Slow methods that can be used for verification as they can also be used // Slow methods that can be used for verification as they can also be used
// with off-heap Addresses. // with off-heap Addresses.
V8_EXPORT_PRIVATE bool InSpaceSlow(Address addr, AllocationSpace space); V8_EXPORT_PRIVATE bool InSpaceSlow(Address addr, AllocationSpace space) const;
static inline Heap* FromWritableHeapObject(HeapObject obj); static inline Heap* FromWritableHeapObject(HeapObject obj);
......
...@@ -68,8 +68,8 @@ class List { ...@@ -68,8 +68,8 @@ class List {
element->list_node().set_next(nullptr); element->list_node().set_next(nullptr);
} }
bool Contains(T* element) { bool Contains(T* element) const {
T* it = front_; const T* it = front_;
while (it) { while (it) {
if (it == element) return true; if (it == element) return true;
it = it->list_node().next(); it = it->list_node().next();
...@@ -77,11 +77,14 @@ class List { ...@@ -77,11 +77,14 @@ class List {
return false; return false;
} }
bool Empty() { return !front_ && !back_; } bool Empty() const { return !front_ && !back_; }
T* front() { return front_; } T* front() { return front_; }
T* back() { return back_; } T* back() { return back_; }
const T* front() const { return front_; }
const T* back() const { return back_; }
private: private:
void AddFirstElement(T* element) { void AddFirstElement(T* element) {
DCHECK(!back_); DCHECK(!back_);
...@@ -129,6 +132,9 @@ class ListNode { ...@@ -129,6 +132,9 @@ class ListNode {
T* next() { return next_; } T* next() { return next_; }
T* prev() { return prev_; } T* prev() { return prev_; }
const T* next() const { return next_; }
const T* prev() const { return prev_; }
void Initialize() { void Initialize() {
next_ = nullptr; next_ = nullptr;
prev_ = nullptr; prev_ = nullptr;
......
...@@ -353,6 +353,7 @@ class MemoryChunk : public BasicMemoryChunk { ...@@ -353,6 +353,7 @@ class MemoryChunk : public BasicMemoryChunk {
} }
heap::ListNode<MemoryChunk>& list_node() { return list_node_; } heap::ListNode<MemoryChunk>& list_node() { return list_node_; }
const heap::ListNode<MemoryChunk>& list_node() const { return list_node_; }
CodeObjectRegistry* GetCodeObjectRegistry() { return code_object_registry_; } CodeObjectRegistry* GetCodeObjectRegistry() { return code_object_registry_; }
......
...@@ -123,19 +123,19 @@ void Space::MoveExternalBackingStoreBytes(ExternalBackingStoreType type, ...@@ -123,19 +123,19 @@ void Space::MoveExternalBackingStoreBytes(ExternalBackingStoreType type,
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// SemiSpace // SemiSpace
bool SemiSpace::Contains(HeapObject o) { bool SemiSpace::Contains(HeapObject o) const {
MemoryChunk* memory_chunk = MemoryChunk::FromHeapObject(o); MemoryChunk* memory_chunk = MemoryChunk::FromHeapObject(o);
if (memory_chunk->IsLargePage()) return false; if (memory_chunk->IsLargePage()) return false;
return id_ == kToSpace ? memory_chunk->IsToPage() return id_ == kToSpace ? memory_chunk->IsToPage()
: memory_chunk->IsFromPage(); : memory_chunk->IsFromPage();
} }
bool SemiSpace::Contains(Object o) { bool SemiSpace::Contains(Object o) const {
return o.IsHeapObject() && Contains(HeapObject::cast(o)); return o.IsHeapObject() && Contains(HeapObject::cast(o));
} }
bool SemiSpace::ContainsSlow(Address a) { bool SemiSpace::ContainsSlow(Address a) const {
for (Page* p : *this) { for (const Page* p : *this) {
if (p == MemoryChunk::FromAddress(a)) return true; if (p == MemoryChunk::FromAddress(a)) return true;
} }
return false; return false;
...@@ -144,33 +144,35 @@ bool SemiSpace::ContainsSlow(Address a) { ...@@ -144,33 +144,35 @@ bool SemiSpace::ContainsSlow(Address a) {
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// NewSpace // NewSpace
bool NewSpace::Contains(Object o) { bool NewSpace::Contains(Object o) const {
return o.IsHeapObject() && Contains(HeapObject::cast(o)); return o.IsHeapObject() && Contains(HeapObject::cast(o));
} }
bool NewSpace::Contains(HeapObject o) { bool NewSpace::Contains(HeapObject o) const {
return MemoryChunk::FromHeapObject(o)->InNewSpace(); return MemoryChunk::FromHeapObject(o)->InNewSpace();
} }
bool NewSpace::ContainsSlow(Address a) { bool NewSpace::ContainsSlow(Address a) const {
return from_space_.ContainsSlow(a) || to_space_.ContainsSlow(a); return from_space_.ContainsSlow(a) || to_space_.ContainsSlow(a);
} }
bool NewSpace::ToSpaceContainsSlow(Address a) { bool NewSpace::ToSpaceContainsSlow(Address a) const {
return to_space_.ContainsSlow(a); return to_space_.ContainsSlow(a);
} }
bool NewSpace::ToSpaceContains(Object o) { return to_space_.Contains(o); } bool NewSpace::ToSpaceContains(Object o) const { return to_space_.Contains(o); }
bool NewSpace::FromSpaceContains(Object o) { return from_space_.Contains(o); } bool NewSpace::FromSpaceContains(Object o) const {
return from_space_.Contains(o);
}
bool PagedSpace::Contains(Address addr) { bool PagedSpace::Contains(Address addr) const {
if (V8_ENABLE_THIRD_PARTY_HEAP_BOOL) { if (V8_ENABLE_THIRD_PARTY_HEAP_BOOL) {
return true; return true;
} }
return Page::FromAddress(addr)->owner() == this; return Page::FromAddress(addr)->owner() == this;
} }
bool PagedSpace::Contains(Object o) { bool PagedSpace::Contains(Object o) const {
if (!o.IsHeapObject()) return false; if (!o.IsHeapObject()) return false;
return Page::FromAddress(o.ptr())->owner() == this; return Page::FromAddress(o.ptr())->owner() == this;
} }
......
...@@ -1628,9 +1628,9 @@ size_t PagedSpace::CommittedPhysicalMemory() { ...@@ -1628,9 +1628,9 @@ size_t PagedSpace::CommittedPhysicalMemory() {
return size; return size;
} }
bool PagedSpace::ContainsSlow(Address addr) { bool PagedSpace::ContainsSlow(Address addr) const {
Page* p = Page::FromAddress(addr); Page* p = Page::FromAddress(addr);
for (Page* page : *this) { for (const Page* page : *this) {
if (page == p) return true; if (page == p) return true;
} }
return false; return false;
......
...@@ -499,6 +499,9 @@ class V8_EXPORT_PRIVATE Space : public Malloced { ...@@ -499,6 +499,9 @@ class V8_EXPORT_PRIVATE Space : public Malloced {
MemoryChunk* first_page() { return memory_chunk_list_.front(); } MemoryChunk* first_page() { return memory_chunk_list_.front(); }
MemoryChunk* last_page() { return memory_chunk_list_.back(); } MemoryChunk* last_page() { return memory_chunk_list_.back(); }
const MemoryChunk* first_page() const { return memory_chunk_list_.front(); }
const MemoryChunk* last_page() const { return memory_chunk_list_.back(); }
heap::List<MemoryChunk>& memory_chunk_list() { return memory_chunk_list_; } heap::List<MemoryChunk>& memory_chunk_list() { return memory_chunk_list_; }
FreeList* free_list() { return free_list_.get(); } FreeList* free_list() { return free_list_.get(); }
...@@ -609,6 +612,13 @@ class Page : public MemoryChunk { ...@@ -609,6 +612,13 @@ class Page : public MemoryChunk {
Page* next_page() { return static_cast<Page*>(list_node_.next()); } Page* next_page() { return static_cast<Page*>(list_node_.next()); }
Page* prev_page() { return static_cast<Page*>(list_node_.prev()); } Page* prev_page() { return static_cast<Page*>(list_node_.prev()); }
const Page* next_page() const {
return static_cast<const Page*>(list_node_.next());
}
const Page* prev_page() const {
return static_cast<const Page*>(list_node_.prev());
}
template <typename Callback> template <typename Callback>
inline void ForAllFreeListCategories(Callback callback) { inline void ForAllFreeListCategories(Callback callback) {
for (int i = kFirstCategory; for (int i = kFirstCategory;
...@@ -848,20 +858,20 @@ class MemoryAllocator { ...@@ -848,20 +858,20 @@ class MemoryAllocator {
void Free(MemoryChunk* chunk); void Free(MemoryChunk* chunk);
// Returns allocated spaces in bytes. // Returns allocated spaces in bytes.
size_t Size() { return size_; } size_t Size() const { return size_; }
// Returns allocated executable spaces in bytes. // Returns allocated executable spaces in bytes.
size_t SizeExecutable() { return size_executable_; } size_t SizeExecutable() const { return size_executable_; }
// Returns the maximum available bytes of heaps. // Returns the maximum available bytes of heaps.
size_t Available() { size_t Available() const {
const size_t size = Size(); const size_t size = Size();
return capacity_ < size ? 0 : capacity_ - size; return capacity_ < size ? 0 : capacity_ - size;
} }
// Returns an indication of whether a pointer is in a space that has // Returns an indication of whether a pointer is in a space that has
// been allocated by this MemoryAllocator. // been allocated by this MemoryAllocator.
V8_INLINE bool IsOutsideAllocatedSpace(Address address) { V8_INLINE bool IsOutsideAllocatedSpace(Address address) const {
return address < lowest_ever_allocated_ || return address < lowest_ever_allocated_ ||
address >= highest_ever_allocated_; address >= highest_ever_allocated_;
} }
...@@ -1107,6 +1117,7 @@ class PageIteratorImpl ...@@ -1107,6 +1117,7 @@ class PageIteratorImpl
}; };
using PageIterator = PageIteratorImpl<Page>; using PageIterator = PageIteratorImpl<Page>;
using ConstPageIterator = PageIteratorImpl<const Page>;
using LargePageIterator = PageIteratorImpl<LargePage>; using LargePageIterator = PageIteratorImpl<LargePage>;
class PageRange { class PageRange {
...@@ -1815,6 +1826,7 @@ class V8_EXPORT_PRIVATE PagedSpace ...@@ -1815,6 +1826,7 @@ class V8_EXPORT_PRIVATE PagedSpace
: NON_EXPORTED_BASE(public SpaceWithLinearArea) { : NON_EXPORTED_BASE(public SpaceWithLinearArea) {
public: public:
using iterator = PageIterator; using iterator = PageIterator;
using const_iterator = ConstPageIterator;
static const size_t kCompactionMemoryWanted = 500 * KB; static const size_t kCompactionMemoryWanted = 500 * KB;
...@@ -1826,9 +1838,9 @@ class V8_EXPORT_PRIVATE PagedSpace ...@@ -1826,9 +1838,9 @@ class V8_EXPORT_PRIVATE PagedSpace
~PagedSpace() override { TearDown(); } ~PagedSpace() override { TearDown(); }
// Checks whether an object/address is in this space. // Checks whether an object/address is in this space.
inline bool Contains(Address a); inline bool Contains(Address a) const;
inline bool Contains(Object o); inline bool Contains(Object o) const;
bool ContainsSlow(Address addr); bool ContainsSlow(Address addr) const;
// Does the space need executable memory? // Does the space need executable memory?
Executability executable() { return executable_; } Executability executable() { return executable_; }
...@@ -2034,10 +2046,16 @@ class V8_EXPORT_PRIVATE PagedSpace ...@@ -2034,10 +2046,16 @@ class V8_EXPORT_PRIVATE PagedSpace
inline size_t RelinkFreeListCategories(Page* page); inline size_t RelinkFreeListCategories(Page* page);
Page* first_page() { return reinterpret_cast<Page*>(Space::first_page()); } Page* first_page() { return reinterpret_cast<Page*>(Space::first_page()); }
const Page* first_page() const {
return reinterpret_cast<const Page*>(Space::first_page());
}
iterator begin() { return iterator(first_page()); } iterator begin() { return iterator(first_page()); }
iterator end() { return iterator(nullptr); } iterator end() { return iterator(nullptr); }
const_iterator begin() const { return const_iterator(first_page()); }
const_iterator end() const { return const_iterator(nullptr); }
// Shrink immortal immovable pages of the space to be exactly the size needed // Shrink immortal immovable pages of the space to be exactly the size needed
// using the high water mark. // using the high water mark.
void ShrinkImmortalImmovablePages(); void ShrinkImmortalImmovablePages();
...@@ -2158,6 +2176,7 @@ enum SemiSpaceId { kFromSpace = 0, kToSpace = 1 }; ...@@ -2158,6 +2176,7 @@ enum SemiSpaceId { kFromSpace = 0, kToSpace = 1 };
class SemiSpace : public Space { class SemiSpace : public Space {
public: public:
using iterator = PageIterator; using iterator = PageIterator;
using const_iterator = ConstPageIterator;
static void Swap(SemiSpace* from, SemiSpace* to); static void Swap(SemiSpace* from, SemiSpace* to);
...@@ -2172,9 +2191,9 @@ class SemiSpace : public Space { ...@@ -2172,9 +2191,9 @@ class SemiSpace : public Space {
current_page_(nullptr), current_page_(nullptr),
pages_used_(0) {} pages_used_(0) {}
inline bool Contains(HeapObject o); inline bool Contains(HeapObject o) const;
inline bool Contains(Object o); inline bool Contains(Object o) const;
inline bool ContainsSlow(Address a); inline bool ContainsSlow(Address a) const;
void SetUp(size_t initial_capacity, size_t maximum_capacity); void SetUp(size_t initial_capacity, size_t maximum_capacity);
void TearDown(); void TearDown();
...@@ -2263,9 +2282,19 @@ class SemiSpace : public Space { ...@@ -2263,9 +2282,19 @@ class SemiSpace : public Space {
Page* first_page() { return reinterpret_cast<Page*>(Space::first_page()); } Page* first_page() { return reinterpret_cast<Page*>(Space::first_page()); }
Page* last_page() { return reinterpret_cast<Page*>(Space::last_page()); } Page* last_page() { return reinterpret_cast<Page*>(Space::last_page()); }
const Page* first_page() const {
return reinterpret_cast<const Page*>(Space::first_page());
}
const Page* last_page() const {
return reinterpret_cast<const Page*>(Space::last_page());
}
iterator begin() { return iterator(first_page()); } iterator begin() { return iterator(first_page()); }
iterator end() { return iterator(nullptr); } iterator end() { return iterator(nullptr); }
const_iterator begin() const { return const_iterator(first_page()); }
const_iterator end() const { return const_iterator(nullptr); }
std::unique_ptr<ObjectIterator> GetObjectIterator(Heap* heap) override; std::unique_ptr<ObjectIterator> GetObjectIterator(Heap* heap) override;
#ifdef DEBUG #ifdef DEBUG
...@@ -2348,15 +2377,16 @@ class V8_EXPORT_PRIVATE NewSpace ...@@ -2348,15 +2377,16 @@ class V8_EXPORT_PRIVATE NewSpace
: NON_EXPORTED_BASE(public SpaceWithLinearArea) { : NON_EXPORTED_BASE(public SpaceWithLinearArea) {
public: public:
using iterator = PageIterator; using iterator = PageIterator;
using const_iterator = ConstPageIterator;
NewSpace(Heap* heap, v8::PageAllocator* page_allocator, NewSpace(Heap* heap, v8::PageAllocator* page_allocator,
size_t initial_semispace_capacity, size_t max_semispace_capacity); size_t initial_semispace_capacity, size_t max_semispace_capacity);
~NewSpace() override { TearDown(); } ~NewSpace() override { TearDown(); }
inline bool ContainsSlow(Address a); inline bool ContainsSlow(Address a) const;
inline bool Contains(Object o); inline bool Contains(Object o) const;
inline bool Contains(HeapObject o); inline bool Contains(HeapObject o) const;
// Tears down the space. Heap memory was not allocated by the space, so it // Tears down the space. Heap memory was not allocated by the space, so it
// is not deallocated here. // is not deallocated here.
...@@ -2530,9 +2560,9 @@ class V8_EXPORT_PRIVATE NewSpace ...@@ -2530,9 +2560,9 @@ class V8_EXPORT_PRIVATE NewSpace
// it in steps to guarantee that the observers are notified periodically. // it in steps to guarantee that the observers are notified periodically.
void UpdateInlineAllocationLimit(size_t size_in_bytes) override; void UpdateInlineAllocationLimit(size_t size_in_bytes) override;
inline bool ToSpaceContainsSlow(Address a); inline bool ToSpaceContainsSlow(Address a) const;
inline bool ToSpaceContains(Object o); inline bool ToSpaceContains(Object o) const;
inline bool FromSpaceContains(Object o); inline bool FromSpaceContains(Object o) const;
// Try to switch the active semispace to a new, empty, page. // Try to switch the active semispace to a new, empty, page.
// Returns false if this isn't possible or reasonable (i.e., there // Returns false if this isn't possible or reasonable (i.e., there
...@@ -2572,6 +2602,9 @@ class V8_EXPORT_PRIVATE NewSpace ...@@ -2572,6 +2602,9 @@ class V8_EXPORT_PRIVATE NewSpace
iterator begin() { return to_space_.begin(); } iterator begin() { return to_space_.begin(); }
iterator end() { return to_space_.end(); } iterator end() { return to_space_.end(); }
const_iterator begin() const { return to_space_.begin(); }
const_iterator end() const { return to_space_.end(); }
std::unique_ptr<ObjectIterator> GetObjectIterator(Heap* heap) override; std::unique_ptr<ObjectIterator> GetObjectIterator(Heap* heap) override;
SemiSpace& from_space() { return from_space_; } SemiSpace& from_space() { return from_space_; }
......
...@@ -12,6 +12,7 @@ namespace heap { ...@@ -12,6 +12,7 @@ namespace heap {
class TestChunk { class TestChunk {
public: public:
heap::ListNode<TestChunk>& list_node() { return list_node_; } heap::ListNode<TestChunk>& list_node() { return list_node_; }
const heap::ListNode<TestChunk>& list_node() const { return list_node_; }
heap::ListNode<TestChunk> list_node_; heap::ListNode<TestChunk> list_node_;
}; };
......
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