Commit 564a2086 authored by yangguo's avatar yangguo Committed by Commit bot

[bootstrapper] no longer use outdated contexts list.

We currently use the outdated contexts list provided by the serializer
to update the receiver (the global proxy) in script contexts. However,
this is not actually necessary, since the global proxy is passed to the
deserializer and replaced as we deserialize.

Originally, the outdated contexts list is to update the global object
field in contexts. This was necessary since at the time the deserializer
creates the native context, the global object has not yet been created.
But the global proxy already exists.

R=bmeurer@chromium.org

Review URL: https://codereview.chromium.org/1488873004

Cr-Commit-Position: refs/heads/master@{#32483}
parent 70e69975
...@@ -185,13 +185,11 @@ class Genesis BASE_EMBEDDED { ...@@ -185,13 +185,11 @@ class Genesis BASE_EMBEDDED {
// Similarly, we want to use the global that has been created by the templates // Similarly, we want to use the global that has been created by the templates
// passed through the API. The global from the snapshot is detached from the // passed through the API. The global from the snapshot is detached from the
// other objects in the snapshot. // other objects in the snapshot.
void HookUpGlobalObject(Handle<JSGlobalObject> global_object, void HookUpGlobalObject(Handle<JSGlobalObject> global_object);
Handle<FixedArray> outdated_contexts);
// The native context has a ScriptContextTable that store declarative bindings // The native context has a ScriptContextTable that store declarative bindings
// made in script scopes. Add a "this" binding to that table pointing to the // made in script scopes. Add a "this" binding to that table pointing to the
// global proxy. // global proxy.
void InstallGlobalThisBinding(); void InstallGlobalThisBinding();
void HookUpGlobalThisBinding(Handle<FixedArray> outdated_contexts);
// New context initialization. Used for creating a context from scratch. // New context initialization. Used for creating a context from scratch.
void InitializeGlobal(Handle<JSGlobalObject> global_object, void InitializeGlobal(Handle<JSGlobalObject> global_object,
Handle<JSFunction> empty_function, Handle<JSFunction> empty_function,
...@@ -923,23 +921,6 @@ void Genesis::InstallGlobalThisBinding() { ...@@ -923,23 +921,6 @@ void Genesis::InstallGlobalThisBinding() {
} }
void Genesis::HookUpGlobalThisBinding(Handle<FixedArray> outdated_contexts) {
// One of these contexts should be the one that declares the global "this"
// binding.
for (int i = 0; i < outdated_contexts->length(); ++i) {
Context* context = Context::cast(outdated_contexts->get(i));
if (context->IsScriptContext()) {
ScopeInfo* scope_info = context->scope_info();
int slot = scope_info->ReceiverContextSlotIndex();
if (slot >= 0) {
DCHECK_EQ(slot, Context::MIN_CONTEXT_SLOTS);
context->set(slot, native_context()->global_proxy());
}
}
}
}
Handle<JSGlobalObject> Genesis::CreateNewGlobals( Handle<JSGlobalObject> Genesis::CreateNewGlobals(
v8::Local<v8::ObjectTemplate> global_proxy_template, v8::Local<v8::ObjectTemplate> global_proxy_template,
Handle<JSGlobalProxy> global_proxy) { Handle<JSGlobalProxy> global_proxy) {
...@@ -1045,8 +1026,7 @@ void Genesis::HookUpGlobalProxy(Handle<JSGlobalObject> global_object, ...@@ -1045,8 +1026,7 @@ void Genesis::HookUpGlobalProxy(Handle<JSGlobalObject> global_object,
} }
void Genesis::HookUpGlobalObject(Handle<JSGlobalObject> global_object, void Genesis::HookUpGlobalObject(Handle<JSGlobalObject> global_object) {
Handle<FixedArray> outdated_contexts) {
Handle<JSGlobalObject> global_object_from_snapshot( Handle<JSGlobalObject> global_object_from_snapshot(
JSGlobalObject::cast(native_context()->extension())); JSGlobalObject::cast(native_context()->extension()));
native_context()->set_extension(*global_object); native_context()->set_extension(*global_object);
...@@ -3107,10 +3087,8 @@ Genesis::Genesis(Isolate* isolate, ...@@ -3107,10 +3087,8 @@ Genesis::Genesis(Isolate* isolate,
// 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.
// Also create a context from scratch to expose natives, if required by flag. // Also create a context from scratch to expose natives, if required by flag.
Handle<FixedArray> outdated_contexts;
if (!isolate->initialized_from_snapshot() || if (!isolate->initialized_from_snapshot() ||
!Snapshot::NewContextFromSnapshot(isolate, global_proxy, !Snapshot::NewContextFromSnapshot(isolate, global_proxy)
&outdated_contexts)
.ToHandle(&native_context_)) { .ToHandle(&native_context_)) {
native_context_ = Handle<Context>(); native_context_ = Handle<Context>();
} }
...@@ -3132,8 +3110,7 @@ Genesis::Genesis(Isolate* isolate, ...@@ -3132,8 +3110,7 @@ Genesis::Genesis(Isolate* isolate,
CreateNewGlobals(global_proxy_template, global_proxy); CreateNewGlobals(global_proxy_template, global_proxy);
HookUpGlobalProxy(global_object, global_proxy); HookUpGlobalProxy(global_object, global_proxy);
HookUpGlobalObject(global_object, outdated_contexts); HookUpGlobalObject(global_object);
HookUpGlobalThisBinding(outdated_contexts);
if (!ConfigureGlobalObjects(global_proxy_template)) return; if (!ConfigureGlobalObjects(global_proxy_template)) return;
} else { } else {
......
...@@ -561,8 +561,7 @@ void Deserializer::Deserialize(Isolate* isolate) { ...@@ -561,8 +561,7 @@ void Deserializer::Deserialize(Isolate* isolate) {
MaybeHandle<Object> Deserializer::DeserializePartial( MaybeHandle<Object> Deserializer::DeserializePartial(
Isolate* isolate, Handle<JSGlobalProxy> global_proxy, Isolate* isolate, Handle<JSGlobalProxy> global_proxy) {
Handle<FixedArray>* outdated_contexts_out) {
Initialize(isolate); Initialize(isolate);
if (!ReserveSpace()) { if (!ReserveSpace()) {
V8::FatalProcessOutOfMemory("deserialize context"); V8::FatalProcessOutOfMemory("deserialize context");
...@@ -579,18 +578,13 @@ MaybeHandle<Object> Deserializer::DeserializePartial( ...@@ -579,18 +578,13 @@ MaybeHandle<Object> Deserializer::DeserializePartial(
OldSpace* code_space = isolate_->heap()->code_space(); OldSpace* code_space = isolate_->heap()->code_space();
Address start_address = code_space->top(); Address start_address = code_space->top();
Object* root; Object* root;
Object* outdated_contexts;
VisitPointer(&root); VisitPointer(&root);
DeserializeDeferredObjects(); DeserializeDeferredObjects();
VisitPointer(&outdated_contexts);
// There's no code deserialized here. If this assert fires then that's // There's no code deserialized here. If this assert fires then that's
// changed and logging should be added to notify the profiler et al of the // changed and logging should be added to notify the profiler et al of the
// new code, which also has to be flushed from instruction cache. // new code, which also has to be flushed from instruction cache.
CHECK_EQ(start_address, code_space->top()); CHECK_EQ(start_address, code_space->top());
CHECK(outdated_contexts->IsFixedArray());
*outdated_contexts_out =
Handle<FixedArray>(FixedArray::cast(outdated_contexts), isolate);
return Handle<Object>(root, isolate); return Handle<Object>(root, isolate);
} }
...@@ -1484,39 +1478,10 @@ void PartialSerializer::Serialize(Object** o) { ...@@ -1484,39 +1478,10 @@ void PartialSerializer::Serialize(Object** o) {
} }
VisitPointer(o); VisitPointer(o);
SerializeDeferredObjects(); SerializeDeferredObjects();
SerializeOutdatedContextsAsFixedArray();
Pad(); Pad();
} }
void PartialSerializer::SerializeOutdatedContextsAsFixedArray() {
int length = outdated_contexts_.length();
if (length == 0) {
FixedArray* empty = isolate_->heap()->empty_fixed_array();
SerializeObject(empty, kPlain, kStartOfObject, 0);
} else {
// Serialize an imaginary fixed array containing outdated contexts.
int size = FixedArray::SizeFor(length);
Allocate(NEW_SPACE, size);
sink_->Put(kNewObject + NEW_SPACE, "emulated FixedArray");
sink_->PutInt(size >> kObjectAlignmentBits, "FixedArray size in words");
Map* map = isolate_->heap()->fixed_array_map();
SerializeObject(map, kPlain, kStartOfObject, 0);
Smi* length_smi = Smi::FromInt(length);
sink_->Put(kOnePointerRawData, "Smi");
for (int i = 0; i < kPointerSize; i++) {
sink_->Put(reinterpret_cast<byte*>(&length_smi)[i], "Byte");
}
for (int i = 0; i < length; i++) {
Context* context = outdated_contexts_[i];
BackReference back_reference = back_reference_map_.Lookup(context);
sink_->Put(kBackref + back_reference.space(), "BackRef");
PutBackReference(context, back_reference);
}
}
}
bool Serializer::ShouldBeSkipped(Object** current) { bool Serializer::ShouldBeSkipped(Object** current) {
Object** roots = isolate()->heap()->roots_array_start(); Object** roots = isolate()->heap()->roots_array_start();
return current == &roots[Heap::kStoreBufferTopRootIndex] return current == &roots[Heap::kStoreBufferTopRootIndex]
...@@ -1852,15 +1817,6 @@ void PartialSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code, ...@@ -1852,15 +1817,6 @@ void PartialSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code,
// 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();
// TODO(yangguo): We probably only need ScriptContext here for post-
// processing in Genesis::HookUpGlobalThisBinding.
if (obj->IsContext() &&
Context::cast(obj)->global_object() == global_object_) {
// Context refers to the current global object. This reference will
// become outdated after deserialization.
outdated_contexts_.Add(Context::cast(obj));
}
} }
......
...@@ -373,9 +373,8 @@ class Deserializer: public SerializerDeserializer { ...@@ -373,9 +373,8 @@ 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.
MaybeHandle<Object> DeserializePartial( MaybeHandle<Object> DeserializePartial(Isolate* isolate,
Isolate* isolate, Handle<JSGlobalProxy> global_proxy, Handle<JSGlobalProxy> global_proxy);
Handle<FixedArray>* outdated_contexts_out);
// Deserialize a shared function info. Fail gracefully. // Deserialize a shared function info. Fail gracefully.
MaybeHandle<SharedFunctionInfo> DeserializeCode(Isolate* isolate); MaybeHandle<SharedFunctionInfo> DeserializeCode(Isolate* isolate);
...@@ -618,7 +617,6 @@ class PartialSerializer : public Serializer { ...@@ -618,7 +617,6 @@ class PartialSerializer : public Serializer {
SnapshotByteSink* sink) SnapshotByteSink* sink)
: Serializer(isolate, sink), : Serializer(isolate, sink),
startup_serializer_(startup_snapshot_serializer), startup_serializer_(startup_snapshot_serializer),
outdated_contexts_(0),
global_object_(NULL) { global_object_(NULL) {
InitializeCodeAddressMap(); InitializeCodeAddressMap();
} }
...@@ -634,10 +632,7 @@ class PartialSerializer : public Serializer { ...@@ -634,10 +632,7 @@ class PartialSerializer : public Serializer {
int PartialSnapshotCacheIndex(HeapObject* o); int PartialSnapshotCacheIndex(HeapObject* o);
bool ShouldBeInThePartialSnapshotCache(HeapObject* o); bool ShouldBeInThePartialSnapshotCache(HeapObject* o);
void SerializeOutdatedContextsAsFixedArray();
Serializer* startup_serializer_; Serializer* startup_serializer_;
List<Context*> outdated_contexts_;
Object* global_object_; Object* global_object_;
PartialCacheIndexMap partial_cache_index_map_; PartialCacheIndexMap partial_cache_index_map_;
DISALLOW_COPY_AND_ASSIGN(PartialSerializer); DISALLOW_COPY_AND_ASSIGN(PartialSerializer);
......
...@@ -66,8 +66,7 @@ bool Snapshot::Initialize(Isolate* isolate) { ...@@ -66,8 +66,7 @@ bool Snapshot::Initialize(Isolate* isolate) {
MaybeHandle<Context> Snapshot::NewContextFromSnapshot( MaybeHandle<Context> Snapshot::NewContextFromSnapshot(
Isolate* isolate, Handle<JSGlobalProxy> global_proxy, Isolate* isolate, Handle<JSGlobalProxy> global_proxy) {
Handle<FixedArray>* outdated_contexts_out) {
if (!isolate->snapshot_available()) return Handle<Context>(); if (!isolate->snapshot_available()) return Handle<Context>();
base::ElapsedTimer timer; base::ElapsedTimer timer;
if (FLAG_profile_deserialization) timer.Start(); if (FLAG_profile_deserialization) timer.Start();
...@@ -77,8 +76,8 @@ MaybeHandle<Context> Snapshot::NewContextFromSnapshot( ...@@ -77,8 +76,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 = deserializer.DeserializePartial( MaybeHandle<Object> maybe_context =
isolate, global_proxy, outdated_contexts_out); deserializer.DeserializePartial(isolate, global_proxy);
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());
......
...@@ -37,8 +37,7 @@ class Snapshot : public AllStatic { ...@@ -37,8 +37,7 @@ 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<JSGlobalProxy> global_proxy, Isolate* isolate, Handle<JSGlobalProxy> global_proxy);
Handle<FixedArray>* outdated_contexts_out);
static bool HaveASnapshotToStartFrom(Isolate* isolate); static bool HaveASnapshotToStartFrom(Isolate* isolate);
......
...@@ -372,17 +372,14 @@ UNINITIALIZED_DEPENDENT_TEST(PartialDeserialization, PartialSerialization) { ...@@ -372,17 +372,14 @@ UNINITIALIZED_DEPENDENT_TEST(PartialDeserialization, PartialSerialization) {
Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate); Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate);
HandleScope handle_scope(isolate); HandleScope handle_scope(isolate);
Handle<Object> root; Handle<Object> root;
Handle<FixedArray> outdated_contexts;
// Intentionally empty handle. The deserializer should not come across // Intentionally empty handle. The deserializer should not come across
// any references to the global proxy in this test. // any references to the global proxy in this test.
Handle<JSGlobalProxy> global_proxy = Handle<JSGlobalProxy>::null(); 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 = root = deserializer.DeserializePartial(isolate, global_proxy)
deserializer.DeserializePartial(isolate, global_proxy, .ToHandleChecked();
&outdated_contexts).ToHandleChecked();
CHECK_EQ(0, outdated_contexts->length());
CHECK(root->IsString()); CHECK(root->IsString());
} }
...@@ -390,9 +387,8 @@ UNINITIALIZED_DEPENDENT_TEST(PartialDeserialization, PartialSerialization) { ...@@ -390,9 +387,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 = root2 = deserializer.DeserializePartial(isolate, global_proxy)
deserializer.DeserializePartial(isolate, global_proxy, .ToHandleChecked();
&outdated_contexts).ToHandleChecked();
CHECK(root2->IsString()); CHECK(root2->IsString());
CHECK(root.is_identical_to(root2)); CHECK(root.is_identical_to(root2));
} }
...@@ -489,29 +485,23 @@ UNINITIALIZED_DEPENDENT_TEST(ContextDeserialization, ContextSerialization) { ...@@ -489,29 +485,23 @@ UNINITIALIZED_DEPENDENT_TEST(ContextDeserialization, ContextSerialization) {
Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate); Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate);
HandleScope handle_scope(isolate); HandleScope handle_scope(isolate);
Handle<Object> root; Handle<Object> root;
Handle<FixedArray> outdated_contexts;
Handle<JSGlobalProxy> global_proxy = Handle<JSGlobalProxy> global_proxy =
isolate->factory()->NewUninitializedJSGlobalProxy(); 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 = root = deserializer.DeserializePartial(isolate, global_proxy)
deserializer.DeserializePartial(isolate, global_proxy, .ToHandleChecked();
&outdated_contexts).ToHandleChecked();
CHECK(root->IsContext()); CHECK(root->IsContext());
CHECK(Handle<Context>::cast(root)->global_proxy() == *global_proxy); CHECK(Handle<Context>::cast(root)->global_proxy() == *global_proxy);
// TODO(yangguo): Introduce proper test once there's a story for the
// outdated_contexts (should only be about ScriptContexts IMHO).
// CHECK_EQ(2, outdated_contexts->length());
} }
Handle<Object> root2; Handle<Object> root2;
{ {
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 = root2 = deserializer.DeserializePartial(isolate, global_proxy)
deserializer.DeserializePartial(isolate, global_proxy, .ToHandleChecked();
&outdated_contexts).ToHandleChecked();
CHECK(root2->IsContext()); CHECK(root2->IsContext());
CHECK(!root.is_identical_to(root2)); CHECK(!root.is_identical_to(root2));
} }
...@@ -628,22 +618,13 @@ UNINITIALIZED_DEPENDENT_TEST(CustomContextDeserialization, ...@@ -628,22 +618,13 @@ UNINITIALIZED_DEPENDENT_TEST(CustomContextDeserialization,
Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate); Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate);
HandleScope handle_scope(isolate); HandleScope handle_scope(isolate);
Handle<Object> root; Handle<Object> root;
Handle<FixedArray> outdated_contexts;
Handle<JSGlobalProxy> global_proxy = Handle<JSGlobalProxy> global_proxy =
isolate->factory()->NewUninitializedJSGlobalProxy(); 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 = root = deserializer.DeserializePartial(isolate, global_proxy)
deserializer.DeserializePartial(isolate, global_proxy, .ToHandleChecked();
&outdated_contexts).ToHandleChecked();
// TODO(yangguo): Introduce proper test once there's a story for the
// outdated_contexts (should only be about ScriptContexts IMHO).
// if (FLAG_global_var_shortcuts) {
// CHECK_EQ(5, outdated_contexts->length());
// } else {
// CHECK_EQ(3, outdated_contexts->length());
// }
CHECK(root->IsContext()); CHECK(root->IsContext());
Handle<Context> context = Handle<Context>::cast(root); Handle<Context> context = Handle<Context>::cast(root);
CHECK(context->global_proxy() == *global_proxy); CHECK(context->global_proxy() == *global_proxy);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment