Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJoyee Cheung <joyeec9h3@gmail.com>2022-03-24 16:37:08 +0300
committerJoyee Cheung <joyeec9h3@gmail.com>2022-03-31 14:29:12 +0300
commit37aee80643822c8c9ff35c906d034ecc8fc448d5 (patch)
tree65a9107f2ed3b7e4cdaf38936a1df65ccd25a587 /src
parent8a297ba3a0aa39afb7c84fceee4accff609b7cfe (diff)
build: add --node-snapshot-main configure option
This adds a --build-snapshot runtime option which is currently only supported by the node_mksnapshot binary, and a --node-snapshot-main configure option that makes use it to run a custom script when building the embedded snapshot. The idea is to have this experimental feature in core as a configure-time feature for now, and investigate the renaming V8 bugs before we make it available to more users via making it a runtime option. PR-URL: https://github.com/nodejs/node/pull/42466 Reviewed-By: Darshan Sen <raisinten@gmail.com> Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com> Reviewed-By: Khaidi Chu <i@2333.moe> Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/node.cc10
-rw-r--r--src/node_binding.cc1
-rw-r--r--src/node_external_reference.h1
-rw-r--r--src/node_options.cc5
-rw-r--r--src/node_options.h1
-rw-r--r--src/node_snapshotable.cc81
-rw-r--r--src/node_snapshotable.h2
7 files changed, 100 insertions, 1 deletions
diff --git a/src/node.cc b/src/node.cc
index e503fd9f5b4..5ba03b75407 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -495,6 +495,10 @@ MaybeLocal<Value> StartExecution(Environment* env, StartExecutionCallback cb) {
return StartExecution(env, "internal/main/inspect");
}
+ if (per_process::cli_options->build_snapshot) {
+ return StartExecution(env, "internal/main/mksnapshot");
+ }
+
if (per_process::cli_options->print_help) {
return StartExecution(env, "internal/main/print_help");
}
@@ -1153,6 +1157,12 @@ int Start(int argc, char** argv) {
return result.exit_code;
}
+ if (per_process::cli_options->build_snapshot) {
+ fprintf(stderr,
+ "--build-snapshot is not yet supported in the node binary\n");
+ return 1;
+ }
+
{
bool use_node_snapshot =
per_process::cli_options->per_isolate->node_snapshot;
diff --git a/src/node_binding.cc b/src/node_binding.cc
index 050c5dff0ad..ed8ab9237fd 100644
--- a/src/node_binding.cc
+++ b/src/node_binding.cc
@@ -59,6 +59,7 @@
V(js_udp_wrap) \
V(messaging) \
V(module_wrap) \
+ V(mksnapshot) \
V(native_module) \
V(options) \
V(os) \
diff --git a/src/node_external_reference.h b/src/node_external_reference.h
index c57a01ff39c..306c726631a 100644
--- a/src/node_external_reference.h
+++ b/src/node_external_reference.h
@@ -66,6 +66,7 @@ class ExternalReferenceRegistry {
V(handle_wrap) \
V(heap_utils) \
V(messaging) \
+ V(mksnapshot) \
V(native_module) \
V(options) \
V(os) \
diff --git a/src/node_options.cc b/src/node_options.cc
index 35ee54d2231..bb568ce458a 100644
--- a/src/node_options.cc
+++ b/src/node_options.cc
@@ -725,6 +725,11 @@ PerProcessOptionsParser::PerProcessOptionsParser(
"disable Object.prototype.__proto__",
&PerProcessOptions::disable_proto,
kAllowedInEnvironment);
+ AddOption("--build-snapshot",
+ "Generate a snapshot blob when the process exits."
+ "Currently only supported in the node_mksnapshot binary.",
+ &PerProcessOptions::build_snapshot,
+ kDisallowedInEnvironment);
// 12.x renamed this inadvertently, so alias it for consistency within the
// release line, while using the original name for consistency with older
diff --git a/src/node_options.h b/src/node_options.h
index 3335c12b8cd..7a73e6e5987 100644
--- a/src/node_options.h
+++ b/src/node_options.h
@@ -229,6 +229,7 @@ class PerProcessOptions : public Options {
bool zero_fill_all_buffers = false;
bool debug_arraybuffer_allocations = false;
std::string disable_proto;
+ bool build_snapshot;
std::vector<std::string> security_reverts;
bool print_bash_completion = false;
diff --git a/src/node_snapshotable.cc b/src/node_snapshotable.cc
index 71b025df81e..327246743bb 100644
--- a/src/node_snapshotable.cc
+++ b/src/node_snapshotable.cc
@@ -18,12 +18,18 @@
namespace node {
using v8::Context;
+using v8::Function;
+using v8::FunctionCallbackInfo;
using v8::HandleScope;
using v8::Isolate;
using v8::Local;
+using v8::MaybeLocal;
using v8::Object;
+using v8::ScriptCompiler;
+using v8::ScriptOrigin;
using v8::SnapshotCreator;
using v8::StartupData;
+using v8::String;
using v8::TryCatch;
using v8::Value;
@@ -130,16 +136,36 @@ void SnapshotBuilder::Generate(SnapshotData* out,
nullptr,
node::EnvironmentFlags::kDefaultFlags,
{});
+ // TODO(joyeecheung): run env->InitializeInspector({}) here.
// Run scripts in lib/internal/bootstrap/
{
TryCatch bootstrapCatch(isolate);
- v8::MaybeLocal<Value> result = env->RunBootstrapping();
+ MaybeLocal<Value> result = env->RunBootstrapping();
if (bootstrapCatch.HasCaught()) {
PrintCaughtException(isolate, context, bootstrapCatch);
}
result.ToLocalChecked();
}
+ // If --build-snapshot is true, lib/internal/main/mksnapshot.js would be
+ // loaded via LoadEnvironment() to execute process.argv[1] as the entry
+ // point (we currently only support this kind of entry point, but we
+ // could also explore snapshotting other kinds of execution modes
+ // in the future).
+ if (per_process::cli_options->build_snapshot) {
+ TryCatch bootstrapCatch(isolate);
+ // TODO(joyeecheung): we could use the result for something special,
+ // like setting up initializers that should be invoked at snapshot
+ // dehydration.
+ MaybeLocal<Value> result =
+ LoadEnvironment(env, StartExecutionCallback{});
+ if (bootstrapCatch.HasCaught()) {
+ PrintCaughtException(isolate, context, bootstrapCatch);
+ }
+ result.ToLocalChecked();
+ // TODO(joyeecheung): run SpinEventLoop here.
+ }
+
if (per_process::enabled_debug_list.enabled(DebugCategory::MKSNAPSHOT)) {
env->PrintAllBaseObjects();
printf("Environment = %p\n", env);
@@ -309,4 +335,57 @@ void SerializeBindingData(Environment* env,
});
}
+namespace mksnapshot {
+
+static void CompileSnapshotMain(const FunctionCallbackInfo<Value>& args) {
+ CHECK(args[0]->IsString());
+ Local<String> filename = args[0].As<String>();
+ Local<String> source = args[1].As<String>();
+ Isolate* isolate = args.GetIsolate();
+ Local<Context> context = isolate->GetCurrentContext();
+ ScriptOrigin origin(isolate, filename, 0, 0, true);
+ // TODO(joyeecheung): do we need all of these? Maybe we would want a less
+ // internal version of them.
+ std::vector<Local<String>> parameters = {
+ FIXED_ONE_BYTE_STRING(isolate, "require"),
+ FIXED_ONE_BYTE_STRING(isolate, "__filename"),
+ FIXED_ONE_BYTE_STRING(isolate, "__dirname"),
+ };
+ ScriptCompiler::Source script_source(source, origin);
+ Local<Function> fn;
+ if (ScriptCompiler::CompileFunctionInContext(context,
+ &script_source,
+ parameters.size(),
+ parameters.data(),
+ 0,
+ nullptr,
+ ScriptCompiler::kEagerCompile)
+ .ToLocal(&fn)) {
+ args.GetReturnValue().Set(fn);
+ }
+}
+
+static void Initialize(Local<Object> target,
+ Local<Value> unused,
+ Local<Context> context,
+ void* priv) {
+ Environment* env = Environment::GetCurrent(context);
+ Isolate* isolate = context->GetIsolate();
+ env->SetMethod(target, "compileSnapshotMain", CompileSnapshotMain);
+ target
+ ->Set(context,
+ FIXED_ONE_BYTE_STRING(isolate, "cleanups"),
+ v8::Array::New(isolate))
+ .Check();
+}
+
+static void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
+ registry->Register(CompileSnapshotMain);
+ registry->Register(MarkBootstrapComplete);
+}
+} // namespace mksnapshot
} // namespace node
+
+NODE_MODULE_CONTEXT_AWARE_INTERNAL(mksnapshot, node::mksnapshot::Initialize)
+NODE_MODULE_EXTERNAL_REFERENCE(mksnapshot,
+ node::mksnapshot::RegisterExternalReferences)
diff --git a/src/node_snapshotable.h b/src/node_snapshotable.h
index 1ccd9a93226..30b684eb68a 100644
--- a/src/node_snapshotable.h
+++ b/src/node_snapshotable.h
@@ -127,6 +127,8 @@ class SnapshotBuilder {
public:
static std::string Generate(const std::vector<std::string> args,
const std::vector<std::string> exec_args);
+
+ // Generate the snapshot into out.
static void Generate(SnapshotData* out,
const std::vector<std::string> args,
const std::vector<std::string> exec_args);