[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: Ulan Degenbaev <ulan@chromium.org> Cr-Commit-Position: refs/heads/master@{#67776}
This commit is contained in:
parent
0062d7594c
commit
9c8a7f84ce
@ -415,7 +415,7 @@ bool Heap::CanExpandOldGeneration(size_t size) {
|
||||
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.
|
||||
return new_space_ != nullptr;
|
||||
}
|
||||
@ -4079,7 +4079,7 @@ const char* Heap::GarbageCollectionReasonToString(
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
bool Heap::Contains(HeapObject value) {
|
||||
bool Heap::Contains(HeapObject value) const {
|
||||
if (V8_ENABLE_THIRD_PARTY_HEAP_BOOL) {
|
||||
return true;
|
||||
}
|
||||
@ -4096,7 +4096,7 @@ bool Heap::Contains(HeapObject 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())) {
|
||||
return false;
|
||||
}
|
||||
@ -4123,7 +4123,7 @@ bool Heap::InSpace(HeapObject value, AllocationSpace space) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
bool Heap::InSpaceSlow(Address addr, AllocationSpace space) {
|
||||
bool Heap::InSpaceSlow(Address addr, AllocationSpace space) const {
|
||||
if (memory_allocator()->IsOutsideAllocatedSpace(addr)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -749,7 +749,7 @@ class Heap {
|
||||
void TearDown();
|
||||
|
||||
// Returns whether SetUp has been called.
|
||||
bool HasBeenSetUp();
|
||||
bool HasBeenSetUp() const;
|
||||
|
||||
// ===========================================================================
|
||||
// Getters for spaces. =======================================================
|
||||
@ -779,6 +779,9 @@ class Heap {
|
||||
GCTracer* tracer() { return tracer_.get(); }
|
||||
|
||||
MemoryAllocator* memory_allocator() { return memory_allocator_.get(); }
|
||||
const MemoryAllocator* memory_allocator() const {
|
||||
return memory_allocator_.get();
|
||||
}
|
||||
|
||||
inline Isolate* isolate();
|
||||
|
||||
@ -1107,15 +1110,15 @@ class Heap {
|
||||
// Checks whether an address/object is in the non-read-only heap (including
|
||||
// auxiliary area and unused area). Use IsValidHeapObject if checking both
|
||||
// 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.
|
||||
// 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
|
||||
// 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);
|
||||
|
||||
|
@ -68,8 +68,8 @@ class List {
|
||||
element->list_node().set_next(nullptr);
|
||||
}
|
||||
|
||||
bool Contains(T* element) {
|
||||
T* it = front_;
|
||||
bool Contains(T* element) const {
|
||||
const T* it = front_;
|
||||
while (it) {
|
||||
if (it == element) return true;
|
||||
it = it->list_node().next();
|
||||
@ -77,11 +77,14 @@ class List {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Empty() { return !front_ && !back_; }
|
||||
bool Empty() const { return !front_ && !back_; }
|
||||
|
||||
T* front() { return front_; }
|
||||
T* back() { return back_; }
|
||||
|
||||
const T* front() const { return front_; }
|
||||
const T* back() const { return back_; }
|
||||
|
||||
private:
|
||||
void AddFirstElement(T* element) {
|
||||
DCHECK(!back_);
|
||||
@ -129,6 +132,9 @@ class ListNode {
|
||||
T* next() { return next_; }
|
||||
T* prev() { return prev_; }
|
||||
|
||||
const T* next() const { return next_; }
|
||||
const T* prev() const { return prev_; }
|
||||
|
||||
void Initialize() {
|
||||
next_ = nullptr;
|
||||
prev_ = nullptr;
|
||||
|
@ -353,6 +353,7 @@ class MemoryChunk : public BasicMemoryChunk {
|
||||
}
|
||||
|
||||
heap::ListNode<MemoryChunk>& list_node() { return list_node_; }
|
||||
const heap::ListNode<MemoryChunk>& list_node() const { return list_node_; }
|
||||
|
||||
CodeObjectRegistry* GetCodeObjectRegistry() { return code_object_registry_; }
|
||||
|
||||
|
@ -123,19 +123,19 @@ void Space::MoveExternalBackingStoreBytes(ExternalBackingStoreType type,
|
||||
// -----------------------------------------------------------------------------
|
||||
// SemiSpace
|
||||
|
||||
bool SemiSpace::Contains(HeapObject o) {
|
||||
bool SemiSpace::Contains(HeapObject o) const {
|
||||
MemoryChunk* memory_chunk = MemoryChunk::FromHeapObject(o);
|
||||
if (memory_chunk->IsLargePage()) return false;
|
||||
return id_ == kToSpace ? memory_chunk->IsToPage()
|
||||
: memory_chunk->IsFromPage();
|
||||
}
|
||||
|
||||
bool SemiSpace::Contains(Object o) {
|
||||
bool SemiSpace::Contains(Object o) const {
|
||||
return o.IsHeapObject() && Contains(HeapObject::cast(o));
|
||||
}
|
||||
|
||||
bool SemiSpace::ContainsSlow(Address a) {
|
||||
for (Page* p : *this) {
|
||||
bool SemiSpace::ContainsSlow(Address a) const {
|
||||
for (const Page* p : *this) {
|
||||
if (p == MemoryChunk::FromAddress(a)) return true;
|
||||
}
|
||||
return false;
|
||||
@ -144,33 +144,35 @@ bool SemiSpace::ContainsSlow(Address a) {
|
||||
// --------------------------------------------------------------------------
|
||||
// NewSpace
|
||||
|
||||
bool NewSpace::Contains(Object o) {
|
||||
bool NewSpace::Contains(Object o) const {
|
||||
return o.IsHeapObject() && Contains(HeapObject::cast(o));
|
||||
}
|
||||
|
||||
bool NewSpace::Contains(HeapObject o) {
|
||||
bool NewSpace::Contains(HeapObject o) const {
|
||||
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);
|
||||
}
|
||||
|
||||
bool NewSpace::ToSpaceContainsSlow(Address a) {
|
||||
bool NewSpace::ToSpaceContainsSlow(Address a) const {
|
||||
return to_space_.ContainsSlow(a);
|
||||
}
|
||||
|
||||
bool NewSpace::ToSpaceContains(Object o) { return to_space_.Contains(o); }
|
||||
bool NewSpace::FromSpaceContains(Object o) { return from_space_.Contains(o); }
|
||||
bool NewSpace::ToSpaceContains(Object o) const { return to_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) {
|
||||
return true;
|
||||
}
|
||||
return Page::FromAddress(addr)->owner() == this;
|
||||
}
|
||||
|
||||
bool PagedSpace::Contains(Object o) {
|
||||
bool PagedSpace::Contains(Object o) const {
|
||||
if (!o.IsHeapObject()) return false;
|
||||
return Page::FromAddress(o.ptr())->owner() == this;
|
||||
}
|
||||
|
@ -1628,9 +1628,9 @@ size_t PagedSpace::CommittedPhysicalMemory() {
|
||||
return size;
|
||||
}
|
||||
|
||||
bool PagedSpace::ContainsSlow(Address addr) {
|
||||
bool PagedSpace::ContainsSlow(Address addr) const {
|
||||
Page* p = Page::FromAddress(addr);
|
||||
for (Page* page : *this) {
|
||||
for (const Page* page : *this) {
|
||||
if (page == p) return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -499,6 +499,9 @@ class V8_EXPORT_PRIVATE Space : public Malloced {
|
||||
MemoryChunk* first_page() { return memory_chunk_list_.front(); }
|
||||
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_; }
|
||||
|
||||
FreeList* free_list() { return free_list_.get(); }
|
||||
@ -609,6 +612,13 @@ class Page : public MemoryChunk {
|
||||
Page* next_page() { return static_cast<Page*>(list_node_.next()); }
|
||||
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>
|
||||
inline void ForAllFreeListCategories(Callback callback) {
|
||||
for (int i = kFirstCategory;
|
||||
@ -848,20 +858,20 @@ class MemoryAllocator {
|
||||
void Free(MemoryChunk* chunk);
|
||||
|
||||
// Returns allocated spaces in bytes.
|
||||
size_t Size() { return size_; }
|
||||
size_t Size() const { return size_; }
|
||||
|
||||
// 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.
|
||||
size_t Available() {
|
||||
size_t Available() const {
|
||||
const size_t size = Size();
|
||||
return capacity_ < size ? 0 : capacity_ - size;
|
||||
}
|
||||
|
||||
// Returns an indication of whether a pointer is in a space that has
|
||||
// been allocated by this MemoryAllocator.
|
||||
V8_INLINE bool IsOutsideAllocatedSpace(Address address) {
|
||||
V8_INLINE bool IsOutsideAllocatedSpace(Address address) const {
|
||||
return address < lowest_ever_allocated_ ||
|
||||
address >= highest_ever_allocated_;
|
||||
}
|
||||
@ -1107,6 +1117,7 @@ class PageIteratorImpl
|
||||
};
|
||||
|
||||
using PageIterator = PageIteratorImpl<Page>;
|
||||
using ConstPageIterator = PageIteratorImpl<const Page>;
|
||||
using LargePageIterator = PageIteratorImpl<LargePage>;
|
||||
|
||||
class PageRange {
|
||||
@ -1815,6 +1826,7 @@ class V8_EXPORT_PRIVATE PagedSpace
|
||||
: NON_EXPORTED_BASE(public SpaceWithLinearArea) {
|
||||
public:
|
||||
using iterator = PageIterator;
|
||||
using const_iterator = ConstPageIterator;
|
||||
|
||||
static const size_t kCompactionMemoryWanted = 500 * KB;
|
||||
|
||||
@ -1826,9 +1838,9 @@ class V8_EXPORT_PRIVATE PagedSpace
|
||||
~PagedSpace() override { TearDown(); }
|
||||
|
||||
// Checks whether an object/address is in this space.
|
||||
inline bool Contains(Address a);
|
||||
inline bool Contains(Object o);
|
||||
bool ContainsSlow(Address addr);
|
||||
inline bool Contains(Address a) const;
|
||||
inline bool Contains(Object o) const;
|
||||
bool ContainsSlow(Address addr) const;
|
||||
|
||||
// Does the space need executable memory?
|
||||
Executability executable() { return executable_; }
|
||||
@ -2034,10 +2046,16 @@ class V8_EXPORT_PRIVATE PagedSpace
|
||||
inline size_t RelinkFreeListCategories(Page* 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 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
|
||||
// using the high water mark.
|
||||
void ShrinkImmortalImmovablePages();
|
||||
@ -2158,6 +2176,7 @@ enum SemiSpaceId { kFromSpace = 0, kToSpace = 1 };
|
||||
class SemiSpace : public Space {
|
||||
public:
|
||||
using iterator = PageIterator;
|
||||
using const_iterator = ConstPageIterator;
|
||||
|
||||
static void Swap(SemiSpace* from, SemiSpace* to);
|
||||
|
||||
@ -2172,9 +2191,9 @@ class SemiSpace : public Space {
|
||||
current_page_(nullptr),
|
||||
pages_used_(0) {}
|
||||
|
||||
inline bool Contains(HeapObject o);
|
||||
inline bool Contains(Object o);
|
||||
inline bool ContainsSlow(Address a);
|
||||
inline bool Contains(HeapObject o) const;
|
||||
inline bool Contains(Object o) const;
|
||||
inline bool ContainsSlow(Address a) const;
|
||||
|
||||
void SetUp(size_t initial_capacity, size_t maximum_capacity);
|
||||
void TearDown();
|
||||
@ -2263,9 +2282,19 @@ class SemiSpace : public Space {
|
||||
Page* first_page() { return reinterpret_cast<Page*>(Space::first_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 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;
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -2348,15 +2377,16 @@ class V8_EXPORT_PRIVATE NewSpace
|
||||
: NON_EXPORTED_BASE(public SpaceWithLinearArea) {
|
||||
public:
|
||||
using iterator = PageIterator;
|
||||
using const_iterator = ConstPageIterator;
|
||||
|
||||
NewSpace(Heap* heap, v8::PageAllocator* page_allocator,
|
||||
size_t initial_semispace_capacity, size_t max_semispace_capacity);
|
||||
|
||||
~NewSpace() override { TearDown(); }
|
||||
|
||||
inline bool ContainsSlow(Address a);
|
||||
inline bool Contains(Object o);
|
||||
inline bool Contains(HeapObject o);
|
||||
inline bool ContainsSlow(Address a) const;
|
||||
inline bool Contains(Object o) const;
|
||||
inline bool Contains(HeapObject o) const;
|
||||
|
||||
// Tears down the space. Heap memory was not allocated by the space, so it
|
||||
// is not deallocated here.
|
||||
@ -2530,9 +2560,9 @@ class V8_EXPORT_PRIVATE NewSpace
|
||||
// it in steps to guarantee that the observers are notified periodically.
|
||||
void UpdateInlineAllocationLimit(size_t size_in_bytes) override;
|
||||
|
||||
inline bool ToSpaceContainsSlow(Address a);
|
||||
inline bool ToSpaceContains(Object o);
|
||||
inline bool FromSpaceContains(Object o);
|
||||
inline bool ToSpaceContainsSlow(Address a) const;
|
||||
inline bool ToSpaceContains(Object o) const;
|
||||
inline bool FromSpaceContains(Object o) const;
|
||||
|
||||
// Try to switch the active semispace to a new, empty, page.
|
||||
// Returns false if this isn't possible or reasonable (i.e., there
|
||||
@ -2572,6 +2602,9 @@ class V8_EXPORT_PRIVATE NewSpace
|
||||
iterator begin() { return to_space_.begin(); }
|
||||
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;
|
||||
|
||||
SemiSpace& from_space() { return from_space_; }
|
||||
|
@ -12,6 +12,7 @@ namespace heap {
|
||||
class TestChunk {
|
||||
public:
|
||||
heap::ListNode<TestChunk>& list_node() { return list_node_; }
|
||||
const heap::ListNode<TestChunk>& list_node() const { return list_node_; }
|
||||
heap::ListNode<TestChunk> list_node_;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user