Correctly reference global proxy in the partial snapshot.
R=verwaest@chromium.org Review URL: https://codereview.chromium.org/853493003 Cr-Commit-Position: refs/heads/master@{#26061}
This commit is contained in:
parent
2ebe24c9cb
commit
fe82e03bb6
@ -183,16 +183,15 @@ class Genesis BASE_EMBEDDED {
|
||||
// Make the "arguments" and "caller" properties throw a TypeError on access.
|
||||
void PoisonArgumentsAndCaller(Handle<Map> map);
|
||||
|
||||
// Creates the global objects using the global and the template passed in
|
||||
// through the API. We call this regardless of whether we are building a
|
||||
// Creates the global objects using the global proxy and the template passed
|
||||
// in through the API. We call this regardless of whether we are building a
|
||||
// context from scratch or using a deserialized one from the partial snapshot
|
||||
// but in the latter case we don't use the objects it produces directly, as
|
||||
// we have to used the deserialized ones that are linked together with the
|
||||
// rest of the context snapshot.
|
||||
Handle<JSGlobalProxy> CreateNewGlobals(
|
||||
Handle<GlobalObject> CreateNewGlobals(
|
||||
v8::Handle<v8::ObjectTemplate> global_proxy_template,
|
||||
MaybeHandle<JSGlobalProxy> maybe_global_proxy,
|
||||
Handle<GlobalObject>* global_object_out);
|
||||
Handle<JSGlobalProxy> global_proxy);
|
||||
// Hooks the given global proxy into the context. If the context was created
|
||||
// by deserialization then this will unhook the global proxy that was
|
||||
// deserialized, leaving the GC to pick it up.
|
||||
@ -757,14 +756,13 @@ void Genesis::CreateRoots() {
|
||||
}
|
||||
|
||||
|
||||
Handle<JSGlobalProxy> Genesis::CreateNewGlobals(
|
||||
Handle<GlobalObject> Genesis::CreateNewGlobals(
|
||||
v8::Handle<v8::ObjectTemplate> global_proxy_template,
|
||||
MaybeHandle<JSGlobalProxy> maybe_global_proxy,
|
||||
Handle<GlobalObject>* global_object_out) {
|
||||
Handle<JSGlobalProxy> global_proxy) {
|
||||
// The argument global_proxy_template aka data is an ObjectTemplateInfo.
|
||||
// It has a constructor pointer that points at global_constructor which is a
|
||||
// FunctionTemplateInfo.
|
||||
// The global_proxy_constructor is used to create or reinitialize the
|
||||
// The global_proxy_constructor is used to (re)initialize the
|
||||
// global_proxy. The global_proxy_constructor also has a prototype_template
|
||||
// pointer that points at js_global_object_template which is an
|
||||
// ObjectTemplateInfo.
|
||||
@ -820,11 +818,8 @@ Handle<JSGlobalProxy> Genesis::CreateNewGlobals(
|
||||
js_global_object_function->initial_map()->set_dictionary_map(true);
|
||||
Handle<GlobalObject> global_object =
|
||||
factory()->NewGlobalObject(js_global_object_function);
|
||||
if (global_object_out != NULL) {
|
||||
*global_object_out = global_object;
|
||||
}
|
||||
|
||||
// Step 2: create or re-initialize the global proxy object.
|
||||
// Step 2: (re)initialize the global proxy object.
|
||||
Handle<JSFunction> global_proxy_function;
|
||||
if (global_proxy_template.IsEmpty()) {
|
||||
Handle<String> name = Handle<String>(heap()->empty_string());
|
||||
@ -850,15 +845,8 @@ Handle<JSGlobalProxy> Genesis::CreateNewGlobals(
|
||||
// Set global_proxy.__proto__ to js_global after ConfigureGlobalObjects
|
||||
// Return the global proxy.
|
||||
|
||||
Handle<JSGlobalProxy> global_proxy;
|
||||
if (maybe_global_proxy.ToHandle(&global_proxy)) {
|
||||
factory()->ReinitializeJSGlobalProxy(global_proxy, global_proxy_function);
|
||||
} else {
|
||||
global_proxy = Handle<JSGlobalProxy>::cast(
|
||||
factory()->NewJSObject(global_proxy_function, TENURED));
|
||||
global_proxy->set_hash(heap()->undefined_value());
|
||||
}
|
||||
return global_proxy;
|
||||
return global_object;
|
||||
}
|
||||
|
||||
|
||||
@ -868,6 +856,10 @@ void Genesis::HookUpGlobalProxy(Handle<GlobalObject> global_object,
|
||||
global_object->set_native_context(*native_context());
|
||||
global_object->set_global_proxy(*global_proxy);
|
||||
global_proxy->set_native_context(*native_context());
|
||||
// If we deserialized the context, the global proxy is already
|
||||
// correctly set up. Otherwise it's undefined.
|
||||
DCHECK(native_context()->get(Context::GLOBAL_PROXY_INDEX)->IsUndefined() ||
|
||||
native_context()->global_proxy() == *global_proxy);
|
||||
native_context()->set_global_proxy(*global_proxy);
|
||||
}
|
||||
|
||||
@ -2736,11 +2728,20 @@ Genesis::Genesis(Isolate* isolate,
|
||||
StackLimitCheck check(isolate);
|
||||
if (check.HasOverflowed()) return;
|
||||
|
||||
// The deserializer needs to hook up references to the global proxy.
|
||||
// Create an uninitialized global proxy now if we don't have one
|
||||
// and initialize it later in CreateNewGlobals.
|
||||
Handle<JSGlobalProxy> global_proxy;
|
||||
if (!maybe_global_proxy.ToHandle(&global_proxy)) {
|
||||
global_proxy = isolate->factory()->NewUninitializedJSGlobalProxy();
|
||||
}
|
||||
|
||||
// We can only de-serialize a context if the isolate was initialized from
|
||||
// a snapshot. Otherwise we have to build the context from scratch.
|
||||
Handle<FixedArray> outdated_contexts;
|
||||
if (!isolate->initialized_from_snapshot() ||
|
||||
!Snapshot::NewContextFromSnapshot(isolate, &outdated_contexts)
|
||||
!Snapshot::NewContextFromSnapshot(isolate, global_proxy,
|
||||
&outdated_contexts)
|
||||
.ToHandle(&native_context_)) {
|
||||
native_context_ = Handle<Context>();
|
||||
}
|
||||
@ -2758,9 +2759,8 @@ Genesis::Genesis(Isolate* isolate,
|
||||
Map::TraceAllTransitions(object_fun->initial_map());
|
||||
}
|
||||
#endif
|
||||
Handle<GlobalObject> global_object;
|
||||
Handle<JSGlobalProxy> global_proxy = CreateNewGlobals(
|
||||
global_proxy_template, maybe_global_proxy, &global_object);
|
||||
Handle<GlobalObject> global_object =
|
||||
CreateNewGlobals(global_proxy_template, global_proxy);
|
||||
|
||||
HookUpGlobalProxy(global_object, global_proxy);
|
||||
HookUpGlobalObject(global_object, outdated_contexts);
|
||||
@ -2773,9 +2773,8 @@ Genesis::Genesis(Isolate* isolate,
|
||||
CreateRoots();
|
||||
Handle<JSFunction> empty_function = CreateEmptyFunction(isolate);
|
||||
CreateStrictModeFunctionMaps(empty_function);
|
||||
Handle<GlobalObject> global_object;
|
||||
Handle<JSGlobalProxy> global_proxy = CreateNewGlobals(
|
||||
global_proxy_template, maybe_global_proxy, &global_object);
|
||||
Handle<GlobalObject> global_object =
|
||||
CreateNewGlobals(global_proxy_template, global_proxy);
|
||||
HookUpGlobalProxy(global_object, global_proxy);
|
||||
InitializeGlobal(global_object, empty_function);
|
||||
InstallJSFunctionResultCaches();
|
||||
|
@ -1958,6 +1958,18 @@ void Factory::ReinitializeJSProxy(Handle<JSProxy> proxy, InstanceType type,
|
||||
}
|
||||
|
||||
|
||||
Handle<JSGlobalProxy> Factory::NewUninitializedJSGlobalProxy() {
|
||||
// Create an empty shell of a JSGlobalProxy that needs to be reinitialized
|
||||
// via ReinitializeJSGlobalProxy later.
|
||||
Handle<Map> map = NewMap(JS_GLOBAL_PROXY_TYPE, JSGlobalProxy::kSize);
|
||||
// Maintain invariant expected from any JSGlobalProxy.
|
||||
map->set_is_access_check_needed(true);
|
||||
CALL_HEAP_FUNCTION(isolate(), isolate()->heap()->AllocateJSObjectFromMap(
|
||||
*map, NOT_TENURED, false),
|
||||
JSGlobalProxy);
|
||||
}
|
||||
|
||||
|
||||
void Factory::ReinitializeJSGlobalProxy(Handle<JSGlobalProxy> object,
|
||||
Handle<JSFunction> constructor) {
|
||||
DCHECK(constructor->has_initial_map());
|
||||
|
@ -465,6 +465,8 @@ class Factory FINAL {
|
||||
void ReinitializeJSGlobalProxy(Handle<JSGlobalProxy> global,
|
||||
Handle<JSFunction> constructor);
|
||||
|
||||
Handle<JSGlobalProxy> NewUninitializedJSGlobalProxy();
|
||||
|
||||
// Change the type of the argument into a JS object/function and reinitialize.
|
||||
void BecomeJSObject(Handle<JSProxy> object);
|
||||
void BecomeJSFunction(Handle<JSProxy> object);
|
||||
|
@ -567,7 +567,6 @@ void JSGlobalProxy::JSGlobalProxyVerify() {
|
||||
VerifyObjectField(JSGlobalProxy::kNativeContextOffset);
|
||||
// Make sure that this object has no properties, elements.
|
||||
CHECK_EQ(0, properties()->length());
|
||||
CHECK_EQ(FAST_HOLEY_SMI_ELEMENTS, GetElementsKind());
|
||||
CHECK_EQ(0, FixedArray::cast(elements())->length());
|
||||
}
|
||||
|
||||
|
@ -700,13 +700,18 @@ void Deserializer::Deserialize(Isolate* isolate) {
|
||||
|
||||
|
||||
MaybeHandle<Object> Deserializer::DeserializePartial(
|
||||
Isolate* isolate, Handle<FixedArray>* outdated_contexts_out) {
|
||||
Isolate* isolate, Handle<JSGlobalProxy> global_proxy,
|
||||
Handle<FixedArray>* outdated_contexts_out) {
|
||||
Initialize(isolate);
|
||||
if (!ReserveSpace()) {
|
||||
FatalProcessOutOfMemory("deserialize context");
|
||||
return MaybeHandle<Object>();
|
||||
}
|
||||
|
||||
Vector<Handle<Object> > attached_objects = Vector<Handle<Object> >::New(1);
|
||||
attached_objects[kGlobalProxyReference] = global_proxy;
|
||||
SetAttachedObjects(attached_objects);
|
||||
|
||||
DisallowHeapAllocation no_gc;
|
||||
// Keep track of the code space start and end pointers in case new
|
||||
// code objects were unserialized
|
||||
@ -734,6 +739,7 @@ MaybeHandle<SharedFunctionInfo> Deserializer::DeserializeCode(
|
||||
if (!ReserveSpace()) {
|
||||
return Handle<SharedFunctionInfo>();
|
||||
} else {
|
||||
deserializing_user_code_ = true;
|
||||
DisallowHeapAllocation no_gc;
|
||||
Object* root;
|
||||
VisitPointer(&root);
|
||||
@ -749,7 +755,7 @@ Deserializer::~Deserializer() {
|
||||
delete external_reference_decoder_;
|
||||
external_reference_decoder_ = NULL;
|
||||
}
|
||||
if (attached_objects_) attached_objects_->Dispose();
|
||||
attached_objects_.Dispose();
|
||||
}
|
||||
|
||||
|
||||
@ -997,9 +1003,9 @@ void Deserializer::ReadData(Object** current, Object** limit, int source_space,
|
||||
new_object = isolate->builtins()->builtin(name); \
|
||||
emit_write_barrier = false; \
|
||||
} else if (where == kAttachedReference) { \
|
||||
DCHECK(deserializing_user_code()); \
|
||||
int index = source_.GetInt(); \
|
||||
new_object = *attached_objects_->at(index); \
|
||||
DCHECK(deserializing_user_code() || index == kGlobalProxyReference); \
|
||||
new_object = *attached_objects_[index]; \
|
||||
emit_write_barrier = isolate->heap()->InNewSpace(new_object); \
|
||||
} else { \
|
||||
DCHECK(where == kBackrefWithSkip); \
|
||||
@ -1396,7 +1402,11 @@ void StartupSerializer::VisitPointers(Object** start, Object** end) {
|
||||
|
||||
|
||||
void PartialSerializer::Serialize(Object** o) {
|
||||
if ((*o)->IsContext()) global_object_ = Context::cast(*o)->global_object();
|
||||
if ((*o)->IsContext()) {
|
||||
Context* context = Context::cast(*o);
|
||||
global_object_ = context->global_object();
|
||||
global_proxy_ = context->global_proxy();
|
||||
}
|
||||
VisitPointer(o);
|
||||
SerializeOutdatedContextsAsFixedArray();
|
||||
Pad();
|
||||
@ -1683,6 +1693,14 @@ void PartialSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code,
|
||||
|
||||
FlushSkip(skip);
|
||||
|
||||
if (obj == global_proxy_) {
|
||||
FlushSkip(skip);
|
||||
DCHECK(how_to_code == kPlain && where_to_point == kStartOfObject);
|
||||
sink_->Put(kAttachedReference + how_to_code + where_to_point, "Reference");
|
||||
sink_->PutInt(kGlobalProxyReference, "kGlobalProxyReferenceIndex");
|
||||
return;
|
||||
}
|
||||
|
||||
// Object has not yet been serialized. Serialize it here.
|
||||
ObjectSerializer serializer(this, obj, sink_, how_to_code, where_to_point);
|
||||
serializer.Serialize();
|
||||
@ -2323,16 +2341,6 @@ int CodeSerializer::AddCodeStubKey(uint32_t stub_key) {
|
||||
}
|
||||
|
||||
|
||||
void CodeSerializer::SerializeSourceObject(HowToCode how_to_code,
|
||||
WhereToPoint where_to_point) {
|
||||
if (FLAG_trace_serializer) PrintF(" Encoding source object\n");
|
||||
|
||||
DCHECK(how_to_code == kPlain && where_to_point == kStartOfObject);
|
||||
sink_->Put(kAttachedReference + how_to_code + where_to_point, "Source");
|
||||
sink_->PutInt(kSourceObjectIndex, "kSourceObjectIndex");
|
||||
}
|
||||
|
||||
|
||||
MaybeHandle<SharedFunctionInfo> CodeSerializer::Deserialize(
|
||||
Isolate* isolate, ScriptData* cached_data, Handle<String> source) {
|
||||
base::ElapsedTimer timer;
|
||||
@ -2363,7 +2371,7 @@ MaybeHandle<SharedFunctionInfo> CodeSerializer::Deserialize(
|
||||
}
|
||||
|
||||
Deserializer deserializer(scd.get());
|
||||
deserializer.SetAttachedObjects(&attached_objects);
|
||||
deserializer.SetAttachedObjects(attached_objects);
|
||||
|
||||
// Deserialize.
|
||||
Handle<SharedFunctionInfo> result;
|
||||
|
@ -449,6 +449,9 @@ class SerializerDeserializer: public ObjectVisitor {
|
||||
// Used as index for the attached reference representing the source object.
|
||||
static const int kSourceObjectReference = 0;
|
||||
|
||||
// Used as index for the attached reference representing the global proxy.
|
||||
static const int kGlobalProxyReference = 0;
|
||||
|
||||
HotObjectsList hot_objects_;
|
||||
};
|
||||
|
||||
@ -506,10 +509,10 @@ class Deserializer: public SerializerDeserializer {
|
||||
template <class Data>
|
||||
explicit Deserializer(Data* data)
|
||||
: isolate_(NULL),
|
||||
attached_objects_(NULL),
|
||||
source_(data->Payload()),
|
||||
external_reference_decoder_(NULL),
|
||||
deserialized_large_objects_(0) {
|
||||
deserialized_large_objects_(0),
|
||||
deserializing_user_code_(false) {
|
||||
DecodeReservation(data->Reservations());
|
||||
}
|
||||
|
||||
@ -519,22 +522,21 @@ class Deserializer: public SerializerDeserializer {
|
||||
void Deserialize(Isolate* isolate);
|
||||
|
||||
// Deserialize a single object and the objects reachable from it.
|
||||
// We may want to abort gracefully even if deserialization fails.
|
||||
MaybeHandle<Object> DeserializePartial(
|
||||
Isolate* isolate, Handle<FixedArray>* outdated_contexts_out);
|
||||
Isolate* isolate, Handle<JSGlobalProxy> global_proxy,
|
||||
Handle<FixedArray>* outdated_contexts_out);
|
||||
|
||||
// Deserialize a shared function info. Fail gracefully.
|
||||
MaybeHandle<SharedFunctionInfo> DeserializeCode(Isolate* isolate);
|
||||
|
||||
void FlushICacheForNewCodeObjects();
|
||||
|
||||
// Serialized user code reference certain objects that are provided in a list
|
||||
// By calling this method, we assume that we are deserializing user code.
|
||||
void SetAttachedObjects(Vector<Handle<Object> >* attached_objects) {
|
||||
// Pass a vector of externally-provided objects referenced by the snapshot.
|
||||
// The ownership to its backing store is handed over as well.
|
||||
void SetAttachedObjects(Vector<Handle<Object> > attached_objects) {
|
||||
attached_objects_ = attached_objects;
|
||||
}
|
||||
|
||||
bool deserializing_user_code() { return attached_objects_ != NULL; }
|
||||
|
||||
private:
|
||||
virtual void VisitPointers(Object** start, Object** end);
|
||||
|
||||
@ -544,6 +546,8 @@ class Deserializer: public SerializerDeserializer {
|
||||
|
||||
void Initialize(Isolate* isolate);
|
||||
|
||||
bool deserializing_user_code() { return deserializing_user_code_; }
|
||||
|
||||
void DecodeReservation(Vector<const SerializedData::Reservation> res);
|
||||
|
||||
bool ReserveSpace();
|
||||
@ -577,7 +581,7 @@ class Deserializer: public SerializerDeserializer {
|
||||
Isolate* isolate_;
|
||||
|
||||
// Objects from the attached object descriptions in the serialized user code.
|
||||
Vector<Handle<Object> >* attached_objects_;
|
||||
Vector<Handle<Object> > attached_objects_;
|
||||
|
||||
SnapshotByteSource source_;
|
||||
// The address of the next object that will be allocated in each space.
|
||||
@ -592,6 +596,8 @@ class Deserializer: public SerializerDeserializer {
|
||||
|
||||
List<HeapObject*> deserialized_large_objects_;
|
||||
|
||||
bool deserializing_user_code_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Deserializer);
|
||||
};
|
||||
|
||||
@ -745,7 +751,8 @@ class PartialSerializer : public Serializer {
|
||||
: Serializer(isolate, sink),
|
||||
startup_serializer_(startup_snapshot_serializer),
|
||||
outdated_contexts_(0),
|
||||
global_object_(NULL) {
|
||||
global_object_(NULL),
|
||||
global_proxy_(NULL) {
|
||||
InitializeCodeAddressMap();
|
||||
}
|
||||
|
||||
@ -774,6 +781,7 @@ class PartialSerializer : public Serializer {
|
||||
Serializer* startup_serializer_;
|
||||
List<BackReference> outdated_contexts_;
|
||||
Object* global_object_;
|
||||
Object* global_proxy_;
|
||||
DISALLOW_COPY_AND_ASSIGN(PartialSerializer);
|
||||
};
|
||||
|
||||
@ -855,8 +863,6 @@ class CodeSerializer : public Serializer {
|
||||
WhereToPoint where_to_point);
|
||||
void SerializeCodeStub(uint32_t stub_key, HowToCode how_to_code,
|
||||
WhereToPoint where_to_point);
|
||||
void SerializeSourceObject(HowToCode how_to_code,
|
||||
WhereToPoint where_to_point);
|
||||
void SerializeGeneric(HeapObject* heap_object, HowToCode how_to_code,
|
||||
WhereToPoint where_to_point);
|
||||
int AddCodeStubKey(uint32_t stub_key);
|
||||
|
@ -54,7 +54,8 @@ bool Snapshot::Initialize(Isolate* isolate) {
|
||||
|
||||
|
||||
MaybeHandle<Context> Snapshot::NewContextFromSnapshot(
|
||||
Isolate* isolate, Handle<FixedArray>* outdated_contexts_out) {
|
||||
Isolate* isolate, Handle<JSGlobalProxy> global_proxy,
|
||||
Handle<FixedArray>* outdated_contexts_out) {
|
||||
if (!HaveASnapshotToStartFrom()) return Handle<Context>();
|
||||
base::ElapsedTimer timer;
|
||||
if (FLAG_profile_deserialization) timer.Start();
|
||||
@ -64,8 +65,8 @@ MaybeHandle<Context> Snapshot::NewContextFromSnapshot(
|
||||
SnapshotData snapshot_data(context_data);
|
||||
Deserializer deserializer(&snapshot_data);
|
||||
|
||||
MaybeHandle<Object> maybe_context =
|
||||
deserializer.DeserializePartial(isolate, outdated_contexts_out);
|
||||
MaybeHandle<Object> maybe_context = deserializer.DeserializePartial(
|
||||
isolate, global_proxy, outdated_contexts_out);
|
||||
Handle<Object> result;
|
||||
if (!maybe_context.ToHandle(&result)) return MaybeHandle<Context>();
|
||||
CHECK(result->IsContext());
|
||||
|
@ -32,7 +32,8 @@ class Snapshot : public AllStatic {
|
||||
static bool Initialize(Isolate* isolate);
|
||||
// Create a new context using the internal partial snapshot.
|
||||
static MaybeHandle<Context> NewContextFromSnapshot(
|
||||
Isolate* isolate, Handle<FixedArray>* outdated_contexts_out);
|
||||
Isolate* isolate, Handle<JSGlobalProxy> global_proxy,
|
||||
Handle<FixedArray>* outdated_contexts_out);
|
||||
|
||||
static bool HaveASnapshotToStartFrom();
|
||||
|
||||
|
@ -394,10 +394,14 @@ UNINITIALIZED_DEPENDENT_TEST(PartialDeserialization, PartialSerialization) {
|
||||
HandleScope handle_scope(isolate);
|
||||
Handle<Object> root;
|
||||
Handle<FixedArray> outdated_contexts;
|
||||
// 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(Vector<const byte>(snapshot, snapshot_size));
|
||||
Deserializer deserializer(&snapshot_data);
|
||||
root = deserializer.DeserializePartial(isolate, &outdated_contexts)
|
||||
root = deserializer.DeserializePartial(isolate, global_proxy,
|
||||
&outdated_contexts)
|
||||
.ToHandleChecked();
|
||||
CHECK_EQ(0, outdated_contexts->length());
|
||||
CHECK(root->IsString());
|
||||
@ -407,7 +411,8 @@ UNINITIALIZED_DEPENDENT_TEST(PartialDeserialization, PartialSerialization) {
|
||||
{
|
||||
SnapshotData snapshot_data(Vector<const byte>(snapshot, snapshot_size));
|
||||
Deserializer deserializer(&snapshot_data);
|
||||
root2 = deserializer.DeserializePartial(isolate, &outdated_contexts)
|
||||
root2 = deserializer.DeserializePartial(isolate, global_proxy,
|
||||
&outdated_contexts)
|
||||
.ToHandleChecked();
|
||||
CHECK(root2->IsString());
|
||||
CHECK(root.is_identical_to(root2));
|
||||
@ -506,12 +511,16 @@ UNINITIALIZED_DEPENDENT_TEST(ContextDeserialization, ContextSerialization) {
|
||||
HandleScope handle_scope(isolate);
|
||||
Handle<Object> root;
|
||||
Handle<FixedArray> outdated_contexts;
|
||||
Handle<JSGlobalProxy> global_proxy =
|
||||
isolate->factory()->NewUninitializedJSGlobalProxy();
|
||||
{
|
||||
SnapshotData snapshot_data(Vector<const byte>(snapshot, snapshot_size));
|
||||
Deserializer deserializer(&snapshot_data);
|
||||
root = deserializer.DeserializePartial(isolate, &outdated_contexts)
|
||||
root = deserializer.DeserializePartial(isolate, global_proxy,
|
||||
&outdated_contexts)
|
||||
.ToHandleChecked();
|
||||
CHECK(root->IsContext());
|
||||
CHECK(Handle<Context>::cast(root)->global_proxy() == *global_proxy);
|
||||
CHECK_EQ(1, outdated_contexts->length());
|
||||
}
|
||||
|
||||
@ -519,7 +528,8 @@ UNINITIALIZED_DEPENDENT_TEST(ContextDeserialization, ContextSerialization) {
|
||||
{
|
||||
SnapshotData snapshot_data(Vector<const byte>(snapshot, snapshot_size));
|
||||
Deserializer deserializer(&snapshot_data);
|
||||
root2 = deserializer.DeserializePartial(isolate, &outdated_contexts)
|
||||
root2 = deserializer.DeserializePartial(isolate, global_proxy,
|
||||
&outdated_contexts)
|
||||
.ToHandleChecked();
|
||||
CHECK(root2->IsContext());
|
||||
CHECK(!root.is_identical_to(root2));
|
||||
@ -554,7 +564,8 @@ UNINITIALIZED_TEST(CustomContextSerialization) {
|
||||
"var e;"
|
||||
"(function() {"
|
||||
" e = function(s) { eval (s); }"
|
||||
"})();");
|
||||
"})();"
|
||||
"var o = this;");
|
||||
}
|
||||
// Make sure all builtin scripts are cached.
|
||||
{
|
||||
@ -625,13 +636,22 @@ UNINITIALIZED_DEPENDENT_TEST(CustomContextDeSerialization,
|
||||
HandleScope handle_scope(isolate);
|
||||
Handle<Object> root;
|
||||
Handle<FixedArray> outdated_contexts;
|
||||
Handle<JSGlobalProxy> global_proxy =
|
||||
isolate->factory()->NewUninitializedJSGlobalProxy();
|
||||
{
|
||||
SnapshotData snapshot_data(Vector<const byte>(snapshot, snapshot_size));
|
||||
Deserializer deserializer(&snapshot_data);
|
||||
root = deserializer.DeserializePartial(isolate, &outdated_contexts)
|
||||
root = deserializer.DeserializePartial(isolate, global_proxy,
|
||||
&outdated_contexts)
|
||||
.ToHandleChecked();
|
||||
CHECK_EQ(2, outdated_contexts->length());
|
||||
CHECK(root->IsContext());
|
||||
Handle<Context> context = Handle<Context>::cast(root);
|
||||
CHECK(context->global_proxy() == *global_proxy);
|
||||
Handle<String> o = isolate->factory()->NewStringFromAsciiChecked("o");
|
||||
Handle<JSObject> global_object(context->global_object(), isolate);
|
||||
Handle<Object> property = JSObject::GetDataProperty(global_object, o);
|
||||
CHECK(property.is_identical_to(global_proxy));
|
||||
}
|
||||
}
|
||||
v8_isolate->Dispose();
|
||||
|
Loading…
Reference in New Issue
Block a user