From 8dfd905ba303998da988bcf0e575e249ce75dd2b Mon Sep 17 00:00:00 2001 From: legendecas Date: Wed, 30 Nov 2022 01:54:52 +0800 Subject: [PATCH] src: add worker per-isolate binding initialization Create worker binding templates in the per-isolate initialization. PR-URL: https://github.com/nodejs/node/pull/45547 Refs: https://github.com/nodejs/node/issues/42528 Reviewed-By: Joyee Cheung Reviewed-By: Colin Ihrig Reviewed-By: James M Snell --- src/async_wrap-inl.h | 6 ++++++ src/async_wrap.cc | 14 ++++++++------ src/async_wrap.h | 2 ++ src/inspector_js_api.cc | 1 + src/node_binding.h | 4 +++- src/node_worker.cc | 35 +++++++++++++++++++++++------------ src/util.cc | 31 +++++++++++++++++++++++++++---- src/util.h | 14 ++++++++++++++ 8 files changed, 84 insertions(+), 23 deletions(-) diff --git a/src/async_wrap-inl.h b/src/async_wrap-inl.h index 08f305da8a3192..30b29c83e0c90c 100644 --- a/src/async_wrap-inl.h +++ b/src/async_wrap-inl.h @@ -80,6 +80,12 @@ inline v8::MaybeLocal AsyncWrap::MakeCallback( return MakeCallback(cb_v.As(), argc, argv); } +// static +inline v8::Local AsyncWrap::GetConstructorTemplate( + Environment* env) { + return GetConstructorTemplate(env->isolate_data()); +} + } // namespace node #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS diff --git a/src/async_wrap.cc b/src/async_wrap.cc index c51d4aaabba285..ff550fdc1de5d0 100644 --- a/src/async_wrap.cc +++ b/src/async_wrap.cc @@ -334,18 +334,20 @@ void AsyncWrap::SetCallbackTrampoline(const FunctionCallbackInfo& args) { } } -Local AsyncWrap::GetConstructorTemplate(Environment* env) { - Local tmpl = env->async_wrap_ctor_template(); +Local AsyncWrap::GetConstructorTemplate( + IsolateData* isolate_data) { + Local tmpl = isolate_data->async_wrap_ctor_template(); if (tmpl.IsEmpty()) { - Isolate* isolate = env->isolate(); + Isolate* isolate = isolate_data->isolate(); tmpl = NewFunctionTemplate(isolate, nullptr); - tmpl->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "AsyncWrap")); - tmpl->Inherit(BaseObject::GetConstructorTemplate(env)); + tmpl->SetClassName( + FIXED_ONE_BYTE_STRING(isolate_data->isolate(), "AsyncWrap")); + tmpl->Inherit(BaseObject::GetConstructorTemplate(isolate_data)); SetProtoMethod(isolate, tmpl, "getAsyncId", AsyncWrap::GetAsyncId); SetProtoMethod(isolate, tmpl, "asyncReset", AsyncWrap::AsyncReset); SetProtoMethod( isolate, tmpl, "getProviderType", AsyncWrap::GetProviderType); - env->set_async_wrap_ctor_template(tmpl); + isolate_data->set_async_wrap_ctor_template(tmpl); } return tmpl; } diff --git a/src/async_wrap.h b/src/async_wrap.h index f7ed25f9eea318..5ccf3f86bac532 100644 --- a/src/async_wrap.h +++ b/src/async_wrap.h @@ -138,6 +138,8 @@ class AsyncWrap : public BaseObject { static constexpr double kInvalidAsyncId = -1; static v8::Local GetConstructorTemplate( + IsolateData* isolate_data); + inline static v8::Local GetConstructorTemplate( Environment* env); static void RegisterExternalReferences(ExternalReferenceRegistry* registry); diff --git a/src/inspector_js_api.cc b/src/inspector_js_api.cc index ed193688ee1da9..3595536c785ed7 100644 --- a/src/inspector_js_api.cc +++ b/src/inspector_js_api.cc @@ -1,3 +1,4 @@ +#include "async_wrap-inl.h" #include "base_object-inl.h" #include "inspector_agent.h" #include "inspector_io.h" diff --git a/src/node_binding.h b/src/node_binding.h index b403bf26b81d91..c140297f5ca936 100644 --- a/src/node_binding.h +++ b/src/node_binding.h @@ -24,7 +24,9 @@ static_assert(static_cast(NM_F_LINKED) == static_cast(node::ModuleFlags::kLinked), "NM_F_LINKED != node::ModuleFlags::kLinked"); -#define NODE_BINDINGS_WITH_PER_ISOLATE_INIT(V) V(builtins) +#define NODE_BINDINGS_WITH_PER_ISOLATE_INIT(V) \ + V(builtins) \ + V(worker) #define NODE_BINDING_CONTEXT_AWARE_CPP(modname, regfunc, priv, flags) \ static node::node_module _module = { \ diff --git a/src/node_worker.cc b/src/node_worker.cc index 5f7d807b1dac8f..b84a39cce330d7 100644 --- a/src/node_worker.cc +++ b/src/node_worker.cc @@ -34,6 +34,7 @@ using v8::MaybeLocal; using v8::Null; using v8::Number; using v8::Object; +using v8::ObjectTemplate; using v8::ResourceConstraints; using v8::SealHandleScope; using v8::String; @@ -876,19 +877,17 @@ void GetEnvMessagePort(const FunctionCallbackInfo& args) { } } -void InitWorker(Local target, - Local unused, - Local context, - void* priv) { - Environment* env = Environment::GetCurrent(context); - Isolate* isolate = env->isolate(); +void CreateWorkerPerIsolateProperties(IsolateData* isolate_data, + Local target) { + Isolate* isolate = isolate_data->isolate(); + Local proto = target->PrototypeTemplate(); { Local w = NewFunctionTemplate(isolate, Worker::New); w->InstanceTemplate()->SetInternalFieldCount( Worker::kInternalFieldCount); - w->Inherit(AsyncWrap::GetConstructorTemplate(env)); + w->Inherit(AsyncWrap::GetConstructorTemplate(isolate_data)); SetProtoMethod(isolate, w, "startThread", Worker::StartThread); SetProtoMethod(isolate, w, "stopThread", Worker::StopThread); @@ -900,7 +899,7 @@ void InitWorker(Local target, SetProtoMethod(isolate, w, "loopIdleTime", Worker::LoopIdleTime); SetProtoMethod(isolate, w, "loopStartTime", Worker::LoopStartTime); - SetConstructorFunction(context, target, "Worker", w); + SetConstructorFunction(isolate, proto, "Worker", w); } { @@ -908,15 +907,24 @@ void InitWorker(Local target, wst->InstanceTemplate()->SetInternalFieldCount( WorkerHeapSnapshotTaker::kInternalFieldCount); - wst->Inherit(AsyncWrap::GetConstructorTemplate(env)); + wst->Inherit(AsyncWrap::GetConstructorTemplate(isolate_data)); Local wst_string = FIXED_ONE_BYTE_STRING(isolate, "WorkerHeapSnapshotTaker"); wst->SetClassName(wst_string); - env->set_worker_heap_snapshot_taker_template(wst->InstanceTemplate()); + isolate_data->set_worker_heap_snapshot_taker_template( + wst->InstanceTemplate()); } - SetMethod(context, target, "getEnvMessagePort", GetEnvMessagePort); + SetMethod(isolate, proto, "getEnvMessagePort", GetEnvMessagePort); +} + +void CreateWorkerPerContextProperties(Local target, + Local unused, + Local context, + void* priv) { + Environment* env = Environment::GetCurrent(context); + Isolate* isolate = env->isolate(); target ->Set(env->context(), @@ -969,6 +977,9 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) { } // namespace worker } // namespace node -NODE_BINDING_CONTEXT_AWARE_INTERNAL(worker, node::worker::InitWorker) +NODE_BINDING_CONTEXT_AWARE_INTERNAL( + worker, node::worker::CreateWorkerPerContextProperties) +NODE_BINDING_PER_ISOLATE_INIT(worker, + node::worker::CreateWorkerPerIsolateProperties) NODE_BINDING_EXTERNAL_REFERENCE(worker, node::worker::RegisterExternalReferences) diff --git a/src/util.cc b/src/util.cc index 762bf393e8e086..78c6123c37a12a 100644 --- a/src/util.cc +++ b/src/util.cc @@ -56,9 +56,13 @@ static std::atomic_int seq = {0}; // Sequence number for diagnostic filenames. namespace node { using v8::ArrayBufferView; +using v8::Context; +using v8::FunctionTemplate; using v8::Isolate; using v8::Local; +using v8::Object; using v8::String; +using v8::Template; using v8::Value; template @@ -482,14 +486,33 @@ void SetConstructorFunction(Local context, context, that, OneByteString(isolate, name), tmpl, flag); } -void SetConstructorFunction(Local context, - Local that, - Local name, - Local tmpl, +void SetConstructorFunction(Local context, + Local that, + Local name, + Local tmpl, SetConstructorFunctionFlag flag) { if (LIKELY(flag == SetConstructorFunctionFlag::SET_CLASS_NAME)) tmpl->SetClassName(name); that->Set(context, name, tmpl->GetFunction(context).ToLocalChecked()).Check(); } +void SetConstructorFunction(Isolate* isolate, + Local