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