Skip to content

Commit 456fca0

Browse files
joyeecheungtargos
authored andcommitted
bootstrap: initialize per-isolate properties of bindings separately
This patch moves the initialization of per-isolate properties of the bindings that are in the embedded snapshot separate from the initialization of their per-context properties. This is necessary for workers to share the isolate snapshot with the main thread and deserialize these properties instead of creating them from scratch. PR-URL: #47768 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Chengzhong Wu <legendecas@gmail.com> Reviewed-By: Minwoo Jung <nodecorelab@gmail.com>
1 parent a0da234 commit 456fca0

22 files changed

+384
-289
lines changed

src/async_wrap.cc

+26-16
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ using v8::MaybeLocal;
4444
using v8::Nothing;
4545
using v8::Number;
4646
using v8::Object;
47+
using v8::ObjectTemplate;
4748
using v8::PropertyAttribute;
4849
using v8::ReadOnly;
4950
using v8::String;
@@ -351,24 +352,31 @@ Local<FunctionTemplate> AsyncWrap::GetConstructorTemplate(
351352
return tmpl;
352353
}
353354

354-
void AsyncWrap::Initialize(Local<Object> target,
355-
Local<Value> unused,
356-
Local<Context> context,
357-
void* priv) {
355+
void AsyncWrap::CreatePerIsolateProperties(IsolateData* isolate_data,
356+
Local<FunctionTemplate> ctor) {
357+
Isolate* isolate = isolate_data->isolate();
358+
Local<ObjectTemplate> target = ctor->InstanceTemplate();
359+
360+
SetMethod(isolate, target, "setupHooks", SetupHooks);
361+
SetMethod(isolate, target, "setCallbackTrampoline", SetCallbackTrampoline);
362+
SetMethod(isolate, target, "pushAsyncContext", PushAsyncContext);
363+
SetMethod(isolate, target, "popAsyncContext", PopAsyncContext);
364+
SetMethod(isolate, target, "executionAsyncResource", ExecutionAsyncResource);
365+
SetMethod(isolate, target, "clearAsyncIdStack", ClearAsyncIdStack);
366+
SetMethod(isolate, target, "queueDestroyAsyncId", QueueDestroyAsyncId);
367+
SetMethod(isolate, target, "setPromiseHooks", SetPromiseHooks);
368+
SetMethod(isolate, target, "registerDestroyHook", RegisterDestroyHook);
369+
AsyncWrap::GetConstructorTemplate(isolate_data);
370+
}
371+
372+
void AsyncWrap::CreatePerContextProperties(Local<Object> target,
373+
Local<Value> unused,
374+
Local<Context> context,
375+
void* priv) {
358376
Environment* env = Environment::GetCurrent(context);
359377
Isolate* isolate = env->isolate();
360378
HandleScope scope(isolate);
361379

362-
SetMethod(context, target, "setupHooks", SetupHooks);
363-
SetMethod(context, target, "setCallbackTrampoline", SetCallbackTrampoline);
364-
SetMethod(context, target, "pushAsyncContext", PushAsyncContext);
365-
SetMethod(context, target, "popAsyncContext", PopAsyncContext);
366-
SetMethod(context, target, "executionAsyncResource", ExecutionAsyncResource);
367-
SetMethod(context, target, "clearAsyncIdStack", ClearAsyncIdStack);
368-
SetMethod(context, target, "queueDestroyAsyncId", QueueDestroyAsyncId);
369-
SetMethod(context, target, "setPromiseHooks", SetPromiseHooks);
370-
SetMethod(context, target, "registerDestroyHook", RegisterDestroyHook);
371-
372380
PropertyAttribute ReadOnlyDontDelete =
373381
static_cast<PropertyAttribute>(ReadOnly | DontDelete);
374382

@@ -625,7 +633,6 @@ void AsyncWrap::AsyncReset(Local<Object> resource, double execution_async_id,
625633
async_id_, trigger_async_id_);
626634
}
627635

628-
629636
void AsyncWrap::EmitAsyncInit(Environment* env,
630637
Local<Object> object,
631638
Local<String> type,
@@ -710,6 +717,9 @@ Local<Object> AsyncWrap::GetOwner(Environment* env, Local<Object> obj) {
710717

711718
} // namespace node
712719

713-
NODE_BINDING_CONTEXT_AWARE_INTERNAL(async_wrap, node::AsyncWrap::Initialize)
720+
NODE_BINDING_CONTEXT_AWARE_INTERNAL(async_wrap,
721+
node::AsyncWrap::CreatePerContextProperties)
722+
NODE_BINDING_PER_ISOLATE_INIT(async_wrap,
723+
node::AsyncWrap::CreatePerIsolateProperties)
714724
NODE_BINDING_EXTERNAL_REFERENCE(async_wrap,
715725
node::AsyncWrap::RegisterExternalReferences)

src/async_wrap.h

+6-4
Original file line numberDiff line numberDiff line change
@@ -145,10 +145,12 @@ class AsyncWrap : public BaseObject {
145145
Environment* env);
146146

147147
static void RegisterExternalReferences(ExternalReferenceRegistry* registry);
148-
static void Initialize(v8::Local<v8::Object> target,
149-
v8::Local<v8::Value> unused,
150-
v8::Local<v8::Context> context,
151-
void* priv);
148+
static void CreatePerContextProperties(v8::Local<v8::Object> target,
149+
v8::Local<v8::Value> unused,
150+
v8::Local<v8::Context> context,
151+
void* priv);
152+
static void CreatePerIsolateProperties(
153+
IsolateData* isolate_data, v8::Local<v8::FunctionTemplate> target);
152154

153155
static void GetAsyncId(const v8::FunctionCallbackInfo<v8::Value>& args);
154156
static void PushAsyncContext(const v8::FunctionCallbackInfo<v8::Value>& args);

src/encoding_binding.cc

+23-14
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@ using v8::ArrayBuffer;
1616
using v8::BackingStore;
1717
using v8::Context;
1818
using v8::FunctionCallbackInfo;
19+
using v8::FunctionTemplate;
1920
using v8::Isolate;
2021
using v8::Local;
2122
using v8::MaybeLocal;
2223
using v8::Object;
24+
using v8::ObjectTemplate;
2325
using v8::String;
2426
using v8::Uint8Array;
2527
using v8::Value;
@@ -216,20 +218,23 @@ void BindingData::ToUnicode(const v8::FunctionCallbackInfo<v8::Value>& args) {
216218
String::NewFromUtf8(env->isolate(), out.c_str()).ToLocalChecked());
217219
}
218220

219-
void BindingData::Initialize(Local<Object> target,
220-
Local<Value> unused,
221-
Local<Context> context,
222-
void* priv) {
221+
void BindingData::CreatePerIsolateProperties(IsolateData* isolate_data,
222+
Local<FunctionTemplate> ctor) {
223+
Isolate* isolate = isolate_data->isolate();
224+
Local<ObjectTemplate> target = ctor->InstanceTemplate();
225+
SetMethod(isolate, target, "encodeInto", EncodeInto);
226+
SetMethodNoSideEffect(isolate, target, "encodeUtf8String", EncodeUtf8String);
227+
SetMethodNoSideEffect(isolate, target, "decodeUTF8", DecodeUTF8);
228+
SetMethodNoSideEffect(isolate, target, "toASCII", ToASCII);
229+
SetMethodNoSideEffect(isolate, target, "toUnicode", ToUnicode);
230+
}
231+
232+
void BindingData::CreatePerContextProperties(Local<Object> target,
233+
Local<Value> unused,
234+
Local<Context> context,
235+
void* priv) {
223236
Realm* realm = Realm::GetCurrent(context);
224-
BindingData* const binding_data =
225-
realm->AddBindingData<BindingData>(context, target);
226-
if (binding_data == nullptr) return;
227-
228-
SetMethod(context, target, "encodeInto", EncodeInto);
229-
SetMethodNoSideEffect(context, target, "encodeUtf8String", EncodeUtf8String);
230-
SetMethodNoSideEffect(context, target, "decodeUTF8", DecodeUTF8);
231-
SetMethodNoSideEffect(context, target, "toASCII", ToASCII);
232-
SetMethodNoSideEffect(context, target, "toUnicode", ToUnicode);
237+
realm->AddBindingData<BindingData>(context, target);
233238
}
234239

235240
void BindingData::RegisterTimerExternalReferences(
@@ -245,7 +250,11 @@ void BindingData::RegisterTimerExternalReferences(
245250
} // namespace node
246251

247252
NODE_BINDING_CONTEXT_AWARE_INTERNAL(
248-
encoding_binding, node::encoding_binding::BindingData::Initialize)
253+
encoding_binding,
254+
node::encoding_binding::BindingData::CreatePerContextProperties)
255+
NODE_BINDING_PER_ISOLATE_INIT(
256+
encoding_binding,
257+
node::encoding_binding::BindingData::CreatePerIsolateProperties)
249258
NODE_BINDING_EXTERNAL_REFERENCE(
250259
encoding_binding,
251260
node::encoding_binding::BindingData::RegisterTimerExternalReferences)

src/encoding_binding.h

+6-4
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,12 @@ class BindingData : public SnapshotableObject {
3535
static void ToASCII(const v8::FunctionCallbackInfo<v8::Value>& args);
3636
static void ToUnicode(const v8::FunctionCallbackInfo<v8::Value>& args);
3737

38-
static void Initialize(v8::Local<v8::Object> target,
39-
v8::Local<v8::Value> unused,
40-
v8::Local<v8::Context> context,
41-
void* priv);
38+
static void CreatePerIsolateProperties(IsolateData* isolate_data,
39+
v8::Local<v8::FunctionTemplate> ctor);
40+
static void CreatePerContextProperties(v8::Local<v8::Object> target,
41+
v8::Local<v8::Value> unused,
42+
v8::Local<v8::Context> context,
43+
void* priv);
4244
static void RegisterTimerExternalReferences(
4345
ExternalReferenceRegistry* registry);
4446

src/handle_wrap.cc

+11-6
Original file line numberDiff line numberDiff line change
@@ -154,19 +154,24 @@ void HandleWrap::OnClose(uv_handle_t* handle) {
154154
wrap->MakeCallback(env->handle_onclose_symbol(), 0, nullptr);
155155
}
156156
}
157-
158157
Local<FunctionTemplate> HandleWrap::GetConstructorTemplate(Environment* env) {
159-
Local<FunctionTemplate> tmpl = env->handle_wrap_ctor_template();
158+
return GetConstructorTemplate(env->isolate_data());
159+
}
160+
161+
Local<FunctionTemplate> HandleWrap::GetConstructorTemplate(
162+
IsolateData* isolate_data) {
163+
Local<FunctionTemplate> tmpl = isolate_data->handle_wrap_ctor_template();
160164
if (tmpl.IsEmpty()) {
161-
Isolate* isolate = env->isolate();
165+
Isolate* isolate = isolate_data->isolate();
162166
tmpl = NewFunctionTemplate(isolate, nullptr);
163-
tmpl->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "HandleWrap"));
164-
tmpl->Inherit(AsyncWrap::GetConstructorTemplate(env));
167+
tmpl->SetClassName(
168+
FIXED_ONE_BYTE_STRING(isolate_data->isolate(), "HandleWrap"));
169+
tmpl->Inherit(AsyncWrap::GetConstructorTemplate(isolate_data));
165170
SetProtoMethod(isolate, tmpl, "close", HandleWrap::Close);
166171
SetProtoMethodNoSideEffect(isolate, tmpl, "hasRef", HandleWrap::HasRef);
167172
SetProtoMethod(isolate, tmpl, "ref", HandleWrap::Ref);
168173
SetProtoMethod(isolate, tmpl, "unref", HandleWrap::Unref);
169-
env->set_handle_wrap_ctor_template(tmpl);
174+
isolate_data->set_handle_wrap_ctor_template(tmpl);
170175
}
171176
return tmpl;
172177
}

