[snapshot] Begin splitting up Deserializer

This begins splitting up the Deserializer class into
{Object,Partial,Startup}Deserializer.  For now, all functionality remains in
the Deserializer base clase, to be refactored in future CLs.  Empty .cc files
are added here to avoid having to touch build files again.

Bug: v8:6624
Change-Id: If563e03492991bd55c91cd2e09312c0a26aaab2c
Reviewed-on: https://chromium-review.googlesource.com/598067
Reviewed-by: Yang Guo <yangguo@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47107}
This commit is contained in:
jgruber 2017-08-02 16:00:37 +02:00 committed by Commit Bot
parent 5a8a7ed83c
commit b68b63fc82
15 changed files with 190 additions and 53 deletions

View File

@ -1902,6 +1902,10 @@ v8_source_set("v8_base") {
"src/snapshot/deserializer.h",
"src/snapshot/natives-common.cc",
"src/snapshot/natives.h",
"src/snapshot/object-deserializer.cc",
"src/snapshot/object-deserializer.h",
"src/snapshot/partial-deserializer.cc",
"src/snapshot/partial-deserializer.h",
"src/snapshot/partial-serializer.cc",
"src/snapshot/partial-serializer.h",
"src/snapshot/serializer-common.cc",
@ -1912,6 +1916,8 @@ v8_source_set("v8_base") {
"src/snapshot/snapshot-source-sink.cc",
"src/snapshot/snapshot-source-sink.h",
"src/snapshot/snapshot.h",
"src/snapshot/startup-deserializer.cc",
"src/snapshot/startup-deserializer.h",
"src/snapshot/startup-serializer.cc",
"src/snapshot/startup-serializer.h",
"src/source-position-table.cc",

View File

@ -521,7 +521,6 @@ class Struct;
class FeedbackVector;
class Variable;
class RelocInfo;
class Deserializer;
class MessageLocation;
typedef bool (*WeakSlotCallback)(Object** pointer);

View File

@ -45,7 +45,7 @@
#include "src/runtime-profiler.h"
#include "src/setup-isolate.h"
#include "src/simulator.h"
#include "src/snapshot/deserializer.h"
#include "src/snapshot/startup-deserializer.h"
#include "src/tracing/tracing-category-observer.h"
#include "src/v8.h"
#include "src/version.h"
@ -2679,7 +2679,7 @@ void PrintBuiltinSizes(Isolate* isolate) {
}
} // namespace
bool Isolate::Init(Deserializer* des) {
bool Isolate::Init(StartupDeserializer* des) {
TRACE_ISOLATE(init);
stress_deopt_count_ = FLAG_deopt_every_n_times;

View File

@ -46,8 +46,8 @@ class AddressToIndexHashMap;
class AstStringConstants;
class BasicBlockProfiler;
class Bootstrapper;
class CancelableTaskManager;
class CallInterfaceDescriptorData;
class CancelableTaskManager;
class CodeAgingHelper;
class CodeEventDispatcher;
class CodeGenerator;
@ -55,15 +55,15 @@ class CodeRange;
class CodeStubDescriptor;
class CodeTracer;
class CompilationCache;
class CompilerDispatcher;
class CompilationStatistics;
class CompilerDispatcher;
class ContextSlotCache;
class Counters;
class CpuFeatures;
class CpuProfiler;
class Debug;
class DeoptimizerData;
class DescriptorLookupCache;
class Deserializer;
class EmptyStatement;
class ExternalCallbackScope;
class ExternalReferenceTable;
@ -76,11 +76,15 @@ class InnerPointerToCodeCache;
class Logger;
class MaterializedObjectStore;
class OptimizingCompileDispatcher;
class PromiseOnStack;
class Redirection;
class RegExpStack;
class RootVisitor;
class RuntimeProfiler;
class SaveContext;
class SetupIsolateDelegate;
class Simulator;
class StartupDeserializer;
class StatsTable;
class StringTracker;
class StubCache;
@ -89,6 +93,7 @@ class ThreadManager;
class ThreadState;
class ThreadVisitor; // Defined in v8threads.h
class UnicodeCache;
template <StateTag Tag> class VMState;
// 'void function pointer', used to roundtrip the
@ -96,12 +101,6 @@ template <StateTag Tag> class VMState;
// assembler.h, where it is defined, here.
typedef void* ExternalReferenceRedirectorPointer();
class Debug;
class PromiseOnStack;
class Redirection;
class Simulator;
namespace interpreter {
class Interpreter;
}
@ -543,7 +542,7 @@ class Isolate {
void InitializeLoggingAndCounters();
bool InitializeCounters(); // Returns false if already initialized.
bool Init(Deserializer* des);
bool Init(StartupDeserializer* des);
// True if at least one thread Enter'ed this isolate.
bool IsInUse() { return entry_stack_ != NULL; }

View File

@ -11,7 +11,7 @@
#include "src/log.h"
#include "src/macro-assembler.h"
#include "src/objects-inl.h"
#include "src/snapshot/deserializer.h"
#include "src/snapshot/object-deserializer.h"
#include "src/snapshot/snapshot.h"
#include "src/version.h"
#include "src/visitors.h"
@ -194,7 +194,7 @@ MaybeHandle<SharedFunctionInfo> CodeSerializer::Deserialize(
return MaybeHandle<SharedFunctionInfo>();
}
Deserializer deserializer(&scd);
ObjectDeserializer deserializer(&scd, false);
deserializer.AddAttachedObject(source);
Vector<const uint32_t> code_stub_keys = scd.CodeStubKeys();
for (int i = 0; i < code_stub_keys.length(); i++) {
@ -204,7 +204,7 @@ MaybeHandle<SharedFunctionInfo> CodeSerializer::Deserialize(
// Deserialize.
Handle<HeapObject> as_heap_object;
if (!deserializer.DeserializeObject(isolate).ToHandle(&as_heap_object)) {
if (!deserializer.Deserialize(isolate).ToHandle(&as_heap_object)) {
// Deserializing may fail if the reservations cannot be fulfilled.
if (FLAG_profile_deserialization) PrintF("[Deserializing failed]\n");
return MaybeHandle<SharedFunctionInfo>();
@ -265,7 +265,7 @@ MaybeHandle<FixedArray> WasmCompiledModuleSerializer::DeserializeWasmModule(
return nothing;
}
Deserializer deserializer(&scd, true);
ObjectDeserializer deserializer(&scd, true);
deserializer.AddAttachedObject(isolate->native_context());
MaybeHandle<String> maybe_wire_bytes_as_string =
@ -283,7 +283,7 @@ MaybeHandle<FixedArray> WasmCompiledModuleSerializer::DeserializeWasmModule(
CodeStub::GetCode(isolate, stub_keys[i]).ToHandleChecked());
}
MaybeHandle<HeapObject> obj = deserializer.DeserializeObject(isolate);
MaybeHandle<HeapObject> obj = deserializer.Deserialize(isolate);
if (obj.is_null() || !obj.ToHandleChecked()->IsFixedArray()) return nothing;
// Cast without type checks, as the module wrapper is not there yet.
Handle<WasmCompiledModule> compiled_module(

View File

@ -28,9 +28,23 @@ class Heap;
// A Deserializer reads a snapshot and reconstructs the Object graph it defines.
class Deserializer : public SerializerDeserializer {
public:
~Deserializer() override;
// Add an object to back an attached reference. The order to add objects must
// mirror the order they are added in the serializer.
void AddAttachedObject(Handle<HeapObject> attached_object) {
attached_objects_.Add(attached_object);
}
void SetRehashability(bool v) { can_rehash_ = v; }
protected:
// This section is temporary while the deserializer is being refactored into
// {object,partial,object}-deserializer.h.
// Create a deserializer from a snapshot byte source.
template <class Data>
explicit Deserializer(Data* data, bool deserializing_user_code = false)
Deserializer(Data* data, bool deserializing_user_code)
: isolate_(NULL),
source_(data->Payload()),
magic_number_(data->GetMagicNumber()),
@ -44,8 +58,6 @@ class Deserializer : public SerializerDeserializer {
DecodeReservation(data->Reservations());
}
~Deserializer() override;
// Deserialize the snapshot into an empty heap.
void Deserialize(Isolate* isolate);
@ -57,14 +69,6 @@ class Deserializer : public SerializerDeserializer {
// Deserialize an object graph. Fail gracefully.
MaybeHandle<HeapObject> DeserializeObject(Isolate* isolate);
// Add an object to back an attached reference. The order to add objects must
// mirror the order they are added in the serializer.
void AddAttachedObject(Handle<HeapObject> attached_object) {
attached_objects_.Add(attached_object);
}
void SetRehashability(bool v) { can_rehash_ = v; }
private:
void VisitRootPointers(Root root, Object** start, Object** end) override;

View File

@ -0,0 +1,9 @@
// Copyright 2017 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/snapshot/object-deserializer.h"
namespace v8 {
namespace internal {} // namespace internal
} // namespace v8

View File

@ -0,0 +1,31 @@
// Copyright 2017 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_SNAPSHOT_OBJECT_DESERIALIZER_H_
#define V8_SNAPSHOT_OBJECT_DESERIALIZER_H_
#include "src/snapshot/deserializer.h"
namespace v8 {
namespace internal {
// Deserializes the object graph rooted at a given object.
// Currently, the ObjectDeserializer is only used to deserialize code objects
// and compiled wasm modules.
class ObjectDeserializer : public Deserializer {
public:
template <class Data>
ObjectDeserializer(Data* data, bool deserializing_user_code)
: Deserializer(data, deserializing_user_code) {}
// Deserialize an object graph. Fail gracefully.
MaybeHandle<HeapObject> Deserialize(Isolate* isolate) {
return DeserializeObject(isolate);
}
};
} // namespace internal
} // namespace v8
#endif // V8_SNAPSHOT_OBJECT_DESERIALIZER_H_

View File

@ -0,0 +1,9 @@
// Copyright 2017 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/snapshot/partial-deserializer.h"
namespace v8 {
namespace internal {} // namespace internal
} // namespace v8

View File

@ -0,0 +1,34 @@
// Copyright 2017 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_SNAPSHOT_PARTIAL_DESERIALIZER_H_
#define V8_SNAPSHOT_PARTIAL_DESERIALIZER_H_
#include "src/snapshot/deserializer.h"
#include "src/snapshot/snapshot.h"
namespace v8 {
namespace internal {
// Deserializes the context-dependent object graph rooted at a given object.
// Currently, the only use-case is to deserialize native contexts.
// The PartialDeserializer is not expected to any deserialize code objects.
class PartialDeserializer : public Deserializer {
public:
explicit PartialDeserializer(SnapshotData* data)
: Deserializer(data, false) {}
// Deserialize a single object and the objects reachable from it.
MaybeHandle<Object> Deserialize(
Isolate* isolate, Handle<JSGlobalProxy> global_proxy,
v8::DeserializeEmbedderFieldsCallback embedder_fields_deserializer) {
return DeserializePartial(isolate, global_proxy,
embedder_fields_deserializer);
}
};
} // namespace internal
} // namespace v8
#endif // V8_SNAPSHOT_PARTIAL_DESERIALIZER_H_

View File

@ -10,8 +10,9 @@
#include "src/base/platform/platform.h"
#include "src/full-codegen/full-codegen.h"
#include "src/objects-inl.h"
#include "src/snapshot/deserializer.h"
#include "src/snapshot/partial-deserializer.h"
#include "src/snapshot/snapshot-source-sink.h"
#include "src/snapshot/startup-deserializer.h"
#include "src/version.h"
namespace v8 {
@ -40,7 +41,7 @@ bool Snapshot::Initialize(Isolate* isolate) {
const v8::StartupData* blob = isolate->snapshot_blob();
Vector<const byte> startup_data = ExtractStartupData(blob);
SnapshotData snapshot_data(startup_data);
Deserializer deserializer(&snapshot_data);
StartupDeserializer deserializer(&snapshot_data);
deserializer.SetRehashability(ExtractRehashability(blob));
bool success = isolate->Init(&deserializer);
if (FLAG_profile_deserialization) {
@ -62,10 +63,10 @@ MaybeHandle<Context> Snapshot::NewContextFromSnapshot(
Vector<const byte> context_data =
ExtractContextData(blob, static_cast<int>(context_index));
SnapshotData snapshot_data(context_data);
Deserializer deserializer(&snapshot_data);
PartialDeserializer deserializer(&snapshot_data);
deserializer.SetRehashability(ExtractRehashability(blob));
MaybeHandle<Object> maybe_context = deserializer.DeserializePartial(
MaybeHandle<Object> maybe_context = deserializer.Deserialize(
isolate, global_proxy, embedder_fields_deserializer);
Handle<Object> result;
if (!maybe_context.ToHandle(&result)) return MaybeHandle<Context>();

View File

@ -0,0 +1,9 @@
// Copyright 2017 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/snapshot/startup-deserializer.h"
namespace v8 {
namespace internal {} // namespace internal
} // namespace v8

View File

@ -0,0 +1,29 @@
// Copyright 2017 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_SNAPSHOT_STARTUP_DESERIALIZER_H_
#define V8_SNAPSHOT_STARTUP_DESERIALIZER_H_
#include "src/snapshot/deserializer.h"
#include "src/snapshot/snapshot.h"
namespace v8 {
namespace internal {
// Initializes an isolate with context-independent data from a given snapshot.
class StartupDeserializer : public Deserializer {
public:
explicit StartupDeserializer(SnapshotData* data)
: Deserializer(data, false) {}
// Deserialize the snapshot into an empty heap.
void Deserialize(Isolate* isolate) {
return Deserializer::Deserialize(isolate);
}
};
} // namespace internal
} // namespace v8
#endif // V8_SNAPSHOT_STARTUP_DESERIALIZER_H_

View File

@ -1341,18 +1341,24 @@
'snapshot/code-serializer.h',
'snapshot/deserializer.cc',
'snapshot/deserializer.h',
'snapshot/natives.h',
'snapshot/natives-common.cc',
'snapshot/natives.h',
'snapshot/object-deserializer.cc',
'snapshot/object-deserializer.h',
'snapshot/partial-deserializer.cc',
'snapshot/partial-deserializer.h',
'snapshot/partial-serializer.cc',
'snapshot/partial-serializer.h',
'snapshot/serializer.cc',
'snapshot/serializer.h',
'snapshot/serializer-common.cc',
'snapshot/serializer-common.h',
'snapshot/snapshot.h',
'snapshot/serializer.h',
'snapshot/snapshot-common.cc',
'snapshot/snapshot.h',
'snapshot/snapshot-source-sink.cc',
'snapshot/snapshot-source-sink.h',
'snapshot/startup-deserializer.cc',
'snapshot/startup-deserializer.h',
'snapshot/startup-serializer.cc',
'snapshot/startup-serializer.h',
'source-position-table.cc',

View File

@ -42,10 +42,11 @@
#include "src/objects-inl.h"
#include "src/runtime/runtime.h"
#include "src/snapshot/code-serializer.h"
#include "src/snapshot/deserializer.h"
#include "src/snapshot/natives.h"
#include "src/snapshot/partial-deserializer.h"
#include "src/snapshot/partial-serializer.h"
#include "src/snapshot/snapshot.h"
#include "src/snapshot/startup-deserializer.h"
#include "src/snapshot/startup-serializer.h"
#include "test/cctest/cctest.h"
#include "test/cctest/heap/heap-utils.h"
@ -137,7 +138,7 @@ v8::Isolate* InitializeFromBlob(Vector<const byte> blob) {
v8::Isolate* v8_isolate = NULL;
{
SnapshotData snapshot_data(blob);
Deserializer deserializer(&snapshot_data);
StartupDeserializer deserializer(&snapshot_data);
TestIsolate* isolate = new TestIsolate(false);
v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
v8::Isolate::Scope isolate_scope(v8_isolate);
@ -377,10 +378,10 @@ UNINITIALIZED_TEST(PartialSerializerObject) {
Handle<JSGlobalProxy> global_proxy = Handle<JSGlobalProxy>::null();
{
SnapshotData snapshot_data(partial_blob);
Deserializer deserializer(&snapshot_data);
PartialDeserializer deserializer(&snapshot_data);
root = deserializer
.DeserializePartial(isolate, global_proxy,
v8::DeserializeInternalFieldsCallback())
.Deserialize(isolate, global_proxy,
v8::DeserializeInternalFieldsCallback())
.ToHandleChecked();
CHECK(root->IsString());
}
@ -388,10 +389,10 @@ UNINITIALIZED_TEST(PartialSerializerObject) {
Handle<Object> root2;
{
SnapshotData snapshot_data(partial_blob);
Deserializer deserializer(&snapshot_data);
PartialDeserializer deserializer(&snapshot_data);
root2 = deserializer
.DeserializePartial(isolate, global_proxy,
v8::DeserializeInternalFieldsCallback())
.Deserialize(isolate, global_proxy,
v8::DeserializeInternalFieldsCallback())
.ToHandleChecked();
CHECK(root2->IsString());
CHECK(root.is_identical_to(root2));
@ -473,10 +474,10 @@ UNINITIALIZED_TEST(PartialSerializerContext) {
JSGlobalProxy::SizeWithEmbedderFields(0));
{
SnapshotData snapshot_data(partial_blob);
Deserializer deserializer(&snapshot_data);
PartialDeserializer deserializer(&snapshot_data);
root = deserializer
.DeserializePartial(isolate, global_proxy,
v8::DeserializeInternalFieldsCallback())
.Deserialize(isolate, global_proxy,
v8::DeserializeInternalFieldsCallback())
.ToHandleChecked();
CHECK(root->IsContext());
CHECK(Handle<Context>::cast(root)->global_proxy() == *global_proxy);
@ -485,10 +486,10 @@ UNINITIALIZED_TEST(PartialSerializerContext) {
Handle<Object> root2;
{
SnapshotData snapshot_data(partial_blob);
Deserializer deserializer(&snapshot_data);
PartialDeserializer deserializer(&snapshot_data);
root2 = deserializer
.DeserializePartial(isolate, global_proxy,
v8::DeserializeInternalFieldsCallback())
.Deserialize(isolate, global_proxy,
v8::DeserializeInternalFieldsCallback())
.ToHandleChecked();
CHECK(root2->IsContext());
CHECK(!root.is_identical_to(root2));
@ -591,10 +592,10 @@ UNINITIALIZED_TEST(PartialSerializerCustomContext) {
JSGlobalProxy::SizeWithEmbedderFields(0));
{
SnapshotData snapshot_data(partial_blob);
Deserializer deserializer(&snapshot_data);
PartialDeserializer deserializer(&snapshot_data);
root = deserializer
.DeserializePartial(isolate, global_proxy,
v8::DeserializeInternalFieldsCallback())
.Deserialize(isolate, global_proxy,
v8::DeserializeInternalFieldsCallback())
.ToHandleChecked();
CHECK(root->IsContext());
Handle<Context> context = Handle<Context>::cast(root);