src: split RunBootstrapping()
Split `RunBootstrapping()` into `BootstrapInternalLoaders()` and `BootstrapNode()` from so the two can be snapshotted incrementally. PR-URL: https://github.com/nodejs/node/pull/27539 Reviewed-By: Anna Henningsen <anna@addaleax.net>
This commit is contained in:
parent
a0d86befb5
commit
077859948d
@ -287,7 +287,7 @@ Environment* CreateEnvironment(IsolateData* isolate_data,
|
|||||||
Environment::kOwnsProcessState |
|
Environment::kOwnsProcessState |
|
||||||
Environment::kOwnsInspector));
|
Environment::kOwnsInspector));
|
||||||
env->InitializeLibuv(per_process::v8_is_profiling);
|
env->InitializeLibuv(per_process::v8_is_profiling);
|
||||||
if (RunBootstrapping(env).IsEmpty()) {
|
if (env->RunBootstrapping().IsEmpty()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -809,6 +809,10 @@ class Environment : public MemoryRetainer {
|
|||||||
int InitializeInspector(inspector::ParentInspectorHandle* parent_handle);
|
int InitializeInspector(inspector::ParentInspectorHandle* parent_handle);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
v8::MaybeLocal<v8::Value> BootstrapInternalLoaders();
|
||||||
|
v8::MaybeLocal<v8::Value> BootstrapNode();
|
||||||
|
v8::MaybeLocal<v8::Value> RunBootstrapping();
|
||||||
|
|
||||||
inline size_t async_callback_scope_depth() const;
|
inline size_t async_callback_scope_depth() const;
|
||||||
inline void PushAsyncCallbackScope();
|
inline void PushAsyncCallbackScope();
|
||||||
inline void PopAsyncCallbackScope();
|
inline void PopAsyncCallbackScope();
|
||||||
|
139
src/node.cc
139
src/node.cc
@ -130,7 +130,6 @@ using options_parser::kAllowedInEnvironment;
|
|||||||
using options_parser::kDisallowedInEnvironment;
|
using options_parser::kDisallowedInEnvironment;
|
||||||
|
|
||||||
using v8::Boolean;
|
using v8::Boolean;
|
||||||
using v8::Context;
|
|
||||||
using v8::EscapableHandleScope;
|
using v8::EscapableHandleScope;
|
||||||
using v8::Exception;
|
using v8::Exception;
|
||||||
using v8::Function;
|
using v8::Function;
|
||||||
@ -277,99 +276,111 @@ void Environment::InitializeDiagnostics() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
MaybeLocal<Value> RunBootstrapping(Environment* env) {
|
MaybeLocal<Value> Environment::BootstrapInternalLoaders() {
|
||||||
CHECK(!env->has_run_bootstrapping_code());
|
EscapableHandleScope scope(isolate_);
|
||||||
|
|
||||||
EscapableHandleScope scope(env->isolate());
|
|
||||||
Isolate* isolate = env->isolate();
|
|
||||||
Local<Context> context = env->context();
|
|
||||||
|
|
||||||
|
|
||||||
// Add a reference to the global object
|
|
||||||
Local<Object> global = context->Global();
|
|
||||||
Local<Object> process = env->process_object();
|
|
||||||
|
|
||||||
// Setting global properties for the bootstrappers to use:
|
|
||||||
// - global
|
|
||||||
// Expose the global object as a property on itself
|
|
||||||
// (Allows you to set stuff on `global` from anywhere in JavaScript.)
|
|
||||||
global->Set(context, FIXED_ONE_BYTE_STRING(env->isolate(), "global"), global)
|
|
||||||
.Check();
|
|
||||||
|
|
||||||
|
|
||||||
// Create binding loaders
|
// Create binding loaders
|
||||||
std::vector<Local<String>> loaders_params = {
|
std::vector<Local<String>> loaders_params = {
|
||||||
env->process_string(),
|
process_string(),
|
||||||
FIXED_ONE_BYTE_STRING(isolate, "getLinkedBinding"),
|
FIXED_ONE_BYTE_STRING(isolate_, "getLinkedBinding"),
|
||||||
FIXED_ONE_BYTE_STRING(isolate, "getInternalBinding"),
|
FIXED_ONE_BYTE_STRING(isolate_, "getInternalBinding"),
|
||||||
env->primordials_string()};
|
primordials_string()};
|
||||||
std::vector<Local<Value>> loaders_args = {
|
std::vector<Local<Value>> loaders_args = {
|
||||||
process,
|
process_object(),
|
||||||
env->NewFunctionTemplate(binding::GetLinkedBinding)
|
NewFunctionTemplate(binding::GetLinkedBinding)
|
||||||
->GetFunction(context)
|
->GetFunction(context())
|
||||||
.ToLocalChecked(),
|
.ToLocalChecked(),
|
||||||
env->NewFunctionTemplate(binding::GetInternalBinding)
|
NewFunctionTemplate(binding::GetInternalBinding)
|
||||||
->GetFunction(context)
|
->GetFunction(context())
|
||||||
.ToLocalChecked(),
|
.ToLocalChecked(),
|
||||||
env->primordials()};
|
primordials()};
|
||||||
|
|
||||||
// Bootstrap internal loaders
|
// Bootstrap internal loaders
|
||||||
MaybeLocal<Value> loader_exports = ExecuteBootstrapper(
|
Local<Value> loader_exports;
|
||||||
env, "internal/bootstrap/loaders", &loaders_params, &loaders_args);
|
if (!ExecuteBootstrapper(
|
||||||
if (loader_exports.IsEmpty()) {
|
this, "internal/bootstrap/loaders", &loaders_params, &loaders_args)
|
||||||
|
.ToLocal(&loader_exports)) {
|
||||||
return MaybeLocal<Value>();
|
return MaybeLocal<Value>();
|
||||||
}
|
}
|
||||||
|
CHECK(loader_exports->IsObject());
|
||||||
Local<Object> loader_exports_obj =
|
Local<Object> loader_exports_obj = loader_exports.As<Object>();
|
||||||
loader_exports.ToLocalChecked().As<Object>();
|
|
||||||
Local<Value> internal_binding_loader =
|
Local<Value> internal_binding_loader =
|
||||||
loader_exports_obj->Get(context, env->internal_binding_string())
|
loader_exports_obj->Get(context(), internal_binding_string())
|
||||||
.ToLocalChecked();
|
.ToLocalChecked();
|
||||||
env->set_internal_binding_loader(internal_binding_loader.As<Function>());
|
CHECK(internal_binding_loader->IsFunction());
|
||||||
|
set_internal_binding_loader(internal_binding_loader.As<Function>());
|
||||||
Local<Value> require =
|
Local<Value> require =
|
||||||
loader_exports_obj->Get(context, env->require_string()).ToLocalChecked();
|
loader_exports_obj->Get(context(), require_string()).ToLocalChecked();
|
||||||
env->set_native_module_require(require.As<Function>());
|
CHECK(require->IsFunction());
|
||||||
|
set_native_module_require(require.As<Function>());
|
||||||
|
|
||||||
|
return scope.Escape(loader_exports);
|
||||||
|
}
|
||||||
|
|
||||||
|
MaybeLocal<Value> Environment::BootstrapNode() {
|
||||||
|
EscapableHandleScope scope(isolate_);
|
||||||
|
|
||||||
|
Local<Object> global = context()->Global();
|
||||||
|
// TODO(joyeecheung): this can be done in JS land now.
|
||||||
|
global->Set(context(), FIXED_ONE_BYTE_STRING(isolate_, "global"), global)
|
||||||
|
.Check();
|
||||||
|
|
||||||
// process, require, internalBinding, isMainThread,
|
// process, require, internalBinding, isMainThread,
|
||||||
// ownsProcessState, primordials
|
// ownsProcessState, primordials
|
||||||
std::vector<Local<String>> node_params = {
|
std::vector<Local<String>> node_params = {
|
||||||
env->process_string(),
|
process_string(),
|
||||||
env->require_string(),
|
require_string(),
|
||||||
env->internal_binding_string(),
|
internal_binding_string(),
|
||||||
FIXED_ONE_BYTE_STRING(isolate, "isMainThread"),
|
FIXED_ONE_BYTE_STRING(isolate_, "isMainThread"),
|
||||||
FIXED_ONE_BYTE_STRING(isolate, "ownsProcessState"),
|
FIXED_ONE_BYTE_STRING(isolate_, "ownsProcessState"),
|
||||||
env->primordials_string()};
|
primordials_string()};
|
||||||
std::vector<Local<Value>> node_args = {
|
std::vector<Local<Value>> node_args = {
|
||||||
process,
|
process_object(),
|
||||||
require,
|
native_module_require(),
|
||||||
internal_binding_loader,
|
internal_binding_loader(),
|
||||||
Boolean::New(isolate, env->is_main_thread()),
|
Boolean::New(isolate_, is_main_thread()),
|
||||||
Boolean::New(isolate, env->owns_process_state()),
|
Boolean::New(isolate_, owns_process_state()),
|
||||||
env->primordials()};
|
primordials()};
|
||||||
|
|
||||||
MaybeLocal<Value> result = ExecuteBootstrapper(
|
MaybeLocal<Value> result = ExecuteBootstrapper(
|
||||||
env, "internal/bootstrap/node", &node_params, &node_args);
|
this, "internal/bootstrap/node", &node_params, &node_args);
|
||||||
|
|
||||||
Local<Object> env_var_proxy;
|
Local<Object> env_var_proxy;
|
||||||
if (!CreateEnvVarProxy(context, isolate, env->as_callback_data())
|
if (!CreateEnvVarProxy(context(), isolate_, as_callback_data())
|
||||||
.ToLocal(&env_var_proxy) ||
|
.ToLocal(&env_var_proxy) ||
|
||||||
process
|
process_object()
|
||||||
->Set(env->context(),
|
->Set(
|
||||||
FIXED_ONE_BYTE_STRING(env->isolate(), "env"),
|
context(), FIXED_ONE_BYTE_STRING(isolate_, "env"), env_var_proxy)
|
||||||
env_var_proxy)
|
.IsNothing()) {
|
||||||
.IsNothing())
|
|
||||||
return MaybeLocal<Value>();
|
return MaybeLocal<Value>();
|
||||||
|
}
|
||||||
|
|
||||||
|
return scope.EscapeMaybe(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
MaybeLocal<Value> Environment::RunBootstrapping() {
|
||||||
|
EscapableHandleScope scope(isolate_);
|
||||||
|
|
||||||
|
CHECK(!has_run_bootstrapping_code());
|
||||||
|
|
||||||
|
if (BootstrapInternalLoaders().IsEmpty()) {
|
||||||
|
return MaybeLocal<Value>();
|
||||||
|
}
|
||||||
|
|
||||||
|
Local<Value> result;
|
||||||
|
if (!BootstrapNode().ToLocal(&result)) {
|
||||||
|
return MaybeLocal<Value>();
|
||||||
|
}
|
||||||
|
|
||||||
// Make sure that no request or handle is created during bootstrap -
|
// Make sure that no request or handle is created during bootstrap -
|
||||||
// if necessary those should be done in pre-execution.
|
// if necessary those should be done in pre-execution.
|
||||||
// TODO(joyeecheung): print handles/requests before aborting
|
// TODO(joyeecheung): print handles/requests before aborting
|
||||||
CHECK(env->req_wrap_queue()->IsEmpty());
|
CHECK(req_wrap_queue()->IsEmpty());
|
||||||
CHECK(env->handle_wrap_queue()->IsEmpty());
|
CHECK(handle_wrap_queue()->IsEmpty());
|
||||||
|
|
||||||
env->set_has_run_bootstrapping_code(true);
|
set_has_run_bootstrapping_code(true);
|
||||||
|
|
||||||
return scope.EscapeMaybe(result);
|
return scope.Escape(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MarkBootstrapComplete(const FunctionCallbackInfo<Value>& args) {
|
void MarkBootstrapComplete(const FunctionCallbackInfo<Value>& args) {
|
||||||
|
@ -275,7 +275,6 @@ void DefineZlibConstants(v8::Local<v8::Object> target);
|
|||||||
v8::Isolate* NewIsolate(v8::Isolate::CreateParams* params,
|
v8::Isolate* NewIsolate(v8::Isolate::CreateParams* params,
|
||||||
uv_loop_t* event_loop,
|
uv_loop_t* event_loop,
|
||||||
MultiIsolatePlatform* platform);
|
MultiIsolatePlatform* platform);
|
||||||
v8::MaybeLocal<v8::Value> RunBootstrapping(Environment* env);
|
|
||||||
v8::MaybeLocal<v8::Value> StartExecution(Environment* env,
|
v8::MaybeLocal<v8::Value> StartExecution(Environment* env,
|
||||||
const char* main_script_id);
|
const char* main_script_id);
|
||||||
v8::MaybeLocal<v8::Object> GetPerContextExports(v8::Local<v8::Context> context);
|
v8::MaybeLocal<v8::Object> GetPerContextExports(v8::Local<v8::Context> context);
|
||||||
|
@ -205,7 +205,7 @@ std::unique_ptr<Environment> NodeMainInstance::CreateMainEnvironment(
|
|||||||
return env;
|
return env;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RunBootstrapping(env.get()).IsEmpty()) {
|
if (env->RunBootstrapping().IsEmpty()) {
|
||||||
*exit_code = 1;
|
*exit_code = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,7 +271,7 @@ void Worker::Run() {
|
|||||||
HandleScope handle_scope(isolate_);
|
HandleScope handle_scope(isolate_);
|
||||||
AsyncCallbackScope callback_scope(env_.get());
|
AsyncCallbackScope callback_scope(env_.get());
|
||||||
env_->async_hooks()->push_async_ids(1, 0);
|
env_->async_hooks()->push_async_ids(1, 0);
|
||||||
if (!RunBootstrapping(env_.get()).IsEmpty()) {
|
if (!env_->RunBootstrapping().IsEmpty()) {
|
||||||
CreateEnvMessagePort(env_.get());
|
CreateEnvMessagePort(env_.get());
|
||||||
if (is_stopped()) return;
|
if (is_stopped()) return;
|
||||||
Debug(this, "Created message port for worker %llu", thread_id_);
|
Debug(this, "Created message port for worker %llu", thread_id_);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user