From 5bcddbbc14c453b369931d01c51541beff76d735 Mon Sep 17 00:00:00 2001 From: Sergey Chernyshev Date: Thu, 25 Apr 2024 01:48:29 +0200 Subject: [PATCH] bootstrap: optimize modules loaded in the built-in snapshot 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: https://github.com/nodejs/node/pull/45849 Backport-PR-URL: https://github.com/nodejs/node/pull/46425 Reviewed-By: Geoffrey Booth Reviewed-By: Chengzhong Wu --- .../bootstrap/switches/is_main_thread.js | 29 +++++++++++++++++++ .../lib/internal/process/pre_execution.js | 18 ++++++------ .../test/parallel/test-bootstrap-modules.js | 3 -- 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/graal-nodejs/lib/internal/bootstrap/switches/is_main_thread.js b/graal-nodejs/lib/internal/bootstrap/switches/is_main_thread.js index ace7dc1c904..212a067e3a7 100644 --- a/graal-nodejs/lib/internal/bootstrap/switches/is_main_thread.js +++ b/graal-nodejs/lib/internal/bootstrap/switches/is_main_thread.js @@ -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'); diff --git a/graal-nodejs/lib/internal/process/pre_execution.js b/graal-nodejs/lib/internal/process/pre_execution.js index bd446d7562c..6ab08e3f7e4 100644 --- a/graal-nodejs/lib/internal/process/pre_execution.js +++ b/graal-nodejs/lib/internal/process/pre_execution.js @@ -14,7 +14,6 @@ const { const { getOptionValue, - getEmbedderOptions, refreshOptions, } = require('internal/options'); const { reconnectZeroFillToggle } = require('internal/buffer'); @@ -74,6 +73,7 @@ function prepareExecution(options) { initializeReport(); initializeSourceMapsHandlers(); initializeDeprecations(); + require('internal/dns/utils').initializeDns(); setupSymbolDisposePolyfill(); @@ -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'); } @@ -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; }, }); @@ -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() { @@ -555,8 +557,6 @@ function initializeCJSLoader() { } function initializeESMLoader() { - if (getEmbedderOptions().shouldNotRegisterESMLoader) return; - const { initializeESM } = require('internal/modules/esm/utils'); initializeESM(); diff --git a/graal-nodejs/test/parallel/test-bootstrap-modules.js b/graal-nodejs/test/parallel/test-bootstrap-modules.js index bf5ae0bdb41..41f3f95fd6b 100644 --- a/graal-nodejs/test/parallel/test-bootstrap-modules.js +++ b/graal-nodejs/test/parallel/test-bootstrap-modules.js @@ -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', @@ -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', @@ -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',