diff options
Diffstat (limited to 'deps/v8/src/heap/read-only-heap.cc')
-rw-r--r-- | deps/v8/src/heap/read-only-heap.cc | 85 |
1 files changed, 50 insertions, 35 deletions
diff --git a/deps/v8/src/heap/read-only-heap.cc b/deps/v8/src/heap/read-only-heap.cc index 1021bc147f..c325aea7e6 100644 --- a/deps/v8/src/heap/read-only-heap.cc +++ b/deps/v8/src/heap/read-only-heap.cc @@ -6,6 +6,7 @@ #include <cstring> +#include "src/base/lsan.h" #include "src/base/once.h" #include "src/heap/heap-inl.h" #include "src/heap/heap-write-barrier-inl.h" @@ -20,29 +21,53 @@ namespace internal { #ifdef V8_SHARED_RO_HEAP V8_DECLARE_ONCE(setup_ro_heap_once); -ReadOnlyHeap* shared_ro_heap = nullptr; +ReadOnlyHeap* ReadOnlyHeap::shared_ro_heap_ = nullptr; #endif // static void ReadOnlyHeap::SetUp(Isolate* isolate, ReadOnlyDeserializer* des) { DCHECK_NOT_NULL(isolate); #ifdef V8_SHARED_RO_HEAP - // Make sure we are only sharing read-only space when deserializing. Otherwise - // we would be trying to create heap objects inside an already initialized - // read-only space. Use ClearSharedHeapForTest if you need a new read-only - // space. - DCHECK_IMPLIES(shared_ro_heap != nullptr, des != nullptr); - - base::CallOnce(&setup_ro_heap_once, [isolate, des]() { - shared_ro_heap = CreateAndAttachToIsolate(isolate); - if (des != nullptr) shared_ro_heap->DeseralizeIntoIsolate(isolate, des); - }); - - isolate->heap()->SetUpFromReadOnlyHeap(shared_ro_heap); + bool call_once_ran = false; + base::Optional<Checksum> des_checksum; +#ifdef DEBUG + if (des != nullptr) des_checksum = des->GetChecksum(); +#endif // DEBUG + + base::CallOnce(&setup_ro_heap_once, + [isolate, des, des_checksum, &call_once_ran]() { + USE(des_checksum); + shared_ro_heap_ = CreateAndAttachToIsolate(isolate); + if (des != nullptr) { +#ifdef DEBUG + shared_ro_heap_->read_only_blob_checksum_ = des_checksum; +#endif // DEBUG + shared_ro_heap_->DeseralizeIntoIsolate(isolate, des); + } + call_once_ran = true; + }); + + USE(call_once_ran); + USE(des_checksum); +#ifdef DEBUG + const base::Optional<Checksum> last_checksum = + shared_ro_heap_->read_only_blob_checksum_; + if (last_checksum || des_checksum) { + // The read-only heap was set up from a snapshot. Make sure it's the always + // the same snapshot. + CHECK_EQ(last_checksum, des_checksum); + } else { + // The read-only heap objects were created. Make sure this happens only + // once, during this call. + CHECK(call_once_ran); + } +#endif // DEBUG + + isolate->SetUpFromReadOnlyHeap(shared_ro_heap_); if (des != nullptr) { void* const isolate_ro_roots = reinterpret_cast<void*>( isolate->roots_table().read_only_roots_begin().address()); - std::memcpy(isolate_ro_roots, shared_ro_heap->read_only_roots_, + std::memcpy(isolate_ro_roots, shared_ro_heap_->read_only_roots_, kEntriesCount * sizeof(Address)); } #else @@ -66,7 +91,7 @@ void ReadOnlyHeap::OnCreateHeapObjectsComplete(Isolate* isolate) { // static ReadOnlyHeap* ReadOnlyHeap::CreateAndAttachToIsolate(Isolate* isolate) { auto* ro_heap = new ReadOnlyHeap(new ReadOnlySpace(isolate->heap())); - isolate->heap()->SetUpFromReadOnlyHeap(ro_heap); + isolate->SetUpFromReadOnlyHeap(ro_heap); return ro_heap; } @@ -77,6 +102,9 @@ void ReadOnlyHeap::InitFromIsolate(Isolate* isolate) { isolate->roots_table().read_only_roots_begin().address()); std::memcpy(read_only_roots_, isolate_ro_roots, kEntriesCount * sizeof(Address)); + // N.B. Since pages are manually allocated with mmap, Lsan doesn't track + // their pointers. Seal explicitly ignores the necessary objects. + LSAN_IGNORE_OBJECT(this); read_only_space_->Seal(ReadOnlySpace::SealMode::kDetachFromHeapAndForget); #else read_only_space_->Seal(ReadOnlySpace::SealMode::kDoNotDetachFromHeap); @@ -94,30 +122,17 @@ void ReadOnlyHeap::OnHeapTearDown() { // static void ReadOnlyHeap::ClearSharedHeapForTest() { #ifdef V8_SHARED_RO_HEAP - DCHECK_NOT_NULL(shared_ro_heap); + DCHECK_NOT_NULL(shared_ro_heap_); // TODO(v8:7464): Just leak read-only space for now. The paged-space heap // is null so there isn't a nice way to do this. - delete shared_ro_heap; - shared_ro_heap = nullptr; + shared_ro_heap_ = nullptr; setup_ro_heap_once = 0; #endif } // static bool ReadOnlyHeap::Contains(HeapObject object) { - return Page::FromAddress(object.ptr())->owner()->identity() == RO_SPACE; -} - -// static -ReadOnlyRoots ReadOnlyHeap::GetReadOnlyRoots(HeapObject object) { -#ifdef V8_SHARED_RO_HEAP - // This fails if we are creating heap objects and the roots haven't yet been - // copied into the read-only heap or it has been cleared for testing. - if (shared_ro_heap != nullptr && shared_ro_heap->init_complete_) { - return ReadOnlyRoots(shared_ro_heap->read_only_roots_); - } -#endif - return ReadOnlyRoots(GetHeapFromWritableObject(object)); + return MemoryChunk::FromHeapObject(object)->InReadOnlySpace(); } Object* ReadOnlyHeap::ExtendReadOnlyObjectCache() { @@ -134,15 +149,15 @@ bool ReadOnlyHeap::read_only_object_cache_is_initialized() const { return read_only_object_cache_.size() > 0; } -ReadOnlyHeapIterator::ReadOnlyHeapIterator(ReadOnlyHeap* ro_heap) - : ReadOnlyHeapIterator(ro_heap->read_only_space()) {} +ReadOnlyHeapObjectIterator::ReadOnlyHeapObjectIterator(ReadOnlyHeap* ro_heap) + : ReadOnlyHeapObjectIterator(ro_heap->read_only_space()) {} -ReadOnlyHeapIterator::ReadOnlyHeapIterator(ReadOnlySpace* ro_space) +ReadOnlyHeapObjectIterator::ReadOnlyHeapObjectIterator(ReadOnlySpace* ro_space) : ro_space_(ro_space), current_page_(ro_space->first_page()), current_addr_(current_page_->area_start()) {} -HeapObject ReadOnlyHeapIterator::Next() { +HeapObject ReadOnlyHeapObjectIterator::Next() { if (current_page_ == nullptr) { return HeapObject(); } |