[snapshot] Simplify deserializer APIs
This moves deserializer setup boilerplate inside the deserializers, and makes improper usage less likely. For instance: ObjectDeserializer deserializer(&scd); /* ... deserializer setup ... */ MaybeHandle<HeapObject> obj = deserializer.Deserialize(isolate); /* ... result checks and casts ... */ has now become: /* All setup and casts inside deserializer, impossible to illegally use the same instance multiple times. */ MaybeHandle<SharedFunctionInfo> maybe_result = ObjectDeserializer::DeserializeSharedFunctionInfo( isolate, &scd, source); Bug: v8:6624 Change-Id: Id5a1848e024e89cf86e5292389ba7c89f31d8e6b Reviewed-on: https://chromium-review.googlesource.com/604791 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#47219}
This commit is contained in:
parent
d929cc755c
commit
95f868595c
@ -2807,9 +2807,7 @@ bool Isolate::Init(StartupDeserializer* des) {
|
||||
{
|
||||
AlwaysAllocateScope always_allocate(this);
|
||||
|
||||
if (!create_heap_objects) {
|
||||
des->Deserialize(this);
|
||||
}
|
||||
if (!create_heap_objects) des->DeserializeInto(this);
|
||||
load_stub_cache_->Initialize();
|
||||
store_stub_cache_->Initialize();
|
||||
setup_delegate_->SetupInterpreter(interpreter_, create_heap_objects);
|
||||
|
@ -194,24 +194,17 @@ MaybeHandle<SharedFunctionInfo> CodeSerializer::Deserialize(
|
||||
return MaybeHandle<SharedFunctionInfo>();
|
||||
}
|
||||
|
||||
ObjectDeserializer deserializer(&scd);
|
||||
deserializer.AddAttachedObject(source);
|
||||
Vector<const uint32_t> code_stub_keys = scd.CodeStubKeys();
|
||||
for (int i = 0; i < code_stub_keys.length(); i++) {
|
||||
deserializer.AddAttachedObject(
|
||||
CodeStub::GetCode(isolate, code_stub_keys[i]).ToHandleChecked());
|
||||
}
|
||||
|
||||
// Deserialize.
|
||||
Handle<HeapObject> as_heap_object;
|
||||
if (!deserializer.Deserialize(isolate).ToHandle(&as_heap_object)) {
|
||||
MaybeHandle<SharedFunctionInfo> maybe_result =
|
||||
ObjectDeserializer::DeserializeSharedFunctionInfo(isolate, &scd, source);
|
||||
|
||||
Handle<SharedFunctionInfo> result;
|
||||
if (!maybe_result.ToHandle(&result)) {
|
||||
// Deserializing may fail if the reservations cannot be fulfilled.
|
||||
if (FLAG_profile_deserialization) PrintF("[Deserializing failed]\n");
|
||||
return MaybeHandle<SharedFunctionInfo>();
|
||||
}
|
||||
|
||||
Handle<SharedFunctionInfo> result =
|
||||
Handle<SharedFunctionInfo>::cast(as_heap_object);
|
||||
if (FLAG_profile_deserialization) {
|
||||
double ms = timer.Elapsed().InMillisecondsF();
|
||||
int length = cached_data->length();
|
||||
@ -265,34 +258,16 @@ MaybeHandle<FixedArray> WasmCompiledModuleSerializer::DeserializeWasmModule(
|
||||
return nothing;
|
||||
}
|
||||
|
||||
ObjectDeserializer deserializer(&scd);
|
||||
deserializer.AddAttachedObject(isolate->native_context());
|
||||
MaybeHandle<WasmCompiledModule> maybe_result =
|
||||
ObjectDeserializer::DeserializeWasmCompiledModule(isolate, &scd,
|
||||
wire_bytes);
|
||||
|
||||
MaybeHandle<String> maybe_wire_bytes_as_string =
|
||||
isolate->factory()->NewStringFromOneByte(wire_bytes, TENURED);
|
||||
Handle<String> wire_bytes_as_string;
|
||||
if (!maybe_wire_bytes_as_string.ToHandle(&wire_bytes_as_string)) {
|
||||
return nothing;
|
||||
}
|
||||
deserializer.AddAttachedObject(
|
||||
handle(SeqOneByteString::cast(*wire_bytes_as_string)));
|
||||
Handle<WasmCompiledModule> result;
|
||||
if (!maybe_result.ToHandle(&result)) return nothing;
|
||||
|
||||
Vector<const uint32_t> stub_keys = scd.CodeStubKeys();
|
||||
for (int i = 0; i < stub_keys.length(); ++i) {
|
||||
deserializer.AddAttachedObject(
|
||||
CodeStub::GetCode(isolate, stub_keys[i]).ToHandleChecked());
|
||||
}
|
||||
|
||||
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(
|
||||
static_cast<WasmCompiledModule*>(*obj.ToHandleChecked()), isolate);
|
||||
|
||||
WasmCompiledModule::ReinitializeAfterDeserialization(isolate,
|
||||
compiled_module);
|
||||
DCHECK(WasmCompiledModule::IsWasmCompiledModule(*compiled_module));
|
||||
return compiled_module;
|
||||
WasmCompiledModule::ReinitializeAfterDeserialization(isolate, result);
|
||||
DCHECK(WasmCompiledModule::IsWasmCompiledModule(*result));
|
||||
return result;
|
||||
}
|
||||
|
||||
void WasmCompiledModuleSerializer::SerializeCodeObject(
|
||||
|
@ -5,13 +5,66 @@
|
||||
#include "src/snapshot/object-deserializer.h"
|
||||
|
||||
#include "src/assembler-inl.h"
|
||||
#include "src/code-stubs.h"
|
||||
#include "src/isolate.h"
|
||||
#include "src/objects.h"
|
||||
#include "src/snapshot/code-serializer.h"
|
||||
#include "src/wasm/wasm-objects.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
MaybeHandle<SharedFunctionInfo>
|
||||
ObjectDeserializer::DeserializeSharedFunctionInfo(
|
||||
Isolate* isolate, const SerializedCodeData* data, Handle<String> source) {
|
||||
ObjectDeserializer d(data);
|
||||
|
||||
d.AddAttachedObject(source);
|
||||
|
||||
Vector<const uint32_t> code_stub_keys = data->CodeStubKeys();
|
||||
for (int i = 0; i < code_stub_keys.length(); i++) {
|
||||
d.AddAttachedObject(
|
||||
CodeStub::GetCode(isolate, code_stub_keys[i]).ToHandleChecked());
|
||||
}
|
||||
|
||||
Handle<HeapObject> result;
|
||||
return d.Deserialize(isolate).ToHandle(&result)
|
||||
? Handle<SharedFunctionInfo>::cast(result)
|
||||
: MaybeHandle<SharedFunctionInfo>();
|
||||
}
|
||||
|
||||
MaybeHandle<WasmCompiledModule>
|
||||
ObjectDeserializer::DeserializeWasmCompiledModule(
|
||||
Isolate* isolate, const SerializedCodeData* data,
|
||||
Vector<const byte> wire_bytes) {
|
||||
ObjectDeserializer d(data);
|
||||
|
||||
d.AddAttachedObject(isolate->native_context());
|
||||
|
||||
MaybeHandle<String> maybe_wire_bytes_as_string =
|
||||
isolate->factory()->NewStringFromOneByte(wire_bytes, TENURED);
|
||||
Handle<String> wire_bytes_as_string;
|
||||
if (!maybe_wire_bytes_as_string.ToHandle(&wire_bytes_as_string)) {
|
||||
return MaybeHandle<WasmCompiledModule>();
|
||||
}
|
||||
d.AddAttachedObject(wire_bytes_as_string);
|
||||
|
||||
Vector<const uint32_t> code_stub_keys = data->CodeStubKeys();
|
||||
for (int i = 0; i < code_stub_keys.length(); i++) {
|
||||
d.AddAttachedObject(
|
||||
CodeStub::GetCode(isolate, code_stub_keys[i]).ToHandleChecked());
|
||||
}
|
||||
|
||||
Handle<HeapObject> result;
|
||||
if (!d.Deserialize(isolate).ToHandle(&result))
|
||||
return MaybeHandle<WasmCompiledModule>();
|
||||
|
||||
if (!result->IsFixedArray()) return MaybeHandle<WasmCompiledModule>();
|
||||
|
||||
// Cast without type checks, as the module wrapper is not there yet.
|
||||
return handle(static_cast<WasmCompiledModule*>(*result), isolate);
|
||||
}
|
||||
|
||||
MaybeHandle<HeapObject> ObjectDeserializer::Deserialize(Isolate* isolate) {
|
||||
Initialize(isolate);
|
||||
if (!ReserveSpace()) return MaybeHandle<HeapObject>();
|
||||
|
@ -11,19 +11,26 @@ namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
class SerializedCodeData;
|
||||
class SharedFunctionInfo;
|
||||
class WasmCompiledModule;
|
||||
|
||||
// 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 final : public Deserializer {
|
||||
public:
|
||||
static MaybeHandle<SharedFunctionInfo> DeserializeSharedFunctionInfo(
|
||||
Isolate* isolate, const SerializedCodeData* data, Handle<String> source);
|
||||
|
||||
static MaybeHandle<WasmCompiledModule> DeserializeWasmCompiledModule(
|
||||
Isolate* isolate, const SerializedCodeData* data,
|
||||
Vector<const byte> wire_bytes);
|
||||
|
||||
private:
|
||||
explicit ObjectDeserializer(const SerializedCodeData* data)
|
||||
: Deserializer(data, true) {}
|
||||
|
||||
// Deserialize an object graph. Fail gracefully.
|
||||
MaybeHandle<HeapObject> Deserialize(Isolate* isolate);
|
||||
|
||||
private:
|
||||
void FlushICacheForNewCodeObjectsAndRecordEmbeddedObjects();
|
||||
void CommitPostProcessedObjects();
|
||||
};
|
||||
|
@ -10,6 +10,21 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
MaybeHandle<Context> PartialDeserializer::DeserializeContext(
|
||||
Isolate* isolate, const SnapshotData* data, bool can_rehash,
|
||||
Handle<JSGlobalProxy> global_proxy,
|
||||
v8::DeserializeEmbedderFieldsCallback embedder_fields_deserializer) {
|
||||
PartialDeserializer d(data);
|
||||
d.SetRehashability(can_rehash);
|
||||
|
||||
MaybeHandle<Object> maybe_result =
|
||||
d.Deserialize(isolate, global_proxy, embedder_fields_deserializer);
|
||||
|
||||
Handle<Object> result;
|
||||
return maybe_result.ToHandle(&result) ? Handle<Context>::cast(result)
|
||||
: MaybeHandle<Context>();
|
||||
}
|
||||
|
||||
MaybeHandle<Object> PartialDeserializer::Deserialize(
|
||||
Isolate* isolate, Handle<JSGlobalProxy> global_proxy,
|
||||
v8::DeserializeEmbedderFieldsCallback embedder_fields_deserializer) {
|
||||
|
@ -11,11 +11,18 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
class Context;
|
||||
|
||||
// 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 deserialize any code objects.
|
||||
class PartialDeserializer final : public Deserializer {
|
||||
public:
|
||||
static MaybeHandle<Context> DeserializeContext(
|
||||
Isolate* isolate, const SnapshotData* data, bool can_rehash,
|
||||
Handle<JSGlobalProxy> global_proxy,
|
||||
v8::DeserializeEmbedderFieldsCallback embedder_fields_deserializer);
|
||||
|
||||
private:
|
||||
explicit PartialDeserializer(const SnapshotData* data)
|
||||
: Deserializer(data, false) {}
|
||||
|
||||
@ -24,7 +31,6 @@ class PartialDeserializer final : public Deserializer {
|
||||
Isolate* isolate, Handle<JSGlobalProxy> global_proxy,
|
||||
v8::DeserializeEmbedderFieldsCallback embedder_fields_deserializer);
|
||||
|
||||
private:
|
||||
void DeserializeEmbedderFields(
|
||||
v8::DeserializeEmbedderFieldsCallback embedder_fields_deserializer);
|
||||
|
||||
|
@ -26,27 +26,25 @@ PartialSerializer::~PartialSerializer() {
|
||||
}
|
||||
|
||||
void PartialSerializer::Serialize(Object** o, bool include_global_proxy) {
|
||||
if ((*o)->IsNativeContext()) {
|
||||
Context* context = Context::cast(*o);
|
||||
reference_map()->AddAttachedReference(context->global_proxy());
|
||||
// The bootstrap snapshot has a code-stub context. When serializing the
|
||||
// partial snapshot, it is chained into the weak context list on the isolate
|
||||
// and it's next context pointer may point to the code-stub context. Clear
|
||||
// it before serializing, it will get re-added to the context list
|
||||
// explicitly when it's loaded.
|
||||
context->set(Context::NEXT_CONTEXT_LINK,
|
||||
isolate_->heap()->undefined_value());
|
||||
DCHECK(!context->global_object()->IsUndefined(context->GetIsolate()));
|
||||
// Reset math random cache to get fresh random numbers.
|
||||
context->set_math_random_index(Smi::kZero);
|
||||
context->set_math_random_cache(isolate_->heap()->undefined_value());
|
||||
DCHECK_NULL(rehashable_global_dictionary_);
|
||||
rehashable_global_dictionary_ =
|
||||
context->global_object()->global_dictionary();
|
||||
} else {
|
||||
// We only do rehashing for native contexts.
|
||||
can_be_rehashed_ = false;
|
||||
}
|
||||
DCHECK((*o)->IsNativeContext());
|
||||
|
||||
Context* context = Context::cast(*o);
|
||||
reference_map()->AddAttachedReference(context->global_proxy());
|
||||
// The bootstrap snapshot has a code-stub context. When serializing the
|
||||
// partial snapshot, it is chained into the weak context list on the isolate
|
||||
// and it's next context pointer may point to the code-stub context. Clear
|
||||
// it before serializing, it will get re-added to the context list
|
||||
// explicitly when it's loaded.
|
||||
context->set(Context::NEXT_CONTEXT_LINK,
|
||||
isolate_->heap()->undefined_value());
|
||||
DCHECK(!context->global_object()->IsUndefined(context->GetIsolate()));
|
||||
// Reset math random cache to get fresh random numbers.
|
||||
context->set_math_random_index(Smi::kZero);
|
||||
context->set_math_random_cache(isolate_->heap()->undefined_value());
|
||||
DCHECK_NULL(rehashable_global_dictionary_);
|
||||
rehashable_global_dictionary_ =
|
||||
context->global_object()->global_dictionary();
|
||||
|
||||
VisitRootPointer(Root::kPartialSnapshotCache, o);
|
||||
SerializeDeferredObjects();
|
||||
SerializeEmbedderFields();
|
||||
|
@ -60,24 +60,25 @@ MaybeHandle<Context> Snapshot::NewContextFromSnapshot(
|
||||
if (FLAG_profile_deserialization) timer.Start();
|
||||
|
||||
const v8::StartupData* blob = isolate->snapshot_blob();
|
||||
bool can_rehash = ExtractRehashability(blob);
|
||||
Vector<const byte> context_data =
|
||||
ExtractContextData(blob, static_cast<int>(context_index));
|
||||
SnapshotData snapshot_data(context_data);
|
||||
PartialDeserializer deserializer(&snapshot_data);
|
||||
deserializer.SetRehashability(ExtractRehashability(blob));
|
||||
|
||||
MaybeHandle<Object> maybe_context = deserializer.Deserialize(
|
||||
isolate, global_proxy, embedder_fields_deserializer);
|
||||
Handle<Object> result;
|
||||
if (!maybe_context.ToHandle(&result)) return MaybeHandle<Context>();
|
||||
CHECK(result->IsContext());
|
||||
MaybeHandle<Context> maybe_result = PartialDeserializer::DeserializeContext(
|
||||
isolate, &snapshot_data, can_rehash, global_proxy,
|
||||
embedder_fields_deserializer);
|
||||
|
||||
Handle<Context> result;
|
||||
if (!maybe_result.ToHandle(&result)) return MaybeHandle<Context>();
|
||||
|
||||
if (FLAG_profile_deserialization) {
|
||||
double ms = timer.Elapsed().InMillisecondsF();
|
||||
int bytes = context_data.length();
|
||||
PrintF("[Deserializing context #%zu (%d bytes) took %0.3f ms]\n",
|
||||
context_index, bytes, ms);
|
||||
}
|
||||
return Handle<Context>::cast(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void ProfileDeserialization(const SnapshotData* startup_snapshot,
|
||||
|
@ -11,7 +11,7 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
void StartupDeserializer::Deserialize(Isolate* isolate) {
|
||||
void StartupDeserializer::DeserializeInto(Isolate* isolate) {
|
||||
Initialize(isolate);
|
||||
if (!ReserveSpace()) V8::FatalProcessOutOfMemory("StartupDeserializer");
|
||||
|
||||
|
@ -18,7 +18,7 @@ class StartupDeserializer final : public Deserializer {
|
||||
: Deserializer(data, false) {}
|
||||
|
||||
// Deserialize the snapshot into an empty heap.
|
||||
void Deserialize(Isolate* isolate);
|
||||
void DeserializeInto(Isolate* isolate);
|
||||
|
||||
private:
|
||||
void FlushICacheForNewIsolate();
|
||||
|
@ -302,106 +302,6 @@ UNINITIALIZED_TEST(StartupSerializerTwiceRunScript) {
|
||||
isolate->Dispose();
|
||||
}
|
||||
|
||||
static void PartiallySerializeObject(Vector<const byte>* startup_blob_out,
|
||||
Vector<const byte>* partial_blob_out) {
|
||||
v8::Isolate* v8_isolate = TestIsolate::NewInitialized(true);
|
||||
Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate);
|
||||
v8_isolate->Enter();
|
||||
{
|
||||
Heap* heap = isolate->heap();
|
||||
|
||||
v8::Persistent<v8::Context> env;
|
||||
{
|
||||
HandleScope scope(isolate);
|
||||
env.Reset(v8_isolate, v8::Context::New(v8_isolate));
|
||||
}
|
||||
CHECK(!env.IsEmpty());
|
||||
{
|
||||
v8::HandleScope handle_scope(v8_isolate);
|
||||
v8::Local<v8::Context>::New(v8_isolate, env)->Enter();
|
||||
}
|
||||
|
||||
heap->CollectAllAvailableGarbage(i::GarbageCollectionReason::kTesting);
|
||||
heap->CollectAllAvailableGarbage(i::GarbageCollectionReason::kTesting);
|
||||
|
||||
Object* raw_foo;
|
||||
{
|
||||
v8::HandleScope handle_scope(v8_isolate);
|
||||
v8::Local<v8::String> foo = v8_str("foo");
|
||||
CHECK(!foo.IsEmpty());
|
||||
raw_foo = *(v8::Utils::OpenHandle(*foo));
|
||||
}
|
||||
|
||||
{
|
||||
v8::HandleScope handle_scope(v8_isolate);
|
||||
v8::Local<v8::Context>::New(v8_isolate, env)->Exit();
|
||||
}
|
||||
env.Reset();
|
||||
|
||||
StartupSerializer startup_serializer(
|
||||
isolate, v8::SnapshotCreator::FunctionCodeHandling::kClear);
|
||||
startup_serializer.SerializeStrongReferences();
|
||||
|
||||
PartialSerializer partial_serializer(isolate, &startup_serializer,
|
||||
v8::SerializeInternalFieldsCallback());
|
||||
partial_serializer.Serialize(&raw_foo, false);
|
||||
|
||||
startup_serializer.SerializeWeakReferencesAndDeferred();
|
||||
|
||||
SnapshotData startup_snapshot(&startup_serializer);
|
||||
SnapshotData partial_snapshot(&partial_serializer);
|
||||
|
||||
*partial_blob_out = WritePayload(partial_snapshot.RawData());
|
||||
*startup_blob_out = WritePayload(startup_snapshot.RawData());
|
||||
}
|
||||
v8_isolate->Exit();
|
||||
v8_isolate->Dispose();
|
||||
}
|
||||
|
||||
UNINITIALIZED_TEST(PartialSerializerObject) {
|
||||
DisableAlwaysOpt();
|
||||
Vector<const byte> startup_blob;
|
||||
Vector<const byte> partial_blob;
|
||||
PartiallySerializeObject(&startup_blob, &partial_blob);
|
||||
|
||||
v8::Isolate* v8_isolate = InitializeFromBlob(startup_blob);
|
||||
startup_blob.Dispose();
|
||||
CHECK(v8_isolate);
|
||||
{
|
||||
v8::Isolate::Scope isolate_scope(v8_isolate);
|
||||
|
||||
Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate);
|
||||
HandleScope handle_scope(isolate);
|
||||
Handle<Object> root;
|
||||
// Intentionally empty handle. The deserializer should not come across
|
||||
// any references to the global proxy in this test.
|
||||
Handle<JSGlobalProxy> global_proxy = Handle<JSGlobalProxy>::null();
|
||||
{
|
||||
SnapshotData snapshot_data(partial_blob);
|
||||
PartialDeserializer deserializer(&snapshot_data);
|
||||
root = deserializer
|
||||
.Deserialize(isolate, global_proxy,
|
||||
v8::DeserializeInternalFieldsCallback())
|
||||
.ToHandleChecked();
|
||||
CHECK(root->IsString());
|
||||
}
|
||||
|
||||
Handle<Object> root2;
|
||||
{
|
||||
SnapshotData snapshot_data(partial_blob);
|
||||
PartialDeserializer deserializer(&snapshot_data);
|
||||
root2 = deserializer
|
||||
.Deserialize(isolate, global_proxy,
|
||||
v8::DeserializeInternalFieldsCallback())
|
||||
.ToHandleChecked();
|
||||
CHECK(root2->IsString());
|
||||
CHECK(root.is_identical_to(root2));
|
||||
}
|
||||
partial_blob.Dispose();
|
||||
}
|
||||
v8_isolate->Dispose();
|
||||
}
|
||||
|
||||
static void PartiallySerializeContext(Vector<const byte>* startup_blob_out,
|
||||
Vector<const byte>* partial_blob_out) {
|
||||
v8::Isolate* v8_isolate = TestIsolate::NewInitialized(true);
|
||||
@ -474,10 +374,9 @@ UNINITIALIZED_TEST(PartialSerializerContext) {
|
||||
JSGlobalProxy::SizeWithEmbedderFields(0));
|
||||
{
|
||||
SnapshotData snapshot_data(partial_blob);
|
||||
PartialDeserializer deserializer(&snapshot_data);
|
||||
root = deserializer
|
||||
.Deserialize(isolate, global_proxy,
|
||||
v8::DeserializeInternalFieldsCallback())
|
||||
root = PartialDeserializer::DeserializeContext(
|
||||
isolate, &snapshot_data, false, global_proxy,
|
||||
v8::DeserializeInternalFieldsCallback())
|
||||
.ToHandleChecked();
|
||||
CHECK(root->IsContext());
|
||||
CHECK(Handle<Context>::cast(root)->global_proxy() == *global_proxy);
|
||||
@ -486,10 +385,9 @@ UNINITIALIZED_TEST(PartialSerializerContext) {
|
||||
Handle<Object> root2;
|
||||
{
|
||||
SnapshotData snapshot_data(partial_blob);
|
||||
PartialDeserializer deserializer(&snapshot_data);
|
||||
root2 = deserializer
|
||||
.Deserialize(isolate, global_proxy,
|
||||
v8::DeserializeInternalFieldsCallback())
|
||||
root2 = PartialDeserializer::DeserializeContext(
|
||||
isolate, &snapshot_data, false, global_proxy,
|
||||
v8::DeserializeInternalFieldsCallback())
|
||||
.ToHandleChecked();
|
||||
CHECK(root2->IsContext());
|
||||
CHECK(!root.is_identical_to(root2));
|
||||
@ -592,10 +490,9 @@ UNINITIALIZED_TEST(PartialSerializerCustomContext) {
|
||||
JSGlobalProxy::SizeWithEmbedderFields(0));
|
||||
{
|
||||
SnapshotData snapshot_data(partial_blob);
|
||||
PartialDeserializer deserializer(&snapshot_data);
|
||||
root = deserializer
|
||||
.Deserialize(isolate, global_proxy,
|
||||
v8::DeserializeInternalFieldsCallback())
|
||||
root = PartialDeserializer::DeserializeContext(
|
||||
isolate, &snapshot_data, false, global_proxy,
|
||||
v8::DeserializeInternalFieldsCallback())
|
||||
.ToHandleChecked();
|
||||
CHECK(root->IsContext());
|
||||
Handle<Context> context = Handle<Context>::cast(root);
|
||||
|
Loading…
Reference in New Issue
Block a user