src/handle_wrap.h

+2
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ class HandleWrap : public AsyncWrap {
7676
virtual void Close(
7777
v8::Local<v8::Value> close_callback = v8::Local<v8::Value>());
7878

79+
static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
80+
IsolateData* isolate_data);
7981
static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
8082
Environment* env);
8183
static void RegisterExternalReferences(ExternalReferenceRegistry* registry);

src/node_binding.h

+8
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,16 @@ static_assert(static_cast<int>(NM_F_LINKED) ==
3131
#endif
3232

3333
#define NODE_BINDINGS_WITH_PER_ISOLATE_INIT(V) \
34+
V(async_wrap) \
35+
V(blob) \
3436
V(builtins) \
37+
V(contextify) \
38+
V(encoding_binding) \
39+
V(fs) \
40+
V(timers) \
41+
V(process_methods) \
3542
V(performance) \
43+
V(url) \
3644
V(worker) \
3745
NODE_BUILTIN_ICU_BINDINGS(V)
3846

src/node_blob.cc

+21-16
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ using v8::Int32;
2929
using v8::Isolate;
3030
using v8::Local;
3131
using v8::Object;
32+
using v8::ObjectTemplate;
3233
using v8::String;
3334
using v8::Uint32;
3435
using v8::Undefined;
@@ -107,23 +108,25 @@ void BlobFromFilePath(const FunctionCallbackInfo<Value>& args) {
107108
}
108109
} // namespace
109110

