Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add cache for process runtime requirements #7601

Merged
merged 1 commit into from
Aug 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading