diff --git a/libs/resolver/cache/deno_dir.rs b/libs/resolver/cache/deno_dir.rs index 76aacfe8911f4f..a1cba769c67255 100644 --- a/libs/resolver/cache/deno_dir.rs +++ b/libs/resolver/cache/deno_dir.rs @@ -66,7 +66,7 @@ impl DenoDir { #[cfg(not(target_arch = "wasm32"))] assert!(root.is_absolute()); - let gen_path = root.join("gen"); + let gen_path = root.join("gen_v2"); Self { root, gen_cache: DiskCache::new(sys, gen_path), diff --git a/libs/resolver/cache/emit.rs b/libs/resolver/cache/emit.rs index 1bdc205dd85068..f1a8d3e448cf8e 100644 --- a/libs/resolver/cache/emit.rs +++ b/libs/resolver/cache/emit.rs @@ -50,6 +50,13 @@ impl EmitCache { } }; + log::debug!("Emit cache version: {:?}", cache_version); + log::debug!( + "Emit cache xxhash64 check: {}", + twox_hash::XxHash64::oneshot(0, b"test") + ); + log::debug!("Emit cache mode: {:?}", mode); + Self { disk_cache, emit_failed_flag: Default::default(), @@ -69,13 +76,15 @@ impl EmitCache { pub fn get_emit_code( &self, specifier: &Url, + transpile_and_emit_options_hash: u64, expected_source_hash: u64, ) -> Option { if matches!(self.mode, Mode::Disable) { return None; } - let emit_filename = self.get_emit_filename(specifier)?; + let emit_filename = + self.get_emit_filename(specifier, transpile_and_emit_options_hash)?; let bytes = self.disk_cache.get(&emit_filename).ok()?; self .file_serializer @@ -83,8 +92,19 @@ impl EmitCache { } /// Sets the emit code in the cache. - pub fn set_emit_code(&self, specifier: &Url, source_hash: u64, code: &[u8]) { - if let Err(err) = self.set_emit_code_result(specifier, source_hash, code) { + pub fn set_emit_code( + &self, + specifier: &Url, + transpile_and_emit_options_hash: u64, + source_hash: u64, + code: &[u8], + ) { + if let Err(err) = self.set_emit_code_result( + specifier, + transpile_and_emit_options_hash, + source_hash, + code, + ) { // might error in cases such as a readonly file system log::debug!("Error saving emit data ({}): {}", specifier, err); // assume the cache can't be written to and disable caching to it @@ -95,6 +115,7 @@ impl EmitCache { fn set_emit_code_result( &self, specifier: &Url, + transpile_and_emit_options_hash: u64, source_hash: u64, code: &[u8], ) -> Result<(), AnyError> { @@ -104,7 +125,7 @@ impl EmitCache { } let emit_filename = self - .get_emit_filename(specifier) + .get_emit_filename(specifier, transpile_and_emit_options_hash) .ok_or_else(|| anyhow!("Could not get emit filename."))?; let cache_data = self.file_serializer.serialize(code, source_hash); self.disk_cache.set(&emit_filename, &cache_data)?; @@ -112,10 +133,18 @@ impl EmitCache { Ok(()) } - fn get_emit_filename(&self, specifier: &Url) -> Option { - self + fn get_emit_filename( + &self, + specifier: &Url, + transpile_and_emit_options_hash: u64, + ) -> Option { + let suffix = self .disk_cache - .get_cache_filename_with_extension(specifier, "js") + .get_cache_filename_with_extension(specifier, "js")?; + let mut path = + PathBuf::from(format!("{:016x}", transpile_and_emit_options_hash)); + path.push(suffix); + Some(path) } } @@ -141,11 +170,22 @@ impl EmitFileSerializer { // verify the meta data file is for this source and CLI version let source_hash = source_hash.parse::().ok()?; if source_hash != expected_source_hash { + log::debug!( + "Emit cache source hash mismatch (expected: {}, actual: {})", + expected_source_hash, + source_hash + ); return None; } let emit_hash = emit_hash.parse::().ok()?; // prevent using an emit from a different cli version or emits that were tampered with - if emit_hash != self.compute_emit_hash(content) { + let expected_emit_hash = self.compute_emit_hash(content); + if emit_hash != expected_emit_hash { + log::debug!( + "Emit cache emit hash mismatch (expected: {}, actual: {})", + expected_emit_hash, + emit_hash + ); return None; } @@ -212,19 +252,19 @@ mod test { temp_dir.path().join("file2.ts").as_path(), ) .unwrap(); - assert_eq!(cache.get_emit_code(&specifier1, 1), None); + assert_eq!(cache.get_emit_code(&specifier1, 1, 1), None); let emit_code1 = "text1".to_string(); let emit_code2 = "text2".to_string(); - cache.set_emit_code(&specifier1, 10, emit_code1.as_bytes()); - cache.set_emit_code(&specifier2, 2, emit_code2.as_bytes()); + cache.set_emit_code(&specifier1, 1, 10, emit_code1.as_bytes()); + cache.set_emit_code(&specifier2, 1, 2, emit_code2.as_bytes()); // providing the incorrect source hash - assert_eq!(cache.get_emit_code(&specifier1, 5), None); + assert_eq!(cache.get_emit_code(&specifier1, 1, 5), None); // providing the correct source hash assert_eq!( - cache.get_emit_code(&specifier1, 10), + cache.get_emit_code(&specifier1, 1, 10), Some(emit_code1.clone()), ); - assert_eq!(cache.get_emit_code(&specifier2, 2), Some(emit_code2)); + assert_eq!(cache.get_emit_code(&specifier2, 1, 2), Some(emit_code2)); // try changing the cli version (should not load previous ones) let cache = EmitCache { @@ -235,8 +275,8 @@ mod test { emit_failed_flag: Default::default(), mode: Mode::Normal, }; - assert_eq!(cache.get_emit_code(&specifier1, 10), None); - cache.set_emit_code(&specifier1, 5, emit_code1.as_bytes()); + assert_eq!(cache.get_emit_code(&specifier1, 1, 10), None); + cache.set_emit_code(&specifier1, 1, 5, emit_code1.as_bytes()); // recreating the cache should still load the data because the CLI version is the same let cache = EmitCache { @@ -247,12 +287,21 @@ mod test { emit_failed_flag: Default::default(), mode: Mode::Normal, }; - assert_eq!(cache.get_emit_code(&specifier1, 5), Some(emit_code1)); + assert_eq!(cache.get_emit_code(&specifier1, 1, 5), Some(emit_code1)); // adding when already exists should not cause issue let emit_code3 = "asdf".to_string(); - 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, 20), Some(emit_code3)); + cache.set_emit_code(&specifier1, 1, 20, emit_code3.as_bytes()); + assert_eq!(cache.get_emit_code(&specifier1, 1, 5), None); + assert_eq!( + cache.get_emit_code(&specifier1, 1, 20).as_deref(), + Some(&*emit_code3) + ); + + // different transpile options should not conflict + let emit_code4 = "qwerty".to_string(); + cache.set_emit_code(&specifier1, 2, 20, emit_code4.as_bytes()); + assert_eq!(cache.get_emit_code(&specifier1, 1, 20), Some(emit_code3)); + assert_eq!(cache.get_emit_code(&specifier1, 2, 20), Some(emit_code4)); } } diff --git a/libs/resolver/emit.rs b/libs/resolver/emit.rs index 320dbdb5f1bf4a..f17f229b9dfd37 100644 --- a/libs/resolver/emit.rs +++ b/libs/resolver/emit.rs @@ -119,7 +119,11 @@ impl .transpile_options()?; let source_hash = self.get_source_hash(module_kind, transpile_and_emit_options, source); - Ok(self.emit_cache.get_emit_code(specifier, source_hash)) + Ok(self.emit_cache.get_emit_code( + specifier, + transpile_and_emit_options.pre_computed_hash, + source_hash, + )) } pub async fn maybe_emit_source( @@ -208,6 +212,7 @@ impl let transpiled_source = emit()?; helper.post_emit_parsed_source( &specifier, + transpile_and_emit_options, &transpiled_source, source_hash, ); @@ -263,6 +268,7 @@ impl .text; helper.post_emit_parsed_source( specifier, + transpile_and_emit_options, &transpiled_source, source_hash, ); @@ -487,9 +493,11 @@ impl .0 .get_source_hash(module_kind, transpile_and_emit_options, source); - if let Some(emit_code) = - self.0.emit_cache.get_emit_code(specifier, source_hash) - { + if let Some(emit_code) = self.0.emit_cache.get_emit_code( + specifier, + transpile_and_emit_options.pre_computed_hash, + source_hash, + ) { PreEmitResult::Cached(emit_code) } else { PreEmitResult::NotCached { source_hash } @@ -499,11 +507,13 @@ impl pub fn post_emit_parsed_source( &self, specifier: &Url, + transpile_and_emit_options: &TranspileAndEmitOptions, transpiled_source: &str, source_hash: u64, ) { self.0.emit_cache.set_emit_code( specifier, + transpile_and_emit_options.pre_computed_hash, source_hash, transpiled_source.as_bytes(), );