Commit b0bcd45d authored by Maciej Goszczycki's avatar Maciej Goszczycki Committed by Commit Bot

[heap] Isolate read-only space creation

This provides a single point where read-only space sharing will be
controlled. Eventually ReadOnlyDeserializer will take ReadOnlyHeap
instead of Isolate, first steps include
https://chromium-review.googlesource.com/c/v8/v8/+/1483054

Bug: v8:7464
Change-Id: I213819aeca6fca335235025c9195edf474230eda
Reviewed-on: https://chromium-review.googlesource.com/c/1489087
Commit-Queue: Maciej Goszczycki <goszczycki@google.com>
Reviewed-by: 's avatarDan Elphick <delphick@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59954}
parent 506f79b8
...@@ -2108,6 +2108,8 @@ v8_source_set("v8_base") { ...@@ -2108,6 +2108,8 @@ v8_source_set("v8_base") {
"src/heap/objects-visiting-inl.h", "src/heap/objects-visiting-inl.h",
"src/heap/objects-visiting.cc", "src/heap/objects-visiting.cc",
"src/heap/objects-visiting.h", "src/heap/objects-visiting.h",
"src/heap/read-only-heap.cc",
"src/heap/read-only-heap.h",
"src/heap/remembered-set.h", "src/heap/remembered-set.h",
"src/heap/scavenge-job.cc", "src/heap/scavenge-job.cc",
"src/heap/scavenge-job.h", "src/heap/scavenge-job.h",
......
...@@ -15,6 +15,7 @@ include_rules = [ ...@@ -15,6 +15,7 @@ include_rules = [
"+src/heap/heap-inl.h", "+src/heap/heap-inl.h",
"+src/heap/heap-write-barrier-inl.h", "+src/heap/heap-write-barrier-inl.h",
"+src/heap/heap-write-barrier.h", "+src/heap/heap-write-barrier.h",
"+src/heap/read-only-heap.h",
"-src/inspector", "-src/inspector",
"-src/interpreter", "-src/interpreter",
"+src/interpreter/bytecode-array-accessor.h", "+src/interpreter/bytecode-array-accessor.h",
......
...@@ -584,7 +584,7 @@ SnapshotCreator::SnapshotCreator(Isolate* isolate, ...@@ -584,7 +584,7 @@ SnapshotCreator::SnapshotCreator(Isolate* isolate,
internal_isolate->set_snapshot_blob(blob); internal_isolate->set_snapshot_blob(blob);
i::Snapshot::Initialize(internal_isolate); i::Snapshot::Initialize(internal_isolate);
} else { } else {
internal_isolate->Init(nullptr); internal_isolate->InitWithoutSnapshot();
} }
data_ = data; data_ = data;
} }
...@@ -8209,7 +8209,7 @@ void Isolate::Initialize(Isolate* isolate, ...@@ -8209,7 +8209,7 @@ void Isolate::Initialize(Isolate* isolate,
} }
base::ElapsedTimer timer; base::ElapsedTimer timer;
if (i::FLAG_profile_deserialization) timer.Start(); if (i::FLAG_profile_deserialization) timer.Start();
i_isolate->Init(nullptr); i_isolate->InitWithoutSnapshot();
if (i::FLAG_profile_deserialization) { if (i::FLAG_profile_deserialization) {
double ms = timer.Elapsed().InMillisecondsF(); double ms = timer.Elapsed().InMillisecondsF();
i::PrintF("[Initializing isolate from scratch took %0.3f ms]\n", ms); i::PrintF("[Initializing isolate from scratch took %0.3f ms]\n", ms);
......
...@@ -663,6 +663,8 @@ enum AllocationSpace { ...@@ -663,6 +663,8 @@ enum AllocationSpace {
FIRST_SPACE = RO_SPACE, FIRST_SPACE = RO_SPACE,
LAST_SPACE = NEW_LO_SPACE, LAST_SPACE = NEW_LO_SPACE,
FIRST_MUTABLE_SPACE = NEW_SPACE,
LAST_MUTABLE_SPACE = NEW_LO_SPACE,
FIRST_GROWABLE_PAGED_SPACE = OLD_SPACE, FIRST_GROWABLE_PAGED_SPACE = OLD_SPACE,
LAST_GROWABLE_PAGED_SPACE = MAP_SPACE LAST_GROWABLE_PAGED_SPACE = MAP_SPACE
}; };
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include "src/heap/object-stats.h" #include "src/heap/object-stats.h"
#include "src/heap/objects-visiting-inl.h" #include "src/heap/objects-visiting-inl.h"
#include "src/heap/objects-visiting.h" #include "src/heap/objects-visiting.h"
#include "src/heap/read-only-heap.h"
#include "src/heap/remembered-set.h" #include "src/heap/remembered-set.h"
#include "src/heap/scavenge-job.h" #include "src/heap/scavenge-job.h"
#include "src/heap/scavenger-inl.h" #include "src/heap/scavenger-inl.h"
...@@ -4493,7 +4494,7 @@ HeapObject Heap::AllocateRawCodeInLargeObjectSpace(int size) { ...@@ -4493,7 +4494,7 @@ HeapObject Heap::AllocateRawCodeInLargeObjectSpace(int size) {
return HeapObject(); return HeapObject();
} }
void Heap::SetUp() { void Heap::SetUp(ReadOnlyHeap* ro_heap) {
#ifdef V8_ENABLE_ALLOCATION_TIMEOUT #ifdef V8_ENABLE_ALLOCATION_TIMEOUT
allocation_timeout_ = NextAllocationTimeout(); allocation_timeout_ = NextAllocationTimeout();
#endif #endif
...@@ -4506,6 +4507,9 @@ void Heap::SetUp() { ...@@ -4506,6 +4507,9 @@ void Heap::SetUp() {
// and old_generation_size_ otherwise. // and old_generation_size_ otherwise.
if (!configured_) ConfigureHeapDefault(); if (!configured_) ConfigureHeapDefault();
DCHECK_NOT_NULL(ro_heap);
read_only_heap_ = ro_heap;
mmap_region_base_ = mmap_region_base_ =
reinterpret_cast<uintptr_t>(v8::internal::GetRandomMmapAddr()) & reinterpret_cast<uintptr_t>(v8::internal::GetRandomMmapAddr()) &
~kMmapRegionMask; ~kMmapRegionMask;
...@@ -4541,7 +4545,8 @@ void Heap::SetUp() { ...@@ -4541,7 +4545,8 @@ void Heap::SetUp() {
space_[i] = nullptr; space_[i] = nullptr;
} }
space_[RO_SPACE] = read_only_space_ = new ReadOnlySpace(this); space_[RO_SPACE] = read_only_space_ = ro_heap->read_only_space();
DCHECK_NOT_NULL(read_only_space_);
space_[NEW_SPACE] = new_space_ = space_[NEW_SPACE] = new_space_ =
new NewSpace(this, memory_allocator_->data_page_allocator(), new NewSpace(this, memory_allocator_->data_page_allocator(),
initial_semispace_size_, max_semi_space_size_); initial_semispace_size_, max_semi_space_size_);
...@@ -4818,7 +4823,9 @@ void Heap::TearDown() { ...@@ -4818,7 +4823,9 @@ void Heap::TearDown() {
tracer_.reset(); tracer_.reset();
for (int i = FIRST_SPACE; i <= LAST_SPACE; i++) { read_only_heap_->OnHeapTearDown();
space_[RO_SPACE] = read_only_space_ = nullptr;
for (int i = FIRST_MUTABLE_SPACE; i <= LAST_MUTABLE_SPACE; i++) {
delete space_[i]; delete space_[i];
space_[i] = nullptr; space_[i] = nullptr;
} }
......
...@@ -76,6 +76,7 @@ class ObjectIterator; ...@@ -76,6 +76,7 @@ class ObjectIterator;
class ObjectStats; class ObjectStats;
class Page; class Page;
class PagedSpace; class PagedSpace;
class ReadOnlyHeap;
class RootVisitor; class RootVisitor;
class ScavengeJob; class ScavengeJob;
class Scavenger; class Scavenger;
...@@ -579,7 +580,7 @@ class Heap { ...@@ -579,7 +580,7 @@ class Heap {
// Prepares the heap, setting up memory areas that are needed in the isolate // Prepares the heap, setting up memory areas that are needed in the isolate
// without actually creating any objects. // without actually creating any objects.
void SetUp(); void SetUp(ReadOnlyHeap* ro_heap);
// (Re-)Initialize hash seed from flag or RNG. // (Re-)Initialize hash seed from flag or RNG.
void InitializeHashSeed(); void InitializeHashSeed();
...@@ -625,6 +626,8 @@ class Heap { ...@@ -625,6 +626,8 @@ class Heap {
// Getters to other components. ============================================== // Getters to other components. ==============================================
// =========================================================================== // ===========================================================================
ReadOnlyHeap* read_only_heap() const { return read_only_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(); }
...@@ -1788,6 +1791,8 @@ class Heap { ...@@ -1788,6 +1791,8 @@ class Heap {
// and after context disposal. // and after context disposal.
int number_of_disposed_maps_ = 0; int number_of_disposed_maps_ = 0;
ReadOnlyHeap* read_only_heap_ = nullptr;
NewSpace* new_space_ = nullptr; NewSpace* new_space_ = nullptr;
OldSpace* old_space_ = nullptr; OldSpace* old_space_ = nullptr;
CodeSpace* code_space_ = nullptr; CodeSpace* code_space_ = nullptr;
......
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/heap/read-only-heap.h"
#include "src/heap/spaces.h"
namespace v8 {
namespace internal {
// static
ReadOnlyHeap* ReadOnlyHeap::GetOrCreateReadOnlyHeap(Heap* heap) {
return new ReadOnlyHeap(new ReadOnlySpace(heap));
}
void ReadOnlyHeap::MaybeDeserialize(Isolate* isolate,
ReadOnlyDeserializer* des) {
des->DeserializeInto(isolate);
}
void ReadOnlyHeap::OnHeapTearDown() {
delete read_only_space_;
delete this;
}
} // namespace internal
} // namespace v8
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_HEAP_READ_ONLY_HEAP_H_
#define V8_HEAP_READ_ONLY_HEAP_H_
#include "src/base/macros.h"
#include "src/heap/heap.h"
#include "src/roots.h"
#include "src/snapshot/read-only-deserializer.h"
namespace v8 {
namespace internal {
class ReadOnlySpace;
// This class transparently manages read-only space, roots and cache creation
// and destruction. Eventually this will allow sharing these artifacts between
// isolates.
class ReadOnlyHeap {
public:
static ReadOnlyHeap* GetOrCreateReadOnlyHeap(Heap* heap);
// If necessary, deserialize read-only objects and set up read-only object
// cache.
void MaybeDeserialize(Isolate* isolate, ReadOnlyDeserializer* des);
// Frees ReadOnlySpace and itself when sharing is disabled. No-op otherwise.
// Read-only data should not be used within the current isolate after this is
// called.
void OnHeapTearDown();
std::vector<Object>* read_only_object_cache() {
return &read_only_object_cache_;
}
ReadOnlySpace* read_only_space() const { return read_only_space_; }
private:
ReadOnlySpace* read_only_space_ = nullptr;
std::vector<Object> read_only_object_cache_;
explicit ReadOnlyHeap(ReadOnlySpace* ro_space) : read_only_space_(ro_space) {}
DISALLOW_COPY_AND_ASSIGN(ReadOnlyHeap);
};
} // namespace internal
} // namespace v8
#endif // V8_HEAP_READ_ONLY_HEAP_H_
...@@ -1436,14 +1436,14 @@ class V8_EXPORT_PRIVATE MemoryAllocator { ...@@ -1436,14 +1436,14 @@ class V8_EXPORT_PRIVATE MemoryAllocator {
Unmapper* unmapper() { return &unmapper_; } Unmapper* unmapper() { return &unmapper_; }
private:
void InitializeCodePageAllocator(v8::PageAllocator* page_allocator,
size_t requested);
// PreFree logically frees the object, i.e., it takes care of the size // PreFree logically frees the object, i.e., it takes care of the size
// bookkeeping and calls the allocation callback. // bookkeeping and calls the allocation callback.
void PreFreeMemory(MemoryChunk* chunk); void PreFreeMemory(MemoryChunk* chunk);
private:
void InitializeCodePageAllocator(v8::PageAllocator* page_allocator,
size_t requested);
// FreeMemory can be called concurrently when PreFree was executed before. // FreeMemory can be called concurrently when PreFree was executed before.
void PerformFreeMemory(MemoryChunk* chunk); void PerformFreeMemory(MemoryChunk* chunk);
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include "src/frames-inl.h" #include "src/frames-inl.h"
#include "src/hash-seed-inl.h" #include "src/hash-seed-inl.h"
#include "src/heap/heap-inl.h" #include "src/heap/heap-inl.h"
#include "src/heap/read-only-heap.h"
#include "src/ic/stub-cache.h" #include "src/ic/stub-cache.h"
#include "src/interpreter/interpreter.h" #include "src/interpreter/interpreter.h"
#include "src/isolate-inl.h" #include "src/isolate-inl.h"
...@@ -64,6 +65,7 @@ ...@@ -64,6 +65,7 @@
#include "src/simulator.h" #include "src/simulator.h"
#include "src/snapshot/embedded-data.h" #include "src/snapshot/embedded-data.h"
#include "src/snapshot/embedded-file-writer.h" #include "src/snapshot/embedded-file-writer.h"
#include "src/snapshot/read-only-deserializer.h"
#include "src/snapshot/startup-deserializer.h" #include "src/snapshot/startup-deserializer.h"
#include "src/string-stream.h" #include "src/string-stream.h"
#include "src/tracing/tracing-category-observer.h" #include "src/tracing/tracing-category-observer.h"
...@@ -3262,11 +3264,24 @@ void Isolate::TearDownEmbeddedBlob() { ...@@ -3262,11 +3264,24 @@ void Isolate::TearDownEmbeddedBlob() {
} }
} }
bool Isolate::Init(StartupDeserializer* des) { bool Isolate::InitWithoutSnapshot() { return Init(nullptr, nullptr); }
bool Isolate::InitWithSnapshot(ReadOnlyDeserializer* read_only_deserializer,
StartupDeserializer* startup_deserializer) {
DCHECK_NOT_NULL(read_only_deserializer);
DCHECK_NOT_NULL(startup_deserializer);
return Init(read_only_deserializer, startup_deserializer);
}
bool Isolate::Init(ReadOnlyDeserializer* read_only_deserializer,
StartupDeserializer* startup_deserializer) {
TRACE_ISOLATE(init); TRACE_ISOLATE(init);
const bool create_heap_objects = (read_only_deserializer == nullptr);
// We either have both or neither.
DCHECK_EQ(create_heap_objects, startup_deserializer == nullptr);
base::ElapsedTimer timer; base::ElapsedTimer timer;
if (des == nullptr && FLAG_profile_deserialization) timer.Start(); if (create_heap_objects && FLAG_profile_deserialization) timer.Start();
time_millis_at_init_ = heap_.MonotonicallyIncreasingTimeInMs(); time_millis_at_init_ = heap_.MonotonicallyIncreasingTimeInMs();
...@@ -3320,7 +3335,8 @@ bool Isolate::Init(StartupDeserializer* des) { ...@@ -3320,7 +3335,8 @@ bool Isolate::Init(StartupDeserializer* des) {
// SetUp the object heap. // SetUp the object heap.
DCHECK(!heap_.HasBeenSetUp()); DCHECK(!heap_.HasBeenSetUp());
heap_.SetUp(); auto* read_only_heap = ReadOnlyHeap::GetOrCreateReadOnlyHeap(&heap_);
heap_.SetUp(read_only_heap);
isolate_data_.external_reference_table()->Init(this); isolate_data_.external_reference_table()->Init(this);
...@@ -3332,7 +3348,6 @@ bool Isolate::Init(StartupDeserializer* des) { ...@@ -3332,7 +3348,6 @@ bool Isolate::Init(StartupDeserializer* des) {
deoptimizer_data_ = new DeoptimizerData(heap()); deoptimizer_data_ = new DeoptimizerData(heap());
const bool create_heap_objects = (des == nullptr);
if (setup_delegate_ == nullptr) { if (setup_delegate_ == nullptr) {
setup_delegate_ = new SetupIsolateDelegate(create_heap_objects); setup_delegate_ = new SetupIsolateDelegate(create_heap_objects);
} }
...@@ -3404,7 +3419,10 @@ bool Isolate::Init(StartupDeserializer* des) { ...@@ -3404,7 +3419,10 @@ bool Isolate::Init(StartupDeserializer* des) {
AlwaysAllocateScope always_allocate(this); AlwaysAllocateScope always_allocate(this);
CodeSpaceMemoryModificationScope modification_scope(&heap_); CodeSpaceMemoryModificationScope modification_scope(&heap_);
if (!create_heap_objects) des->DeserializeInto(this); if (!create_heap_objects) {
read_only_heap->MaybeDeserialize(this, read_only_deserializer);
startup_deserializer->DeserializeInto(this);
}
load_stub_cache_->Initialize(); load_stub_cache_->Initialize();
store_stub_cache_->Initialize(); store_stub_cache_->Initialize();
interpreter_->Initialize(); interpreter_->Initialize();
...@@ -3463,7 +3481,7 @@ bool Isolate::Init(StartupDeserializer* des) { ...@@ -3463,7 +3481,7 @@ bool Isolate::Init(StartupDeserializer* des) {
ast_string_constants_ = new AstStringConstants(this, HashSeed(this)); ast_string_constants_ = new AstStringConstants(this, HashSeed(this));
} }
initialized_from_snapshot_ = (des != nullptr); initialized_from_snapshot_ = !create_heap_objects;
if (!FLAG_inline_new) heap_.DisableInlineAllocation(); if (!FLAG_inline_new) heap_.DisableInlineAllocation();
...@@ -3476,7 +3494,7 @@ bool Isolate::Init(StartupDeserializer* des) { ...@@ -3476,7 +3494,7 @@ bool Isolate::Init(StartupDeserializer* des) {
sampling_flags); sampling_flags);
} }
if (des == nullptr && FLAG_profile_deserialization) { if (create_heap_objects && FLAG_profile_deserialization) {
double ms = timer.Elapsed().InMillisecondsF(); double ms = timer.Elapsed().InMillisecondsF();
PrintF("[Initializing isolate from scratch took %0.3f ms]\n", ms); PrintF("[Initializing isolate from scratch took %0.3f ms]\n", ms);
} }
...@@ -3484,7 +3502,6 @@ bool Isolate::Init(StartupDeserializer* des) { ...@@ -3484,7 +3502,6 @@ bool Isolate::Init(StartupDeserializer* des) {
return true; return true;
} }
void Isolate::Enter() { void Isolate::Enter() {
Isolate* current_isolate = nullptr; Isolate* current_isolate = nullptr;
PerIsolateThreadData* current_data = CurrentPerIsolateThreadData(); PerIsolateThreadData* current_data = CurrentPerIsolateThreadData();
......
...@@ -84,6 +84,7 @@ class MaterializedObjectStore; ...@@ -84,6 +84,7 @@ class MaterializedObjectStore;
class Microtask; class Microtask;
class MicrotaskQueue; class MicrotaskQueue;
class OptimizingCompileDispatcher; class OptimizingCompileDispatcher;
class ReadOnlyDeserializer;
class RegExpStack; class RegExpStack;
class RootVisitor; class RootVisitor;
class RuntimeProfiler; class RuntimeProfiler;
...@@ -518,7 +519,9 @@ class Isolate final : private HiddenFactory { ...@@ -518,7 +519,9 @@ class Isolate final : private HiddenFactory {
void InitializeLoggingAndCounters(); void InitializeLoggingAndCounters();
bool InitializeCounters(); // Returns false if already initialized. bool InitializeCounters(); // Returns false if already initialized.
bool Init(StartupDeserializer* des); bool InitWithoutSnapshot();
bool InitWithSnapshot(ReadOnlyDeserializer* read_only_deserializer,
StartupDeserializer* startup_deserializer);
// True if at least one thread Enter'ed this isolate. // True if at least one thread Enter'ed this isolate.
bool IsInUse() { return entry_stack_ != nullptr; } bool IsInUse() { return entry_stack_ != nullptr; }
...@@ -1349,10 +1352,6 @@ class Isolate final : private HiddenFactory { ...@@ -1349,10 +1352,6 @@ class Isolate final : private HiddenFactory {
void AddDetachedContext(Handle<Context> context); void AddDetachedContext(Handle<Context> context);
void CheckDetachedContextsAfterGC(); void CheckDetachedContextsAfterGC();
std::vector<Object>* read_only_object_cache() {
return &read_only_object_cache_;
}
std::vector<Object>* partial_snapshot_cache() { std::vector<Object>* partial_snapshot_cache() {
return &partial_snapshot_cache_; return &partial_snapshot_cache_;
} }
...@@ -1498,6 +1497,9 @@ class Isolate final : private HiddenFactory { ...@@ -1498,6 +1497,9 @@ class Isolate final : private HiddenFactory {
explicit Isolate(std::unique_ptr<IsolateAllocator> isolate_allocator); explicit Isolate(std::unique_ptr<IsolateAllocator> isolate_allocator);
~Isolate(); ~Isolate();
bool Init(ReadOnlyDeserializer* read_only_deserializer,
StartupDeserializer* startup_deserializer);
void CheckIsolateLayout(); void CheckIsolateLayout();
class ThreadDataTable { class ThreadDataTable {
...@@ -1751,7 +1753,6 @@ class Isolate final : private HiddenFactory { ...@@ -1751,7 +1753,6 @@ class Isolate final : private HiddenFactory {
v8::Isolate::UseCounterCallback use_counter_callback_ = nullptr; v8::Isolate::UseCounterCallback use_counter_callback_ = nullptr;
std::vector<Object> read_only_object_cache_;
std::vector<Object> partial_snapshot_cache_; std::vector<Object> partial_snapshot_cache_;
// Used during builtins compilation to build the builtins constants table, // Used during builtins compilation to build the builtins constants table,
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "src/assembler-inl.h" #include "src/assembler-inl.h"
#include "src/heap/heap-inl.h" #include "src/heap/heap-inl.h"
#include "src/heap/heap-write-barrier-inl.h" #include "src/heap/heap-write-barrier-inl.h"
#include "src/heap/read-only-heap.h"
#include "src/interpreter/interpreter.h" #include "src/interpreter/interpreter.h"
#include "src/isolate.h" #include "src/isolate.h"
#include "src/log.h" #include "src/log.h"
...@@ -794,8 +795,9 @@ TSlot Deserializer::ReadDataCase(Isolate* isolate, TSlot current, ...@@ -794,8 +795,9 @@ TSlot Deserializer::ReadDataCase(Isolate* isolate, TSlot current,
hot_objects_.Add(heap_object); hot_objects_.Add(heap_object);
} else if (bytecode == kReadOnlyObjectCache) { } else if (bytecode == kReadOnlyObjectCache) {
int cache_index = source_.GetInt(); int cache_index = source_.GetInt();
heap_object = heap_object = HeapObject::cast(
HeapObject::cast(isolate->read_only_object_cache()->at(cache_index)); isolate->heap()->read_only_heap()->read_only_object_cache()->at(
cache_index));
DCHECK(!Heap::InYoungGeneration(heap_object)); DCHECK(!Heap::InYoungGeneration(heap_object));
emit_write_barrier = false; emit_write_barrier = false;
} else if (bytecode == kPartialSnapshotCache) { } else if (bytecode == kPartialSnapshotCache) {
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "src/api.h" #include "src/api.h"
#include "src/heap/heap-inl.h" // crbug.com/v8/8499 #include "src/heap/heap-inl.h" // crbug.com/v8/8499
#include "src/heap/read-only-heap.h"
#include "src/objects/slots.h" #include "src/objects/slots.h"
#include "src/snapshot/snapshot.h" #include "src/snapshot/snapshot.h"
#include "src/v8threads.h" #include "src/v8threads.h"
...@@ -25,19 +26,24 @@ void ReadOnlyDeserializer::DeserializeInto(Isolate* isolate) { ...@@ -25,19 +26,24 @@ void ReadOnlyDeserializer::DeserializeInto(Isolate* isolate) {
// No active handles. // No active handles.
DCHECK(isolate->handle_scope_implementer()->blocks()->empty()); DCHECK(isolate->handle_scope_implementer()->blocks()->empty());
// Partial snapshot cache is not yet populated. // Partial snapshot cache is not yet populated.
DCHECK(isolate->read_only_object_cache()->empty()); DCHECK(isolate->heap()->read_only_heap()->read_only_object_cache()->empty());
DCHECK(isolate->partial_snapshot_cache()->empty()); DCHECK(isolate->partial_snapshot_cache()->empty());
// Builtins are not yet created. // Builtins are not yet created.
DCHECK(!isolate->builtins()->is_initialized()); DCHECK(!isolate->builtins()->is_initialized());
{ {
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
ReadOnlyRoots roots(isolate);
ReadOnlyRoots(isolate).Iterate(this); roots.Iterate(this);
isolate->heap()->read_only_space()->RepairFreeListsAfterDeserialization(); isolate->heap()
->read_only_heap()
->read_only_space()
->RepairFreeListsAfterDeserialization();
// Deserialize the Read-only Object Cache. // Deserialize the Read-only Object Cache.
std::vector<Object>* cache = isolate->read_only_object_cache(); std::vector<Object>* cache =
isolate->heap()->read_only_heap()->read_only_object_cache();
for (size_t i = 0;; ++i) { for (size_t i = 0;; ++i) {
// Extend the array ready to get a value when deserializing. // Extend the array ready to get a value when deserializing.
if (cache->size() <= i) cache->push_back(Smi::kZero); if (cache->size() <= i) cache->push_back(Smi::kZero);
...@@ -45,15 +51,15 @@ void ReadOnlyDeserializer::DeserializeInto(Isolate* isolate) { ...@@ -45,15 +51,15 @@ void ReadOnlyDeserializer::DeserializeInto(Isolate* isolate) {
// cache and eventually terminates the cache with undefined. // cache and eventually terminates the cache with undefined.
VisitRootPointer(Root::kReadOnlyObjectCache, nullptr, VisitRootPointer(Root::kReadOnlyObjectCache, nullptr,
FullObjectSlot(&cache->at(i))); FullObjectSlot(&cache->at(i)));
if (cache->at(i)->IsUndefined(isolate)) break; if (cache->at(i)->IsUndefined(roots)) break;
} }
DeserializeDeferredObjects(); DeserializeDeferredObjects();
} }
}
void ReadOnlyDeserializer::RehashHeap() { if (FLAG_rehash_snapshot && can_rehash()) {
DCHECK(FLAG_rehash_snapshot && can_rehash()); isolate_->heap()->InitializeHashSeed();
Rehash(); Rehash();
}
} }
} // namespace internal } // namespace internal
......
...@@ -20,12 +20,6 @@ class ReadOnlyDeserializer final : public Deserializer { ...@@ -20,12 +20,6 @@ class ReadOnlyDeserializer final : public Deserializer {
// Deserialize the snapshot into an empty heap. // Deserialize the snapshot into an empty heap.
void DeserializeInto(Isolate* isolate); void DeserializeInto(Isolate* isolate);
private:
friend class StartupDeserializer;
// Rehash after deserializing.
void RehashHeap();
}; };
} // namespace internal } // namespace internal
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "src/base/platform/platform.h" #include "src/base/platform/platform.h"
#include "src/counters.h" #include "src/counters.h"
#include "src/snapshot/partial-deserializer.h" #include "src/snapshot/partial-deserializer.h"
#include "src/snapshot/read-only-deserializer.h"
#include "src/snapshot/startup-deserializer.h" #include "src/snapshot/startup-deserializer.h"
#include "src/version.h" #include "src/version.h"
...@@ -44,10 +45,12 @@ bool Snapshot::Initialize(Isolate* isolate) { ...@@ -44,10 +45,12 @@ bool Snapshot::Initialize(Isolate* isolate) {
SnapshotData startup_snapshot_data(startup_data); SnapshotData startup_snapshot_data(startup_data);
Vector<const byte> read_only_data = ExtractReadOnlyData(blob); Vector<const byte> read_only_data = ExtractReadOnlyData(blob);
SnapshotData read_only_snapshot_data(read_only_data); SnapshotData read_only_snapshot_data(read_only_data);
StartupDeserializer deserializer(&startup_snapshot_data, StartupDeserializer startup_deserializer(&startup_snapshot_data);
&read_only_snapshot_data); ReadOnlyDeserializer read_only_deserializer(&read_only_snapshot_data);
deserializer.SetRehashability(ExtractRehashability(blob)); startup_deserializer.SetRehashability(ExtractRehashability(blob));
bool success = isolate->Init(&deserializer); read_only_deserializer.SetRehashability(ExtractRehashability(blob));
bool success =
isolate->InitWithSnapshot(&read_only_deserializer, &startup_deserializer);
if (FLAG_profile_deserialization) { if (FLAG_profile_deserialization) {
double ms = timer.Elapsed().InMillisecondsF(); double ms = timer.Elapsed().InMillisecondsF();
int bytes = startup_data.length(); int bytes = startup_data.length();
......
...@@ -67,6 +67,7 @@ class Snapshot : public AllStatic { ...@@ -67,6 +67,7 @@ class Snapshot : public AllStatic {
// ---------------- Helper methods ---------------- // ---------------- Helper methods ----------------
static bool HasContextSnapshot(Isolate* isolate, size_t index); static bool HasContextSnapshot(Isolate* isolate, size_t index);
static bool EmbedsScript(Isolate* isolate);
// To be implemented by the snapshot source. // To be implemented by the snapshot source.
static const v8::StartupData* DefaultSnapshotBlob(); static const v8::StartupData* DefaultSnapshotBlob();
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#include "src/api.h" #include "src/api.h"
#include "src/assembler-inl.h" #include "src/assembler-inl.h"
#include "src/heap/heap-inl.h" #include "src/heap/heap-inl.h"
#include "src/snapshot/read-only-deserializer.h"
#include "src/snapshot/snapshot.h" #include "src/snapshot/snapshot.h"
#include "src/v8threads.h" #include "src/v8threads.h"
...@@ -17,10 +16,6 @@ namespace internal { ...@@ -17,10 +16,6 @@ namespace internal {
void StartupDeserializer::DeserializeInto(Isolate* isolate) { void StartupDeserializer::DeserializeInto(Isolate* isolate) {
Initialize(isolate); Initialize(isolate);
ReadOnlyDeserializer read_only_deserializer(read_only_data_);
read_only_deserializer.SetRehashability(can_rehash());
read_only_deserializer.DeserializeInto(isolate);
if (!allocator()->ReserveSpace()) { if (!allocator()->ReserveSpace()) {
V8::FatalProcessOutOfMemory(isolate, "StartupDeserializer"); V8::FatalProcessOutOfMemory(isolate, "StartupDeserializer");
} }
...@@ -64,8 +59,7 @@ void StartupDeserializer::DeserializeInto(Isolate* isolate) { ...@@ -64,8 +59,7 @@ void StartupDeserializer::DeserializeInto(Isolate* isolate) {
LogNewMapEvents(); LogNewMapEvents();
if (FLAG_rehash_snapshot && can_rehash()) { if (FLAG_rehash_snapshot && can_rehash()) {
isolate->heap()->InitializeHashSeed(); // Hash seed was initalized in ReadOnlyDeserializer.
read_only_deserializer.RehashHeap();
Rehash(); Rehash();
} }
} }
......
...@@ -14,9 +14,8 @@ namespace internal { ...@@ -14,9 +14,8 @@ namespace internal {
// Initializes an isolate with context-independent data from a given snapshot. // Initializes an isolate with context-independent data from a given snapshot.
class StartupDeserializer final : public Deserializer { class StartupDeserializer final : public Deserializer {
public: public:
StartupDeserializer(const SnapshotData* startup_data, explicit StartupDeserializer(const SnapshotData* startup_data)
const SnapshotData* read_only_data) : Deserializer(startup_data, false) {}
: Deserializer(startup_data, false), read_only_data_(read_only_data) {}
// Deserialize the snapshot into an empty heap. // Deserialize the snapshot into an empty heap.
void DeserializeInto(Isolate* isolate); void DeserializeInto(Isolate* isolate);
...@@ -24,8 +23,6 @@ class StartupDeserializer final : public Deserializer { ...@@ -24,8 +23,6 @@ class StartupDeserializer final : public Deserializer {
private: private:
void FlushICache(); void FlushICache();
void LogNewMapEvents(); void LogNewMapEvents();
const SnapshotData* read_only_data_;
}; };
} // namespace internal } // namespace internal
......
...@@ -51,6 +51,7 @@ ...@@ -51,6 +51,7 @@
#include "src/snapshot/natives.h" #include "src/snapshot/natives.h"
#include "src/snapshot/partial-deserializer.h" #include "src/snapshot/partial-deserializer.h"
#include "src/snapshot/partial-serializer.h" #include "src/snapshot/partial-serializer.h"
#include "src/snapshot/read-only-deserializer.h"
#include "src/snapshot/read-only-serializer.h" #include "src/snapshot/read-only-serializer.h"
#include "src/snapshot/snapshot.h" #include "src/snapshot/snapshot.h"
#include "src/snapshot/startup-deserializer.h" #include "src/snapshot/startup-deserializer.h"
...@@ -92,7 +93,7 @@ class TestSerializer { ...@@ -92,7 +93,7 @@ class TestSerializer {
v8::Isolate* v8_isolate = NewIsolate(kEnableSerializer, kGenerateHeap); v8::Isolate* v8_isolate = NewIsolate(kEnableSerializer, kGenerateHeap);
v8::Isolate::Scope isolate_scope(v8_isolate); v8::Isolate::Scope isolate_scope(v8_isolate);
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
isolate->Init(nullptr); isolate->Init(nullptr, nullptr);
isolate->heap()->read_only_space()->ClearStringPaddingIfNeeded(); isolate->heap()->read_only_space()->ClearStringPaddingIfNeeded();
return v8_isolate; return v8_isolate;
} }
...@@ -100,13 +101,14 @@ class TestSerializer { ...@@ -100,13 +101,14 @@ class TestSerializer {
static v8::Isolate* NewIsolateFromBlob(StartupBlobs& blobs) { static v8::Isolate* NewIsolateFromBlob(StartupBlobs& blobs) {
SnapshotData startup_snapshot(blobs.startup); SnapshotData startup_snapshot(blobs.startup);
SnapshotData read_only_snapshot(blobs.read_only); SnapshotData read_only_snapshot(blobs.read_only);
StartupDeserializer deserializer(&startup_snapshot, &read_only_snapshot); ReadOnlyDeserializer read_only_deserializer(&read_only_snapshot);
StartupDeserializer startup_deserializer(&startup_snapshot);
const bool kEnableSerializer = false; const bool kEnableSerializer = false;
const bool kGenerateHeap = false; const bool kGenerateHeap = false;
v8::Isolate* v8_isolate = NewIsolate(kEnableSerializer, kGenerateHeap); v8::Isolate* v8_isolate = NewIsolate(kEnableSerializer, kGenerateHeap);
v8::Isolate::Scope isolate_scope(v8_isolate); v8::Isolate::Scope isolate_scope(v8_isolate);
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
isolate->Init(&deserializer); isolate->Init(&read_only_deserializer, &startup_deserializer);
return v8_isolate; return v8_isolate;
} }
......
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