Skip to content

Commit

Permalink
fix: use hash of in-memory bytes only for code cache (denoland#23966)
Browse files Browse the repository at this point in the history
* denoland/deno_core#752
* denoland/deno_core#753

Did benchmarking on this and it's slightly faster (couple ms) or equal
to in performance as main.

Closes denoland#23904
  • Loading branch information
dsherret committed May 24, 2024
1 parent 92a8d09 commit b21004b
Show file tree
Hide file tree
Showing 11 changed files with 93 additions and 174 deletions.
13 changes: 7 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ repository = "https://github.com/denoland/deno"

[workspace.dependencies]
deno_ast = { version = "=0.38.2", features = ["transpiling"] }
deno_core = { version = "0.282.0" }
deno_core = { version = "0.283.0" }

deno_bench_util = { version = "0.147.0", path = "./bench_util" }
deno_lockfile = "0.19.0"
Expand Down Expand Up @@ -174,6 +174,7 @@ tokio = { version = "1.36.0", features = ["full"] }
tokio-metrics = { version = "0.3.0", features = ["rt"] }
tokio-util = "0.7.4"
tower-lsp = { version = "=0.20.0", features = ["proposed"] }
twox-hash = "=1.6.3"
# Upgrading past 2.4.1 may cause WPT failures
url = { version = "< 2.5.0", features = ["serde", "expose_internals"] }
uuid = { version = "1.3.0", features = ["v4"] }
Expand Down
2 changes: 1 addition & 1 deletion cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ thiserror.workspace = true
tokio.workspace = true
tokio-util.workspace = true
tower-lsp.workspace = true
twox-hash = "=1.6.3"
twox-hash.workspace = true
typed-arena = "=2.0.1"
uuid = { workspace = true, features = ["serde"] }
walkdir = "=2.3.2"
Expand Down
31 changes: 15 additions & 16 deletions cli/cache/code_cache.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.

use deno_ast::ModuleSpecifier;
use deno_core::error::AnyError;
use deno_runtime::code_cache;
use deno_runtime::deno_webstorage::rusqlite::params;
Expand All @@ -21,7 +22,6 @@ pub static CODE_CACHE_DB: CacheDBConfiguration = CacheDBConfiguration {
on_failure: CacheFailure::Blackhole,
};

#[derive(Clone)]
pub struct CodeCache {
inner: CodeCacheInner,
}
Expand Down Expand Up @@ -52,28 +52,28 @@ impl CodeCache {

pub fn get_sync(
&self,
specifier: &str,
specifier: &ModuleSpecifier,
code_cache_type: code_cache::CodeCacheType,
source_hash: &str,
source_hash: u64,
) -> Option<Vec<u8>> {
Self::ensure_ok(self.inner.get_sync(
specifier,
specifier.as_str(),
code_cache_type,
source_hash,
&source_hash.to_string(),
))
}

pub fn set_sync(
&self,
specifier: &str,
specifier: &ModuleSpecifier,
code_cache_type: code_cache::CodeCacheType,
source_hash: &str,
source_hash: u64,
data: &[u8],
) {
Self::ensure_ok(self.inner.set_sync(
specifier,
specifier.as_str(),
code_cache_type,
source_hash,
&source_hash.to_string(),
data,
));
}
Expand All @@ -82,25 +82,24 @@ impl CodeCache {
impl code_cache::CodeCache for CodeCache {
fn get_sync(
&self,
specifier: &str,
specifier: &ModuleSpecifier,
code_cache_type: code_cache::CodeCacheType,
source_hash: &str,
source_hash: u64,
) -> Option<Vec<u8>> {
self.get_sync(specifier, code_cache_type, source_hash)
}

fn set_sync(
&self,
specifier: &str,
specifier: ModuleSpecifier,
code_cache_type: code_cache::CodeCacheType,
source_hash: &str,
source_hash: u64,
data: &[u8],
) {
self.set_sync(specifier, code_cache_type, source_hash, data);
self.set_sync(&specifier, code_cache_type, source_hash, data);
}
}

#[derive(Clone)]
struct CodeCacheInner {
conn: CacheDB,
}
Expand Down Expand Up @@ -135,7 +134,7 @@ impl CodeCacheInner {
&self,
specifier: &str,
code_cache_type: code_cache::CodeCacheType,
source_hash: &str,
source_hash: &str, // use string because sqlite doesn't have a u64 type
data: &[u8],
) -> Result<(), AnyError> {
let sql = "
Expand Down
17 changes: 0 additions & 17 deletions cli/cache/module_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,23 +87,6 @@ impl ModuleInfoCache {
}
}

pub fn get_module_source_hash(
&self,
specifier: &ModuleSpecifier,
media_type: MediaType,
) -> Result<Option<ModuleInfoCacheSourceHash>, AnyError> {
let query = "SELECT source_hash FROM moduleinfocache WHERE specifier=?1 AND media_type=?2";
let res = self.conn.query_row(
query,
params![specifier.as_str(), serialize_media_type(media_type)],
|row| {
let source_hash: String = row.get(0)?;
Ok(ModuleInfoCacheSourceHash(source_hash))
},
)?;
Ok(res)
}

pub fn get_module_info(
&self,
specifier: &ModuleSpecifier,
Expand Down
1 change: 0 additions & 1 deletion cli/factory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -798,7 +798,6 @@ impl CliFactory {
},
self.emitter()?.clone(),
self.main_module_graph_container().await?.clone(),
self.module_info_cache()?.clone(),
self.module_load_preparer().await?.clone(),
cli_node_resolver.clone(),
NpmModuleLoader::new(
Expand Down
92 changes: 28 additions & 64 deletions cli/module_loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::args::CliOptions;
use crate::args::DenoSubcommand;
use crate::args::TsTypeLib;
use crate::cache::CodeCache;
use crate::cache::ModuleInfoCache;
use crate::cache::FastInsecureHasher;
use crate::cache::ParsedSourceCache;
use crate::emit::Emitter;
use crate::factory::CliFactory;
Expand Down Expand Up @@ -55,6 +55,7 @@ use deno_core::ModuleSpecifier;
use deno_core::ModuleType;
use deno_core::RequestedModuleType;
use deno_core::ResolutionKind;
use deno_core::SourceCodeCacheInfo;
use deno_core::SourceMapGetter;
use deno_graph::source::ResolutionMode;
use deno_graph::source::Resolver;
Expand All @@ -67,7 +68,6 @@ use deno_graph::Resolution;
use deno_lockfile::Lockfile;
use deno_runtime::code_cache;
use deno_runtime::deno_node::NodeResolutionMode;
use deno_runtime::fs_util::code_timestamp;
use deno_runtime::permissions::PermissionsContainer;
use deno_semver::npm::NpmPackageReqReference;

Expand Down Expand Up @@ -221,7 +221,6 @@ struct SharedCliModuleLoaderState {
code_cache: Option<Arc<CodeCache>>,
emitter: Arc<Emitter>,
main_module_graph_container: Arc<MainModuleGraphContainer>,
module_info_cache: Arc<ModuleInfoCache>,
module_load_preparer: Arc<ModuleLoadPreparer>,
node_resolver: Arc<CliNodeResolver>,
npm_module_loader: NpmModuleLoader,
Expand All @@ -240,7 +239,6 @@ impl CliModuleLoaderFactory {
code_cache: Option<Arc<CodeCache>>,
emitter: Arc<Emitter>,
main_module_graph_container: Arc<MainModuleGraphContainer>,
module_info_cache: Arc<ModuleInfoCache>,
module_load_preparer: Arc<ModuleLoadPreparer>,
node_resolver: Arc<CliNodeResolver>,
npm_module_loader: NpmModuleLoader,
Expand All @@ -261,7 +259,6 @@ impl CliModuleLoaderFactory {
code_cache,
emitter,
main_module_graph_container,
module_info_cache,
module_load_preparer,
node_resolver,
npm_module_loader,
Expand Down Expand Up @@ -388,27 +385,20 @@ impl<TGraphContainer: ModuleGraphContainer>
}

let code_cache = if module_type == ModuleType::JavaScript {
self.shared.code_cache.as_ref().and_then(|cache| {
let code_hash = self
.get_code_hash_or_timestamp(specifier, code_source.media_type)
.ok()
.flatten();
if let Some(code_hash) = code_hash {
cache
.get_sync(
specifier.as_str(),
code_cache::CodeCacheType::EsModule,
&code_hash,
)
.map(Cow::from)
.inspect(|_| {
// This log line is also used by tests.
log::debug!(
"V8 code cache hit for ES module: {specifier}, [{code_hash:?}]"
);
})
} else {
None
self.shared.code_cache.as_ref().map(|cache| {
let code_hash = FastInsecureHasher::hash(&code);
let data = cache
.get_sync(specifier, code_cache::CodeCacheType::EsModule, code_hash)
.map(Cow::from)
.inspect(|_| {
// This log line is also used by tests.
log::debug!(
"V8 code cache hit for ES module: {specifier}, [{code_hash:?}]"
);
});
SourceCodeCacheInfo {
hash: code_hash,
data,
}
})
} else {
Expand Down Expand Up @@ -589,25 +579,6 @@ impl<TGraphContainer: ModuleGraphContainer>
resolution.map_err(|err| err.into())
}

fn get_code_hash_or_timestamp(
&self,
specifier: &ModuleSpecifier,
media_type: MediaType,
) -> Result<Option<String>, AnyError> {
let hash = self
.shared
.module_info_cache
.get_module_source_hash(specifier, media_type)?;
if let Some(hash) = hash {
return Ok(Some(hash.into()));
}

// Use the modified timestamp from the local file system if we don't have a hash.
let timestamp = code_timestamp(specifier.as_str())
.map(|timestamp| timestamp.to_string())?;
Ok(Some(timestamp))
}

async fn load_prepared_module(
&self,
specifier: &ModuleSpecifier,
Expand Down Expand Up @@ -865,28 +836,21 @@ impl<TGraphContainer: ModuleGraphContainer> ModuleLoader

fn code_cache_ready(
&self,
specifier: &ModuleSpecifier,
specifier: ModuleSpecifier,
source_hash: u64,
code_cache: &[u8],
) -> Pin<Box<dyn Future<Output = ()>>> {
if let Some(cache) = self.0.shared.code_cache.as_ref() {
let media_type = MediaType::from_specifier(specifier);
let code_hash = self
.0
.get_code_hash_or_timestamp(specifier, media_type)
.ok()
.flatten();
if let Some(code_hash) = code_hash {
// This log line is also used by tests.
log::debug!(
"Updating V8 code cache for ES module: {specifier}, [{code_hash:?}]"
);
cache.set_sync(
specifier.as_str(),
code_cache::CodeCacheType::EsModule,
&code_hash,
code_cache,
);
}
// This log line is also used by tests.
log::debug!(
"Updating V8 code cache for ES module: {specifier}, [{source_hash:?}]"
);
cache.set_sync(
&specifier,
code_cache::CodeCacheType::EsModule,
source_hash,
code_cache,
);
}
std::future::ready(()).boxed_local()
}
Expand Down
1 change: 1 addition & 0 deletions runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ signal-hook = "0.3.17"
signal-hook-registry = "1.4.0"
tokio.workspace = true
tokio-metrics.workspace = true
twox-hash.workspace = true
uuid.workspace = true
which = "4.2.5"

Expand Down
10 changes: 6 additions & 4 deletions runtime/code_cache.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.

use deno_core::ModuleSpecifier;

pub enum CodeCacheType {
EsModule,
Script,
Expand All @@ -17,15 +19,15 @@ impl CodeCacheType {
pub trait CodeCache: Send + Sync {
fn get_sync(
&self,
specifier: &str,
specifier: &ModuleSpecifier,
code_cache_type: CodeCacheType,
source_hash: &str,
source_hash: u64,
) -> Option<Vec<u8>>;
fn set_sync(
&self,
specifier: &str,
specifier: ModuleSpecifier,
code_cache_type: CodeCacheType,
source_hash: &str,
source_hash: u64,
data: &[u8],
);
}
Loading

0 comments on commit b21004b

Please sign in to comment.