aboutsummaryrefslogtreecommitdiff
path: root/deps/v8/src/heap/read-only-heap.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/heap/read-only-heap.cc')
-rw-r--r--deps/v8/src/heap/read-only-heap.cc85
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();
}