From a1764f7690cfdc3e42724fcad29ef954b7e576a4 Mon Sep 17 00:00:00 2001 From: Matt Mastracci Date: Tue, 4 Apr 2023 06:46:31 -0600 Subject: refactor(core): Improve ergonomics of managing ASCII strings (#18498) This is a follow-on to the earlier work in reducing string copies, mainly focused on ensuring that ASCII strings are easy to provide to the JS runtime. While we are replacing a 16-byte reference in a number of places with a 24-byte structure (measured via `std::mem::size_of`), the reduction in copies wins out over the additional size of the arguments passed into functions. Benchmarking shows approximately the same if not slightly less wallclock time/instructions retired, but I believe this continues to open up further refactoring opportunities. --- runtime/build.rs | 2 +- runtime/web_worker.rs | 13 ++++++++----- runtime/worker.rs | 17 ++++++++++------- 3 files changed, 19 insertions(+), 13 deletions(-) (limited to 'runtime') diff --git a/runtime/build.rs b/runtime/build.rs index 809e32a76..eb8cc34a6 100644 --- a/runtime/build.rs +++ b/runtime/build.rs @@ -42,7 +42,7 @@ mod startup_snapshot { let parsed = deno_ast::parse_module(ParseParams { specifier: file_source.specifier.to_string(), - text_info: SourceTextInfo::from_string(code.take_as_string()), + text_info: SourceTextInfo::from_string(code.as_str().to_owned()), media_type, capture_tokens: false, scope_analysis: false, diff --git a/runtime/web_worker.rs b/runtime/web_worker.rs index 8bd5cf21e..4be40c9b0 100644 --- a/runtime/web_worker.rs +++ b/runtime/web_worker.rs @@ -9,6 +9,7 @@ use crate::BootstrapOptions; use deno_broadcast_channel::InMemoryBroadcastChannel; use deno_cache::CreateCache; use deno_cache::SqliteBackedCache; +use deno_core::ascii_str; use deno_core::error::AnyError; use deno_core::error::JsError; use deno_core::futures::channel::mpsc; @@ -572,11 +573,13 @@ impl WebWorker { // TODO(bartlomieju): this could be done using V8 API, without calling `execute_script`. // Save a reference to function that will start polling for messages // from a worker host; it will be called after the user code is loaded. - let script = r#" + let script = ascii_str!( + r#" const pollForMessages = globalThis.pollForMessages; delete globalThis.pollForMessages; pollForMessages - "#; + "# + ); let poll_for_messages_fn = self .js_runtime .execute_script(located_script_name!(), script) @@ -585,10 +588,10 @@ impl WebWorker { } /// See [JsRuntime::execute_script](deno_core::JsRuntime::execute_script) - pub fn execute_script>( + pub fn execute_script( &mut self, name: &'static str, - source_code: S, + source_code: ModuleCode, ) -> Result<(), AnyError> { self.js_runtime.execute_script(name, source_code)?; Ok(()) @@ -777,7 +780,7 @@ pub fn run_web_worker( // Execute provided source code immediately let result = if let Some(source_code) = maybe_source_code.take() { - let r = worker.execute_script(located_script_name!(), source_code); + let r = worker.execute_script(located_script_name!(), source_code.into()); worker.start_polling_for_messages(); r } else { diff --git a/runtime/worker.rs b/runtime/worker.rs index 48bf7b09f..ea1e5e046 100644 --- a/runtime/worker.rs +++ b/runtime/worker.rs @@ -11,6 +11,7 @@ use std::task::Poll; use deno_broadcast_channel::InMemoryBroadcastChannel; use deno_cache::CreateCache; use deno_cache::SqliteBackedCache; +use deno_core::ascii_str; use deno_core::error::AnyError; use deno_core::error::JsError; use deno_core::futures::Future; @@ -370,10 +371,10 @@ impl MainWorker { } /// See [JsRuntime::execute_script](deno_core::JsRuntime::execute_script) - pub fn execute_script>( + pub fn execute_script( &mut self, script_name: &'static str, - source_code: S, + source_code: ModuleCode, ) -> Result, AnyError> { self.js_runtime.execute_script(script_name, source_code) } @@ -510,12 +511,12 @@ impl MainWorker { &mut self, script_name: &'static str, ) -> Result<(), AnyError> { - self.execute_script( + self.js_runtime.execute_script( script_name, // NOTE(@bartlomieju): not using `globalThis` here, because user might delete // it. Instead we're using global `dispatchEvent` function which will // used a saved reference to global scope. - "dispatchEvent(new Event('load'))", + ascii_str!("dispatchEvent(new Event('load'))"), )?; Ok(()) } @@ -527,12 +528,12 @@ impl MainWorker { &mut self, script_name: &'static str, ) -> Result<(), AnyError> { - self.execute_script( + self.js_runtime.execute_script( script_name, // NOTE(@bartlomieju): not using `globalThis` here, because user might delete // it. Instead we're using global `dispatchEvent` function which will // used a saved reference to global scope. - "dispatchEvent(new Event('unload'))", + ascii_str!("dispatchEvent(new Event('unload'))"), )?; Ok(()) } @@ -549,7 +550,9 @@ impl MainWorker { // NOTE(@bartlomieju): not using `globalThis` here, because user might delete // it. Instead we're using global `dispatchEvent` function which will // used a saved reference to global scope. - "dispatchEvent(new Event('beforeunload', { cancelable: true }));", + ascii_str!( + "dispatchEvent(new Event('beforeunload', { cancelable: true }));" + ), )?; let local_value = value.open(&mut self.js_runtime.handle_scope()); Ok(local_value.is_false()) -- cgit v1.2.3