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 {
// 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
// other objects in the snapshot.
void HookUpGlobalObject(Handle<JSGlobalObject> global_object,
Handle<FixedArray> outdated_contexts);
void HookUpGlobalObject(Handle<JSGlobalObject> global_object);
// The native context has a ScriptContextTable that store declarative bindings
// made in script scopes. Add a "this" binding to that table pointing to the
// global proxy.
void InstallGlobalThisBinding();
void HookUpGlobalThisBinding(Handle<FixedArray> outdated_contexts);
// New context initialization. Used for creating a context from scratch.
void InitializeGlobal(Handle<JSGlobalObject> global_object,
Handle<JSFunction> empty_function,
......@@ -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(
v8::Local<v8::ObjectTemplate> global_proxy_template,
Handle<JSGlobalProxy> global_proxy) {
......@@ -1045,8 +1026,7 @@ void Genesis::HookUpGlobalProxy(Handle<JSGlobalObject> global_object,
}
void Genesis::HookUpGlobalObject(Handle<JSGlobalObject> global_object,
Handle<FixedArray> outdated_contexts) {
void Genesis::HookUpGlobalObject(Handle<JSGlobalObject> global_object) {
Handle<JSGlobalObject> global_object_from_snapshot(
JSGlobalObject::cast(native_context()->extension()));
native_context()->set_extension(*global_object);
......@@ -3107,10 +3087,8 @@ Genesis::Genesis(Isolate* isolate,
// We can only de-serialize a context if the isolate was initialized from
// a snapshot. Otherwise we have to build the context from scratch.
// Also create a context from scratch to expose natives, if required by flag.
Handle<FixedArray> outdated_contexts;
if (!isolate->initialized_from_snapshot() ||
!Snapshot::NewContextFromSnapshot(isolate, global_proxy,
&outdated_contexts)
!Snapshot::NewContextFromSnapshot(isolate, global_proxy)
.ToHandle(&native_context_)) {
native_context_ = Handle<Context>();
}
......@@ -3132,8 +3110,7 @@ Genesis::Genesis(Isolate* isolate,
CreateNewGlobals(global_proxy_template, global_proxy);
HookUpGlobalProxy(global_object, global_proxy);
HookUpGlobalObject(global_object, outdated_contexts);
HookUpGlobalThisBinding(outdated_contexts);
HookUpGlobalObject(global_object);
if (!ConfigureGlobalObjects(global_proxy_template)) return;
} else {
......
......@@ -561,8 +561,7 @@ void Deserializer::Deserialize(Isolate* isolate) {
MaybeHandle<Object> Deserializer::DeserializePartial(
Isolate* isolate, Handle<JSGlobalProxy> global_proxy,
Handle<FixedArray>* outdated_contexts_out) {
Isolate* isolate, Handle<JSGlobalProxy> global_proxy) {
Initialize(isolate);
if (!ReserveSpace()) {
V8::FatalProcessOutOfMemory("deserialize context");
......@@ -579,18 +578,13 @@ MaybeHandle<Object> Deserializer::DeserializePartial(
OldSpace* code_space = isolate_->heap()->code_space();
Address start_address = code_space->top();
Object* root;
Object* outdated_contexts;
VisitPointer(&root);
DeserializeDeferredObjects();
VisitPointer(&outdated_contexts);
// 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
// new code, which also has to be flushed from instruction cache.
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);
}
......@@ -1484,39 +1478,10 @@ void PartialSerializer::Serialize(Object** o) {
}
VisitPointer(o);
SerializeDeferredObjects();
SerializeOutdatedContextsAsFixedArray();
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) {
Object** roots = isolate()->heap()->roots_array_start();
return current == &roots[Heap::kStoreBufferTopRootIndex]
......@@ -1852,15 +1817,6 @@ void PartialSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code,
// Object has not yet been serialized. Serialize it here.
ObjectSerializer serializer(this, obj, sink_, how_to_code, where_to_point);
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 {
void Deserialize(Isolate* isolate);
// Deserialize a single object and the objects reachable from it.
MaybeHandle<Object> DeserializePartial(
Isolate* isolate, Handle<JSGlobalProxy> global_proxy,
Handle<FixedArray>* outdated_contexts_out);
MaybeHandle<Object> DeserializePartial(Isolate* isolate,
Handle<JSGlobalProxy> global_proxy);
// Deserialize a shared function info. Fail gracefully.
MaybeHandle<SharedFunctionInfo> DeserializeCode(Isolate* isolate);
......@@ -618,7 +617,6 @@ class PartialSerializer : public Serializer {
SnapshotByteSink* sink)
: Serializer(isolate, sink),
startup_serializer_(startup_snapshot_serializer),
outdated_contexts_(0),
global_object_(NULL) {
InitializeCodeAddressMap();
}
......@@ -634,10 +632,7 @@ class PartialSerializer : public Serializer {
int PartialSnapshotCacheIndex(HeapObject* o);
bool ShouldBeInThePartialSnapshotCache(HeapObject* o);
void SerializeOutdatedContextsAsFixedArray();
Serializer* startup_serializer_;
List<Context*> outdated_contexts_;
Object* global_object_;
PartialCacheIndexMap partial_cache_index_map_;
DISALLOW_COPY_AND_ASSIGN(PartialSerializer);
......
......@@ -66,8 +66,7 @@ bool Snapshot::Initialize(Isolate* isolate) {
MaybeHandle<Context> Snapshot::NewContextFromSnapshot(
Isolate* isolate, Handle<JSGlobalProxy> global_proxy,
Handle<FixedArray>* outdated_contexts_out) {
Isolate* isolate, Handle<JSGlobalProxy> global_proxy) {
if (!isolate->snapshot_available()) return Handle<Context>();
base::ElapsedTimer timer;
if (FLAG_profile_deserialization) timer.Start();
......@@ -77,8 +76,8 @@ MaybeHandle<Context> Snapshot::NewContextFromSnapshot(
SnapshotData snapshot_data(context_data);
Deserializer deserializer(&snapshot_data);
MaybeHandle<Object> maybe_context = deserializer.DeserializePartial(
isolate, global_proxy, outdated_contexts_out);
MaybeHandle<Object> maybe_context =
deserializer.DeserializePartial(isolate, global_proxy);
Handle<Object> result;
if (!maybe_context.ToHandle(&result)) return MaybeHandle<Context>();
CHECK(result->IsContext());
......
......@@ -37,8 +37,7 @@ 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<JSGlobalProxy> global_proxy,
Handle<FixedArray>* outdated_contexts_out);
Isolate* isolate, Handle<JSGlobalProxy> global_proxy);
static bool HaveASnapshotToStartFrom(Isolate* isolate);
......
......@@ -372,17 +372,14 @@ UNINITIALIZED_DEPENDENT_TEST(PartialDeserialization, PartialSerialization) {
Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate);
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, global_proxy,
&outdated_contexts).ToHandleChecked();
CHECK_EQ(0, outdated_contexts->length());
root = deserializer.DeserializePartial(isolate, global_proxy)
.ToHandleChecked();
CHECK(root->IsString());
}
......@@ -390,9 +387,8 @@ UNINITIALIZED_DEPENDENT_TEST(PartialDeserialization, PartialSerialization) {
{
SnapshotData snapshot_data(Vector<const byte>(snapshot, snapshot_size));
Deserializer deserializer(&snapshot_data);
root2 =
deserializer.DeserializePartial(isolate, global_proxy,
&outdated_contexts).ToHandleChecked();
root2 = deserializer.DeserializePartial(isolate, global_proxy)
.ToHandleChecked();
CHECK(root2->IsString());
CHECK(root.is_identical_to(root2));
}
......@@ -489,29 +485,23 @@ UNINITIALIZED_DEPENDENT_TEST(ContextDeserialization, ContextSerialization) {
Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate);
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, global_proxy,
&outdated_contexts).ToHandleChecked();
root = deserializer.DeserializePartial(isolate, global_proxy)
.ToHandleChecked();
CHECK(root->IsContext());
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;
{
SnapshotData snapshot_data(Vector<const byte>(snapshot, snapshot_size));
Deserializer deserializer(&snapshot_data);
root2 =
deserializer.DeserializePartial(isolate, global_proxy,
&outdated_contexts).ToHandleChecked();
root2 = deserializer.DeserializePartial(isolate, global_proxy)
.ToHandleChecked();
CHECK(root2->IsContext());
CHECK(!root.is_identical_to(root2));
}
......@@ -628,22 +618,13 @@ UNINITIALIZED_DEPENDENT_TEST(CustomContextDeserialization,
Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate);
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, global_proxy,
&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());
// }
root = deserializer.DeserializePartial(isolate, global_proxy)
.ToHandleChecked();
CHECK(root->IsContext());
Handle<Context> context = Handle<Context>::cast(root);
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