Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
bootstrap: support more builtins in the embedded code cache
This patch:

- Make NativeModuleLoader::LookupAndCompile() detect parameters based
  on module IDs. This allows us to compile more builtins when
  generating the embedded bootstrap, including
  - internal/per_context/*
  - internal/bootstrap/*
  - internal/main/*
- Move pre_execution.js to lib/internal/process as it needs to be
  compiled as a regular built-in module, unlike other scripts
  in lib/internal/bootstrap
- Move markBootstrapComplete() to the performance binding instead of
  making it a function-wrapper-based global to reduce number of
  special cases.
  • Loading branch information
joyeecheung committed Aug 3, 2022
commit 7159b0810a00168706b1797c0dcda0175e170e22
2 changes: 2 additions & 0 deletions lib/internal/bootstrap/loaders.js
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,8 @@ class NativeModule {
requireWithFallbackInDeps : nativeModuleRequire;

const fn = compileFunction(id);
// Arguments must match the parameters specified in
// NativeModuleLoader::LookupAndCompile().
fn(this.exports, requireFn, this, process, internalBinding, primordials);

this.loaded = true;
Expand Down
2 changes: 0 additions & 2 deletions lib/internal/main/.eslintrc.yaml

This file was deleted.

5 changes: 3 additions & 2 deletions lib/internal/main/check_syntax.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@

const { getOptionValue } = require('internal/options');
const {
prepareMainThreadExecution
} = require('internal/bootstrap/pre_execution');
prepareMainThreadExecution,
markBootstrapComplete
} = require('internal/process/pre_execution');

const {
readStdin
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
// that depends on run time states.
// It is currently only intended for preparing contexts for embedders.

/* global markBootstrapComplete */
const {
prepareMainThreadExecution
} = require('internal/bootstrap/pre_execution');
prepareMainThreadExecution,
markBootstrapComplete
} = require('internal/process/pre_execution');

prepareMainThreadExecution();
markBootstrapComplete();
5 changes: 3 additions & 2 deletions lib/internal/main/eval_stdin.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
// Stdin is not a TTY, we will read it and execute it.

const {
prepareMainThreadExecution
} = require('internal/bootstrap/pre_execution');
prepareMainThreadExecution,
markBootstrapComplete
} = require('internal/process/pre_execution');

const { getOptionValue } = require('internal/options');

Expand Down
5 changes: 3 additions & 2 deletions lib/internal/main/eval_string.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ const {
} = primordials;

const {
prepareMainThreadExecution
} = require('internal/bootstrap/pre_execution');
prepareMainThreadExecution,
markBootstrapComplete
} = require('internal/process/pre_execution');
const { evalModule, evalScript } = require('internal/process/execution');
const { addBuiltinLibsToObject } = require('internal/modules/cjs/helpers');

Expand Down
5 changes: 3 additions & 2 deletions lib/internal/main/inspect.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
// `node inspect ...` or `node debug ...`

const {
prepareMainThreadExecution
} = require('internal/bootstrap/pre_execution');
prepareMainThreadExecution,
markBootstrapComplete
} = require('internal/process/pre_execution');

prepareMainThreadExecution();

Expand Down
5 changes: 3 additions & 2 deletions lib/internal/main/print_help.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ const { types } = internalBinding('options');
const hasCrypto = Boolean(process.versions.openssl);

const {
prepareMainThreadExecution
} = require('internal/bootstrap/pre_execution');
prepareMainThreadExecution,
markBootstrapComplete
} = require('internal/process/pre_execution');

const typeLookup = [];
for (const key of ObjectKeys(types))
Expand Down
5 changes: 3 additions & 2 deletions lib/internal/main/prof_process.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
'use strict';

const {
prepareMainThreadExecution
} = require('internal/bootstrap/pre_execution');
prepareMainThreadExecution,
markBootstrapComplete
} = require('internal/process/pre_execution');

prepareMainThreadExecution();
markBootstrapComplete();
Expand Down
5 changes: 3 additions & 2 deletions lib/internal/main/repl.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
// the main module is not specified and stdin is a TTY.

const {
prepareMainThreadExecution
} = require('internal/bootstrap/pre_execution');
prepareMainThreadExecution,
markBootstrapComplete
} = require('internal/process/pre_execution');

const esmLoader = require('internal/process/esm_loader');
const {
Expand Down
5 changes: 3 additions & 2 deletions lib/internal/main/run_main_module.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
'use strict';

const {
prepareMainThreadExecution
} = require('internal/bootstrap/pre_execution');
prepareMainThreadExecution,
markBootstrapComplete
} = require('internal/process/pre_execution');

prepareMainThreadExecution(true);

Expand Down
3 changes: 2 additions & 1 deletion lib/internal/main/test_runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ const {
} = primordials;
const {
prepareMainThreadExecution,
} = require('internal/bootstrap/pre_execution');
markBootstrapComplete
} = require('internal/process/pre_execution');
const { spawn } = require('child_process');
const { readdirSync, statSync } = require('fs');
const console = require('internal/console/global');
Expand Down
5 changes: 3 additions & 2 deletions lib/internal/main/worker_thread.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ const {
initializeReport,
initializeSourceMapsHandlers,
loadPreloadModules,
setupTraceCategoryState
} = require('internal/bootstrap/pre_execution');
setupTraceCategoryState,
markBootstrapComplete
} = require('internal/process/pre_execution');

