mirror of
https://github.com/zebrajr/node.git
synced 2026-01-15 12:15:26 +00:00
src: use v8::(Des|S)erializeInternalFieldsCallback
Previously V8 would just try to serialize the context data fields "verbatim" by copying the pointer values. This patch makes use of the new callbacks so that at serialization, the embedder data for the context can at least be serialized in a meaningful way (which are all reset to empty for now). Otherwise the upstream may have difficulties serializing these pointer values "verbatim" especially with the introduction of external pointer tables, even though the verbatim pointer values from a previous process is meaningless to Node.js. For Node.js the callback currently just checks that the slots are know. We will reassign the pointers with newly created native structures during deserialization and there isn't much we can reuse for now. PR-URL: https://github.com/nodejs/node/pull/53217 Refs: https://chromium-review.googlesource.com/c/v8/v8/+/5512712/comments/cfc2b28d_c921ac80?tab=comments Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
This commit is contained in:
@@ -458,7 +458,13 @@ Environment* CreateEnvironment(
|
||||
if (use_snapshot) {
|
||||
context = Context::FromSnapshot(isolate,
|
||||
SnapshotData::kNodeMainContextIndex,
|
||||
{DeserializeNodeInternalFields, env})
|
||||
v8::DeserializeInternalFieldsCallback(
|
||||
DeserializeNodeInternalFields, env),
|
||||
nullptr,
|
||||
MaybeLocal<Value>(),
|
||||
nullptr,
|
||||
v8::DeserializeContextDataCallback(
|
||||
DeserializeNodeContextData, env))
|
||||
.ToLocalChecked();
|
||||
|
||||
CHECK(!context.IsEmpty());
|
||||
|
||||
@@ -1155,8 +1155,11 @@ ExitCode SnapshotBuilder::CreateSnapshot(SnapshotData* out,
|
||||
CHECK_EQ(index, SnapshotData::kNodeVMContextIndex);
|
||||
index = creator->AddContext(base_context);
|
||||
CHECK_EQ(index, SnapshotData::kNodeBaseContextIndex);
|
||||
index = creator->AddContext(main_context,
|
||||
{SerializeNodeContextInternalFields, env});
|
||||
index = creator->AddContext(
|
||||
main_context,
|
||||
v8::SerializeInternalFieldsCallback(SerializeNodeContextInternalFields,
|
||||
env),
|
||||
v8::SerializeContextDataCallback(SerializeNodeContextData, env));
|
||||
CHECK_EQ(index, SnapshotData::kNodeMainContextIndex);
|
||||
}
|
||||
|
||||
@@ -1255,6 +1258,41 @@ std::string SnapshotableObject::GetTypeName() const {
|
||||
}
|
||||
}
|
||||
|
||||
void DeserializeNodeContextData(Local<Context> holder,
|
||||
int index,
|
||||
StartupData payload,
|
||||
void* callback_data) {
|
||||
// This is unreachable for now. We will reset all the pointers in
|
||||
// Environment::AssignToContext() via the realm constructor.
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
StartupData SerializeNodeContextData(Local<Context> holder,
|
||||
int index,
|
||||
void* callback_data) {
|
||||
// For now we just reset all of them in Environment::AssignToContext().
|
||||
// We return empty data here to make sure that the embedder data serialized
|
||||
// into the snapshot is reproducible and V8 doesn't have to try to serialize
|
||||
// the pointer values that won't be useful during deserialization.
|
||||
switch (index) {
|
||||
case ContextEmbedderIndex::kEnvironment:
|
||||
case ContextEmbedderIndex::kContextifyContext:
|
||||
case ContextEmbedderIndex::kRealm:
|
||||
case ContextEmbedderIndex::kContextTag: {
|
||||
void* data = holder->GetAlignedPointerFromEmbedderData(index);
|
||||
per_process::Debug(
|
||||
DebugCategory::MKSNAPSHOT,
|
||||
"Serialize context data, index=%d, holder=%p, ptr=%p\n",
|
||||
static_cast<int>(index),
|
||||
*holder,
|
||||
data);
|
||||
return {nullptr, 0};
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
void DeserializeNodeInternalFields(Local<Object> holder,
|
||||
int index,
|
||||
StartupData payload,
|
||||
|
||||
@@ -126,10 +126,17 @@ class SnapshotableObject : public BaseObject {
|
||||
v8::StartupData SerializeNodeContextInternalFields(v8::Local<v8::Object> holder,
|
||||
int index,
|
||||
void* env);
|
||||
v8::StartupData SerializeNodeContextData(v8::Local<v8::Context> holder,
|
||||
int index,
|
||||
void* env);
|
||||
void DeserializeNodeInternalFields(v8::Local<v8::Object> holder,
|
||||
int index,
|
||||
v8::StartupData payload,
|
||||
void* env);
|
||||
void DeserializeNodeContextData(v8::Local<v8::Context> holder,
|
||||
int index,
|
||||
v8::StartupData payload,
|
||||
void* env);
|
||||
void SerializeSnapshotableObjects(Realm* realm,
|
||||
v8::SnapshotCreator* creator,
|
||||
RealmSerializeInfo* info);
|
||||
|
||||
Reference in New Issue
Block a user