Commit 7485b129 authored by Dan Elphick's avatar Dan Elphick Committed by Commit Bot

[heap] Start making ReadOnlySpace Pages relocatable

Adds Page::MakeHeaderRelocatable that clears pointers to objects
outside the space. In this case relocatable means the entire page
heading is position independent in memory, meaning it could be saved to
disk and reloaded at a different memory location in a new process
without there being any invalid pointers.

Currently this only affects mutex_, locate_tracker_ and reservation_.

Additionally makes VerifyHeap work when there's no mutex in a Page.

This is just a stepping stone to making the Pages headers relocatable
since heap_ and owner_ still point out of the Page.

Also removes the empty ReadOnlySpace destructor.

Bug: v8:7464
Change-Id: Ife3c06575fa73a5818c4991fb9bec30a5f43901d
Reviewed-on: https://chromium-review.googlesource.com/1054879Reviewed-by: 's avatarHannes Payer <hpayer@chromium.org>
Commit-Queue: Dan Elphick <delphick@chromium.org>
Cr-Commit-Position: refs/heads/master@{#53196}
parent b1fb9e90
......@@ -203,11 +203,21 @@ typedef LazyStaticInstance<RecursiveMutex,
// object was created, the LockGuard is destructed and the mutex is released.
// The LockGuard class is non-copyable.
template <typename Mutex>
// Controls whether a LockGuard always requires a valid Mutex or will just
// ignore it if it's nullptr.
enum class NullBehavior { kRequireNotNull, kIgnoreIfNull };
template <typename Mutex, NullBehavior Behavior = NullBehavior::kRequireNotNull>
class LockGuard final {
public:
explicit LockGuard(Mutex* mutex) : mutex_(mutex) { mutex_->Lock(); }
~LockGuard() { mutex_->Unlock(); }
explicit LockGuard(Mutex* mutex) : mutex_(mutex) {
if (Behavior == NullBehavior::kRequireNotNull || mutex_ != nullptr) {
mutex_->Lock();
}
}
~LockGuard() {
if (mutex_ != nullptr) mutex_->Unlock();
}
private:
Mutex* mutex_;
......
......@@ -3804,7 +3804,10 @@ void CollectSlots(MemoryChunk* chunk, Address start, Address end,
void Heap::VerifyRememberedSetFor(HeapObject* object) {
MemoryChunk* chunk = MemoryChunk::FromAddress(object->address());
base::LockGuard<base::Mutex> lock_guard(chunk->mutex());
DCHECK_IMPLIES(chunk->mutex() == nullptr, InReadOnlySpace(object));
// In RO_SPACE chunk->mutex() may be nullptr, so just ignore it.
base::LockGuard<base::Mutex, base::NullBehavior::kIgnoreIfNull> lock_guard(
chunk->mutex());
Address start = object->address();
Address end = start + object->Size();
std::set<Address> old_to_new;
......
......@@ -3190,10 +3190,24 @@ ReadOnlySpace::ReadOnlySpace(Heap* heap, AllocationSpace id,
is_string_padding_cleared_(heap->isolate()->initialized_from_snapshot()) {
}
void ReadOnlyPage::MakeHeaderRelocatable() {
if (mutex_ != nullptr) {
// TODO(v8:7464): heap_ and owner_ need to be cleared as well.
delete mutex_;
mutex_ = nullptr;
local_tracker_ = nullptr;
reservation_.Reset();
}
}
void ReadOnlySpace::SetPermissionsForPages(PageAllocator::Permission access) {
const size_t page_size = MemoryAllocator::GetCommitPageSize();
const size_t area_start_offset = RoundUp(Page::kObjectStartOffset, page_size);
for (Page* page : *this) {
for (Page* p : *this) {
ReadOnlyPage* page = static_cast<ReadOnlyPage*>(p);
if (access == PageAllocator::kRead) {
page->MakeHeaderRelocatable();
}
CHECK(SetPermissions(page->address() + area_start_offset,
page->size() - area_start_offset, access));
}
......
......@@ -868,6 +868,13 @@ class Page : public MemoryChunk {
friend class MemoryAllocator;
};
class ReadOnlyPage : public Page {
public:
// Clears any pointers in the header that point out of the page that would
// otherwise make the header non-relocatable.
void MakeHeaderRelocatable();
};
class LargePage : public MemoryChunk {
public:
HeapObject* GetObject() { return HeapObject::FromAddress(area_start()); }
......@@ -2935,11 +2942,6 @@ class ReadOnlySpace : public PagedSpace {
ReadOnlySpace(Heap* heap, AllocationSpace id, Executability executable);
~ReadOnlySpace() {
// Mark as writable as tearing down the space writes to it.
// MarkAsReadWrite();
}
void ClearStringPaddingIfNeeded();
void MarkAsReadOnly();
......
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