const {
threadId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,10 @@ function loadPreloadModules() {
}
}

function markBootstrapComplete() {
internalBinding('performance').markBootstrapComplete();
}

module.exports = {
refreshRuntimeOptions,
patchProcessObject,
Expand All @@ -616,5 +620,6 @@ module.exports = {
setupInspectorHooks,
initializeReport,
initializeCJSLoader,
initializeWASI
initializeWASI,
markBootstrapComplete
};
6 changes: 3 additions & 3 deletions lib/internal/v8/startup_snapshot.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ const {
setSerializeCallback,
setDeserializeCallback,
setDeserializeMainFunction: _setDeserializeMainFunction,
markBootstrapComplete
} = internalBinding('mksnapshot');

function isBuildingSnapshot() {
Expand Down Expand Up @@ -87,8 +86,9 @@ function setDeserializeMainFunction(callback, data) {

_setDeserializeMainFunction(function deserializeMain() {
const {
prepareMainThreadExecution
} = require('internal/bootstrap/pre_execution');
prepareMainThreadExecution,
markBootstrapComplete
} = require('internal/process/pre_execution');

// This should be in sync with run_main_module.js until we make that
// a built-in main function.
Expand Down
15 changes: 6 additions & 9 deletions src/api/environment.cc
Original file line number Diff line number Diff line change
Expand Up @@ -452,13 +452,12 @@ MaybeLocal<Value> LoadEnvironment(
native_module::NativeModuleLoader::Add(
name.c_str(), UnionBytes(**main_utf16, main_utf16->length()));
env->set_main_utf16(std::move(main_utf16));
std::vector<Local<String>> params = {
env->process_string(),
env->require_string()};
// Arguments must match the parameters specified in
// NativeModuleLoader::LookupAndCompile().
std::vector<Local<Value>> args = {
env->process_object(),
env->native_module_require()};
return ExecuteBootstrapper(env, name.c_str(), &params, &args);
return ExecuteBootstrapper(env, name.c_str(), &args);
});
}

Expand Down Expand Up @@ -683,8 +682,6 @@ Maybe<bool> InitializePrimordials(Local<Context> context) {

Local<String> primordials_string =
FIXED_ONE_BYTE_STRING(isolate, "primordials");
Local<String> global_string = FIXED_ONE_BYTE_STRING(isolate, "global");
Local<String> exports_string = FIXED_ONE_BYTE_STRING(isolate, "exports");

// Create primordials first and make it available to per-context scripts.
Local<Object> primordials = Object::New(isolate);
Expand All @@ -700,12 +697,12 @@ Maybe<bool> InitializePrimordials(Local<Context> context) {
nullptr};

for (const char** module = context_files; *module != nullptr; module++) {
std::vector<Local<String>> parameters = {
global_string, exports_string, primordials_string};
// Arguments must match the parameters specified in
// NativeModuleLoader::LookupAndCompile().
Local<Value> arguments[] = {context->Global(), exports, primordials};
MaybeLocal<Function> maybe_fn =
native_module::NativeModuleLoader::LookupAndCompile(
context, *module, &parameters, nullptr);
context, *module, nullptr);
Local<Function> fn;
if (!maybe_fn.ToLocal(&fn)) {
return Nothing<bool>();
Expand Down
67 changes: 20 additions & 47 deletions src/node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -170,11 +170,10 @@ void SignalExit(int signo, siginfo_t* info, void* ucontext) {

MaybeLocal<Value> ExecuteBootstrapper(Environment* env,
const char* id,
std::vector<Local<String>>* parameters,
std::vector<Local<Value>>* arguments) {
EscapableHandleScope scope(env->isolate());
MaybeLocal<Function> maybe_fn =
NativeModuleLoader::LookupAndCompile(env->context(), id, parameters, env);
NativeModuleLoader::LookupAndCompile(env->context(), id, env);

Local<Function> fn;
if (!maybe_fn.ToLocal(&fn)) {
Expand Down Expand Up @@ -293,12 +292,8 @@ void Environment::InitializeDiagnostics() {
MaybeLocal<Value> Environment::BootstrapInternalLoaders() {
EscapableHandleScope scope(isolate_);

// Create binding loaders
std::vector<Local<String>> loaders_params = {
process_string(),
FIXED_ONE_BYTE_STRING(isolate_, "getLinkedBinding"),
FIXED_ONE_BYTE_STRING(isolate_, "getInternalBinding"),
primordials_string()};
// Arguments must match the parameters specified in
// NativeModuleLoader::LookupAndCompile().
std::vector<Local<Value>> loaders_args = {
process_object(),
NewFunctionTemplate(isolate_, binding::GetLinkedBinding)
Expand All @@ -311,8 +306,7 @@ MaybeLocal<Value> Environment::BootstrapInternalLoaders() {

// Bootstrap internal loaders
Local<Value> loader_exports;
if (!ExecuteBootstrapper(
this, "internal/bootstrap/loaders", &loaders_params, &loaders_args)
if (!ExecuteBootstrapper(this, "internal/bootstrap/loaders", &loaders_args)
.ToLocal(&loader_exports)) {
return MaybeLocal<Value>();
}
Expand All @@ -334,28 +328,25 @@ MaybeLocal<Value> Environment::BootstrapInternalLoaders() {
MaybeLocal<Value> Environment::BootstrapNode() {
EscapableHandleScope scope(isolate_);

// Arguments must match the parameters specified in
// NativeModuleLoader::LookupAndCompile().
// process, require, internalBinding, primordials
std::vector<Local<String>> node_params = {
process_string(),
require_string(),
internal_binding_string(),
primordials_string()};
std::vector<Local<Value>> node_args = {
process_object(),
native_module_require(),
internal_binding_loader(),
primordials()};

MaybeLocal<Value> result = ExecuteBootstrapper(
this, "internal/bootstrap/node", &node_params, &node_args);
MaybeLocal<Value> result =
ExecuteBootstrapper(this, "internal/bootstrap/node", &node_args);

if (result.IsEmpty()) {
return MaybeLocal<Value>();
}

if (!no_browser_globals()) {
result = ExecuteBootstrapper(
this, "internal/bootstrap/browser", &node_params, &node_args);
result =
ExecuteBootstrapper(this, "internal/bootstrap/browser", &node_args);

if (result.IsEmpty()) {
return MaybeLocal<Value>();
Expand All @@ -366,8 +357,7 @@ MaybeLocal<Value> Environment::BootstrapNode() {
auto thread_switch_id =
is_main_thread() ? "internal/bootstrap/switches/is_main_thread"
: "internal/bootstrap/switches/is_not_main_thread";
result =
ExecuteBootstrapper(this, thread_switch_id, &node_params, &node_args);
result = ExecuteBootstrapper(this, thread_switch_id, &node_args);

if (result.IsEmpty()) {
return MaybeLocal<Value>();
Expand All @@ -377,8 +367,7 @@ MaybeLocal<Value> Environment::BootstrapNode() {
owns_process_state()
? "internal/bootstrap/switches/does_own_process_state"
: "internal/bootstrap/switches/does_not_own_process_state";
result = ExecuteBootstrapper(
this, process_state_switch_id, &node_params, &node_args);
result = ExecuteBootstrapper(this, process_state_switch_id, &node_args);

if (result.IsEmpty()) {
return MaybeLocal<Value>();
Expand Down Expand Up @@ -420,35 +409,20 @@ MaybeLocal<Value> Environment::RunBootstrapping() {
return scope.Escape(result);
}

void MarkBootstrapComplete(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
env->performance_state()->Mark(
performance::NODE_PERFORMANCE_MILESTONE_BOOTSTRAP_COMPLETE);
}

static
MaybeLocal<Value> StartExecution(Environment* env, const char* main_script_id) {
EscapableHandleScope scope(env->isolate());
CHECK_NOT_NULL(main_script_id);

std::vector<Local<String>> parameters = {
env->process_string(),
env->require_string(),
env->internal_binding_string(),
env->primordials_string(),
FIXED_ONE_BYTE_STRING(env->isolate(), "markBootstrapComplete")};

std::vector<Local<Value>> arguments = {
env->process_object(),
env->native_module_require(),
env->internal_binding_loader(),
env->primordials(),
NewFunctionTemplate(env->isolate(), MarkBootstrapComplete)
->GetFunction(env->context())
.ToLocalChecked()};
// Arguments must match the parameters specified in
// NativeModuleLoader::LookupAndCompile().
std::vector<Local<Value>> arguments = {env->process_object(),
env->native_module_require(),
env->internal_binding_loader(),
env->primordials()};

return scope.EscapeMaybe(
ExecuteBootstrapper(env, main_script_id, &parameters, &arguments));
ExecuteBootstrapper(env, main_script_id, &arguments));
}

MaybeLocal<Value> StartExecution(Environment* env, StartExecutionCallback cb) {
Expand All @@ -461,8 +435,7 @@ MaybeLocal<Value> StartExecution(Environment* env, StartExecutionCallback cb) {
if (cb != nullptr) {
EscapableHandleScope scope(env->isolate());

if (StartExecution(env, "internal/bootstrap/environment").IsEmpty())
return {};
if (StartExecution(env, "internal/main/environment").IsEmpty()) return {};

StartExecutionCallbackInfo info = {
env->process_object(),
Expand Down
1 change: 0 additions & 1 deletion src/node_internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,6 @@ v8::MaybeLocal<v8::Object> GetPerContextExports(v8::Local<v8::Context> context);
v8::MaybeLocal<v8::Value> ExecuteBootstrapper(
Environment* env,
const char* id,
std::vector<v8::Local<v8::String>>* parameters,
std::vector<v8::Local<v8::Value>>* arguments);
void MarkBootstrapComplete(const v8::FunctionCallbackInfo<v8::Value>& args);

Expand Down
Loading