Skip to content

Commit

Permalink
bootstrap: optimize modules loaded in the built-in snapshot
Browse files Browse the repository at this point in the history
Preload essential modules and lazy-load non-essential ones.
After this patch, all modules listed by running this snippet:

```
const list = process.moduleLoadList.join('\n');
require('fs').writeSync(1, list, 'utf-8');
```

(which is roughly the same list as the one in
test-bootstrap-module.js for the main thread)
are loaded from the snapshot so no additional compilation cost
is incurred.

PR-URL: nodejs/node#45849
Backport-PR-URL: nodejs/node#46425
Reviewed-By: Geoffrey Booth <[email protected]>
Reviewed-By: Chengzhong Wu <[email protected]>
  • Loading branch information
sercher committed Apr 25, 2024
1 parent 8ce4419 commit 5bcddbb
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 12 deletions.
29 changes: 29 additions & 0 deletions graal-nodejs/lib/internal/bootstrap/switches/is_main_thread.js
Original file line number Diff line number Diff line change
Expand Up @@ -286,3 +286,32 @@ rawMethods.resetStdioForTesting = function() {
stdout = undefined;
stderr = undefined;
};

// Needed by the module loader and generally needed everywhere.
require('fs');
require('util');
require('url');

require('internal/modules/cjs/loader');
require('internal/modules/esm/utils');
require('internal/vm/module');
// Needed to refresh the time origin.
require('internal/perf/utils');
// Needed to register the async hooks.
if (internalBinding('config').hasInspector) {
require('internal/inspector_async_hook');
}
// Needed to set the wasm web API callbacks.
internalBinding('wasm_web_api');
// Needed to detect whether it's on main thread.
internalBinding('worker');
// Needed to setup source maps.
require('internal/source_map/source_map_cache');
// Needed by most execution modes.
require('internal/modules/run_main');
// Needed to refresh DNS configurations.
require('internal/dns/utils');
// Needed by almost all execution modes. It's fine to
// load them into the snapshot as long as we don't run
// any of the initialization.
require('internal/process/pre_execution');
18 changes: 9 additions & 9 deletions graal-nodejs/lib/internal/process/pre_execution.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ const {

const {
getOptionValue,
getEmbedderOptions,
refreshOptions,
} = require('internal/options');
const { reconnectZeroFillToggle } = require('internal/buffer');
Expand Down Expand Up @@ -74,6 +73,7 @@ function prepareExecution(options) {
initializeReport();
initializeSourceMapsHandlers();
initializeDeprecations();

require('internal/dns/utils').initializeDns();

setupSymbolDisposePolyfill();
Expand Down Expand Up @@ -275,8 +275,9 @@ function setupFetch() {
}

// The WebAssembly Web API: https://webassembly.github.io/spec/web-api
const { wasmStreamingCallback } = require('internal/wasm_web_api');
internalBinding('wasm_web_api').setImplementation(wasmStreamingCallback);
internalBinding('wasm_web_api').setImplementation((streamState, source) => {
require('internal/wasm_web_api').wasmStreamingCallback(streamState, source);
});
require('internal/graal/wasm');
}

Expand Down Expand Up @@ -334,12 +335,12 @@ function setupStacktracePrinterOnSigint() {
}

function initializeReport() {
const { report } = require('internal/process/report');
ObjectDefineProperty(process, 'report', {
__proto__: null,
enumerable: true,
configurable: true,
get() {
const { report } = require('internal/process/report');
return report;
},
});
Expand All @@ -354,9 +355,10 @@ function setupDebugEnv() {

// This has to be called after initializeReport() is called
function initializeReportSignalHandlers() {
const { addSignalHandler } = require('internal/process/report');

addSignalHandler();
if (getOptionValue('--report-on-signal')) {
const { addSignalHandler } = require('internal/process/report');
addSignalHandler();
}
}

function initializeHeapSnapshotSignalHandlers() {
Expand Down Expand Up @@ -555,8 +557,6 @@ function initializeCJSLoader() {
}

function initializeESMLoader() {
if (getEmbedderOptions().shouldNotRegisterESMLoader) return;

const { initializeESM } = require('internal/modules/esm/utils');
initializeESM();

Expand Down
3 changes: 0 additions & 3 deletions graal-nodejs/test/parallel/test-bootstrap-modules.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ const expectedModules = new Set([
'Internal Binding options',
'Internal Binding performance',
'Internal Binding process_methods',
'Internal Binding report',
'Internal Binding string_decoder',
'Internal Binding symbols',
'Internal Binding task_queue',
Expand Down Expand Up @@ -66,7 +65,6 @@ const expectedModules = new Set([
'NativeModule internal/process/per_thread',
'NativeModule internal/process/pre_execution',
'NativeModule internal/process/promises',
'NativeModule internal/process/report',
'NativeModule internal/process/signal',
'NativeModule internal/process/task_queues',
'NativeModule internal/process/warning',
Expand All @@ -81,7 +79,6 @@ const expectedModules = new Set([
'NativeModule internal/validators',
'NativeModule internal/vm',
'NativeModule internal/vm/module',
'NativeModule internal/wasm_web_api',
'NativeModule internal/webidl',
'NativeModule internal/worker/js_transferable',
'Internal Binding blob',
Expand Down

0 comments on commit 5bcddbb

Please sign in to comment.