Commit 9cd0de73 authored by yangguo's avatar yangguo Committed by Commit bot

[serializer] change internal field callbacks to take data pointer.

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

Review-Url: https://codereview.chromium.org/2628093003
Cr-Commit-Position: refs/heads/master@{#42268}
parent 9884fb91
...@@ -6281,17 +6281,33 @@ class V8_EXPORT EmbedderHeapTracer { ...@@ -6281,17 +6281,33 @@ class V8_EXPORT EmbedderHeapTracer {
}; };
/** /**
* Callback to the embedder used in SnapshotCreator to handle internal fields. * Callback and supporting data used in SnapshotCreator to implement embedder
*/ * logic to serialize internal fields.
typedef StartupData (*SerializeInternalFieldsCallback)(Local<Object> holder, */
int index); struct SerializeInternalFieldsCallback {
typedef StartupData (*CallbackFunction)(Local<Object> holder, int index,
void* data);
SerializeInternalFieldsCallback(CallbackFunction function = nullptr,
void* data_arg = nullptr)
: callback(function), data(data_arg) {}
CallbackFunction callback;
void* data;
};
/** /**
* Callback to the embedder used to deserialize internal fields. * Callback and supporting data used to implement embedder logic to deserialize
* internal fields.
*/ */
typedef void (*DeserializeInternalFieldsCallback)(Local<Object> holder, struct DeserializeInternalFieldsCallback {
int index, typedef void (*CallbackFunction)(Local<Object> holder, int index,
StartupData payload); StartupData payload, void* data);
DeserializeInternalFieldsCallback(CallbackFunction function = nullptr,
void* data_arg = nullptr)
: callback(function), data(data_arg) {}
void (*callback)(Local<Object> holder, int index, StartupData payload,
void* data);
void* data;
};
/** /**
* Isolate represents an isolated instance of the V8 engine. V8 isolates have * Isolate represents an isolated instance of the V8 engine. V8 isolates have
...@@ -7689,7 +7705,8 @@ class V8_EXPORT SnapshotCreator { ...@@ -7689,7 +7705,8 @@ class V8_EXPORT SnapshotCreator {
* \returns the index of the context in the snapshot blob. * \returns the index of the context in the snapshot blob.
*/ */
size_t AddContext(Local<Context> context, size_t AddContext(Local<Context> context,
SerializeInternalFieldsCallback callback = nullptr); SerializeInternalFieldsCallback callback =
SerializeInternalFieldsCallback());
/** /**
* Add a template to be included in the snapshot blob. * Add a template to be included in the snapshot blob.
...@@ -8029,7 +8046,8 @@ class V8_EXPORT Context { ...@@ -8029,7 +8046,8 @@ class V8_EXPORT Context {
static MaybeLocal<Context> FromSnapshot( static MaybeLocal<Context> FromSnapshot(
Isolate* isolate, size_t context_snapshot_index, Isolate* isolate, size_t context_snapshot_index,
DeserializeInternalFieldsCallback internal_fields_deserializer = nullptr, DeserializeInternalFieldsCallback internal_fields_deserializer =
DeserializeInternalFieldsCallback(),
ExtensionConfiguration* extensions = nullptr, ExtensionConfiguration* extensions = nullptr,
MaybeLocal<Value> global_object = MaybeLocal<Value>()); MaybeLocal<Value> global_object = MaybeLocal<Value>());
......
...@@ -615,8 +615,8 @@ StartupData SnapshotCreator::CreateBlob( ...@@ -615,8 +615,8 @@ StartupData SnapshotCreator::CreateBlob(
{ {
// The default snapshot does not support internal fields. // The default snapshot does not support internal fields.
i::PartialSerializer partial_serializer(isolate, &startup_serializer, i::PartialSerializer partial_serializer(
nullptr); isolate, &startup_serializer, v8::SerializeInternalFieldsCallback());
partial_serializer.Serialize(&default_context, false); partial_serializer.Serialize(&default_context, false);
context_snapshots.Add(new i::SnapshotData(&partial_serializer)); context_snapshots.Add(new i::SnapshotData(&partial_serializer));
} }
...@@ -6297,7 +6297,7 @@ Local<Context> v8::Context::New(v8::Isolate* external_isolate, ...@@ -6297,7 +6297,7 @@ Local<Context> v8::Context::New(v8::Isolate* external_isolate,
v8::MaybeLocal<ObjectTemplate> global_template, v8::MaybeLocal<ObjectTemplate> global_template,
v8::MaybeLocal<Value> global_object) { v8::MaybeLocal<Value> global_object) {
return NewContext(external_isolate, extensions, global_template, return NewContext(external_isolate, extensions, global_template,
global_object, 0, nullptr); global_object, 0, DeserializeInternalFieldsCallback());
} }
MaybeLocal<Context> v8::Context::FromSnapshot( MaybeLocal<Context> v8::Context::FromSnapshot(
...@@ -6334,7 +6334,8 @@ MaybeLocal<Object> v8::Context::NewRemoteContext( ...@@ -6334,7 +6334,8 @@ MaybeLocal<Object> v8::Context::NewRemoteContext(
"Global template needs to have access check handlers."); "Global template needs to have access check handlers.");
i::Handle<i::JSGlobalProxy> global_proxy = i::Handle<i::JSGlobalProxy> global_proxy =
CreateEnvironment<i::JSGlobalProxy>(isolate, nullptr, global_template, CreateEnvironment<i::JSGlobalProxy>(isolate, nullptr, global_template,
global_object, 0, nullptr); global_object, 0,
DeserializeInternalFieldsCallback());
if (global_proxy.is_null()) { if (global_proxy.is_null()) {
if (isolate->has_pending_exception()) { if (isolate->has_pending_exception()) {
isolate->OptionalRescheduleException(true); isolate->OptionalRescheduleException(true);
......
...@@ -466,7 +466,8 @@ bool Debug::Load() { ...@@ -466,7 +466,8 @@ bool Debug::Load() {
static const int kFirstContextSnapshotIndex = 0; static const int kFirstContextSnapshotIndex = 0;
Handle<Context> context = isolate_->bootstrapper()->CreateEnvironment( Handle<Context> context = isolate_->bootstrapper()->CreateEnvironment(
MaybeHandle<JSGlobalProxy>(), v8::Local<ObjectTemplate>(), &no_extensions, MaybeHandle<JSGlobalProxy>(), v8::Local<ObjectTemplate>(), &no_extensions,
kFirstContextSnapshotIndex, nullptr, DEBUG_CONTEXT); kFirstContextSnapshotIndex, v8::DeserializeInternalFieldsCallback(),
DEBUG_CONTEXT);
// Fail if no context could be created. // Fail if no context could be created.
if (context.is_null()) return false; if (context.is_null()) return false;
......
...@@ -221,7 +221,7 @@ void Deserializer::DeserializeInternalFields( ...@@ -221,7 +221,7 @@ void Deserializer::DeserializeInternalFields(
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
DisallowJavascriptExecution no_js(isolate_); DisallowJavascriptExecution no_js(isolate_);
DisallowCompilation no_compile(isolate_); DisallowCompilation no_compile(isolate_);
DCHECK_NOT_NULL(internal_fields_deserializer); DCHECK_NOT_NULL(internal_fields_deserializer.callback);
for (int code = source_.Get(); code != kSynchronize; code = source_.Get()) { for (int code = source_.Get(); code != kSynchronize; code = source_.Get()) {
HandleScope scope(isolate_); HandleScope scope(isolate_);
int space = code & kSpaceMask; int space = code & kSpaceMask;
...@@ -233,8 +233,9 @@ void Deserializer::DeserializeInternalFields( ...@@ -233,8 +233,9 @@ void Deserializer::DeserializeInternalFields(
int size = source_.GetInt(); int size = source_.GetInt();
byte* data = new byte[size]; byte* data = new byte[size];
source_.CopyRaw(data, size); source_.CopyRaw(data, size);
internal_fields_deserializer(v8::Utils::ToLocal(obj), index, internal_fields_deserializer.callback(v8::Utils::ToLocal(obj), index,
{reinterpret_cast<char*>(data), size}); {reinterpret_cast<char*>(data), size},
internal_fields_deserializer.data);
delete[] data; delete[] data;
} }
} }
......
...@@ -103,7 +103,7 @@ void PartialSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code, ...@@ -103,7 +103,7 @@ void PartialSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code,
if (obj->IsJSObject()) { if (obj->IsJSObject()) {
JSObject* jsobj = JSObject::cast(obj); JSObject* jsobj = JSObject::cast(obj);
if (jsobj->GetInternalFieldCount() > 0) { if (jsobj->GetInternalFieldCount() > 0) {
DCHECK_NOT_NULL(serialize_internal_fields_); DCHECK_NOT_NULL(serialize_internal_fields_.callback);
internal_field_holders_.Add(jsobj); internal_field_holders_.Add(jsobj);
} }
} }
...@@ -132,7 +132,7 @@ void PartialSerializer::SerializeInternalFields() { ...@@ -132,7 +132,7 @@ void PartialSerializer::SerializeInternalFields() {
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
DisallowJavascriptExecution no_js(isolate()); DisallowJavascriptExecution no_js(isolate());
DisallowCompilation no_compile(isolate()); DisallowCompilation no_compile(isolate());
DCHECK_NOT_NULL(serialize_internal_fields_); DCHECK_NOT_NULL(serialize_internal_fields_.callback);
sink_.Put(kInternalFieldsData, "internal fields data"); sink_.Put(kInternalFieldsData, "internal fields data");
while (internal_field_holders_.length() > 0) { while (internal_field_holders_.length() > 0) {
HandleScope scope(isolate()); HandleScope scope(isolate());
...@@ -142,7 +142,8 @@ void PartialSerializer::SerializeInternalFields() { ...@@ -142,7 +142,8 @@ void PartialSerializer::SerializeInternalFields() {
int internal_fields_count = obj->GetInternalFieldCount(); int internal_fields_count = obj->GetInternalFieldCount();
for (int i = 0; i < internal_fields_count; i++) { for (int i = 0; i < internal_fields_count; i++) {
if (obj->GetInternalField(i)->IsHeapObject()) continue; if (obj->GetInternalField(i)->IsHeapObject()) continue;
StartupData data = serialize_internal_fields_(v8::Utils::ToLocal(obj), i); StartupData data = serialize_internal_fields_.callback(
v8::Utils::ToLocal(obj), i, serialize_internal_fields_.data);
sink_.Put(kNewObject + reference.space(), "internal field holder"); sink_.Put(kNewObject + reference.space(), "internal field holder");
PutBackReference(*obj, reference); PutBackReference(*obj, reference);
sink_.PutInt(i, "internal field index"); sink_.PutInt(i, "internal field index");
......
...@@ -285,7 +285,8 @@ static void PartiallySerializeObject(Vector<const byte>* startup_blob_out, ...@@ -285,7 +285,8 @@ static void PartiallySerializeObject(Vector<const byte>* startup_blob_out,
isolate, v8::SnapshotCreator::FunctionCodeHandling::kClear); isolate, v8::SnapshotCreator::FunctionCodeHandling::kClear);
startup_serializer.SerializeStrongReferences(); startup_serializer.SerializeStrongReferences();
PartialSerializer partial_serializer(isolate, &startup_serializer, nullptr); PartialSerializer partial_serializer(isolate, &startup_serializer,
v8::SerializeInternalFieldsCallback());
partial_serializer.Serialize(&raw_foo, false); partial_serializer.Serialize(&raw_foo, false);
startup_serializer.SerializeWeakReferencesAndDeferred(); startup_serializer.SerializeWeakReferencesAndDeferred();
...@@ -321,7 +322,9 @@ UNINITIALIZED_TEST(PartialSerializerObject) { ...@@ -321,7 +322,9 @@ UNINITIALIZED_TEST(PartialSerializerObject) {
{ {
SnapshotData snapshot_data(partial_blob); SnapshotData snapshot_data(partial_blob);
Deserializer deserializer(&snapshot_data); Deserializer deserializer(&snapshot_data);
root = deserializer.DeserializePartial(isolate, global_proxy, nullptr) root = deserializer
.DeserializePartial(isolate, global_proxy,
v8::DeserializeInternalFieldsCallback())
.ToHandleChecked(); .ToHandleChecked();
CHECK(root->IsString()); CHECK(root->IsString());
} }
...@@ -330,7 +333,9 @@ UNINITIALIZED_TEST(PartialSerializerObject) { ...@@ -330,7 +333,9 @@ UNINITIALIZED_TEST(PartialSerializerObject) {
{ {
SnapshotData snapshot_data(partial_blob); SnapshotData snapshot_data(partial_blob);
Deserializer deserializer(&snapshot_data); Deserializer deserializer(&snapshot_data);
root2 = deserializer.DeserializePartial(isolate, global_proxy, nullptr) root2 = deserializer
.DeserializePartial(isolate, global_proxy,
v8::DeserializeInternalFieldsCallback())
.ToHandleChecked(); .ToHandleChecked();
CHECK(root2->IsString()); CHECK(root2->IsString());
CHECK(root.is_identical_to(root2)); CHECK(root.is_identical_to(root2));
...@@ -385,7 +390,8 @@ static void PartiallySerializeContext(Vector<const byte>* startup_blob_out, ...@@ -385,7 +390,8 @@ static void PartiallySerializeContext(Vector<const byte>* startup_blob_out,
startup_serializer.SerializeStrongReferences(); startup_serializer.SerializeStrongReferences();
SnapshotByteSink partial_sink; SnapshotByteSink partial_sink;
PartialSerializer partial_serializer(isolate, &startup_serializer, nullptr); PartialSerializer partial_serializer(isolate, &startup_serializer,
v8::SerializeInternalFieldsCallback());
partial_serializer.Serialize(&raw_context, false); partial_serializer.Serialize(&raw_context, false);
startup_serializer.SerializeWeakReferencesAndDeferred(); startup_serializer.SerializeWeakReferencesAndDeferred();
...@@ -419,7 +425,9 @@ UNINITIALIZED_TEST(PartialSerializerContext) { ...@@ -419,7 +425,9 @@ UNINITIALIZED_TEST(PartialSerializerContext) {
{ {
SnapshotData snapshot_data(partial_blob); SnapshotData snapshot_data(partial_blob);
Deserializer deserializer(&snapshot_data); Deserializer deserializer(&snapshot_data);
root = deserializer.DeserializePartial(isolate, global_proxy, nullptr) root = deserializer
.DeserializePartial(isolate, global_proxy,
v8::DeserializeInternalFieldsCallback())
.ToHandleChecked(); .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);
...@@ -429,7 +437,9 @@ UNINITIALIZED_TEST(PartialSerializerContext) { ...@@ -429,7 +437,9 @@ UNINITIALIZED_TEST(PartialSerializerContext) {
{ {
SnapshotData snapshot_data(partial_blob); SnapshotData snapshot_data(partial_blob);
Deserializer deserializer(&snapshot_data); Deserializer deserializer(&snapshot_data);
root2 = deserializer.DeserializePartial(isolate, global_proxy, nullptr) root2 = deserializer
.DeserializePartial(isolate, global_proxy,
v8::DeserializeInternalFieldsCallback())
.ToHandleChecked(); .ToHandleChecked();
CHECK(root2->IsContext()); CHECK(root2->IsContext());
CHECK(!root.is_identical_to(root2)); CHECK(!root.is_identical_to(root2));
...@@ -505,7 +515,8 @@ static void PartiallySerializeCustomContext( ...@@ -505,7 +515,8 @@ static void PartiallySerializeCustomContext(
startup_serializer.SerializeStrongReferences(); startup_serializer.SerializeStrongReferences();
SnapshotByteSink partial_sink; SnapshotByteSink partial_sink;
PartialSerializer partial_serializer(isolate, &startup_serializer, nullptr); PartialSerializer partial_serializer(isolate, &startup_serializer,
v8::SerializeInternalFieldsCallback());
partial_serializer.Serialize(&raw_context, false); partial_serializer.Serialize(&raw_context, false);
startup_serializer.SerializeWeakReferencesAndDeferred(); startup_serializer.SerializeWeakReferencesAndDeferred();
...@@ -539,7 +550,9 @@ UNINITIALIZED_TEST(PartialSerializerCustomContext) { ...@@ -539,7 +550,9 @@ UNINITIALIZED_TEST(PartialSerializerCustomContext) {
{ {
SnapshotData snapshot_data(partial_blob); SnapshotData snapshot_data(partial_blob);
Deserializer deserializer(&snapshot_data); Deserializer deserializer(&snapshot_data);
root = deserializer.DeserializePartial(isolate, global_proxy, nullptr) root = deserializer
.DeserializePartial(isolate, global_proxy,
v8::DeserializeInternalFieldsCallback())
.ToHandleChecked(); .ToHandleChecked();
CHECK(root->IsContext()); CHECK(root->IsContext());
Handle<Context> context = Handle<Context>::cast(root); Handle<Context> context = Handle<Context>::cast(root);
...@@ -2161,25 +2174,27 @@ struct InternalFieldData { ...@@ -2161,25 +2174,27 @@ struct InternalFieldData {
uint32_t data; uint32_t data;
}; };
v8::StartupData SerializeInternalFields(v8::Local<v8::Object> holder, v8::StartupData SerializeInternalFields(v8::Local<v8::Object> holder, int index,
int index) { void* data) {
InternalFieldData* data = static_cast<InternalFieldData*>( CHECK_EQ(reinterpret_cast<void*>(2016), data);
InternalFieldData* internal_field = static_cast<InternalFieldData*>(
holder->GetAlignedPointerFromInternalField(index)); holder->GetAlignedPointerFromInternalField(index));
int size = sizeof(*data); int size = sizeof(*internal_field);
char* payload = new char[size]; char* payload = new char[size];
// We simply use memcpy to serialize the content. // We simply use memcpy to serialize the content.
memcpy(payload, data, size); memcpy(payload, internal_field, size);
return {payload, size}; return {payload, size};
} }
std::vector<InternalFieldData*> deserialized_data; std::vector<InternalFieldData*> deserialized_data;
void DeserializeInternalFields(v8::Local<v8::Object> holder, int index, void DeserializeInternalFields(v8::Local<v8::Object> holder, int index,
v8::StartupData payload) { v8::StartupData payload, void* data) {
InternalFieldData* data = new InternalFieldData{0}; CHECK_EQ(reinterpret_cast<void*>(2017), data);
memcpy(data, payload.data, payload.raw_size); InternalFieldData* internal_field = new InternalFieldData{0};
holder->SetAlignedPointerInInternalField(index, data); memcpy(internal_field, payload.data, payload.raw_size);
deserialized_data.push_back(data); holder->SetAlignedPointerInInternalField(index, internal_field);
deserialized_data.push_back(internal_field);
} }
TEST(SnapshotCreatorTemplates) { TEST(SnapshotCreatorTemplates) {
...@@ -2231,7 +2246,10 @@ TEST(SnapshotCreatorTemplates) { ...@@ -2231,7 +2246,10 @@ TEST(SnapshotCreatorTemplates) {
c->SetInternalField(2, field_external); c->SetInternalField(2, field_external);
CHECK(context->Global()->Set(context, v8_str("a"), a).FromJust()); CHECK(context->Global()->Set(context, v8_str("a"), a).FromJust());
CHECK_EQ(0u, creator.AddContext(context, SerializeInternalFields)); CHECK_EQ(0u,
creator.AddContext(context, v8::SerializeInternalFieldsCallback(
SerializeInternalFields,
reinterpret_cast<void*>(2016))));
CHECK_EQ(0u, creator.AddTemplate(callback)); CHECK_EQ(0u, creator.AddTemplate(callback));
CHECK_EQ(1u, creator.AddTemplate(global_template)); CHECK_EQ(1u, creator.AddTemplate(global_template));
} }
...@@ -2255,7 +2273,10 @@ TEST(SnapshotCreatorTemplates) { ...@@ -2255,7 +2273,10 @@ TEST(SnapshotCreatorTemplates) {
// Create a new context without a new object template. // Create a new context without a new object template.
v8::HandleScope handle_scope(isolate); v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Local<v8::Context> context =
v8::Context::FromSnapshot(isolate, 0, DeserializeInternalFields) v8::Context::FromSnapshot(
isolate, 0,
v8::DeserializeInternalFieldsCallback(
DeserializeInternalFields, reinterpret_cast<void*>(2017)))
.ToLocalChecked(); .ToLocalChecked();
v8::Context::Scope context_scope(context); v8::Context::Scope context_scope(context);
ExpectInt32("f()", 42); ExpectInt32("f()", 42);
...@@ -2408,7 +2429,10 @@ TEST(SnapshotCreatorIncludeGlobalProxy) { ...@@ -2408,7 +2429,10 @@ TEST(SnapshotCreatorIncludeGlobalProxy) {
.ToLocalChecked()) .ToLocalChecked())
.FromJust()); .FromJust());
CHECK_EQ(0u, creator.AddContext(context, SerializeInternalFields)); CHECK_EQ(0u,
creator.AddContext(context, v8::SerializeInternalFieldsCallback(
SerializeInternalFields,
reinterpret_cast<void*>(2016))));
} }
blob = blob =
creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear); creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
...@@ -2452,8 +2476,12 @@ TEST(SnapshotCreatorIncludeGlobalProxy) { ...@@ -2452,8 +2476,12 @@ TEST(SnapshotCreatorIncludeGlobalProxy) {
// will use the global object from the snapshot, including interceptor. // will use the global object from the snapshot, including interceptor.
v8::HandleScope handle_scope(isolate); v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Local<v8::Context> context =
v8::Context::FromSnapshot(isolate, 0, DeserializeInternalFields) v8::Context::FromSnapshot(
isolate, 0,
v8::DeserializeInternalFieldsCallback(
DeserializeInternalFields, reinterpret_cast<void*>(2017)))
.ToLocalChecked(); .ToLocalChecked();
{ {
v8::Context::Scope context_scope(context); v8::Context::Scope context_scope(context);
ExpectInt32("f()", 42); ExpectInt32("f()", 42);
...@@ -2480,8 +2508,11 @@ TEST(SnapshotCreatorIncludeGlobalProxy) { ...@@ -2480,8 +2508,11 @@ TEST(SnapshotCreatorIncludeGlobalProxy) {
// New context, but reuse global proxy. // New context, but reuse global proxy.
v8::ExtensionConfiguration* no_extensions = nullptr; v8::ExtensionConfiguration* no_extensions = nullptr;
v8::Local<v8::Context> context2 = v8::Local<v8::Context> context2 =
v8::Context::FromSnapshot(isolate, 0, DeserializeInternalFields, v8::Context::FromSnapshot(
no_extensions, global) isolate, 0,
v8::DeserializeInternalFieldsCallback(
DeserializeInternalFields, reinterpret_cast<void*>(2017)),
no_extensions, global)
.ToLocalChecked(); .ToLocalChecked();
{ {
v8::Context::Scope context_scope(context2); v8::Context::Scope context_scope(context2);
......
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