Commit bee5b996 authored by Leszek Swirski's avatar Leszek Swirski Committed by Commit Bot

[serializer] Remove Deserializer::Initialize

Remove the separate Initialize method from Deserializer, opting instead
to pass around SnapshotData where appropriate and pass the isolate
directly into the Deserializer's constructor.

Change-Id: I0092fadd9c81f14b2ce75145fd81af37c3947c65
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2448466
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Commit-Queue: Dan Elphick <delphick@chromium.org>
Auto-Submit: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: 's avatarDan Elphick <delphick@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70310}
parent f6bc6b6d
...@@ -3397,13 +3397,14 @@ void Isolate::TearDownEmbeddedBlob() { ...@@ -3397,13 +3397,14 @@ void Isolate::TearDownEmbeddedBlob() {
} }
} }
bool Isolate::InitWithoutSnapshot() { return Init(nullptr, nullptr); } bool Isolate::InitWithoutSnapshot() { return Init(nullptr, nullptr, false); }
bool Isolate::InitWithSnapshot(ReadOnlyDeserializer* read_only_deserializer, bool Isolate::InitWithSnapshot(SnapshotData* startup_snapshot_data,
StartupDeserializer* startup_deserializer) { SnapshotData* read_only_snapshot_data,
DCHECK_NOT_NULL(read_only_deserializer); bool can_rehash) {
DCHECK_NOT_NULL(startup_deserializer); DCHECK_NOT_NULL(startup_snapshot_data);
return Init(read_only_deserializer, startup_deserializer); DCHECK_NOT_NULL(read_only_snapshot_data);
return Init(startup_snapshot_data, read_only_snapshot_data, can_rehash);
} }
static std::string AddressToString(uintptr_t address) { static std::string AddressToString(uintptr_t address) {
...@@ -3452,12 +3453,12 @@ using MapOfLoadsAndStoresPerFunction = ...@@ -3452,12 +3453,12 @@ using MapOfLoadsAndStoresPerFunction =
MapOfLoadsAndStoresPerFunction* stack_access_count_map = nullptr; MapOfLoadsAndStoresPerFunction* stack_access_count_map = nullptr;
} // namespace } // namespace
bool Isolate::Init(ReadOnlyDeserializer* read_only_deserializer, bool Isolate::Init(SnapshotData* startup_snapshot_data,
StartupDeserializer* startup_deserializer) { SnapshotData* read_only_snapshot_data, bool can_rehash) {
TRACE_ISOLATE(init); TRACE_ISOLATE(init);
const bool create_heap_objects = (read_only_deserializer == nullptr); const bool create_heap_objects = (read_only_snapshot_data == nullptr);
// We either have both or neither. // We either have both or neither.
DCHECK_EQ(create_heap_objects, startup_deserializer == nullptr); DCHECK_EQ(create_heap_objects, startup_snapshot_data == nullptr);
base::ElapsedTimer timer; base::ElapsedTimer timer;
if (create_heap_objects && FLAG_profile_deserialization) timer.Start(); if (create_heap_objects && FLAG_profile_deserialization) timer.Start();
...@@ -3518,7 +3519,7 @@ bool Isolate::Init(ReadOnlyDeserializer* read_only_deserializer, ...@@ -3518,7 +3519,7 @@ bool Isolate::Init(ReadOnlyDeserializer* read_only_deserializer,
// SetUp the object heap. // SetUp the object heap.
DCHECK(!heap_.HasBeenSetUp()); DCHECK(!heap_.HasBeenSetUp());
heap_.SetUp(); heap_.SetUp();
ReadOnlyHeap::SetUp(this, read_only_deserializer); ReadOnlyHeap::SetUp(this, read_only_snapshot_data, can_rehash);
heap_.SetUpSpaces(); heap_.SetUpSpaces();
isolate_data_.external_reference_table()->Init(this); isolate_data_.external_reference_table()->Init(this);
...@@ -3609,7 +3610,9 @@ bool Isolate::Init(ReadOnlyDeserializer* read_only_deserializer, ...@@ -3609,7 +3610,9 @@ bool Isolate::Init(ReadOnlyDeserializer* read_only_deserializer,
heap_.read_only_space()->ClearStringPaddingIfNeeded(); heap_.read_only_space()->ClearStringPaddingIfNeeded();
read_only_heap_->OnCreateHeapObjectsComplete(this); read_only_heap_->OnCreateHeapObjectsComplete(this);
} else { } else {
startup_deserializer->DeserializeInto(this); StartupDeserializer startup_deserializer(this, startup_snapshot_data,
can_rehash);
startup_deserializer.DeserializeIntoIsolate();
} }
load_stub_cache_->Initialize(); load_stub_cache_->Initialize();
store_stub_cache_->Initialize(); store_stub_cache_->Initialize();
......
...@@ -92,14 +92,13 @@ class OptimizingCompileDispatcher; ...@@ -92,14 +92,13 @@ class OptimizingCompileDispatcher;
class PersistentHandles; class PersistentHandles;
class PersistentHandlesList; class PersistentHandlesList;
class ReadOnlyArtifacts; class ReadOnlyArtifacts;
class ReadOnlyDeserializer;
class RegExpStack; class RegExpStack;
class RootVisitor; class RootVisitor;
class RuntimeProfiler; class RuntimeProfiler;
class SetupIsolateDelegate; class SetupIsolateDelegate;
class Simulator; class Simulator;
class SnapshotData;
class StandardFrame; class StandardFrame;
class StartupDeserializer;
class StringTable; class StringTable;
class StubCache; class StubCache;
class ThreadManager; class ThreadManager;
...@@ -570,8 +569,8 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory { ...@@ -570,8 +569,8 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
bool InitializeCounters(); // Returns false if already initialized. bool InitializeCounters(); // Returns false if already initialized.
bool InitWithoutSnapshot(); bool InitWithoutSnapshot();
bool InitWithSnapshot(ReadOnlyDeserializer* read_only_deserializer, bool InitWithSnapshot(SnapshotData* startup_snapshot_data,
StartupDeserializer* startup_deserializer); SnapshotData* read_only_snapshot_data, bool can_rehash);
// 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; }
...@@ -1596,8 +1595,8 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory { ...@@ -1596,8 +1595,8 @@ class V8_EXPORT_PRIVATE 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, bool Init(SnapshotData* startup_snapshot_data,
StartupDeserializer* startup_deserializer); SnapshotData* read_only_snapshot_data, bool can_rehash);
void CheckIsolateLayout(); void CheckIsolateLayout();
......
...@@ -60,21 +60,24 @@ bool ReadOnlyHeap::IsSharedMemoryAvailable() { ...@@ -60,21 +60,24 @@ bool ReadOnlyHeap::IsSharedMemoryAvailable() {
SoleReadOnlyHeap* SoleReadOnlyHeap::shared_ro_heap_ = nullptr; SoleReadOnlyHeap* SoleReadOnlyHeap::shared_ro_heap_ = nullptr;
// static // static
void ReadOnlyHeap::SetUp(Isolate* isolate, ReadOnlyDeserializer* des) { void ReadOnlyHeap::SetUp(Isolate* isolate,
SnapshotData* read_only_snapshot_data,
bool can_rehash) {
DCHECK_NOT_NULL(isolate); DCHECK_NOT_NULL(isolate);
if (IsReadOnlySpaceShared()) { if (IsReadOnlySpaceShared()) {
ReadOnlyHeap* ro_heap; ReadOnlyHeap* ro_heap;
if (des != nullptr) { if (read_only_snapshot_data != nullptr) {
bool read_only_heap_created = false; bool read_only_heap_created = false;
base::MutexGuard guard(read_only_heap_creation_mutex_.Pointer()); base::MutexGuard guard(read_only_heap_creation_mutex_.Pointer());
std::shared_ptr<ReadOnlyArtifacts> artifacts = std::shared_ptr<ReadOnlyArtifacts> artifacts =
read_only_artifacts_.Get().lock(); read_only_artifacts_.Get().lock();
if (!artifacts) { if (!artifacts) {
artifacts = InitializeSharedReadOnlyArtifacts(); artifacts = InitializeSharedReadOnlyArtifacts();
artifacts->InitializeChecksum(des); artifacts->InitializeChecksum(read_only_snapshot_data);
ro_heap = CreateInitalHeapForBootstrapping(isolate, artifacts); ro_heap = CreateInitalHeapForBootstrapping(isolate, artifacts);
ro_heap->DeseralizeIntoIsolate(isolate, des); ro_heap->DeseralizeIntoIsolate(isolate, read_only_snapshot_data,
can_rehash);
read_only_heap_created = true; read_only_heap_created = true;
} else { } else {
// With pointer compression, there is one ReadOnlyHeap per Isolate. // With pointer compression, there is one ReadOnlyHeap per Isolate.
...@@ -82,7 +85,8 @@ void ReadOnlyHeap::SetUp(Isolate* isolate, ReadOnlyDeserializer* des) { ...@@ -82,7 +85,8 @@ void ReadOnlyHeap::SetUp(Isolate* isolate, ReadOnlyDeserializer* des) {
ro_heap = artifacts->GetReadOnlyHeapForIsolate(isolate); ro_heap = artifacts->GetReadOnlyHeapForIsolate(isolate);
isolate->SetUpFromReadOnlyArtifacts(artifacts, ro_heap); isolate->SetUpFromReadOnlyArtifacts(artifacts, ro_heap);
} }
artifacts->VerifyChecksum(des, read_only_heap_created); artifacts->VerifyChecksum(read_only_snapshot_data,
read_only_heap_created);
ro_heap->InitializeIsolateRoots(isolate); ro_heap->InitializeIsolateRoots(isolate);
} else { } else {
// This path should only be taken in mksnapshot, should only be run once // This path should only be taken in mksnapshot, should only be run once
...@@ -94,21 +98,24 @@ void ReadOnlyHeap::SetUp(Isolate* isolate, ReadOnlyDeserializer* des) { ...@@ -94,21 +98,24 @@ void ReadOnlyHeap::SetUp(Isolate* isolate, ReadOnlyDeserializer* des) {
artifacts = InitializeSharedReadOnlyArtifacts(); artifacts = InitializeSharedReadOnlyArtifacts();
ro_heap = CreateInitalHeapForBootstrapping(isolate, artifacts); ro_heap = CreateInitalHeapForBootstrapping(isolate, artifacts);
artifacts->VerifyChecksum(des, true); artifacts->VerifyChecksum(read_only_snapshot_data, true);
} }
} else { } else {
auto* ro_heap = new ReadOnlyHeap(new ReadOnlySpace(isolate->heap())); auto* ro_heap = new ReadOnlyHeap(new ReadOnlySpace(isolate->heap()));
isolate->SetUpFromReadOnlyArtifacts(nullptr, ro_heap); isolate->SetUpFromReadOnlyArtifacts(nullptr, ro_heap);
if (des != nullptr) { if (read_only_snapshot_data != nullptr) {
ro_heap->DeseralizeIntoIsolate(isolate, des); ro_heap->DeseralizeIntoIsolate(isolate, read_only_snapshot_data,
can_rehash);
} }
} }
} }
void ReadOnlyHeap::DeseralizeIntoIsolate(Isolate* isolate, void ReadOnlyHeap::DeseralizeIntoIsolate(Isolate* isolate,
ReadOnlyDeserializer* des) { SnapshotData* read_only_snapshot_data,
DCHECK_NOT_NULL(des); bool can_rehash) {
des->DeserializeInto(isolate); DCHECK_NOT_NULL(read_only_snapshot_data);
ReadOnlyDeserializer des(isolate, read_only_snapshot_data, can_rehash);
des.DeserializeIntoIsolate();
InitFromIsolate(isolate); InitFromIsolate(isolate);
} }
......
...@@ -25,10 +25,10 @@ class BasicMemoryChunk; ...@@ -25,10 +25,10 @@ class BasicMemoryChunk;
class Isolate; class Isolate;
class Page; class Page;
class ReadOnlyArtifacts; class ReadOnlyArtifacts;
class ReadOnlyDeserializer;
class ReadOnlyPage; class ReadOnlyPage;
class ReadOnlySpace; class ReadOnlySpace;
class SharedReadOnlySpace; class SharedReadOnlySpace;
class SnapshotData;
// This class transparently manages read-only space, roots and cache creation // This class transparently manages read-only space, roots and cache creation
// and destruction. // and destruction.
...@@ -47,7 +47,8 @@ class ReadOnlyHeap { ...@@ -47,7 +47,8 @@ class ReadOnlyHeap {
// V8_SHARED_RO_HEAP is enabled, a lock will be held until that method is // V8_SHARED_RO_HEAP is enabled, a lock will be held until that method is
// called. // called.
// TODO(v8:7464): Ideally we'd create this without needing a heap. // TODO(v8:7464): Ideally we'd create this without needing a heap.
static void SetUp(Isolate* isolate, ReadOnlyDeserializer* des); static void SetUp(Isolate* isolate, SnapshotData* read_only_snapshot_data,
bool can_rehash);
// Indicates that the isolate has been set up and all read-only space objects // Indicates that the isolate has been set up and all read-only space objects
// have been created and will not be written to. This should only be called if // have been created and will not be written to. This should only be called if
// a deserializer was not previously provided to Setup. When V8_SHARED_RO_HEAP // a deserializer was not previously provided to Setup. When V8_SHARED_RO_HEAP
...@@ -101,7 +102,9 @@ class ReadOnlyHeap { ...@@ -101,7 +102,9 @@ class ReadOnlyHeap {
Isolate* isolate, std::shared_ptr<ReadOnlyArtifacts> artifacts); Isolate* isolate, std::shared_ptr<ReadOnlyArtifacts> artifacts);
// Runs the read-only deserializer and calls InitFromIsolate to complete // Runs the read-only deserializer and calls InitFromIsolate to complete
// read-only heap initialization. // read-only heap initialization.
void DeseralizeIntoIsolate(Isolate* isolate, ReadOnlyDeserializer* des); void DeseralizeIntoIsolate(Isolate* isolate,
SnapshotData* read_only_snapshot_data,
bool can_rehash);
// Initializes read-only heap from an already set-up isolate, copying // Initializes read-only heap from an already set-up isolate, copying
// read-only roots from the isolate. This then seals the space off from // read-only roots from the isolate. This then seals the space off from
// further writes, marks it as read-only and detaches it from the heap // further writes, marks it as read-only and detaches it from the heap
......
...@@ -39,22 +39,24 @@ void ReadOnlyArtifacts::set_read_only_heap( ...@@ -39,22 +39,24 @@ void ReadOnlyArtifacts::set_read_only_heap(
read_only_heap_ = std::move(read_only_heap); read_only_heap_ = std::move(read_only_heap);
} }
void ReadOnlyArtifacts::InitializeChecksum(ReadOnlyDeserializer* des) { void ReadOnlyArtifacts::InitializeChecksum(
SnapshotData* read_only_snapshot_data) {
#ifdef DEBUG #ifdef DEBUG
read_only_blob_checksum_ = des->GetChecksum(); read_only_blob_checksum_ = Checksum(read_only_snapshot_data->Payload());
#endif // DEBUG #endif // DEBUG
} }
void ReadOnlyArtifacts::VerifyChecksum(ReadOnlyDeserializer* des, void ReadOnlyArtifacts::VerifyChecksum(SnapshotData* read_only_snapshot_data,
bool read_only_heap_created) { bool read_only_heap_created) {
#ifdef DEBUG #ifdef DEBUG
if (read_only_blob_checksum_) { if (read_only_blob_checksum_) {
// The read-only heap was set up from a snapshot. Make sure it's the always // The read-only heap was set up from a snapshot. Make sure it's the always
// the same snapshot. // the same snapshot.
CHECK_WITH_MSG(des->GetChecksum(), uint32_t snapshot_checksum = Checksum(read_only_snapshot_data->Payload());
CHECK_WITH_MSG(snapshot_checksum,
"Attempt to create the read-only heap after already " "Attempt to create the read-only heap after already "
"creating from a snapshot."); "creating from a snapshot.");
CHECK_EQ(read_only_blob_checksum_, des->GetChecksum()); CHECK_EQ(read_only_blob_checksum_, snapshot_checksum);
} else { } else {
// If there's no checksum, then that means the read-only heap objects are // If there's no checksum, then that means the read-only heap objects are
// being created. // being created.
......
...@@ -20,9 +20,9 @@ ...@@ -20,9 +20,9 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
class ReadOnlyDeserializer;
class MemoryAllocator; class MemoryAllocator;
class ReadOnlyHeap; class ReadOnlyHeap;
class SnapshotData;
class ReadOnlyPage : public BasicMemoryChunk { class ReadOnlyPage : public BasicMemoryChunk {
public: public:
...@@ -100,8 +100,9 @@ class ReadOnlyArtifacts { ...@@ -100,8 +100,9 @@ class ReadOnlyArtifacts {
void set_read_only_heap(std::unique_ptr<ReadOnlyHeap> read_only_heap); void set_read_only_heap(std::unique_ptr<ReadOnlyHeap> read_only_heap);
ReadOnlyHeap* read_only_heap() const { return read_only_heap_.get(); } ReadOnlyHeap* read_only_heap() const { return read_only_heap_.get(); }
void InitializeChecksum(ReadOnlyDeserializer* des); void InitializeChecksum(SnapshotData* read_only_snapshot_data);
void VerifyChecksum(ReadOnlyDeserializer* des, bool read_only_heap_created); void VerifyChecksum(SnapshotData* read_only_snapshot_data,
bool read_only_heap_created);
protected: protected:
ReadOnlyArtifacts() = default; ReadOnlyArtifacts() = default;
......
...@@ -17,8 +17,7 @@ MaybeHandle<Context> ContextDeserializer::DeserializeContext( ...@@ -17,8 +17,7 @@ MaybeHandle<Context> ContextDeserializer::DeserializeContext(
Isolate* isolate, const SnapshotData* data, bool can_rehash, Isolate* isolate, const SnapshotData* data, bool can_rehash,
Handle<JSGlobalProxy> global_proxy, Handle<JSGlobalProxy> global_proxy,
v8::DeserializeEmbedderFieldsCallback embedder_fields_deserializer) { v8::DeserializeEmbedderFieldsCallback embedder_fields_deserializer) {
ContextDeserializer d(data); ContextDeserializer d(isolate, data, can_rehash);
d.SetRehashability(can_rehash);
MaybeHandle<Object> maybe_result = MaybeHandle<Object> maybe_result =
d.Deserialize(isolate, global_proxy, embedder_fields_deserializer); d.Deserialize(isolate, global_proxy, embedder_fields_deserializer);
...@@ -31,8 +30,6 @@ MaybeHandle<Context> ContextDeserializer::DeserializeContext( ...@@ -31,8 +30,6 @@ MaybeHandle<Context> ContextDeserializer::DeserializeContext(
MaybeHandle<Object> ContextDeserializer::Deserialize( MaybeHandle<Object> ContextDeserializer::Deserialize(
Isolate* isolate, Handle<JSGlobalProxy> global_proxy, Isolate* isolate, Handle<JSGlobalProxy> global_proxy,
v8::DeserializeEmbedderFieldsCallback embedder_fields_deserializer) { v8::DeserializeEmbedderFieldsCallback embedder_fields_deserializer) {
Initialize(isolate);
// Replace serialized references to the global proxy and its map with the // Replace serialized references to the global proxy and its map with the
// given global proxy and its map. // given global proxy and its map.
AddAttachedObject(global_proxy); AddAttachedObject(global_proxy);
......
...@@ -13,6 +13,7 @@ namespace v8 { ...@@ -13,6 +13,7 @@ namespace v8 {
namespace internal { namespace internal {
class Context; class Context;
class Isolate;
// Deserializes the context-dependent object graph rooted at a given object. // Deserializes the context-dependent object graph rooted at a given object.
// The ContextDeserializer is not expected to deserialize any code objects. // The ContextDeserializer is not expected to deserialize any code objects.
...@@ -24,8 +25,10 @@ class V8_EXPORT_PRIVATE ContextDeserializer final : public Deserializer { ...@@ -24,8 +25,10 @@ class V8_EXPORT_PRIVATE ContextDeserializer final : public Deserializer {
v8::DeserializeEmbedderFieldsCallback embedder_fields_deserializer); v8::DeserializeEmbedderFieldsCallback embedder_fields_deserializer);
private: private:
explicit ContextDeserializer(const SnapshotData* data) explicit ContextDeserializer(Isolate* isolate, const SnapshotData* data,
: Deserializer(data, false) {} bool can_rehash)
: Deserializer(isolate, data->Payload(), data->GetMagicNumber(), false,
can_rehash) {}
// Deserialize a single object and the objects reachable from it. // Deserialize a single object and the objects reachable from it.
MaybeHandle<Object> Deserialize( MaybeHandle<Object> Deserialize(
......
...@@ -194,12 +194,23 @@ int Deserializer::WriteExternalPointer(TSlot dest, Address value) { ...@@ -194,12 +194,23 @@ int Deserializer::WriteExternalPointer(TSlot dest, Address value) {
return (kExternalPointerSize / TSlot::kSlotDataSize); return (kExternalPointerSize / TSlot::kSlotDataSize);
} }
void Deserializer::Initialize(Isolate* isolate) { Deserializer::Deserializer(Isolate* isolate, Vector<const byte> payload,
DCHECK_NULL(isolate_); uint32_t magic_number, bool deserializing_user_code,
bool can_rehash)
: isolate_(isolate),
source_(payload),
magic_number_(magic_number),
deserializing_user_code_(deserializing_user_code),
can_rehash_(can_rehash) {
DCHECK_NOT_NULL(isolate); DCHECK_NOT_NULL(isolate);
isolate_ = isolate;
isolate_->RegisterDeserializerStarted(); isolate_->RegisterDeserializerStarted();
// We start the indices here at 1, so that we can distinguish between an
// actual index and a nullptr (serialized as kNullRefSentinel) in a
// deserialized object requiring fix-up.
STATIC_ASSERT(kNullRefSentinel == 0);
backing_stores_.push_back({});
#ifdef DEBUG #ifdef DEBUG
num_api_references_ = 0; num_api_references_ = 0;
// The read-only deserializer is run by read-only heap set-up before the // The read-only deserializer is run by read-only heap set-up before the
...@@ -234,7 +245,7 @@ Deserializer::~Deserializer() { ...@@ -234,7 +245,7 @@ Deserializer::~Deserializer() {
DCHECK_EQ(num_unresolved_forward_refs_, 0); DCHECK_EQ(num_unresolved_forward_refs_, 0);
DCHECK(unresolved_forward_refs_.empty()); DCHECK(unresolved_forward_refs_.empty());
#endif // DEBUG #endif // DEBUG
if (isolate_) isolate_->RegisterDeserializerFinished(); isolate_->RegisterDeserializerFinished();
} }
// This is called on the roots. It is the driver of the deserialization // This is called on the roots. It is the driver of the deserialization
......
...@@ -47,26 +47,14 @@ class V8_EXPORT_PRIVATE Deserializer : public SerializerDeserializer { ...@@ -47,26 +47,14 @@ class V8_EXPORT_PRIVATE Deserializer : public SerializerDeserializer {
~Deserializer() override; ~Deserializer() override;
void SetRehashability(bool v) { can_rehash_ = v; }
uint32_t GetChecksum() const { return source_.GetChecksum(); } uint32_t GetChecksum() const { return source_.GetChecksum(); }
protected: protected:
// Create a deserializer from a snapshot byte source. // Create a deserializer from a snapshot byte source.
template <class Data> Deserializer(Isolate* isolate, Vector<const byte> payload,
Deserializer(Data* data, bool deserializing_user_code) uint32_t magic_number, bool deserializing_user_code,
: isolate_(nullptr), bool can_rehash);
source_(data->Payload()),
magic_number_(data->GetMagicNumber()),
deserializing_user_code_(deserializing_user_code),
can_rehash_(false) {
// We start the indices here at 1, so that we can distinguish between an
// actual index and a nullptr (serialized as kNullRefSentinel) in a
// deserialized object requiring fix-up.
STATIC_ASSERT(kNullRefSentinel == 0);
backing_stores_.push_back({});
}
void Initialize(Isolate* isolate);
void DeserializeDeferredObjects(); void DeserializeDeferredObjects();
// Create Log events for newly deserialized objects. // Create Log events for newly deserialized objects.
......
...@@ -15,18 +15,20 @@ ...@@ -15,18 +15,20 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
ObjectDeserializer::ObjectDeserializer(const SerializedCodeData* data) ObjectDeserializer::ObjectDeserializer(Isolate* isolate,
: Deserializer(data, true) {} const SerializedCodeData* data)
: Deserializer(isolate, data->Payload(), data->GetMagicNumber(), true,
false) {}
MaybeHandle<SharedFunctionInfo> MaybeHandle<SharedFunctionInfo>
ObjectDeserializer::DeserializeSharedFunctionInfo( ObjectDeserializer::DeserializeSharedFunctionInfo(
Isolate* isolate, const SerializedCodeData* data, Handle<String> source) { Isolate* isolate, const SerializedCodeData* data, Handle<String> source) {
ObjectDeserializer d(data); ObjectDeserializer d(isolate, data);
d.AddAttachedObject(source); d.AddAttachedObject(source);
Handle<HeapObject> result; Handle<HeapObject> result;
return d.Deserialize(isolate).ToHandle(&result) return d.Deserialize().ToHandle(&result)
? Handle<SharedFunctionInfo>::cast(result) ? Handle<SharedFunctionInfo>::cast(result)
: MaybeHandle<SharedFunctionInfo>(); : MaybeHandle<SharedFunctionInfo>();
} }
...@@ -39,11 +41,9 @@ ObjectDeserializer::DeserializeSharedFunctionInfoOffThread( ...@@ -39,11 +41,9 @@ ObjectDeserializer::DeserializeSharedFunctionInfoOffThread(
UNREACHABLE(); UNREACHABLE();
} }
MaybeHandle<HeapObject> ObjectDeserializer::Deserialize(Isolate* isolate) { MaybeHandle<HeapObject> ObjectDeserializer::Deserialize() {
Initialize(isolate);
DCHECK(deserializing_user_code()); DCHECK(deserializing_user_code());
HandleScope scope(isolate); HandleScope scope(isolate());
Handle<HeapObject> result; Handle<HeapObject> result;
{ {
result = ReadObject(); result = ReadObject();
......
...@@ -23,10 +23,10 @@ class ObjectDeserializer final : public Deserializer { ...@@ -23,10 +23,10 @@ class ObjectDeserializer final : public Deserializer {
Handle<String> source); Handle<String> source);
private: private:
explicit ObjectDeserializer(const SerializedCodeData* data); explicit ObjectDeserializer(Isolate* isolate, const SerializedCodeData* data);
// Deserialize an object graph. Fail gracefully. // Deserialize an object graph. Fail gracefully.
MaybeHandle<HeapObject> Deserialize(Isolate* isolate); MaybeHandle<HeapObject> Deserialize();
void LinkAllocationSites(); void LinkAllocationSites();
void CommitPostProcessedObjects(); void CommitPostProcessedObjects();
......
...@@ -14,25 +14,24 @@ ...@@ -14,25 +14,24 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
void ReadOnlyDeserializer::DeserializeInto(Isolate* isolate) { void ReadOnlyDeserializer::DeserializeIntoIsolate() {
Initialize(isolate); HandleScope scope(isolate());
HandleScope scope(isolate);
ReadOnlyHeap* ro_heap = isolate->read_only_heap(); ReadOnlyHeap* ro_heap = isolate()->read_only_heap();
// No active threads. // No active threads.
DCHECK_NULL(isolate->thread_manager()->FirstThreadStateInUse()); DCHECK_NULL(isolate()->thread_manager()->FirstThreadStateInUse());
// No active handles. // No active handles.
DCHECK(isolate->handle_scope_implementer()->blocks()->empty()); DCHECK(isolate()->handle_scope_implementer()->blocks()->empty());
// Read-only object cache is not yet populated. // Read-only object cache is not yet populated.
DCHECK(!ro_heap->read_only_object_cache_is_initialized()); DCHECK(!ro_heap->read_only_object_cache_is_initialized());
// Startup object cache is not yet populated. // Startup object cache is not yet populated.
DCHECK(isolate->startup_object_cache()->empty()); DCHECK(isolate()->startup_object_cache()->empty());
// Builtins are not yet created. // Builtins are not yet created.
DCHECK(!isolate->builtins()->is_initialized()); DCHECK(!isolate()->builtins()->is_initialized());
{ {
ReadOnlyRoots roots(isolate); ReadOnlyRoots roots(isolate());
roots.Iterate(this); roots.Iterate(this);
ro_heap->read_only_space()->RepairFreeSpacesAfterDeserialization(); ro_heap->read_only_space()->RepairFreeSpacesAfterDeserialization();
...@@ -51,7 +50,7 @@ void ReadOnlyDeserializer::DeserializeInto(Isolate* isolate) { ...@@ -51,7 +50,7 @@ void ReadOnlyDeserializer::DeserializeInto(Isolate* isolate) {
} }
if (FLAG_rehash_snapshot && can_rehash()) { if (FLAG_rehash_snapshot && can_rehash()) {
isolate->heap()->InitializeHashSeed(); isolate()->heap()->InitializeHashSeed();
Rehash(); Rehash();
} }
} }
......
...@@ -16,11 +16,13 @@ namespace internal { ...@@ -16,11 +16,13 @@ namespace internal {
// Read-only object cache used by the other deserializers. // Read-only object cache used by the other deserializers.
class ReadOnlyDeserializer final : public Deserializer { class ReadOnlyDeserializer final : public Deserializer {
public: public:
explicit ReadOnlyDeserializer(const SnapshotData* data) explicit ReadOnlyDeserializer(Isolate* isolate, const SnapshotData* data,
: Deserializer(data, false) {} bool can_rehash)
: Deserializer(isolate, data->Payload(), data->GetMagicNumber(), false,
can_rehash) {}
// Deserialize the snapshot into an empty heap. // Deserialize the snapshot into an empty heap.
void DeserializeInto(Isolate* isolate); void DeserializeIntoIsolate();
}; };
} // namespace internal } // namespace internal
......
...@@ -158,12 +158,9 @@ bool Snapshot::Initialize(Isolate* isolate) { ...@@ -158,12 +158,9 @@ bool Snapshot::Initialize(Isolate* isolate) {
SnapshotData startup_snapshot_data(MaybeDecompress(startup_data)); SnapshotData startup_snapshot_data(MaybeDecompress(startup_data));
SnapshotData read_only_snapshot_data(MaybeDecompress(read_only_data)); SnapshotData read_only_snapshot_data(MaybeDecompress(read_only_data));
StartupDeserializer startup_deserializer(&startup_snapshot_data); bool success = isolate->InitWithSnapshot(&startup_snapshot_data,
ReadOnlyDeserializer read_only_deserializer(&read_only_snapshot_data); &read_only_snapshot_data,
startup_deserializer.SetRehashability(ExtractRehashability(blob)); ExtractRehashability(blob));
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();
......
...@@ -14,32 +14,31 @@ ...@@ -14,32 +14,31 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
void StartupDeserializer::DeserializeInto(Isolate* isolate) { void StartupDeserializer::DeserializeIntoIsolate() {
Initialize(isolate); HandleScope scope(isolate());
HandleScope scope(isolate);
// No active threads. // No active threads.
DCHECK_NULL(isolate->thread_manager()->FirstThreadStateInUse()); DCHECK_NULL(isolate()->thread_manager()->FirstThreadStateInUse());
// No active handles. // No active handles.
DCHECK(isolate->handle_scope_implementer()->blocks()->empty()); DCHECK(isolate()->handle_scope_implementer()->blocks()->empty());
// Startup object cache is not yet populated. // Startup object cache is not yet populated.
DCHECK(isolate->startup_object_cache()->empty()); DCHECK(isolate()->startup_object_cache()->empty());
// Builtins are not yet created. // Builtins are not yet created.
DCHECK(!isolate->builtins()->is_initialized()); DCHECK(!isolate()->builtins()->is_initialized());
{ {
isolate->heap()->IterateSmiRoots(this); isolate()->heap()->IterateSmiRoots(this);
isolate->heap()->IterateRoots( isolate()->heap()->IterateRoots(
this, this,
base::EnumSet<SkipRoot>{SkipRoot::kUnserializable, SkipRoot::kWeak}); base::EnumSet<SkipRoot>{SkipRoot::kUnserializable, SkipRoot::kWeak});
Iterate(isolate, this); Iterate(isolate(), this);
DeserializeStringTable(); DeserializeStringTable();
isolate->heap()->IterateWeakRoots( isolate()->heap()->IterateWeakRoots(
this, base::EnumSet<SkipRoot>{SkipRoot::kUnserializable}); this, base::EnumSet<SkipRoot>{SkipRoot::kUnserializable});
DeserializeDeferredObjects(); DeserializeDeferredObjects();
RestoreExternalReferenceRedirectors(isolate, accessor_infos()); RestoreExternalReferenceRedirectors(isolate(), accessor_infos());
RestoreExternalReferenceRedirectors(isolate, call_handler_infos()); RestoreExternalReferenceRedirectors(isolate(), call_handler_infos());
// Flush the instruction cache for the entire code-space. Must happen after // Flush the instruction cache for the entire code-space. Must happen after
// builtins deserialization. // builtins deserialization.
...@@ -48,20 +47,20 @@ void StartupDeserializer::DeserializeInto(Isolate* isolate) { ...@@ -48,20 +47,20 @@ void StartupDeserializer::DeserializeInto(Isolate* isolate) {
CheckNoArrayBufferBackingStores(); CheckNoArrayBufferBackingStores();
isolate->heap()->set_native_contexts_list( isolate()->heap()->set_native_contexts_list(
ReadOnlyRoots(isolate).undefined_value()); ReadOnlyRoots(isolate()).undefined_value());
// The allocation site list is build during root iteration, but if no sites // The allocation site list is build during root iteration, but if no sites
// were encountered then it needs to be initialized to undefined. // were encountered then it needs to be initialized to undefined.
if (isolate->heap()->allocation_sites_list() == Smi::zero()) { if (isolate()->heap()->allocation_sites_list() == Smi::zero()) {
isolate->heap()->set_allocation_sites_list( isolate()->heap()->set_allocation_sites_list(
ReadOnlyRoots(isolate).undefined_value()); ReadOnlyRoots(isolate()).undefined_value());
} }
isolate->heap()->set_dirty_js_finalization_registries_list( isolate()->heap()->set_dirty_js_finalization_registries_list(
ReadOnlyRoots(isolate).undefined_value()); ReadOnlyRoots(isolate()).undefined_value());
isolate->heap()->set_dirty_js_finalization_registries_list_tail( isolate()->heap()->set_dirty_js_finalization_registries_list_tail(
ReadOnlyRoots(isolate).undefined_value()); ReadOnlyRoots(isolate()).undefined_value());
isolate->builtins()->MarkInitialized(); isolate()->builtins()->MarkInitialized();
LogNewMapEvents(); LogNewMapEvents();
WeakenDescriptorArrays(); WeakenDescriptorArrays();
......
...@@ -15,11 +15,14 @@ namespace internal { ...@@ -15,11 +15,14 @@ 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:
explicit StartupDeserializer(const SnapshotData* startup_data) explicit StartupDeserializer(Isolate* isolate,
: Deserializer(startup_data, false) {} const SnapshotData* startup_data,
bool can_rehash)
: Deserializer(isolate, startup_data->Payload(),
startup_data->GetMagicNumber(), false, can_rehash) {}
// Deserialize the snapshot into an empty heap. // Deserialize the snapshot into an empty heap.
void DeserializeInto(Isolate* isolate); void DeserializeIntoIsolate();
private: private:
void DeserializeStringTable(); void DeserializeStringTable();
......
...@@ -94,21 +94,19 @@ class TestSerializer { ...@@ -94,21 +94,19 @@ 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, nullptr); isolate->Init(nullptr, nullptr, false);
return v8_isolate; return v8_isolate;
} }
static v8::Isolate* NewIsolateFromBlob(const StartupBlobs& blobs) { static v8::Isolate* NewIsolateFromBlob(const 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);
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(&read_only_deserializer, &startup_deserializer); isolate->Init(&startup_snapshot, &read_only_snapshot, false);
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