diff options
author | Divy Srivastava <dj.srivastava23@gmail.com> | 2023-11-12 20:52:59 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-13 04:52:59 +0000 |
commit | 1ef617e8f3d48098e69e222b6eb6fe981aeca1c3 (patch) | |
tree | 8ab4fab5b5b248d51575e874f240c16fba4ae268 /runtime | |
parent | 39223f709bcb86069f3aa8eab7a4be80304128e6 (diff) |
perf: lazy bootstrap options - first pass (#21164)
Move most runtime options to be lazily loaded. Constant options will be
covered in a different PR.
Towards https://github.com/denoland/deno/issues/21133
Diffstat (limited to 'runtime')
-rw-r--r-- | runtime/js/06_util.js | 26 | ||||
-rw-r--r-- | runtime/js/98_global_scope.js | 43 | ||||
-rw-r--r-- | runtime/js/99_main.js | 113 | ||||
-rw-r--r-- | runtime/ops/bootstrap.rs | 61 | ||||
-rw-r--r-- | runtime/ops/mod.rs | 1 | ||||
-rw-r--r-- | runtime/web_worker.rs | 2 | ||||
-rw-r--r-- | runtime/worker.rs | 7 | ||||
-rw-r--r-- | runtime/worker_bootstrap.rs | 24 |
8 files changed, 133 insertions, 144 deletions
diff --git a/runtime/js/06_util.js b/runtime/js/06_util.js index 971957b7e..c9fd4befe 100644 --- a/runtime/js/06_util.js +++ b/runtime/js/06_util.js @@ -1,5 +1,7 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. +const core = globalThis.Deno.core; +const ops = core.ops; const primordials = globalThis.__bootstrap.primordials; const { Promise, @@ -14,18 +16,18 @@ const LogLevel = { Debug: 4, }; -let logLevel = 3; -let logSource = "JS"; +const logSource = "JS"; -function setLogLevel(level, source) { - logLevel = level; - if (source) { - logSource = source; +let logLevel_ = null; +function logLevel() { + if (logLevel_ === null) { + logLevel_ = ops.op_bootstrap_log_level() || 3; } + return logLevel_; } function log(...args) { - if (logLevel >= LogLevel.Debug) { + if (logLevel() >= LogLevel.Debug) { // if we destructure `console` off `globalThis` too early, we don't bind to // the right console, therefore we don't log anything out. globalThis.console.error( @@ -83,12 +85,4 @@ function getterOnly(getter) { }; } -export { - createResolvable, - getterOnly, - log, - nonEnumerable, - readOnly, - setLogLevel, - writable, -}; +export { createResolvable, getterOnly, log, nonEnumerable, readOnly, writable }; diff --git a/runtime/js/98_global_scope.js b/runtime/js/98_global_scope.js index 6c650da10..aada57d70 100644 --- a/runtime/js/98_global_scope.js +++ b/runtime/js/98_global_scope.js @@ -1,6 +1,7 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. const core = globalThis.Deno.core; +const ops = core.ops; const primordials = globalThis.__bootstrap.primordials; const { ObjectDefineProperties, @@ -157,19 +158,19 @@ class Navigator { const navigator = webidl.createBranded(Navigator); -let numCpus, userAgent, language; - -function setNumCpus(val) { - numCpus = val; -} - -function setUserAgent(val) { - userAgent = val; +function memoizeLazy(f) { + let v_ = null; + return () => { + if (v_ === null) { + v_ = f(); + } + return v_; + }; } -function setLanguage(val) { - language = val; -} +const numCpus = memoizeLazy(() => ops.op_bootstrap_numcpus()); +const userAgent = memoizeLazy(() => ops.op_bootstrap_user_agent()); +const language = memoizeLazy(() => ops.op_bootstrap_language()); ObjectDefineProperties(Navigator.prototype, { hardwareConcurrency: { @@ -177,7 +178,7 @@ ObjectDefineProperties(Navigator.prototype, { enumerable: true, get() { webidl.assertBranded(this, NavigatorPrototype); - return numCpus; + return numCpus(); }, }, userAgent: { @@ -185,7 +186,7 @@ ObjectDefineProperties(Navigator.prototype, { enumerable: true, get() { webidl.assertBranded(this, NavigatorPrototype); - return userAgent; + return userAgent(); }, }, language: { @@ -193,7 +194,7 @@ ObjectDefineProperties(Navigator.prototype, { enumerable: true, get() { webidl.assertBranded(this, NavigatorPrototype); - return language; + return language(); }, }, languages: { @@ -201,7 +202,7 @@ ObjectDefineProperties(Navigator.prototype, { enumerable: true, get() { webidl.assertBranded(this, NavigatorPrototype); - return [language]; + return [language()]; }, }, }); @@ -225,7 +226,7 @@ ObjectDefineProperties(WorkerNavigator.prototype, { enumerable: true, get() { webidl.assertBranded(this, WorkerNavigatorPrototype); - return numCpus; + return numCpus(); }, }, userAgent: { @@ -233,7 +234,7 @@ ObjectDefineProperties(WorkerNavigator.prototype, { enumerable: true, get() { webidl.assertBranded(this, WorkerNavigatorPrototype); - return userAgent; + return userAgent(); }, }, language: { @@ -241,7 +242,7 @@ ObjectDefineProperties(WorkerNavigator.prototype, { enumerable: true, get() { webidl.assertBranded(this, WorkerNavigatorPrototype); - return language; + return language(); }, }, languages: { @@ -249,7 +250,7 @@ ObjectDefineProperties(WorkerNavigator.prototype, { enumerable: true, get() { webidl.assertBranded(this, WorkerNavigatorPrototype); - return [language]; + return [language()]; }, }, }); @@ -284,9 +285,7 @@ const workerRuntimeGlobalProperties = { export { mainRuntimeGlobalProperties, - setLanguage, - setNumCpus, - setUserAgent, + memoizeLazy, unstableWindowOrWorkerGlobalScope, windowOrWorkerGlobalScope, workerRuntimeGlobalProperties, diff --git a/runtime/js/99_main.js b/runtime/js/99_main.js index b06cef651..06a7d605d 100644 --- a/runtime/js/99_main.js +++ b/runtime/js/99_main.js @@ -26,7 +26,6 @@ const { ObjectAssign, ObjectDefineProperties, ObjectDefineProperty, - ObjectFreeze, ObjectPrototypeIsPrototypeOf, ObjectSetPrototypeOf, PromisePrototypeThen, @@ -50,7 +49,7 @@ import { getNoColor, inspectArgs, quoteString, - setNoColor, + setNoColorFn, wrapConsole, } from "ext:deno_console/01_console.js"; import * as performance from "ext:deno_web/15_performance.js"; @@ -67,9 +66,7 @@ import * as webidl from "ext:deno_webidl/00_webidl.js"; import DOMException from "ext:deno_web/01_dom_exception.js"; import { mainRuntimeGlobalProperties, - setLanguage, - setNumCpus, - setUserAgent, + memoizeLazy, unstableWindowOrWorkerGlobalScope, windowOrWorkerGlobalScope, workerRuntimeGlobalProperties, @@ -241,6 +238,11 @@ function opMainModule() { return ops.op_main_module(); } +const opArgs = memoizeLazy(() => ops.op_bootstrap_args()); +const opPid = memoizeLazy(() => ops.op_bootstrap_pid()); +const opPpid = memoizeLazy(() => ops.op_ppid()); +setNoColorFn(() => ops.op_bootstrap_no_color()); + function formatException(error) { if (ObjectPrototypeIsPrototypeOf(ErrorPrototype, error)) { return null; @@ -327,10 +329,6 @@ function runtimeStart( v8Version, tsVersion, target, - logLevel, - noColor, - isTty, - source, ) { core.setMacrotaskCallback(timers.handleTimerMacrotask); core.setMacrotaskCallback(promiseRejectMacrotaskCallback); @@ -343,8 +341,6 @@ function runtimeStart( tsVersion, ); core.setBuildInfo(target); - util.setLogLevel(logLevel, source); - setNoColor(noColor || !isTty); } const pendingRejections = []; @@ -461,25 +457,16 @@ function bootstrapMainRuntime(runtimeOptions) { const nodeBootstrap = globalThis.nodeBootstrap; const { - 0: args, - 1: cpuCount, - 2: logLevel, - 3: denoVersion, - 4: locale, - 5: location_, - 6: noColor, - 7: isTty, - 8: tsVersion, - 9: unstableFlag, - 10: unstableFeatures, - 11: pid, - 12: target, - 13: v8Version, - 14: userAgent, - 15: inspectFlag, - // 16: enableTestingFeaturesFlag - 17: hasNodeModulesDir, - 18: maybeBinaryNpmCommandName, + 0: denoVersion, + 1: location_, + 2: tsVersion, + 3: unstableFlag, + 4: unstableFeatures, + 5: target, + 6: v8Version, + 7: inspectFlag, + 9: hasNodeModulesDir, + 10: maybeBinaryNpmCommandName, } = runtimeOptions; performance.setTimeOrigin(DateNow()); @@ -538,27 +525,13 @@ function bootstrapMainRuntime(runtimeOptions) { v8Version, tsVersion, target, - logLevel, - noColor, - isTty, ); - setNumCpus(cpuCount); - setUserAgent(userAgent); - setLanguage(locale); - - let ppid = undefined; ObjectDefineProperties(finalDenoNs, { - pid: util.readOnly(pid), - ppid: util.getterOnly(() => { - // lazy because it's expensive - if (ppid === undefined) { - ppid = ops.op_ppid(); - } - return ppid; - }), - noColor: util.readOnly(noColor), - args: util.readOnly(ObjectFreeze(args)), + pid: util.getterOnly(opPid), + ppid: util.getterOnly(opPpid), + noColor: util.getterOnly(getNoColor), + args: util.getterOnly(opArgs), mainModule: util.getterOnly(opMainModule), }); @@ -593,8 +566,6 @@ function bootstrapMainRuntime(runtimeOptions) { // `Deno` with `Deno` namespace from "./deno.ts". ObjectDefineProperty(globalThis, "Deno", util.readOnly(finalDenoNs)); - util.log("args", args); - if (nodeBootstrap) { nodeBootstrap(hasNodeModulesDir, maybeBinaryNpmCommandName); } @@ -612,25 +583,16 @@ function bootstrapWorkerRuntime( const nodeBootstrap = globalThis.nodeBootstrap; const { - 0: args, - 1: cpuCount, - 2: logLevel, - 3: denoVersion, - 4: locale, - 5: location_, - 6: noColor, - 7: isTty, - 8: tsVersion, - 9: unstableFlag, - 10: unstableFeatures, - 11: pid, - 12: target, - 13: v8Version, - 14: userAgent, - // 15: inspectFlag, - 16: enableTestingFeaturesFlag, - 17: hasNodeModulesDir, - 18: maybeBinaryNpmCommandName, + 0: denoVersion, + 1: location_, + 2: tsVersion, + 3: unstableFlag, + 4: unstableFeatures, + 5: target, + 6: v8Version, + 8: enableTestingFeaturesFlag, + 9: hasNodeModulesDir, + 10: maybeBinaryNpmCommandName, } = runtimeOptions; performance.setTimeOrigin(DateNow()); @@ -686,18 +648,11 @@ function bootstrapWorkerRuntime( v8Version, tsVersion, target, - logLevel, - noColor, - isTty, internalName ?? name, ); location.setLocationHref(location_); - setNumCpus(cpuCount); - setUserAgent(userAgent); - setLanguage(locale); - globalThis.pollForMessages = pollForMessages; // TODO(bartlomieju): deprecate --unstable @@ -710,9 +665,9 @@ function bootstrapWorkerRuntime( } } ObjectDefineProperties(finalDenoNs, { - pid: util.readOnly(pid), - noColor: util.readOnly(noColor), - args: util.readOnly(ObjectFreeze(args)), + pid: util.getterOnly(opPid), + noColor: util.getterOnly(getNoColor), + args: util.getterOnly(opArgs), }); // Setup `Deno` global - we're actually overriding already // existing global `Deno` with `Deno` namespace from "./deno.ts". diff --git a/runtime/ops/bootstrap.rs b/runtime/ops/bootstrap.rs new file mode 100644 index 000000000..1b86a7509 --- /dev/null +++ b/runtime/ops/bootstrap.rs @@ -0,0 +1,61 @@ +// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. + +use deno_core::op2; +use deno_core::OpState; + +use crate::BootstrapOptions; + +deno_core::extension!( + deno_bootstrap, + ops = [ + op_bootstrap_args, + op_bootstrap_pid, + op_bootstrap_numcpus, + op_bootstrap_user_agent, + op_bootstrap_language, + op_bootstrap_log_level, + op_bootstrap_no_color, + ], +); + +#[op2] +#[serde] +pub fn op_bootstrap_args(state: &mut OpState) -> Vec<String> { + state.borrow::<BootstrapOptions>().args.clone() +} + +#[op2(fast)] +#[smi] +pub fn op_bootstrap_pid() -> u32 { + std::process::id() +} + +#[op2(fast)] +#[smi] +pub fn op_bootstrap_numcpus(state: &mut OpState) -> u32 { + state.borrow::<BootstrapOptions>().cpu_count as u32 +} + +#[op2] +#[string] +pub fn op_bootstrap_user_agent(state: &mut OpState) -> String { + state.borrow::<BootstrapOptions>().user_agent.clone() +} + +#[op2] +#[string] +pub fn op_bootstrap_language(state: &mut OpState) -> String { + state.borrow::<BootstrapOptions>().locale.clone() +} + +#[op2(fast)] +#[smi] +pub fn op_bootstrap_log_level(state: &mut OpState) -> i32 { + state.borrow::<BootstrapOptions>().log_level as i32 +} + +#[op2(fast)] +pub fn op_bootstrap_no_color(state: &mut OpState) -> bool { + let options = state.borrow::<BootstrapOptions>(); + options.no_color || !options.is_tty +} diff --git a/runtime/ops/mod.rs b/runtime/ops/mod.rs index bafa6c571..0d285a808 100644 --- a/runtime/ops/mod.rs +++ b/runtime/ops/mod.rs @@ -1,5 +1,6 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. +pub mod bootstrap; pub mod fs_events; pub mod http; pub mod os; diff --git a/runtime/web_worker.rs b/runtime/web_worker.rs index 1a1bc2431..54cafe87b 100644 --- a/runtime/web_worker.rs +++ b/runtime/web_worker.rs @@ -476,6 +476,7 @@ impl WebWorker { ops::signal::deno_signal::init_ops_and_esm(), ops::tty::deno_tty::init_ops_and_esm(), ops::http::deno_http_runtime::init_ops_and_esm(), + ops::bootstrap::deno_bootstrap::init_ops_and_esm(), deno_permissions_web_worker::init_ops_and_esm( permissions, enable_testing_features, @@ -608,6 +609,7 @@ impl WebWorker { } pub fn bootstrap(&mut self, options: &BootstrapOptions) { + self.js_runtime.op_state().borrow_mut().put(options.clone()); // Instead of using name for log we use `worker-${id}` because // WebWorkers can have empty string as name. { diff --git a/runtime/worker.rs b/runtime/worker.rs index d551af782..9a9802c12 100644 --- a/runtime/worker.rs +++ b/runtime/worker.rs @@ -264,7 +264,7 @@ impl MainWorker { ) -> Self { let bootstrap_options = options.bootstrap.clone(); let mut worker = Self::from_options(main_module, permissions, options); - worker.bootstrap(&bootstrap_options); + worker.bootstrap(bootstrap_options); worker } @@ -380,6 +380,7 @@ impl MainWorker { ops::signal::deno_signal::init_ops_and_esm(), ops::tty::deno_tty::init_ops_and_esm(), ops::http::deno_http_runtime::init_ops_and_esm(), + ops::bootstrap::deno_bootstrap::init_ops_and_esm(), deno_permissions_worker::init_ops_and_esm( permissions, enable_testing_features, @@ -454,7 +455,6 @@ impl MainWorker { let inspector = js_runtime.inspector(); op_state.borrow_mut().put(inspector); } - let bootstrap_fn_global = { let context = js_runtime.main_context(); let scope = &mut js_runtime.handle_scope(); @@ -486,7 +486,8 @@ impl MainWorker { } } - pub fn bootstrap(&mut self, options: &BootstrapOptions) { + pub fn bootstrap(&mut self, options: BootstrapOptions) { + self.js_runtime.op_state().borrow_mut().put(options.clone()); let scope = &mut self.js_runtime.handle_scope(); let args = options.as_v8(scope); let bootstrap_fn = self.bootstrap_fn_global.take().unwrap(); diff --git a/runtime/worker_bootstrap.rs b/runtime/worker_bootstrap.rs index 9f2393ba4..3bcf45dd0 100644 --- a/runtime/worker_bootstrap.rs +++ b/runtime/worker_bootstrap.rs @@ -107,36 +107,20 @@ impl Default for BootstrapOptions { /// Keep this in sync with `99_main.js`. #[derive(Serialize)] struct BootstrapV8<'a>( - // args - &'a Vec<String>, - // cpu_count - i32, - // log_level - i32, // runtime_version &'a str, - // locale - &'a str, // location Option<&'a str>, - // no_color - bool, - // is_tty - bool, // ts_version &'a str, // unstable bool, // granular unstable flags &'a [i32], - // process_id - i32, // env!("TARGET") &'a str, // v8_version &'a str, - // user_agent - &'a str, // inspect bool, // enable_testing_features @@ -157,21 +141,13 @@ impl BootstrapOptions { let ser = deno_core::serde_v8::Serializer::new(&scope); let bootstrap = BootstrapV8( - &self.args, - self.cpu_count as _, - self.log_level as _, &self.runtime_version, - &self.locale, self.location.as_ref().map(|l| l.as_str()), - self.no_color, - self.is_tty, &self.ts_version, self.unstable, self.unstable_features.as_ref(), - std::process::id() as _, env!("TARGET"), deno_core::v8_version(), - &self.user_agent, self.inspect, self.enable_testing_features, self.has_node_modules_dir, |