mirror of
https://github.com/denoland/deno.git
synced 2024-11-21 20:38:55 +00:00
perf: pass transpiled module to deno_core as known string (#26555)
This commit is contained in:
parent
d92d2fe9b0
commit
f0f476e584
25
cli/cache/emit.rs
vendored
25
cli/cache/emit.rs
vendored
@ -39,7 +39,7 @@ impl EmitCache {
|
|||||||
&self,
|
&self,
|
||||||
specifier: &ModuleSpecifier,
|
specifier: &ModuleSpecifier,
|
||||||
expected_source_hash: u64,
|
expected_source_hash: u64,
|
||||||
) -> Option<Vec<u8>> {
|
) -> Option<String> {
|
||||||
let emit_filename = self.get_emit_filename(specifier)?;
|
let emit_filename = self.get_emit_filename(specifier)?;
|
||||||
let bytes = self.disk_cache.get(&emit_filename).ok()?;
|
let bytes = self.disk_cache.get(&emit_filename).ok()?;
|
||||||
self
|
self
|
||||||
@ -100,7 +100,7 @@ impl EmitFileSerializer {
|
|||||||
&self,
|
&self,
|
||||||
mut bytes: Vec<u8>,
|
mut bytes: Vec<u8>,
|
||||||
expected_source_hash: u64,
|
expected_source_hash: u64,
|
||||||
) -> Option<Vec<u8>> {
|
) -> Option<String> {
|
||||||
let last_newline_index = bytes.iter().rposition(|&b| b == b'\n')?;
|
let last_newline_index = bytes.iter().rposition(|&b| b == b'\n')?;
|
||||||
let (content, last_line) = bytes.split_at(last_newline_index);
|
let (content, last_line) = bytes.split_at(last_newline_index);
|
||||||
let hashes = last_line.strip_prefix(LAST_LINE_PREFIX.as_bytes())?;
|
let hashes = last_line.strip_prefix(LAST_LINE_PREFIX.as_bytes())?;
|
||||||
@ -120,7 +120,7 @@ impl EmitFileSerializer {
|
|||||||
|
|
||||||
// everything looks good, truncate and return it
|
// everything looks good, truncate and return it
|
||||||
bytes.truncate(content.len());
|
bytes.truncate(content.len());
|
||||||
Some(bytes)
|
String::from_utf8(bytes).ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn serialize(&self, code: &[u8], source_hash: u64) -> Vec<u8> {
|
pub fn serialize(&self, code: &[u8], source_hash: u64) -> Vec<u8> {
|
||||||
@ -170,8 +170,6 @@ mod test {
|
|||||||
},
|
},
|
||||||
emit_failed_flag: Default::default(),
|
emit_failed_flag: Default::default(),
|
||||||
};
|
};
|
||||||
let to_string =
|
|
||||||
|bytes: Vec<u8>| -> String { String::from_utf8(bytes).unwrap() };
|
|
||||||
|
|
||||||
let specifier1 =
|
let specifier1 =
|
||||||
ModuleSpecifier::from_file_path(temp_dir.path().join("file1.ts"))
|
ModuleSpecifier::from_file_path(temp_dir.path().join("file1.ts"))
|
||||||
@ -188,13 +186,10 @@ mod test {
|
|||||||
assert_eq!(cache.get_emit_code(&specifier1, 5), None);
|
assert_eq!(cache.get_emit_code(&specifier1, 5), None);
|
||||||
// providing the correct source hash
|
// providing the correct source hash
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
cache.get_emit_code(&specifier1, 10).map(to_string),
|
cache.get_emit_code(&specifier1, 10),
|
||||||
Some(emit_code1.clone()),
|
Some(emit_code1.clone()),
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(cache.get_emit_code(&specifier2, 2), Some(emit_code2));
|
||||||
cache.get_emit_code(&specifier2, 2).map(to_string),
|
|
||||||
Some(emit_code2)
|
|
||||||
);
|
|
||||||
|
|
||||||
// try changing the cli version (should not load previous ones)
|
// try changing the cli version (should not load previous ones)
|
||||||
let cache = EmitCache {
|
let cache = EmitCache {
|
||||||
@ -215,18 +210,12 @@ mod test {
|
|||||||
},
|
},
|
||||||
emit_failed_flag: Default::default(),
|
emit_failed_flag: Default::default(),
|
||||||
};
|
};
|
||||||
assert_eq!(
|
assert_eq!(cache.get_emit_code(&specifier1, 5), Some(emit_code1));
|
||||||
cache.get_emit_code(&specifier1, 5).map(to_string),
|
|
||||||
Some(emit_code1)
|
|
||||||
);
|
|
||||||
|
|
||||||
// adding when already exists should not cause issue
|
// adding when already exists should not cause issue
|
||||||
let emit_code3 = "asdf".to_string();
|
let emit_code3 = "asdf".to_string();
|
||||||
cache.set_emit_code(&specifier1, 20, emit_code3.as_bytes());
|
cache.set_emit_code(&specifier1, 20, emit_code3.as_bytes());
|
||||||
assert_eq!(cache.get_emit_code(&specifier1, 5), None);
|
assert_eq!(cache.get_emit_code(&specifier1, 5), None);
|
||||||
assert_eq!(
|
assert_eq!(cache.get_emit_code(&specifier1, 20), Some(emit_code3));
|
||||||
cache.get_emit_code(&specifier1, 20).map(to_string),
|
|
||||||
Some(emit_code3)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
55
cli/emit.rs
55
cli/emit.rs
@ -13,7 +13,6 @@ use deno_core::error::AnyError;
|
|||||||
use deno_core::futures::stream::FuturesUnordered;
|
use deno_core::futures::stream::FuturesUnordered;
|
||||||
use deno_core::futures::FutureExt;
|
use deno_core::futures::FutureExt;
|
||||||
use deno_core::futures::StreamExt;
|
use deno_core::futures::StreamExt;
|
||||||
use deno_core::ModuleCodeBytes;
|
|
||||||
use deno_core::ModuleSpecifier;
|
use deno_core::ModuleSpecifier;
|
||||||
use deno_graph::MediaType;
|
use deno_graph::MediaType;
|
||||||
use deno_graph::Module;
|
use deno_graph::Module;
|
||||||
@ -94,7 +93,7 @@ impl Emitter {
|
|||||||
&self,
|
&self,
|
||||||
specifier: &ModuleSpecifier,
|
specifier: &ModuleSpecifier,
|
||||||
source: &str,
|
source: &str,
|
||||||
) -> Option<Vec<u8>> {
|
) -> Option<String> {
|
||||||
let source_hash = self.get_source_hash(source);
|
let source_hash = self.get_source_hash(source);
|
||||||
self.emit_cache.get_emit_code(specifier, source_hash)
|
self.emit_cache.get_emit_code(specifier, source_hash)
|
||||||
}
|
}
|
||||||
@ -104,7 +103,7 @@ impl Emitter {
|
|||||||
specifier: &ModuleSpecifier,
|
specifier: &ModuleSpecifier,
|
||||||
media_type: MediaType,
|
media_type: MediaType,
|
||||||
source: &Arc<str>,
|
source: &Arc<str>,
|
||||||
) -> Result<ModuleCodeBytes, AnyError> {
|
) -> Result<String, AnyError> {
|
||||||
// Note: keep this in sync with the sync version below
|
// Note: keep this in sync with the sync version below
|
||||||
let helper = EmitParsedSourceHelper(self);
|
let helper = EmitParsedSourceHelper(self);
|
||||||
match helper.pre_emit_parsed_source(specifier, source) {
|
match helper.pre_emit_parsed_source(specifier, source) {
|
||||||
@ -113,7 +112,7 @@ impl Emitter {
|
|||||||
let parsed_source_cache = self.parsed_source_cache.clone();
|
let parsed_source_cache = self.parsed_source_cache.clone();
|
||||||
let transpile_and_emit_options =
|
let transpile_and_emit_options =
|
||||||
self.transpile_and_emit_options.clone();
|
self.transpile_and_emit_options.clone();
|
||||||
let transpile_result = deno_core::unsync::spawn_blocking({
|
let transpiled_source = deno_core::unsync::spawn_blocking({
|
||||||
let specifier = specifier.clone();
|
let specifier = specifier.clone();
|
||||||
let source = source.clone();
|
let source = source.clone();
|
||||||
move || -> Result<_, AnyError> {
|
move || -> Result<_, AnyError> {
|
||||||
@ -129,11 +128,12 @@ impl Emitter {
|
|||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.unwrap()?;
|
.unwrap()?;
|
||||||
Ok(helper.post_emit_parsed_source(
|
helper.post_emit_parsed_source(
|
||||||
specifier,
|
specifier,
|
||||||
transpile_result,
|
&transpiled_source,
|
||||||
source_hash,
|
source_hash,
|
||||||
))
|
);
|
||||||
|
Ok(transpiled_source)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -143,13 +143,13 @@ impl Emitter {
|
|||||||
specifier: &ModuleSpecifier,
|
specifier: &ModuleSpecifier,
|
||||||
media_type: MediaType,
|
media_type: MediaType,
|
||||||
source: &Arc<str>,
|
source: &Arc<str>,
|
||||||
) -> Result<ModuleCodeBytes, AnyError> {
|
) -> Result<String, AnyError> {
|
||||||
// Note: keep this in sync with the async version above
|
// Note: keep this in sync with the async version above
|
||||||
let helper = EmitParsedSourceHelper(self);
|
let helper = EmitParsedSourceHelper(self);
|
||||||
match helper.pre_emit_parsed_source(specifier, source) {
|
match helper.pre_emit_parsed_source(specifier, source) {
|
||||||
PreEmitResult::Cached(emitted_text) => Ok(emitted_text),
|
PreEmitResult::Cached(emitted_text) => Ok(emitted_text),
|
||||||
PreEmitResult::NotCached { source_hash } => {
|
PreEmitResult::NotCached { source_hash } => {
|
||||||
let transpile_result = EmitParsedSourceHelper::transpile(
|
let transpiled_source = EmitParsedSourceHelper::transpile(
|
||||||
&self.parsed_source_cache,
|
&self.parsed_source_cache,
|
||||||
specifier,
|
specifier,
|
||||||
source.clone(),
|
source.clone(),
|
||||||
@ -157,11 +157,12 @@ impl Emitter {
|
|||||||
&self.transpile_and_emit_options.0,
|
&self.transpile_and_emit_options.0,
|
||||||
&self.transpile_and_emit_options.1,
|
&self.transpile_and_emit_options.1,
|
||||||
)?;
|
)?;
|
||||||
Ok(helper.post_emit_parsed_source(
|
helper.post_emit_parsed_source(
|
||||||
specifier,
|
specifier,
|
||||||
transpile_result,
|
&transpiled_source,
|
||||||
source_hash,
|
source_hash,
|
||||||
))
|
);
|
||||||
|
Ok(transpiled_source)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -227,7 +228,7 @@ impl Emitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum PreEmitResult {
|
enum PreEmitResult {
|
||||||
Cached(ModuleCodeBytes),
|
Cached(String),
|
||||||
NotCached { source_hash: u64 },
|
NotCached { source_hash: u64 },
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,7 +246,7 @@ impl<'a> EmitParsedSourceHelper<'a> {
|
|||||||
if let Some(emit_code) =
|
if let Some(emit_code) =
|
||||||
self.0.emit_cache.get_emit_code(specifier, source_hash)
|
self.0.emit_cache.get_emit_code(specifier, source_hash)
|
||||||
{
|
{
|
||||||
PreEmitResult::Cached(emit_code.into_boxed_slice().into())
|
PreEmitResult::Cached(emit_code)
|
||||||
} else {
|
} else {
|
||||||
PreEmitResult::NotCached { source_hash }
|
PreEmitResult::NotCached { source_hash }
|
||||||
}
|
}
|
||||||
@ -258,21 +259,14 @@ impl<'a> EmitParsedSourceHelper<'a> {
|
|||||||
media_type: MediaType,
|
media_type: MediaType,
|
||||||
transpile_options: &deno_ast::TranspileOptions,
|
transpile_options: &deno_ast::TranspileOptions,
|
||||||
emit_options: &deno_ast::EmitOptions,
|
emit_options: &deno_ast::EmitOptions,
|
||||||
) -> Result<TranspileResult, AnyError> {
|
) -> Result<String, AnyError> {
|
||||||
// nothing else needs the parsed source at this point, so remove from
|
// nothing else needs the parsed source at this point, so remove from
|
||||||
// the cache in order to not transpile owned
|
// the cache in order to not transpile owned
|
||||||
let parsed_source = parsed_source_cache
|
let parsed_source = parsed_source_cache
|
||||||
.remove_or_parse_module(specifier, source, media_type)?;
|
.remove_or_parse_module(specifier, source, media_type)?;
|
||||||
ensure_no_import_assertion(&parsed_source)?;
|
ensure_no_import_assertion(&parsed_source)?;
|
||||||
Ok(parsed_source.transpile(transpile_options, emit_options)?)
|
let transpile_result =
|
||||||
}
|
parsed_source.transpile(transpile_options, emit_options)?;
|
||||||
|
|
||||||
pub fn post_emit_parsed_source(
|
|
||||||
&self,
|
|
||||||
specifier: &ModuleSpecifier,
|
|
||||||
transpile_result: TranspileResult,
|
|
||||||
source_hash: u64,
|
|
||||||
) -> ModuleCodeBytes {
|
|
||||||
let transpiled_source = match transpile_result {
|
let transpiled_source = match transpile_result {
|
||||||
TranspileResult::Owned(source) => source,
|
TranspileResult::Owned(source) => source,
|
||||||
TranspileResult::Cloned(source) => {
|
TranspileResult::Cloned(source) => {
|
||||||
@ -281,12 +275,21 @@ impl<'a> EmitParsedSourceHelper<'a> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
debug_assert!(transpiled_source.source_map.is_none());
|
debug_assert!(transpiled_source.source_map.is_none());
|
||||||
|
let text = String::from_utf8(transpiled_source.source)?;
|
||||||
|
Ok(text)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn post_emit_parsed_source(
|
||||||
|
&self,
|
||||||
|
specifier: &ModuleSpecifier,
|
||||||
|
transpiled_source: &str,
|
||||||
|
source_hash: u64,
|
||||||
|
) {
|
||||||
self.0.emit_cache.set_emit_code(
|
self.0.emit_cache.set_emit_code(
|
||||||
specifier,
|
specifier,
|
||||||
source_hash,
|
source_hash,
|
||||||
&transpiled_source.source,
|
transpiled_source.as_bytes(),
|
||||||
);
|
);
|
||||||
transpiled_source.source.into_boxed_slice().into()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -541,7 +541,8 @@ impl<TGraphContainer: ModuleGraphContainer>
|
|||||||
self.parsed_source_cache.free(specifier);
|
self.parsed_source_cache.free(specifier);
|
||||||
|
|
||||||
Ok(Some(ModuleCodeStringSource {
|
Ok(Some(ModuleCodeStringSource {
|
||||||
code: ModuleSourceCode::Bytes(transpile_result),
|
// note: it's faster to provide a string if we know it's a string
|
||||||
|
code: ModuleSourceCode::String(transpile_result.into()),
|
||||||
found_url: specifier.clone(),
|
found_url: specifier.clone(),
|
||||||
media_type,
|
media_type,
|
||||||
}))
|
}))
|
||||||
@ -571,7 +572,8 @@ impl<TGraphContainer: ModuleGraphContainer>
|
|||||||
self.parsed_source_cache.free(specifier);
|
self.parsed_source_cache.free(specifier);
|
||||||
|
|
||||||
Ok(Some(ModuleCodeStringSource {
|
Ok(Some(ModuleCodeStringSource {
|
||||||
code: ModuleSourceCode::Bytes(transpile_result),
|
// note: it's faster to provide a string if we know it's a string
|
||||||
|
code: ModuleSourceCode::String(transpile_result.into()),
|
||||||
found_url: specifier.clone(),
|
found_url: specifier.clone(),
|
||||||
media_type,
|
media_type,
|
||||||
}))
|
}))
|
||||||
|
@ -613,7 +613,7 @@ impl<'a> DenoCompileBinaryWriter<'a> {
|
|||||||
.emitter
|
.emitter
|
||||||
.emit_parsed_source(&m.specifier, m.media_type, &m.source)
|
.emit_parsed_source(&m.specifier, m.media_type, &m.source)
|
||||||
.await?;
|
.await?;
|
||||||
source.to_vec()
|
source.into_bytes()
|
||||||
} else {
|
} else {
|
||||||
m.source.as_bytes().to_vec()
|
m.source.as_bytes().to_vec()
|
||||||
};
|
};
|
||||||
|
@ -571,7 +571,7 @@ pub async fn cover_files(
|
|||||||
| MediaType::Cjs
|
| MediaType::Cjs
|
||||||
| MediaType::Mjs
|
| MediaType::Mjs
|
||||||
| MediaType::Json => None,
|
| MediaType::Json => None,
|
||||||
MediaType::Dts | MediaType::Dmts | MediaType::Dcts => Some(Vec::new()),
|
MediaType::Dts | MediaType::Dmts | MediaType::Dcts => Some(String::new()),
|
||||||
MediaType::TypeScript
|
MediaType::TypeScript
|
||||||
| MediaType::Jsx
|
| MediaType::Jsx
|
||||||
| MediaType::Mts
|
| MediaType::Mts
|
||||||
@ -593,8 +593,7 @@ pub async fn cover_files(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
let runtime_code: String = match transpiled_code {
|
let runtime_code: String = match transpiled_code {
|
||||||
Some(code) => String::from_utf8(code)
|
Some(code) => code,
|
||||||
.with_context(|| format!("Failed decoding {}", file.specifier))?,
|
|
||||||
None => original_source.to_string(),
|
None => original_source.to_string(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user