110-
void Blob::Initialize(
111-
Local<Object> target,
112-
Local<Value> unused,
113-
Local<Context> context,
114-
void* priv) {
115-
Realm* realm = Realm::GetCurrent(context);
111+
void Blob::CreatePerIsolateProperties(IsolateData* isolate_data,
112+
Local<FunctionTemplate> ctor) {
113+
Isolate* isolate = isolate_data->isolate();
114+
Local<ObjectTemplate> target = ctor->InstanceTemplate();
116115

117-
BlobBindingData* const binding_data =
118-
realm->AddBindingData<BlobBindingData>(context, target);
119-
if (binding_data == nullptr) return;
116+
SetMethod(isolate, target, "createBlob", New);
117+
SetMethod(isolate, target, "storeDataObject", StoreDataObject);
118+
SetMethod(isolate, target, "getDataObject", GetDataObject);
119+
SetMethod(isolate, target, "revokeObjectURL", RevokeObjectURL);
120+
SetMethod(isolate, target, "concat", Concat);
121+
SetMethod(isolate, target, "createBlobFromFilePath", BlobFromFilePath);
122+
}
120123

121-
SetMethod(context, target, "createBlob", New);
122-
SetMethod(context, target, "storeDataObject", StoreDataObject);
123-
SetMethod(context, target, "getDataObject", GetDataObject);
124-
SetMethod(context, target, "revokeObjectURL", RevokeObjectURL);
125-
SetMethod(context, target, "concat", Concat);
126-
SetMethod(context, target, "createBlobFromFilePath", BlobFromFilePath);
124+
void Blob::CreatePerContextProperties(Local<Object> target,
125+
Local<Value> unused,
126+
Local<Context> context,
127+
void* priv) {
128+
Realm* realm = Realm::GetCurrent(context);
129+
realm->AddBindingData<BlobBindingData>(context, target);
127130
}
128131

129132
Local<FunctionTemplate> Blob::GetConstructorTemplate(Environment* env) {
@@ -562,5 +565,7 @@ void Blob::RegisterExternalReferences(ExternalReferenceRegistry* registry) {
562565

563566
} // namespace node
564567

565-
NODE_BINDING_CONTEXT_AWARE_INTERNAL(blob, node::Blob::Initialize)
568+
NODE_BINDING_CONTEXT_AWARE_INTERNAL(blob,
569+
node::Blob::CreatePerContextProperties)
570+
NODE_BINDING_PER_ISOLATE_INIT(blob, node::Blob::CreatePerIsolateProperties)
566571
NODE_BINDING_EXTERNAL_REFERENCE(blob, node::Blob::RegisterExternalReferences)

src/node_blob.h

+6-5
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,12 @@ class Blob : public BaseObject {
2626
static void RegisterExternalReferences(
2727
ExternalReferenceRegistry* registry);
2828

29-
static void Initialize(
30-
v8::Local<v8::Object> target,
31-
v8::Local<v8::Value> unused,
32-
v8::Local<v8::Context> context,
33-
void* priv);
29+
static void CreatePerIsolateProperties(IsolateData* isolate_data,
30+
v8::Local<v8::FunctionTemplate> ctor);
31+
static void CreatePerContextProperties(v8::Local<v8::Object> target,
32+
v8::Local<v8::Value> unused,
33+
v8::Local<v8::Context> context,
34+
void* priv);
3435

3536
static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
3637
static void GetReader(const v8::FunctionCallbackInfo<v8::Value>& args);

0 commit comments

Comments
 (0)