Skip to content

Commit

Permalink
bootstrap: support more builtins in the embedded code cache
Browse files Browse the repository at this point in the history
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.

PR-URL: #44018
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
  • Loading branch information
joyeecheung authored and ruyadorno committed Aug 22, 2022
1 parent 116dccc commit e7d101f
Show file tree
Hide file tree
Showing 27 changed files with 156 additions and 137 deletions.
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
4 changes: 2 additions & 2 deletions lib/internal/bootstrap/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//
// This file is expected not to perform any asynchronous operations itself
// when being executed - those should be done in either
// `lib/internal/bootstrap/pre_execution.js` or in main scripts. The majority
// `lib/internal/process/pre_execution.js` or in main scripts. The majority
// of the code here focuses on setting up the global proxy and the process
// object in a synchronous manner.
// As special caution is given to the performance of the startup process,
Expand All @@ -28,7 +28,7 @@
// Then, depending on how the Node.js instance is launched, one of the main
// scripts in `lib/internal/main` will be selected by C++ to start the actual
// execution. They may run additional setups exported by
// `lib/internal/bootstrap/pre_execution.js` depending on the runtime states.
// `lib/internal/process/pre_execution.js` depending on the runtime states.

'use strict';

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 @@ -4,8 +4,9 @@
// instead of actually running the file.

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
2 changes: 1 addition & 1 deletion lib/internal/main/mksnapshot.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ function requireForUserSnapshot(id) {
function main() {
const {
prepareMainThreadExecution
} = require('internal/bootstrap/pre_execution');
} = require('internal/process/pre_execution');

prepareMainThreadExecution(true, false);

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 @@ -572,6 +572,10 @@ function loadPreloadModules() {
}
}

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

module.exports = {
refreshRuntimeOptions,
patchProcessObject,
Expand All @@ -592,5 +596,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
2 changes: 1 addition & 1 deletion lib/internal/wasm_web_api.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ function lazyUndici() {

// This is essentially an implementation of a v8::WasmStreamingCallback, except
// that it is implemented in JavaScript because the fetch() implementation is
// difficult to use from C++. See lib/internal/bootstrap/pre_execution.js and
// difficult to use from C++. See lib/internal/process/pre_execution.js and
// src/node_wasm_web_api.cc that interact with this function.
function wasmStreamingCallback(streamState, source) {
(async () => {
Expand Down
15 changes: 6 additions & 9 deletions src/api/environment.cc
Original file line number Diff line number Diff line change
Expand Up @@ -445,13 +445,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 @@ -676,8 +675,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 @@ -693,12 +690,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

0 comments on commit e7d101f

Please sign in to comment.