diff --git a/src/api/environment.cc b/src/api/environment.cc index 2cc2108b4c0f1c..45fa330b599503 100644 --- a/src/api/environment.cc +++ b/src/api/environment.cc @@ -458,7 +458,13 @@ Environment* CreateEnvironment( if (use_snapshot) { context = Context::FromSnapshot(isolate, SnapshotData::kNodeMainContextIndex, - {DeserializeNodeInternalFields, env}) + v8::DeserializeInternalFieldsCallback( + DeserializeNodeInternalFields, env), + nullptr, + MaybeLocal(), + nullptr, + v8::DeserializeContextDataCallback( + DeserializeNodeContextData, env)) .ToLocalChecked(); CHECK(!context.IsEmpty()); diff --git a/src/node_snapshotable.cc b/src/node_snapshotable.cc index 683f36839e0de2..ec01c2d0d5ac18 100644 --- a/src/node_snapshotable.cc +++ b/src/node_snapshotable.cc @@ -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 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 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(index), + *holder, + data); + return {nullptr, 0}; + } + default: + UNREACHABLE(); + } +} + void DeserializeNodeInternalFields(Local holder, int index, StartupData payload, diff --git a/src/node_snapshotable.h b/src/node_snapshotable.h index 5e281b8155c810..600e56c481be90 100644 --- a/src/node_snapshotable.h +++ b/src/node_snapshotable.h @@ -126,10 +126,17 @@ class SnapshotableObject : public BaseObject { v8::StartupData SerializeNodeContextInternalFields(v8::Local holder, int index, void* env); +v8::StartupData SerializeNodeContextData(v8::Local holder, + int index, + void* env); void DeserializeNodeInternalFields(v8::Local holder, int index, v8::StartupData payload, void* env); +void DeserializeNodeContextData(v8::Local holder, + int index, + v8::StartupData payload, + void* env); void SerializeSnapshotableObjects(Realm* realm, v8::SnapshotCreator* creator, RealmSerializeInfo* info);