Skip to content

Commit

Permalink
feat: add cache for process runtime requirements (#7601)
Browse files Browse the repository at this point in the history
  • Loading branch information
ahabhgk authored Aug 16, 2024
1 parent a3897c7 commit 0148015
Show file tree
Hide file tree
Showing 13 changed files with 219 additions and 154 deletions.
3 changes: 2 additions & 1 deletion crates/rspack_binding_values/src/codegen_result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ impl From<CodeGenerationResults> for JsCodegenerationResults {
rspack_core::RuntimeMode::Empty => {}
rspack_core::RuntimeMode::SingleEntry => {
runtime_map.insert(
get_runtime_key(runtime_result_map.single_runtime.expect("exist")),
get_runtime_key(runtime_result_map.single_runtime.as_ref().expect("exist"))
.to_string(),
id_result_map
.get(&runtime_result_map.single_value.expect("TODO"))
.expect("TODO")
Expand Down
4 changes: 2 additions & 2 deletions crates/rspack_core/src/build_chunk_graph/code_splitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use rustc_hash::{FxHashMap as HashMap, FxHashSet as HashSet, FxHasher};

use crate::dependencies_block::AsyncDependenciesToInitialChunkError;
use crate::{
add_connection_states, assign_depth, assign_depths, get_entry_runtime,
add_connection_states, assign_depth, assign_depths, get_entry_runtime, merge_runtime,
AsyncDependenciesBlockIdentifier, ChunkGroup, ChunkGroupKind, ChunkGroupOptions, ChunkGroupUkey,
ChunkLoading, ChunkUkey, Compilation, ConnectionId, ConnectionState, DependenciesBlock,
EntryDependency, EntryRuntime, GroupOptions, Logger, ModuleDependency, ModuleGraph,
Expand Down Expand Up @@ -791,7 +791,7 @@ Or do you want to use the entrypoints '{name}' and '{runtime}' independently on
.chunk_by_ukey
.entry(*chunk_ukey)
.and_modify(|chunk| {
chunk.runtime.extend(cgi.runtime.clone());
chunk.runtime = merge_runtime(&chunk.runtime, &cgi.runtime);
});
}
}
Expand Down
4 changes: 2 additions & 2 deletions crates/rspack_core/src/chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use rspack_hash::{RspackHash, RspackHashDigest};
use rustc_hash::{FxHashMap as HashMap, FxHashSet as HashSet, FxHasher};

use crate::{
compare_chunk_group, get_chunk_group_from_ukey, sort_group_by_index, ChunkGraph,
compare_chunk_group, get_chunk_group_from_ukey, merge_runtime, sort_group_by_index, ChunkGraph,
ChunkGroupOrderKey,
};
use crate::{ChunkGroupByUkey, ChunkGroupUkey, ChunkUkey, SourceType};
Expand Down Expand Up @@ -117,7 +117,7 @@ impl Chunk {
new_chunk.add_group(group.ukey);
});
new_chunk.id_name_hints.extend(self.id_name_hints.clone());
new_chunk.runtime.extend(self.runtime.clone());
new_chunk.runtime = merge_runtime(&new_chunk.runtime, &self.runtime);
}

pub fn can_be_initial(&self, chunk_group_by_ukey: &ChunkGroupByUkey) -> bool {
Expand Down
2 changes: 1 addition & 1 deletion crates/rspack_core/src/chunk_graph/chunk_graph_module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ impl ChunkGraph {
cgm.hashes = Some(hashes);
}

#[instrument(name = "chunk_graph:get_module_graph_hash", skip_all)]
#[instrument(name = "chunk_graph:get_module_graph_hash", skip_all, fields(module = ?module.identifier()))]
pub fn get_module_graph_hash(
&self,
module: &dyn Module,
Expand Down
136 changes: 61 additions & 75 deletions crates/rspack_core/src/compiler/compilation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ define_hook!(CompilationOptimizeChunkModules: AsyncSeriesBail(compilation: &mut
define_hook!(CompilationModuleIds: SyncSeries(compilation: &mut Compilation));
define_hook!(CompilationChunkIds: SyncSeries(compilation: &mut Compilation));
define_hook!(CompilationRuntimeModule: AsyncSeries(compilation: &mut Compilation, module: &ModuleIdentifier, chunk: &ChunkUkey));
define_hook!(CompilationRuntimeRequirementInModule: SyncSeriesBail(compilation: &mut Compilation, module_identifier: &ModuleIdentifier, runtime_requirements: &RuntimeGlobals, runtime_requirements_mut: &mut RuntimeGlobals));
define_hook!(CompilationRuntimeRequirementInModule: SyncSeriesBail(compilation: &Compilation, module_identifier: &ModuleIdentifier, runtime_requirements: &RuntimeGlobals, runtime_requirements_mut: &mut RuntimeGlobals));
define_hook!(CompilationAdditionalChunkRuntimeRequirements: SyncSeries(compilation: &mut Compilation, chunk_ukey: &ChunkUkey, runtime_requirements: &mut RuntimeGlobals));
define_hook!(CompilationAdditionalTreeRuntimeRequirements: AsyncSeries(compilation: &mut Compilation, chunk_ukey: &ChunkUkey, runtime_requirements: &mut RuntimeGlobals));
define_hook!(CompilationRuntimeRequirementInTree: SyncSeriesBail(compilation: &mut Compilation, chunk_ukey: &ChunkUkey, runtime_requirements: &RuntimeGlobals, runtime_requirements_mut: &mut RuntimeGlobals));
Expand Down Expand Up @@ -757,7 +757,7 @@ impl Compilation {
cache_counter: &mut Option<CacheCount>,
filter_op: impl Fn(&(ModuleIdentifier, &Box<dyn Module>)) -> bool + Sync + Send,
) -> Result<()> {
let results = compilation.code_generation_modules(
compilation.code_generation_modules(
cache_counter,
compilation
.get_module_graph()
Expand All @@ -766,15 +766,7 @@ impl Compilation {
.filter(filter_op)
.map(|(id, _)| id)
.collect(),
)?;

results.iter().for_each(|module_identifier| {
compilation
.code_generated_modules
.insert(*module_identifier);
});

Ok(())
)
}

run_iteration(self, &mut codegen_cache_counter, |(_, module)| {
Expand All @@ -796,7 +788,7 @@ impl Compilation {
&mut self,
cache_counter: &mut Option<CacheCount>,
modules: IdentifierSet,
) -> Result<Vec<ModuleIdentifier>> {
) -> Result<()> {
let chunk_graph = &self.chunk_graph;
let module_graph = self.get_module_graph();
let mut jobs = Vec::new();
Expand Down Expand Up @@ -860,31 +852,28 @@ impl Compilation {
.map(|(res, runtimes, from_cache)| (module, res, runtimes, from_cache))
})
.collect::<Result<Vec<_>>>()?;
let results = results
.into_iter()
.map(|(module, codegen_res, runtimes, from_cache)| {
if let Some(counter) = cache_counter {
if from_cache {
counter.hit();
} else {
counter.miss();
}
for (module, codegen_res, runtimes, from_cache) in results {
if let Some(counter) = cache_counter {
if from_cache {
counter.hit();
} else {
counter.miss();
}
}

let codegen_res_id = codegen_res.id;
let codegen_res_id = codegen_res.id;
self
.code_generation_results
.module_generation_result_map
.insert(codegen_res_id, codegen_res);
for runtime in runtimes {
self
.code_generation_results
.module_generation_result_map
.insert(codegen_res_id, codegen_res);
for runtime in runtimes {
self
.code_generation_results
.add(module, runtime, codegen_res_id);
}
module
});

Ok(results.collect())
.add(module, runtime, codegen_res_id);
}
self.code_generated_modules.insert(module);
}
Ok(())
}

#[instrument(name = "compilation::create_module_assets", skip_all)]
Expand Down Expand Up @@ -1324,52 +1313,49 @@ impl Compilation {

let logger = self.get_logger("rspack.Compilation");
let start = logger.time("runtime requirements.modules");
let mut module_runtime_requirements = modules
let results: Vec<(ModuleIdentifier, RuntimeSpec, RuntimeGlobals)> = modules
.into_par_iter()
.filter_map(|module_identifier| {
if self
.filter(|module| self.chunk_graph.get_number_of_module_chunks(*module) > 0)
.flat_map(|module| {
self
.chunk_graph
.get_number_of_module_chunks(module_identifier)
> 0
{
let mut module_runtime_requirements: Vec<(RuntimeSpec, RuntimeGlobals)> = vec![];
for runtime in self
.chunk_graph
.get_module_runtimes(module_identifier, &self.chunk_by_ukey)
.values()
{
let runtime_requirements = self
.get_module_runtimes(module, &self.chunk_by_ukey)
.into_values()
.map(|runtime| (module, runtime))
.collect::<Vec<_>>()
})
.map(|(module, runtime)| {
let runtime_requirements = self
.old_cache
.process_runtime_requirements_occasion
.use_cache(module, &runtime, self, |module, runtime| {
let mut runtime_requirements = self
.code_generation_results
.get_runtime_requirements(&module_identifier, Some(runtime));
module_runtime_requirements.push((runtime.clone(), runtime_requirements));
}
return Some((module_identifier, module_runtime_requirements));
}
None
.get_runtime_requirements(&module, Some(runtime));
process_runtime_requirement_hook(
&mut runtime_requirements,
|runtime_requirements, runtime_requirements_mut| {
plugin_driver
.compilation_hooks
.runtime_requirement_in_module
.call(
self,
&module,
runtime_requirements,
runtime_requirements_mut,
)?;
Ok(())
},
)?;
Ok(runtime_requirements)
})?;
Ok((module, runtime, runtime_requirements))
})
.collect::<Vec<_>>();

for (module_identifier, runtime_requirements) in module_runtime_requirements.iter_mut() {
for (runtime, requirements) in runtime_requirements.iter_mut() {
process_runtime_requirement_hook(
requirements,
|runtime_requirements, runtime_requirements_mut| {
plugin_driver
.compilation_hooks
.runtime_requirement_in_module
.call(
self,
module_identifier,
runtime_requirements,
runtime_requirements_mut,
)?;
Ok(())
},
)?;
self
.chunk_graph
.add_module_runtime_requirements(*module_identifier, runtime, *requirements)
}
.collect::<Result<_>>()?;
for (module, runtime, runtime_requirements) in results {
self
.chunk_graph
.add_module_runtime_requirements(module, &runtime, runtime_requirements);
}
logger.time_end(start);

Expand Down
16 changes: 8 additions & 8 deletions crates/rspack_core/src/compiler/hmr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,14 @@ where
let (old_all_modules, old_runtime_modules) = collect_changed_modules(old.compilation)?;
// TODO: should use `records`

let mut all_old_runtime: RuntimeSpec = Default::default();
for entry_ukey in old.compilation.get_chunk_graph_entries() {
if let Some(runtime) = get_chunk_from_ukey(&entry_ukey, &old.compilation.chunk_by_ukey)
.map(|entry_chunk| entry_chunk.runtime.clone())
{
all_old_runtime.extend(runtime);
}
}
let all_old_runtime = RuntimeSpec::from_iter(
old
.compilation
.get_chunk_graph_entries()
.into_iter()
.filter_map(|entry_ukey| get_chunk_from_ukey(&entry_ukey, &old.compilation.chunk_by_ukey))
.flat_map(|entry_chunk| entry_chunk.runtime.clone()),
);

let mut old_chunks: Vec<(String, RuntimeSpec)> = vec![];
for (_, chunk) in old.compilation.chunk_by_ukey.iter() {
Expand Down
19 changes: 3 additions & 16 deletions crates/rspack_core/src/compiler/module_executor/execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,7 @@ impl Task<MakeTaskContext> for ExecuteTask {

chunk.id = chunk.name.clone();
chunk.ids = vec![chunk.id.clone().expect("id is set")];
let runtime = {
let mut runtime = RuntimeSpec::default();
runtime.insert("build time".into());
runtime
};
let runtime = RuntimeSpec::from_iter(once("build time".into()));

chunk.runtime = runtime.clone();

Expand Down Expand Up @@ -163,21 +159,12 @@ impl Task<MakeTaskContext> for ExecuteTask {

compilation.create_module_hashes(modules.par_iter().copied())?;

let code_generation_results =
compilation.code_generation_modules(&mut None, modules.clone())?;

code_generation_results
.iter()
.for_each(|module_identifier| {
compilation
.code_generated_modules
.insert(*module_identifier);
});
compilation.code_generation_modules(&mut None, modules.clone())?;

Handle::current().block_on(async {
compilation
.process_runtime_requirements(
modules.clone(),
Vec::from_iter(modules.iter().copied()),
once(chunk_ukey),
once(chunk_ukey),
compilation.plugin_driver.clone(),
Expand Down
8 changes: 7 additions & 1 deletion crates/rspack_core/src/old_cache/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,16 @@ mod local;
mod occasion;
mod storage;
pub use local::*;
use occasion::{CodeGenerateOccasion, CreateChunkAssetsOccasion};
use occasion::{
CodeGenerateOccasion, CreateChunkAssetsOccasion, ProcessRuntimeRequirementsOccasion,
};
use storage::new_storage;

#[derive(Debug)]
pub struct Cache {
is_idle: AtomicBool,
pub code_generate_occasion: CodeGenerateOccasion,
pub process_runtime_requirements_occasion: ProcessRuntimeRequirementsOccasion,
pub create_chunk_assets_occasion: CreateChunkAssetsOccasion,
}

Expand All @@ -27,6 +30,9 @@ impl Cache {
Self {
is_idle: true.into(),
code_generate_occasion: CodeGenerateOccasion::new(new_storage(&options.cache)),
process_runtime_requirements_occasion: ProcessRuntimeRequirementsOccasion::new(new_storage(
&options.cache,
)),
create_chunk_assets_occasion: CreateChunkAssetsOccasion::new(new_storage(&options.cache)),
}
}
Expand Down
1 change: 1 addition & 0 deletions crates/rspack_core/src/old_cache/occasion/code_generate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ impl CodeGenerateOccasion {
Self { storage }
}

#[tracing::instrument(skip_all, fields(module = ?job.module))]
pub fn use_cache(
&self,
job: CodeGenerationJob,
Expand Down
2 changes: 2 additions & 0 deletions crates/rspack_core/src/old_cache/occasion/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
mod code_generate;
pub use code_generate::*;
mod process_runtime_requirements;
pub use process_runtime_requirements::*;
mod create_chunk_assets;
pub use create_chunk_assets::*;
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use rspack_collections::Identifier;
use rspack_error::Result;

use crate::old_cache::storage;
use crate::{get_runtime_key, Compilation, ModuleIdentifier, RuntimeGlobals, RuntimeSpec};

type Storage = dyn storage::Storage<RuntimeGlobals>;

#[derive(Debug)]
pub struct ProcessRuntimeRequirementsOccasion {
storage: Option<Box<Storage>>,
}

impl ProcessRuntimeRequirementsOccasion {
pub fn new(storage: Option<Box<Storage>>) -> Self {
Self { storage }
}

#[tracing::instrument(skip_all, fields(module = ?module))]
pub fn use_cache(
&self,
module: ModuleIdentifier,
runtime: &RuntimeSpec,
compilation: &Compilation,
provide: impl Fn(ModuleIdentifier, &RuntimeSpec) -> Result<RuntimeGlobals>,
) -> Result<RuntimeGlobals> {
let storage = match &self.storage {
Some(s) => s,
None => {
let res = provide(module, runtime)?;
return Ok(res);
}
};
let hash = compilation
.chunk_graph
.get_module_hash(module, runtime)
.expect("should have cgm hash in process_runtime_requirements");
let cache_key = Identifier::from(format!(
"{}|{}|{}",
module,
hash.encoded(),
get_runtime_key(runtime)
));
if let Some(value) = storage.get(&cache_key) {
Ok(value)
} else {
let res = provide(module, runtime)?;
storage.set(cache_key, res);
Ok(res)
}
}
}
Loading

1 comment on commit 0148015

@rspack-bot
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ“ Ran ecosystem CI: Open

suite result
modernjs ❌ failure
_selftest βœ… success
nx ❌ failure
rspress βœ… success
rslib βœ… success
rsbuild ❌ failure
examples βœ… success

Please sign in to comment.