Skip to content

Commit

Permalink
Reduce script copies
Browse files Browse the repository at this point in the history
  • Loading branch information
mmastrac committed Mar 21, 2023
1 parent 4c34a2f commit b96a592
Show file tree
Hide file tree
Showing 18 changed files with 356 additions and 118 deletions.
5 changes: 3 additions & 2 deletions bench_util/js_runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ pub fn bench_js_async_with(
opts.benching_inner
};
let looped = loop_code(inner_iters, src);
let src = looped.as_ref();
// Get a &'static str by leaking -- this is fine because it's benchmarking code
let src = Box::leak(looped.into_boxed_str());
if is_profiling() {
for _ in 0..opts.profiling_outer {
tokio_runtime.block_on(inner_async(src, &mut runtime));
Expand All @@ -115,7 +116,7 @@ pub fn bench_js_async_with(
}
}

async fn inner_async(src: &str, runtime: &mut JsRuntime) {
async fn inner_async(src: &'static str, runtime: &mut JsRuntime) {
runtime.execute_script("inner_loop", src).unwrap();
runtime.run_event_loop(false).await.unwrap();
}
7 changes: 4 additions & 3 deletions cli/emit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::cache::FastInsecureHasher;
use crate::cache::ParsedSourceCache;

use deno_core::error::AnyError;
use deno_core::ModuleCode;
use deno_core::ModuleSpecifier;
use deno_graph::MediaType;
use std::sync::Arc;
Expand All @@ -27,11 +28,11 @@ pub fn emit_parsed_source(
source: &Arc<str>,
emit_options: &deno_ast::EmitOptions,
emit_config_hash: u64,
) -> Result<String, AnyError> {
) -> Result<ModuleCode, AnyError> {
let source_hash = get_source_hash(source, emit_config_hash);

if let Some(emit_code) = emit_cache.get_emit_code(specifier, source_hash) {
Ok(emit_code)
Ok(emit_code.into())
} else {
// this will use a cached version if it exists
let parsed_source = parsed_source_cache.get_or_parse_module(
Expand All @@ -42,6 +43,6 @@ pub fn emit_parsed_source(
let transpiled_source = parsed_source.transpile(emit_options)?;
debug_assert!(transpiled_source.source_map.is_none());
emit_cache.set_emit_code(specifier, source_hash, &transpiled_source.text);
Ok(transpiled_source.text)
Ok(transpiled_source.text.into())
}
}
4 changes: 2 additions & 2 deletions cli/lsp/tsc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2854,7 +2854,7 @@ fn start(runtime: &mut JsRuntime, debug: bool) -> Result<(), AnyError> {
let init_config = json!({ "debug": debug });
let init_src = format!("globalThis.serverInit({init_config});");

runtime.execute_script(&located_script_name!(), &init_src)?;
runtime.execute_script(&located_script_name!(), init_src)?;
Ok(())
}

Expand Down Expand Up @@ -3442,7 +3442,7 @@ pub fn request(
};
let mark = performance.mark("request", Some(request_params.clone()));
let request_src = format!("globalThis.serverRequest({request_params});");
runtime.execute_script(&located_script_name!(), &request_src)?;
runtime.execute_script(&located_script_name!(), request_src)?;

let op_state = runtime.op_state();
let mut op_state = op_state.borrow_mut();
Expand Down
19 changes: 11 additions & 8 deletions cli/module_loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use deno_core::error::AnyError;
use deno_core::futures::future::FutureExt;
use deno_core::futures::Future;
use deno_core::resolve_url;
use deno_core::ModuleCode;
use deno_core::ModuleLoader;
use deno_core::ModuleSource;
use deno_core::ModuleSpecifier;
Expand All @@ -30,7 +31,7 @@ use std::rc::Rc;
use std::str;

struct ModuleCodeSource {
pub code: String,
pub code: ModuleCode,
pub found_url: ModuleSpecifier,
pub media_type: MediaType,
}
Expand Down Expand Up @@ -91,7 +92,7 @@ impl CliModuleLoader {
specifier,
..
})) => Ok(ModuleCodeSource {
code: source.to_string(),
code: source.into(),
found_url: specifier.clone(),
media_type: *media_type,
}),
Expand All @@ -101,13 +102,15 @@ impl CliModuleLoader {
specifier,
..
})) => {
let code = match media_type {
let code: ModuleCode = match media_type {
MediaType::JavaScript
| MediaType::Unknown
| MediaType::Cjs
| MediaType::Mjs
| MediaType::Json => source.to_string(),
MediaType::Dts | MediaType::Dcts | MediaType::Dmts => "".to_string(),
| MediaType::Json => source.into(),
MediaType::Dts | MediaType::Dcts | MediaType::Dmts => {
Default::default()
}
MediaType::TypeScript
| MediaType::Mts
| MediaType::Cts
Expand All @@ -133,7 +136,7 @@ impl CliModuleLoader {
self.ps.parsed_source_cache.free(specifier);

Ok(ModuleCodeSource {
code,
code: code.into(),
found_url: specifier.clone(),
media_type: *media_type,
})
Expand Down Expand Up @@ -191,7 +194,7 @@ impl CliModuleLoader {
)?
};
ModuleCodeSource {
code,
code: code.into(),
found_url: specifier.clone(),
media_type: MediaType::from(specifier),
}
Expand All @@ -208,7 +211,7 @@ impl CliModuleLoader {
code_without_source_map(code_source.code)
};
Ok(ModuleSource {
code: code.into_bytes().into_boxed_slice(),
code,
module_url_specified: specifier.to_string(),
module_url_found: code_source.found_url.to_string(),
module_type: match code_source.media_type {
Expand Down
4 changes: 2 additions & 2 deletions cli/standalone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ impl ModuleLoader for EmbeddedModuleLoader {
async move {
if let Some((source, _)) = is_data_uri {
return Ok(deno_core::ModuleSource {
code: source.into_bytes().into_boxed_slice(),
code: source.into(),
module_type: deno_core::ModuleType::JavaScript,
module_url_specified: module_specifier.to_string(),
module_url_found: module_specifier.to_string(),
Expand All @@ -192,7 +192,7 @@ impl ModuleLoader for EmbeddedModuleLoader {
.to_owned();

Ok(deno_core::ModuleSource {
code: code.into_bytes().into_boxed_slice(),
code: code.into(),
module_type: match module.kind {
eszip::ModuleKind::JavaScript => deno_core::ModuleType::JavaScript,
eszip::ModuleKind::Json => deno_core::ModuleType::Json,
Expand Down
24 changes: 13 additions & 11 deletions cli/tools/coverage/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use deno_core::serde_json;
use deno_core::sourcemap::SourceMap;
use deno_core::url::Url;
use deno_core::LocalInspectorSession;
use deno_core::ModuleCode;
use regex::Regex;
use std::fs;
use std::fs::File;
Expand Down Expand Up @@ -170,16 +171,16 @@ struct CoverageReport {

fn generate_coverage_report(
script_coverage: &ScriptCoverage,
script_source: &str,
script_source: String,
maybe_source_map: &Option<Vec<u8>>,
output: &Option<PathBuf>,
) -> CoverageReport {
let maybe_source_map = maybe_source_map
.as_ref()
.map(|source_map| SourceMap::from_slice(source_map).unwrap());
let text_lines = TextLines::new(script_source);
let text_lines = TextLines::new(&script_source);

let comment_ranges = deno_ast::lex(script_source, MediaType::JavaScript)
let comment_ranges = deno_ast::lex(&script_source, MediaType::JavaScript)
.into_iter()
.filter(|item| {
matches!(item.inner, deno_ast::TokenOrComment::Comment { .. })
Expand Down Expand Up @@ -680,22 +681,22 @@ pub async fn cover_files(
})?;

// Check if file was transpiled
let original_source = &file.source;
let transpiled_code = match file.media_type {
let original_source = file.source.clone();
let transpiled_code: ModuleCode = match file.media_type {
MediaType::JavaScript
| MediaType::Unknown
| MediaType::Cjs
| MediaType::Mjs
| MediaType::Json => file.source.as_ref().to_string(),
MediaType::Dts | MediaType::Dmts | MediaType::Dcts => "".to_string(),
| MediaType::Json => file.source.into(),
MediaType::Dts | MediaType::Dmts | MediaType::Dcts => Default::default(),
MediaType::TypeScript
| MediaType::Jsx
| MediaType::Mts
| MediaType::Cts
| MediaType::Tsx => {
let source_hash = get_source_hash(&file.source, ps.emit_options_hash);
match ps.emit_cache.get_emit_code(&file.specifier, source_hash) {
Some(code) => code,
Some(code) => code.into(),
None => {
return Err(anyhow!(
"Missing transpiled source code for: \"{}\".
Expand All @@ -710,15 +711,16 @@ pub async fn cover_files(
}
};

let source_map = source_map_from_code(&transpiled_code);
let coverage_report = generate_coverage_report(
&script_coverage,
&transpiled_code,
&source_map_from_code(&transpiled_code),
transpiled_code.to_string(),
&source_map,
&out_mode,
);

if !coverage_report.found_lines.is_empty() {
reporter.report(&coverage_report, original_source)?;
reporter.report(&coverage_report, &original_source)?;
}
}

Expand Down
2 changes: 1 addition & 1 deletion cli/tsc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -879,7 +879,7 @@ pub fn exec(request: Request) -> Result<Response, AnyError> {
runtime
.execute_script(&located_script_name!(), startup_source)
.context("Could not properly start the compiler runtime.")?;
runtime.execute_script(&located_script_name!(), &exec_source)?;
runtime.execute_script(&located_script_name!(), exec_source)?;

let op_state = runtime.op_state();
let mut op_state = op_state.borrow_mut();
Expand Down
33 changes: 18 additions & 15 deletions cli/util/text_encoding.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.

use deno_core::ModuleCode;
use encoding_rs::*;
use std::borrow::Cow;
use std::io::Error;
Expand Down Expand Up @@ -53,11 +54,12 @@ pub fn strip_bom(text: &str) -> &str {
}
}

static SOURCE_MAP_PREFIX: &str =
"//# sourceMappingURL=data:application/json;base64,";
static SOURCE_MAP_PREFIX: &[u8] =
b"//# sourceMappingURL=data:application/json;base64,";

pub fn source_map_from_code(code: &str) -> Option<Vec<u8>> {
let last_line = code.rsplit(|u| u == '\n').next()?;
pub fn source_map_from_code(code: &ModuleCode) -> Option<Vec<u8>> {
let bytes = code.as_bytes();
let last_line = bytes.rsplit(|u| *u == b'\n').next()?;
if last_line.starts_with(SOURCE_MAP_PREFIX) {
let input = last_line.split_at(SOURCE_MAP_PREFIX.len()).1;
let decoded_map = base64::decode(input)
Expand All @@ -68,17 +70,18 @@ pub fn source_map_from_code(code: &str) -> Option<Vec<u8>> {
}
}

pub fn code_without_source_map(mut code: String) -> String {
if let Some(last_line_index) = code.rfind('\n') {
if code[last_line_index + 1..].starts_with(SOURCE_MAP_PREFIX) {
code.truncate(last_line_index + 1);
code
} else {
code
/// Truncate the source code before the source map.
pub fn code_without_source_map(mut code: ModuleCode) -> ModuleCode {
let bytes = code.as_bytes();
for i in (0..bytes.len()).rev() {
if bytes[i] == b'\n' {
if bytes[i + 1..].starts_with(SOURCE_MAP_PREFIX) {
code.truncate(i + 1);
}
return code;
}
} else {
code
}
code
}

#[cfg(test)]
Expand Down Expand Up @@ -155,8 +158,8 @@ mod tests {
"\n",
);

fn run_test(input: &str, output: &str) {
assert_eq!(code_without_source_map(input.to_string()), output);
fn run_test(input: &'static str, output: &'static str) {
assert_eq!(code_without_source_map(input.into()).to_string(), output);
}
}
}
2 changes: 1 addition & 1 deletion core/examples/eval_js_value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ fn main() {

fn eval(
context: &mut JsRuntime,
code: &str,
code: &'static str,
) -> Result<serde_json::Value, String> {
let res = context.execute_script("<anon>", code);
match res {
Expand Down
2 changes: 1 addition & 1 deletion core/examples/ts_module_loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ impl ModuleLoader for TypescriptModuleLoader {
code
};
let module = ModuleSource {
code: code.into_bytes().into_boxed_slice(),
code: code.into(),
module_type,
module_url_specified: module_specifier.to_string(),
module_url_found: module_specifier.to_string(),
Expand Down
10 changes: 5 additions & 5 deletions core/extensions.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
use crate::modules::ModuleCode;
use crate::OpState;
use anyhow::Context as _;
use anyhow::Error;
Expand All @@ -23,13 +24,12 @@ pub enum ExtensionFileSourceCode {
}

impl ExtensionFileSourceCode {
pub fn load(&self) -> Result<String, Error> {
pub fn load(&self) -> Result<ModuleCode, Error> {
match self {
ExtensionFileSourceCode::IncludedInBinary(code) => Ok(code.to_string()),
ExtensionFileSourceCode::IncludedInBinary(code) => Ok((*code).into()),
ExtensionFileSourceCode::LoadedFromFsDuringSnapshot(path) => {
let msg = format!("Failed to read \"{}\"", path.display());
let code = std::fs::read_to_string(path).context(msg)?;
Ok(code)
let msg = || format!("Failed to read \"{}\"", path.display());
Ok(std::fs::read_to_string(path).with_context(msg)?.into())
}
}
}
Expand Down
1 change: 1 addition & 0 deletions core/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ pub use crate::module_specifier::ModuleSpecifier;
pub use crate::modules::ExtModuleLoader;
pub use crate::modules::ExtModuleLoaderCb;
pub use crate::modules::FsModuleLoader;
pub use crate::modules::ModuleCode;
pub use crate::modules::ModuleId;
pub use crate::modules::ModuleLoader;
pub use crate::modules::ModuleSource;
Expand Down
Loading

0 comments on commit b96a592

Please sign in to comment.