Commit 55e8c2e4 authored by yangguo's avatar yangguo Committed by Commit bot

[serializer] allocate global proxy with the expected size.

If a context snapshot includes the global proxy constructor function, we
expect the incoming global proxy to have the correct instance size so
that we can reinitialize it with said constructor. However, when the
bootstrapper allocates a new global proxy, we need to know the expected
size.

We solve this by storing the size on the to-be-serialized isolate.

R=jochen@chromium.org, peria@chromium.org
BUG=chromium:617892

Review-Url: https://codereview.chromium.org/2585693002
Cr-Commit-Position: refs/heads/master@{#41756}
parent a492ab38
......@@ -551,6 +551,8 @@ StartupData SnapshotCreator::CreateBlob(
DCHECK(!data->created_);
DCHECK(!data->default_context_.IsEmpty());
int num_additional_contexts = static_cast<int>(data->contexts_.Size());
{
int num_templates = static_cast<int>(data->templates_.Size());
i::HandleScope scope(isolate);
......@@ -561,6 +563,18 @@ StartupData SnapshotCreator::CreateBlob(
}
isolate->heap()->SetSerializedTemplates(*templates);
data->templates_.Clear();
// We need to store the global proxy size upfront in case we need the
// bootstrapper to create a global proxy before we deserialize the context.
i::Handle<i::FixedArray> global_proxy_sizes =
isolate->factory()->NewFixedArray(num_additional_contexts, i::TENURED);
for (int i = 0; i < num_additional_contexts; i++) {
i::Handle<i::Context> context =
v8::Utils::OpenHandle(*data->contexts_.Get(i));
global_proxy_sizes->set(i,
i::Smi::FromInt(context->global_proxy()->Size()));
}
isolate->heap()->SetSerializedGlobalProxySizes(*global_proxy_sizes);
}
// If we don't do this then we end up with a stray root pointing at the
......@@ -571,7 +585,6 @@ StartupData SnapshotCreator::CreateBlob(
i::DisallowHeapAllocation no_gc_from_here_on;
int num_additional_contexts = static_cast<int>(data->contexts_.Size());
i::List<i::Object*> contexts(num_additional_contexts);
i::Object* default_context;
{
......
......@@ -4473,12 +4473,22 @@ Genesis::Genesis(Isolate* isolate,
// and initialize it later in CreateNewGlobals.
Handle<JSGlobalProxy> global_proxy;
if (!maybe_global_proxy.ToHandle(&global_proxy)) {
const int internal_field_count =
!global_proxy_template.IsEmpty()
? global_proxy_template->InternalFieldCount()
: 0;
global_proxy = isolate->factory()->NewUninitializedJSGlobalProxy(
JSGlobalProxy::SizeWithInternalFields(internal_field_count));
int instance_size = 0;
if (context_snapshot_index > 0) {
// The global proxy function to reinitialize this global proxy is in the
// context that is yet to be deserialized. We need to prepare a global
// proxy of the correct size.
Object* size = isolate->heap()->serialized_global_proxy_sizes()->get(
static_cast<int>(context_snapshot_index) - 1);
instance_size = Smi::cast(size)->value();
} else {
instance_size = JSGlobalProxy::SizeWithInternalFields(
global_proxy_template.IsEmpty()
? 0
: global_proxy_template->InternalFieldCount());
}
global_proxy =
isolate->factory()->NewUninitializedJSGlobalProxy(instance_size);
}
// We can only de-serialize a context if the isolate was initialized from
......
......@@ -812,9 +812,16 @@ int Heap::GetNextTemplateSerialNumber() {
void Heap::SetSerializedTemplates(FixedArray* templates) {
DCHECK_EQ(empty_fixed_array(), serialized_templates());
DCHECK(isolate()->serializer_enabled());
set_serialized_templates(templates);
}
void Heap::SetSerializedGlobalProxySizes(FixedArray* sizes) {
DCHECK_EQ(empty_fixed_array(), serialized_global_proxy_sizes());
DCHECK(isolate()->serializer_enabled());
set_serialized_global_proxy_sizes(sizes);
}
void Heap::CreateObjectStats() {
if (V8_LIKELY(FLAG_gc_stats == 0)) return;
if (!live_object_stats_) {
......
......@@ -2863,6 +2863,7 @@ void Heap::CreateInitialObjects() {
set_array_buffer_neutering_protector(*cell);
set_serialized_templates(empty_fixed_array());
set_serialized_global_proxy_sizes(empty_fixed_array());
set_weak_stack_trace_list(Smi::kZero);
......@@ -2896,6 +2897,7 @@ bool Heap::RootCanBeWrittenAfterInitialization(Heap::RootListIndex root_index) {
case kNoScriptSharedFunctionInfosRootIndex:
case kWeakStackTraceListRootIndex:
case kSerializedTemplatesRootIndex:
case kSerializedGlobalProxySizesRootIndex:
case kPublicSymbolTableRootIndex:
case kApiSymbolTableRootIndex:
case kApiPrivateSymbolTableRootIndex:
......
......@@ -210,6 +210,7 @@ using v8::MemoryPressureLevel;
V(Object, weak_stack_trace_list, WeakStackTraceList) \
V(Object, noscript_shared_function_infos, NoScriptSharedFunctionInfos) \
V(FixedArray, serialized_templates, SerializedTemplates) \
V(FixedArray, serialized_global_proxy_sizes, SerializedGlobalProxySizes) \
/* Configured values */ \
V(TemplateList, message_listeners, MessageListeners) \
V(Code, js_entry_code, JsEntryCode) \
......@@ -877,6 +878,7 @@ class Heap {
inline int GetNextTemplateSerialNumber();
inline void SetSerializedTemplates(FixedArray* templates);
inline void SetSerializedGlobalProxySizes(FixedArray* sizes);
// For post mortem debugging.
void RememberUnmappedPage(Address page, bool compacted);
......
......@@ -2384,6 +2384,7 @@ TEST(SnapshotCreatorIncludeGlobalProxy) {
v8::ObjectTemplate::New(isolate);
v8::Local<v8::FunctionTemplate> callback =
v8::FunctionTemplate::New(isolate, SerializedCallback);
global_template->SetInternalFieldCount(3);
global_template->Set(v8_str("f"), callback);
global_template->SetHandler(v8::NamedPropertyHandlerConfiguration(
NamedPropertyGetterForSerialization));
......@@ -2455,6 +2456,7 @@ TEST(SnapshotCreatorIncludeGlobalProxy) {
}
v8::Local<v8::Object> global = context->Global();
CHECK_EQ(3, global->InternalFieldCount());
context->DetachGlobal();
// New context, but reuse 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