Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bootstrap: initialize per-isolate properties of bindings separately #47768

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 26 additions & 16 deletions src/async_wrap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ using v8::MaybeLocal;
using v8::Nothing;
using v8::Number;
using v8::Object;
using v8::ObjectTemplate;
using v8::PropertyAttribute;
using v8::ReadOnly;
using v8::String;
Expand Down Expand Up @@ -351,24 +352,31 @@ Local<FunctionTemplate> AsyncWrap::GetConstructorTemplate(
return tmpl;
}

void AsyncWrap::Initialize(Local<Object> target,
Local<Value> unused,
Local<Context> context,
void* priv) {
void AsyncWrap::CreatePerIsolateProperties(IsolateData* isolate_data,
Local<FunctionTemplate> ctor) {
Isolate* isolate = isolate_data->isolate();
Local<ObjectTemplate> target = ctor->InstanceTemplate();

SetMethod(isolate, target, "setupHooks", SetupHooks);
SetMethod(isolate, target, "setCallbackTrampoline", SetCallbackTrampoline);
SetMethod(isolate, target, "pushAsyncContext", PushAsyncContext);
SetMethod(isolate, target, "popAsyncContext", PopAsyncContext);
SetMethod(isolate, target, "executionAsyncResource", ExecutionAsyncResource);
SetMethod(isolate, target, "clearAsyncIdStack", ClearAsyncIdStack);
SetMethod(isolate, target, "queueDestroyAsyncId", QueueDestroyAsyncId);
SetMethod(isolate, target, "setPromiseHooks", SetPromiseHooks);
SetMethod(isolate, target, "registerDestroyHook", RegisterDestroyHook);
AsyncWrap::GetConstructorTemplate(isolate_data);
}

void AsyncWrap::CreatePerContextProperties(Local<Object> target,
Local<Value> unused,
Local<Context> context,
void* priv) {
Environment* env = Environment::GetCurrent(context);
Isolate* isolate = env->isolate();
HandleScope scope(isolate);

SetMethod(context, target, "setupHooks", SetupHooks);
SetMethod(context, target, "setCallbackTrampoline", SetCallbackTrampoline);
SetMethod(context, target, "pushAsyncContext", PushAsyncContext);
SetMethod(context, target, "popAsyncContext", PopAsyncContext);
SetMethod(context, target, "executionAsyncResource", ExecutionAsyncResource);
SetMethod(context, target, "clearAsyncIdStack", ClearAsyncIdStack);
SetMethod(context, target, "queueDestroyAsyncId", QueueDestroyAsyncId);
SetMethod(context, target, "setPromiseHooks", SetPromiseHooks);
SetMethod(context, target, "registerDestroyHook", RegisterDestroyHook);

PropertyAttribute ReadOnlyDontDelete =
static_cast<PropertyAttribute>(ReadOnly | DontDelete);

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


void AsyncWrap::EmitAsyncInit(Environment* env,
Local<Object> object,
Local<String> type,
Expand Down Expand Up @@ -710,6 +717,9 @@ Local<Object> AsyncWrap::GetOwner(Environment* env, Local<Object> obj) {

} // namespace node

NODE_BINDING_CONTEXT_AWARE_INTERNAL(async_wrap, node::AsyncWrap::Initialize)
NODE_BINDING_CONTEXT_AWARE_INTERNAL(async_wrap,
node::AsyncWrap::CreatePerContextProperties)
NODE_BINDING_PER_ISOLATE_INIT(async_wrap,
node::AsyncWrap::CreatePerIsolateProperties)
NODE_BINDING_EXTERNAL_REFERENCE(async_wrap,
node::AsyncWrap::RegisterExternalReferences)
10 changes: 6 additions & 4 deletions src/async_wrap.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,10 +147,12 @@ class AsyncWrap : public BaseObject {
Environment* env);

static void RegisterExternalReferences(ExternalReferenceRegistry* registry);
static void Initialize(v8::Local<v8::Object> target,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv);
static void CreatePerContextProperties(v8::Local<v8::Object> target,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv);
static void CreatePerIsolateProperties(
IsolateData* isolate_data, v8::Local<v8::FunctionTemplate> target);

static void GetAsyncId(const v8::FunctionCallbackInfo<v8::Value>& args);
static void PushAsyncContext(const v8::FunctionCallbackInfo<v8::Value>& args);
Expand Down
37 changes: 23 additions & 14 deletions src/encoding_binding.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ using v8::ArrayBuffer;
using v8::BackingStore;
using v8::Context;
using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
using v8::Isolate;
using v8::Local;
using v8::MaybeLocal;
using v8::Object;
using v8::ObjectTemplate;
using v8::String;
using v8::Uint8Array;
using v8::Value;
Expand Down Expand Up @@ -216,20 +218,23 @@ void BindingData::ToUnicode(const v8::FunctionCallbackInfo<v8::Value>& args) {
String::NewFromUtf8(env->isolate(), out.c_str()).ToLocalChecked());
}

void BindingData::Initialize(Local<Object> target,
Local<Value> unused,
Local<Context> context,
void* priv) {
void BindingData::CreatePerIsolateProperties(IsolateData* isolate_data,
Local<FunctionTemplate> ctor) {
Isolate* isolate = isolate_data->isolate();
Local<ObjectTemplate> target = ctor->InstanceTemplate();
SetMethod(isolate, target, "encodeInto", EncodeInto);
SetMethodNoSideEffect(isolate, target, "encodeUtf8String", EncodeUtf8String);
SetMethodNoSideEffect(isolate, target, "decodeUTF8", DecodeUTF8);
SetMethodNoSideEffect(isolate, target, "toASCII", ToASCII);
SetMethodNoSideEffect(isolate, target, "toUnicode", ToUnicode);
}

void BindingData::CreatePerContextProperties(Local<Object> target,
Local<Value> unused,
Local<Context> context,
void* priv) {
Realm* realm = Realm::GetCurrent(context);
BindingData* const binding_data =
realm->AddBindingData<BindingData>(context, target);
if (binding_data == nullptr) return;

SetMethod(context, target, "encodeInto", EncodeInto);
SetMethodNoSideEffect(context, target, "encodeUtf8String", EncodeUtf8String);
SetMethodNoSideEffect(context, target, "decodeUTF8", DecodeUTF8);
SetMethodNoSideEffect(context, target, "toASCII", ToASCII);
SetMethodNoSideEffect(context, target, "toUnicode", ToUnicode);
realm->AddBindingData<BindingData>(context, target);
}

void BindingData::RegisterTimerExternalReferences(
Expand All @@ -245,7 +250,11 @@ void BindingData::RegisterTimerExternalReferences(
} // namespace node

NODE_BINDING_CONTEXT_AWARE_INTERNAL(
encoding_binding, node::encoding_binding::BindingData::Initialize)
encoding_binding,
node::encoding_binding::BindingData::CreatePerContextProperties)
NODE_BINDING_PER_ISOLATE_INIT(
encoding_binding,
node::encoding_binding::BindingData::CreatePerIsolateProperties)
NODE_BINDING_EXTERNAL_REFERENCE(
encoding_binding,
node::encoding_binding::BindingData::RegisterTimerExternalReferences)
10 changes: 6 additions & 4 deletions src/encoding_binding.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,12 @@ class BindingData : public SnapshotableObject {
static void ToASCII(const v8::FunctionCallbackInfo<v8::Value>& args);
static void ToUnicode(const v8::FunctionCallbackInfo<v8::Value>& args);

static void Initialize(v8::Local<v8::Object> target,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv);
static void CreatePerIsolateProperties(IsolateData* isolate_data,
v8::Local<v8::FunctionTemplate> ctor);
static void CreatePerContextProperties(v8::Local<v8::Object> target,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv);
static void RegisterTimerExternalReferences(
ExternalReferenceRegistry* registry);

Expand Down
15 changes: 10 additions & 5 deletions src/env.cc
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,11 @@ void IsolateData::DeserializeProperties(const IsolateDataSerializeInfo* info) {
size_t i = 0;
HandleScope handle_scope(isolate_);

if (per_process::enabled_debug_list.enabled(DebugCategory::MKSNAPSHOT)) {
fprintf(stderr, "deserializing IsolateDataSerializeInfo...\n");
std::cerr << *info << "\n";
}

#define VP(PropertyName, StringValue) V(Private, PropertyName)
#define VY(PropertyName, StringValue) V(Symbol, PropertyName)
#define VS(PropertyName, StringValue) V(String, PropertyName)
Expand Down Expand Up @@ -1704,6 +1709,11 @@ void Environment::RunDeserializeRequests() {
void Environment::DeserializeProperties(const EnvSerializeInfo* info) {
Local<Context> ctx = context();

if (enabled_debug_list_.enabled(DebugCategory::MKSNAPSHOT)) {
fprintf(stderr, "deserializing EnvSerializeInfo...\n");
std::cerr << *info << "\n";
}

RunDeserializeRequests();

async_hooks_.Deserialize(ctx);
Expand All @@ -1716,11 +1726,6 @@ void Environment::DeserializeProperties(const EnvSerializeInfo* info) {
should_abort_on_uncaught_toggle_.Deserialize(ctx);

principal_realm_->DeserializeProperties(&info->principal_realm);

if (enabled_debug_list_.enabled(DebugCategory::MKSNAPSHOT)) {
fprintf(stderr, "deserializing...\n");
std::cerr << *info << "\n";
}
}

uint64_t GuessMemoryAvailableToTheProcess() {
Expand Down
2 changes: 1 addition & 1 deletion src/env_properties.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
// Symbols are per-isolate primitives but Environment proxies them
// for the sake of convenience.
#define PER_ISOLATE_SYMBOL_PROPERTIES(V) \
V(fs_use_promises_symbol, "fs_use_promises_symbol") \
V(async_id_symbol, "async_id_symbol") \
V(handle_onclose_symbol, "handle_onclose") \
V(no_message_symbol, "no_message_symbol") \
Expand Down Expand Up @@ -390,7 +391,6 @@
V(domexception_function, v8::Function) \
V(enhance_fatal_stack_after_inspector, v8::Function) \
V(enhance_fatal_stack_before_inspector, v8::Function) \
V(fs_use_promises_symbol, v8::Symbol) \
V(get_source_map_error_source, v8::Function) \
V(host_import_module_dynamically_callback, v8::Function) \
V(host_initialize_import_meta_object_callback, v8::Function) \
Expand Down
17 changes: 11 additions & 6 deletions src/handle_wrap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -154,19 +154,24 @@ void HandleWrap::OnClose(uv_handle_t* handle) {
wrap->MakeCallback(env->handle_onclose_symbol(), 0, nullptr);
}
}

Local<FunctionTemplate> HandleWrap::GetConstructorTemplate(Environment* env) {
Local<FunctionTemplate> tmpl = env->handle_wrap_ctor_template();
return GetConstructorTemplate(env->isolate_data());
}

Local<FunctionTemplate> HandleWrap::GetConstructorTemplate(
IsolateData* isolate_data) {
Local<FunctionTemplate> tmpl = isolate_data->handle_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(), "HandleWrap"));
tmpl->Inherit(AsyncWrap::GetConstructorTemplate(env));
tmpl->SetClassName(
FIXED_ONE_BYTE_STRING(isolate_data->isolate(), "HandleWrap"));
tmpl->Inherit(AsyncWrap::GetConstructorTemplate(isolate_data));
SetProtoMethod(isolate, tmpl, "close", HandleWrap::Close);
SetProtoMethodNoSideEffect(isolate, tmpl, "hasRef", HandleWrap::HasRef);
SetProtoMethod(isolate, tmpl, "ref", HandleWrap::Ref);
SetProtoMethod(isolate, tmpl, "unref", HandleWrap::Unref);
env->set_handle_wrap_ctor_template(tmpl);
isolate_data->set_handle_wrap_ctor_template(tmpl);
}
return tmpl;
}
Expand Down
2 changes: 2 additions & 0 deletions src/handle_wrap.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ class HandleWrap : public AsyncWrap {
virtual void Close(
v8::Local<v8::Value> close_callback = v8::Local<v8::Value>());

static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
IsolateData* isolate_data);
static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
Environment* env);
static void RegisterExternalReferences(ExternalReferenceRegistry* registry);
Expand Down
8 changes: 8 additions & 0 deletions src/node_binding.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,16 @@ static_assert(static_cast<int>(NM_F_LINKED) ==
#endif

#define NODE_BINDINGS_WITH_PER_ISOLATE_INIT(V) \
V(async_wrap) \
V(blob) \
V(builtins) \
V(contextify) \
V(encoding_binding) \
V(fs) \
V(timers) \
V(process_methods) \
V(performance) \
V(url) \
V(worker) \
NODE_BUILTIN_ICU_BINDINGS(V)

Expand Down
37 changes: 21 additions & 16 deletions src/node_blob.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ using v8::Int32;
using v8::Isolate;
using v8::Local;
using v8::Object;
using v8::ObjectTemplate;
using v8::String;
using v8::Uint32;
using v8::Undefined;
Expand Down Expand Up @@ -107,23 +108,25 @@ void BlobFromFilePath(const FunctionCallbackInfo<Value>& args) {
}
} // namespace

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

BlobBindingData* const binding_data =
realm->AddBindingData<BlobBindingData>(context, target);
if (binding_data == nullptr) return;
SetMethod(isolate, target, "createBlob", New);
SetMethod(isolate, target, "storeDataObject", StoreDataObject);
SetMethod(isolate, target, "getDataObject", GetDataObject);
SetMethod(isolate, target, "revokeObjectURL", RevokeObjectURL);
SetMethod(isolate, target, "concat", Concat);
SetMethod(isolate, target, "createBlobFromFilePath", BlobFromFilePath);
}

SetMethod(context, target, "createBlob", New);
SetMethod(context, target, "storeDataObject", StoreDataObject);
SetMethod(context, target, "getDataObject", GetDataObject);
SetMethod(context, target, "revokeObjectURL", RevokeObjectURL);
SetMethod(context, target, "concat", Concat);
SetMethod(context, target, "createBlobFromFilePath", BlobFromFilePath);
void Blob::CreatePerContextProperties(Local<Object> target,
Local<Value> unused,
Local<Context> context,
void* priv) {
Realm* realm = Realm::GetCurrent(context);
realm->AddBindingData<BlobBindingData>(context, target);
}

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

} // namespace node

NODE_BINDING_CONTEXT_AWARE_INTERNAL(blob, node::Blob::Initialize)
NODE_BINDING_CONTEXT_AWARE_INTERNAL(blob,
node::Blob::CreatePerContextProperties)
NODE_BINDING_PER_ISOLATE_INIT(blob, node::Blob::CreatePerIsolateProperties)
NODE_BINDING_EXTERNAL_REFERENCE(blob, node::Blob::RegisterExternalReferences)
11 changes: 6 additions & 5 deletions src/node_blob.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,12 @@ class Blob : public BaseObject {
static void RegisterExternalReferences(
ExternalReferenceRegistry* registry);

static void Initialize(
v8::Local<v8::Object> target,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv);
static void CreatePerIsolateProperties(IsolateData* isolate_data,
v8::Local<v8::FunctionTemplate> ctor);
static void CreatePerContextProperties(v8::Local<v8::Object> target,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv);

static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
static void GetReader(const v8::FunctionCallbackInfo<v8::Value>& args);
Expand Down
Loading