[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}
This commit is contained in:
yangguo 2017-01-12 04:25:58 -08:00 committed by Commit bot
parent 9884fb91e1
commit 9cd0de73dc
6 changed files with 97 additions and 44 deletions

View File

@ -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,
int index,
StartupData payload);
struct DeserializeInternalFieldsCallback {
typedef void (*CallbackFunction)(Local<Object> holder, int index,
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
@ -7689,7 +7705,8 @@ class V8_EXPORT SnapshotCreator {
* \returns the index of the context in the snapshot blob.
*/
size_t AddContext(Local<Context> context,
SerializeInternalFieldsCallback callback = nullptr);
SerializeInternalFieldsCallback callback =
SerializeInternalFieldsCallback());
/**
* Add a template to be included in the snapshot blob.
@ -8029,7 +8046,8 @@ class V8_EXPORT Context {
static MaybeLocal<Context> FromSnapshot(
Isolate* isolate, size_t context_snapshot_index,
DeserializeInternalFieldsCallback internal_fields_deserializer = nullptr,
DeserializeInternalFieldsCallback internal_fields_deserializer =
DeserializeInternalFieldsCallback(),
ExtensionConfiguration* extensions = nullptr,
MaybeLocal<Value> global_object = MaybeLocal<Value>());

View File

@ -615,8 +615,8 @@ StartupData SnapshotCreator::CreateBlob(
{
// The default snapshot does not support internal fields.
i::PartialSerializer partial_serializer(isolate, &startup_serializer,
nullptr);
i::PartialSerializer partial_serializer(
isolate, &startup_serializer, v8::SerializeInternalFieldsCallback());
partial_serializer.Serialize(&default_context, false);
context_snapshots.Add(new i::SnapshotData(&partial_serializer));
}
@ -6297,7 +6297,7 @@ Local<Context> v8::Context::New(v8::Isolate* external_isolate,
v8::MaybeLocal<ObjectTemplate> global_template,
v8::MaybeLocal<Value> global_object) {
return NewContext(external_isolate, extensions, global_template,
global_object, 0, nullptr);
global_object, 0, DeserializeInternalFieldsCallback());
}
MaybeLocal<Context> v8::Context::FromSnapshot(
@ -6334,7 +6334,8 @@ MaybeLocal<Object> v8::Context::NewRemoteContext(
"Global template needs to have access check handlers.");
i::Handle<i::JSGlobalProxy> global_proxy =
CreateEnvironment<i::JSGlobalProxy>(isolate, nullptr, global_template,
global_object, 0, nullptr);
global_object, 0,
DeserializeInternalFieldsCallback());
if (global_proxy.is_null()) {
if (isolate->has_pending_exception()) {
isolate->OptionalRescheduleException(true);

View File

@ -466,7 +466,8 @@ bool Debug::Load() {
static const int kFirstContextSnapshotIndex = 0;
Handle<Context> context = isolate_->bootstrapper()->CreateEnvironment(
MaybeHandle<JSGlobalProxy>(), v8::Local<ObjectTemplate>(), &no_extensions,
kFirstContextSnapshotIndex, nullptr, DEBUG_CONTEXT);
kFirstContextSnapshotIndex, v8::DeserializeInternalFieldsCallback(),
DEBUG_CONTEXT);
// Fail if no context could be created.
if (context.is_null()) return false;

View File

@ -221,7 +221,7 @@ void Deserializer::DeserializeInternalFields(
DisallowHeapAllocation no_gc;
DisallowJavascriptExecution no_js(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()) {
HandleScope scope(isolate_);
int space = code & kSpaceMask;
@ -233,8 +233,9 @@ void Deserializer::DeserializeInternalFields(
int size = source_.GetInt();
byte* data = new byte[size];
source_.CopyRaw(data, size);
internal_fields_deserializer(v8::Utils::ToLocal(obj), index,
{reinterpret_cast<char*>(data), size});
internal_fields_deserializer.callback(v8::Utils::ToLocal(obj), index,
{reinterpret_cast<char*>(data), size},
internal_fields_deserializer.data);
delete[] data;
}
}

View File

@ -103,7 +103,7 @@ void PartialSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code,
if (obj->IsJSObject()) {
JSObject* jsobj = JSObject::cast(obj);
if (jsobj->GetInternalFieldCount() > 0) {
DCHECK_NOT_NULL(serialize_internal_fields_);
DCHECK_NOT_NULL(serialize_internal_fields_.callback);
internal_field_holders_.Add(jsobj);
}
}
@ -132,7 +132,7 @@ void PartialSerializer::SerializeInternalFields() {
DisallowHeapAllocation no_gc;
DisallowJavascriptExecution no_js(isolate());
DisallowCompilation no_compile(isolate());
DCHECK_NOT_NULL(serialize_internal_fields_);
DCHECK_NOT_NULL(serialize_internal_fields_.callback);
sink_.Put(kInternalFieldsData, "internal fields data");
while (internal_field_holders_.length() > 0) {
HandleScope scope(isolate());
@ -142,7 +142,8 @@ void PartialSerializer::SerializeInternalFields() {
int internal_fields_count = obj->GetInternalFieldCount();
for (int i = 0; i < internal_fields_count; i++) {
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");
PutBackReference(*obj, reference);
sink_.PutInt(i, "internal field index");

View File

@ -285,7 +285,8 @@ static void PartiallySerializeObject(Vector<const byte>* startup_blob_out,
isolate, v8::SnapshotCreator::FunctionCodeHandling::kClear);
startup_serializer.SerializeStrongReferences();
PartialSerializer partial_serializer(isolate, &startup_serializer, nullptr);
PartialSerializer partial_serializer(isolate, &startup_serializer,
v8::SerializeInternalFieldsCallback());
partial_serializer.Serialize(&raw_foo, false);
startup_serializer.SerializeWeakReferencesAndDeferred();
@ -321,7 +322,9 @@ UNINITIALIZED_TEST(PartialSerializerObject) {
{
SnapshotData snapshot_data(partial_blob);
Deserializer deserializer(&snapshot_data);
root = deserializer.DeserializePartial(isolate, global_proxy, nullptr)
root = deserializer
.DeserializePartial(isolate, global_proxy,
v8::DeserializeInternalFieldsCallback())
.ToHandleChecked();
CHECK(root->IsString());
}
@ -330,7 +333,9 @@ UNINITIALIZED_TEST(PartialSerializerObject) {
{
SnapshotData snapshot_data(partial_blob);
Deserializer deserializer(&snapshot_data);
root2 = deserializer.DeserializePartial(isolate, global_proxy, nullptr)
root2 = deserializer
.DeserializePartial(isolate, global_proxy,
v8::DeserializeInternalFieldsCallback())
.ToHandleChecked();
CHECK(root2->IsString());
CHECK(root.is_identical_to(root2));
@ -385,7 +390,8 @@ static void PartiallySerializeContext(Vector<const byte>* startup_blob_out,
startup_serializer.SerializeStrongReferences();
SnapshotByteSink partial_sink;
PartialSerializer partial_serializer(isolate, &startup_serializer, nullptr);
PartialSerializer partial_serializer(isolate, &startup_serializer,
v8::SerializeInternalFieldsCallback());
partial_serializer.Serialize(&raw_context, false);
startup_serializer.SerializeWeakReferencesAndDeferred();
@ -419,7 +425,9 @@ UNINITIALIZED_TEST(PartialSerializerContext) {
{
SnapshotData snapshot_data(partial_blob);
Deserializer deserializer(&snapshot_data);
root = deserializer.DeserializePartial(isolate, global_proxy, nullptr)
root = deserializer
.DeserializePartial(isolate, global_proxy,
v8::DeserializeInternalFieldsCallback())
.ToHandleChecked();
CHECK(root->IsContext());
CHECK(Handle<Context>::cast(root)->global_proxy() == *global_proxy);
@ -429,7 +437,9 @@ UNINITIALIZED_TEST(PartialSerializerContext) {
{
SnapshotData snapshot_data(partial_blob);
Deserializer deserializer(&snapshot_data);
root2 = deserializer.DeserializePartial(isolate, global_proxy, nullptr)
root2 = deserializer
.DeserializePartial(isolate, global_proxy,
v8::DeserializeInternalFieldsCallback())
.ToHandleChecked();
CHECK(root2->IsContext());
CHECK(!root.is_identical_to(root2));
@ -505,7 +515,8 @@ static void PartiallySerializeCustomContext(
startup_serializer.SerializeStrongReferences();
SnapshotByteSink partial_sink;
PartialSerializer partial_serializer(isolate, &startup_serializer, nullptr);
PartialSerializer partial_serializer(isolate, &startup_serializer,
v8::SerializeInternalFieldsCallback());
partial_serializer.Serialize(&raw_context, false);
startup_serializer.SerializeWeakReferencesAndDeferred();
@ -539,7 +550,9 @@ UNINITIALIZED_TEST(PartialSerializerCustomContext) {
{
SnapshotData snapshot_data(partial_blob);
Deserializer deserializer(&snapshot_data);
root = deserializer.DeserializePartial(isolate, global_proxy, nullptr)
root = deserializer
.DeserializePartial(isolate, global_proxy,
v8::DeserializeInternalFieldsCallback())
.ToHandleChecked();
CHECK(root->IsContext());
Handle<Context> context = Handle<Context>::cast(root);
@ -2161,25 +2174,27 @@ struct InternalFieldData {
uint32_t data;
};
v8::StartupData SerializeInternalFields(v8::Local<v8::Object> holder,
int index) {
InternalFieldData* data = static_cast<InternalFieldData*>(
v8::StartupData SerializeInternalFields(v8::Local<v8::Object> holder, int index,
void* data) {
CHECK_EQ(reinterpret_cast<void*>(2016), data);
InternalFieldData* internal_field = static_cast<InternalFieldData*>(
holder->GetAlignedPointerFromInternalField(index));
int size = sizeof(*data);
int size = sizeof(*internal_field);
char* payload = new char[size];
// We simply use memcpy to serialize the content.
memcpy(payload, data, size);
memcpy(payload, internal_field, size);
return {payload, size};
}
std::vector<InternalFieldData*> deserialized_data;
void DeserializeInternalFields(v8::Local<v8::Object> holder, int index,
v8::StartupData payload) {
InternalFieldData* data = new InternalFieldData{0};
memcpy(data, payload.data, payload.raw_size);
holder->SetAlignedPointerInInternalField(index, data);
deserialized_data.push_back(data);
v8::StartupData payload, void* data) {
CHECK_EQ(reinterpret_cast<void*>(2017), data);
InternalFieldData* internal_field = new InternalFieldData{0};
memcpy(internal_field, payload.data, payload.raw_size);
holder->SetAlignedPointerInInternalField(index, internal_field);
deserialized_data.push_back(internal_field);
}
TEST(SnapshotCreatorTemplates) {
@ -2231,7 +2246,10 @@ TEST(SnapshotCreatorTemplates) {
c->SetInternalField(2, field_external);
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(1u, creator.AddTemplate(global_template));
}
@ -2255,7 +2273,10 @@ TEST(SnapshotCreatorTemplates) {
// Create a new context without a new object template.
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context =
v8::Context::FromSnapshot(isolate, 0, DeserializeInternalFields)
v8::Context::FromSnapshot(
isolate, 0,
v8::DeserializeInternalFieldsCallback(
DeserializeInternalFields, reinterpret_cast<void*>(2017)))
.ToLocalChecked();
v8::Context::Scope context_scope(context);
ExpectInt32("f()", 42);
@ -2408,7 +2429,10 @@ TEST(SnapshotCreatorIncludeGlobalProxy) {
.ToLocalChecked())
.FromJust());
CHECK_EQ(0u, creator.AddContext(context, SerializeInternalFields));
CHECK_EQ(0u,
creator.AddContext(context, v8::SerializeInternalFieldsCallback(
SerializeInternalFields,
reinterpret_cast<void*>(2016))));
}
blob =
creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
@ -2452,8 +2476,12 @@ TEST(SnapshotCreatorIncludeGlobalProxy) {
// will use the global object from the snapshot, including interceptor.
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context =
v8::Context::FromSnapshot(isolate, 0, DeserializeInternalFields)
v8::Context::FromSnapshot(
isolate, 0,
v8::DeserializeInternalFieldsCallback(
DeserializeInternalFields, reinterpret_cast<void*>(2017)))
.ToLocalChecked();
{
v8::Context::Scope context_scope(context);
ExpectInt32("f()", 42);
@ -2480,8 +2508,11 @@ TEST(SnapshotCreatorIncludeGlobalProxy) {
// New context, but reuse global proxy.
v8::ExtensionConfiguration* no_extensions = nullptr;
v8::Local<v8::Context> context2 =
v8::Context::FromSnapshot(isolate, 0, DeserializeInternalFields,
no_extensions, global)
v8::Context::FromSnapshot(
isolate, 0,
v8::DeserializeInternalFieldsCallback(
DeserializeInternalFields, reinterpret_cast<void*>(2017)),
no_extensions, global)
.ToLocalChecked();
{
v8::Context::Scope context_scope(context2);