Skip to content

Commit d9915de

Browse files
authored
refactor: move pass into separate folder and driven by run_passes (#12735)
* chore: add rspack_passes.md * refactor: move pass into separate folder and drive by run_passes * chore: use function * refactor: move more into run_passes * chore: fix stats logging * chore: fix stats.logging
1 parent 785c0f6 commit d9915de

File tree

24 files changed

+2135
-1854
lines changed

24 files changed

+2135
-1854
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
use super::*;
2+
use crate::logger::Logger;
3+
4+
pub async fn after_seal_pass(
5+
compilation: &mut Compilation,
6+
plugin_driver: SharedPluginDriver,
7+
) -> Result<()> {
8+
let logger = compilation.get_logger("rspack.Compilation");
9+
let start = logger.time("after seal");
10+
compilation.after_seal(plugin_driver).await?;
11+
logger.time_end(start);
12+
Ok(())
13+
}
14+
15+
impl Compilation {
16+
#[instrument("Compilation:after_seal", target=TRACING_BENCH_TARGET,skip_all)]
17+
async fn after_seal(&mut self, plugin_driver: SharedPluginDriver) -> Result<()> {
18+
plugin_driver.compilation_hooks.after_seal.call(self).await
19+
}
20+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
use super::*;
2+
3+
pub fn assign_runtime_ids(compilation: &mut Compilation) {
4+
fn process_entrypoint(
5+
entrypoint_ukey: &ChunkGroupUkey,
6+
chunk_group_by_ukey: &ChunkGroupByUkey,
7+
chunk_by_ukey: &ChunkByUkey,
8+
chunk_graph: &mut ChunkGraph,
9+
) {
10+
let entrypoint = chunk_group_by_ukey.expect_get(entrypoint_ukey);
11+
let runtime = entrypoint
12+
.kind
13+
.get_entry_options()
14+
.and_then(|o| match &o.runtime {
15+
Some(EntryRuntime::String(s)) => Some(s.to_owned()),
16+
_ => None,
17+
})
18+
.or(entrypoint.name().map(|n| n.to_string()));
19+
if let (Some(runtime), Some(chunk)) = (
20+
runtime,
21+
chunk_by_ukey.get(&entrypoint.get_runtime_chunk(chunk_group_by_ukey)),
22+
) {
23+
chunk_graph.set_runtime_id(runtime, chunk.id().map(|id| id.to_string()));
24+
}
25+
}
26+
for i in compilation.entrypoints.iter() {
27+
process_entrypoint(
28+
i.1,
29+
&compilation.chunk_group_by_ukey,
30+
&compilation.chunk_by_ukey,
31+
&mut compilation.chunk_graph,
32+
)
33+
}
34+
for i in compilation.async_entrypoints.iter() {
35+
process_entrypoint(
36+
i,
37+
&compilation.chunk_group_by_ukey,
38+
&compilation.chunk_by_ukey,
39+
&mut compilation.chunk_graph,
40+
)
41+
}
42+
}

crates/rspack_core/src/compilation/build_chunk_graph/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use crate::{Compilation, incremental::IncrementalPasses};
77
pub(crate) mod artifact;
88
pub(crate) mod code_splitter;
99
pub(crate) mod incremental;
10+
pub(crate) mod pass;
1011

1112
#[instrument("Compilation:build_chunk_graph", skip_all)]
1213
pub fn build_chunk_graph(compilation: &mut Compilation) -> rspack_error::Result<()> {
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
use rspack_error::Result;
2+
3+
use crate::{
4+
compilation::{
5+
Compilation,
6+
build_chunk_graph::{artifact::use_code_splitting_cache, build_chunk_graph},
7+
},
8+
logger::Logger,
9+
};
10+
11+
pub async fn build_chunk_graph_pass(compilation: &mut Compilation) -> Result<()> {
12+
let logger = compilation.get_logger("rspack.Compilation");
13+
compilation.module_graph_cache_artifact.freeze();
14+
use_code_splitting_cache(compilation, |compilation| async {
15+
let start = logger.time("rebuild chunk graph");
16+
build_chunk_graph(compilation)?;
17+
compilation
18+
.chunk_graph
19+
.generate_dot(compilation, "after-code-splitting")
20+
.await;
21+
logger.time_end(start);
22+
Ok(compilation)
23+
})
24+
.await?;
25+
Ok(())
26+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
use super::*;
2+
use crate::logger::Logger;
3+
4+
pub async fn chunk_ids_pass(
5+
compilation: &mut Compilation,
6+
plugin_driver: SharedPluginDriver,
7+
) -> Result<()> {
8+
let logger = compilation.get_logger("rspack.Compilation");
9+
let start = logger.time("chunk ids");
10+
11+
// Check if CHUNK_IDS pass is disabled, and clear artifact if needed
12+
if !compilation
13+
.incremental
14+
.passes_enabled(IncrementalPasses::CHUNK_IDS)
15+
{
16+
compilation.named_chunk_ids_artifact.clear();
17+
}
18+
19+
let mut diagnostics = vec![];
20+
let mut chunk_by_ukey = mem::take(&mut compilation.chunk_by_ukey);
21+
let mut named_chunk_ids_artifact = mem::take(&mut compilation.named_chunk_ids_artifact);
22+
plugin_driver
23+
.compilation_hooks
24+
.chunk_ids
25+
.call(
26+
compilation,
27+
&mut chunk_by_ukey,
28+
&mut named_chunk_ids_artifact,
29+
&mut diagnostics,
30+
)
31+
.await
32+
.map_err(|e| e.wrap_err("caused by plugins in Compilation.hooks.chunkIds"))?;
33+
compilation.chunk_by_ukey = chunk_by_ukey;
34+
compilation.named_chunk_ids_artifact = named_chunk_ids_artifact;
35+
compilation.extend_diagnostics(diagnostics);
36+
logger.time_end(start);
37+
Ok(())
38+
}
Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
use super::*;
2+
use crate::logger::Logger;
3+
4+
pub async fn code_generation_pass(
5+
compilation: &mut Compilation,
6+
plugin_driver: SharedPluginDriver,
7+
) -> Result<()> {
8+
let logger = compilation.get_logger("rspack.Compilation");
9+
let start = logger.time("code generation");
10+
let code_generation_modules = if let Some(mutations) = compilation
11+
.incremental
12+
.mutations_read(IncrementalPasses::MODULES_CODEGEN)
13+
&& !compilation.code_generation_results.is_empty()
14+
{
15+
let revoked_modules = mutations.iter().filter_map(|mutation| match mutation {
16+
Mutation::ModuleRemove { module } => Some(*module),
17+
_ => None,
18+
});
19+
for revoked_module in revoked_modules {
20+
compilation.code_generation_results.remove(&revoked_module);
21+
}
22+
let modules: IdentifierSet = mutations
23+
.iter()
24+
.filter_map(|mutation| match mutation {
25+
Mutation::ModuleSetHashes { module } => Some(*module),
26+
_ => None,
27+
})
28+
.collect();
29+
// also cleanup for updated modules, for `insert(); insert();` the second insert() won't override the first insert() on code_generation_results
30+
for module in &modules {
31+
compilation.code_generation_results.remove(module);
32+
}
33+
tracing::debug!(target: incremental::TRACING_TARGET, passes = %IncrementalPasses::MODULES_CODEGEN, %mutations);
34+
let logger = compilation.get_logger("rspack.incremental.modulesCodegen");
35+
logger.log(format!(
36+
"{} modules are affected, {} in total",
37+
modules.len(),
38+
compilation.get_module_graph().modules().len()
39+
));
40+
modules
41+
} else {
42+
compilation.code_generation_results = Default::default();
43+
compilation
44+
.get_module_graph()
45+
.modules()
46+
.keys()
47+
.copied()
48+
.collect()
49+
};
50+
compilation.code_generation(code_generation_modules).await?;
51+
52+
let mut diagnostics = vec![];
53+
plugin_driver
54+
.compilation_hooks
55+
.after_code_generation
56+
.call(compilation, &mut diagnostics)
57+
.await
58+
.map_err(|e| e.wrap_err("caused by plugins in Compilation.hooks.afterCodeGeneration"))?;
59+
compilation.extend_diagnostics(diagnostics);
60+
61+
logger.time_end(start);
62+
Ok(())
63+
}
64+
65+
impl Compilation {
66+
#[instrument("Compilation:code_generation",target=TRACING_BENCH_TARGET, skip_all)]
67+
async fn code_generation(&mut self, modules: IdentifierSet) -> Result<()> {
68+
let logger = self.get_logger("rspack.Compilation");
69+
let mut codegen_cache_counter = match self.options.cache {
70+
CacheOptions::Disabled => None,
71+
_ => Some(logger.cache("module code generation cache")),
72+
};
73+
74+
let module_graph = self.get_module_graph();
75+
let mut no_codegen_dependencies_modules = IdentifierSet::default();
76+
let mut has_codegen_dependencies_modules = IdentifierSet::default();
77+
for module_identifier in modules {
78+
let module = module_graph
79+
.module_by_identifier(&module_identifier)
80+
.expect("should have module");
81+
if module.get_code_generation_dependencies().is_none() {
82+
no_codegen_dependencies_modules.insert(module_identifier);
83+
} else {
84+
has_codegen_dependencies_modules.insert(module_identifier);
85+
}
86+
}
87+
88+
self
89+
.code_generation_modules(&mut codegen_cache_counter, no_codegen_dependencies_modules)
90+
.await?;
91+
self
92+
.code_generation_modules(&mut codegen_cache_counter, has_codegen_dependencies_modules)
93+
.await?;
94+
95+
if let Some(counter) = codegen_cache_counter {
96+
logger.cache_end(counter);
97+
}
98+
99+
Ok(())
100+
}
101+
102+
pub(crate) async fn code_generation_modules(
103+
&mut self,
104+
cache_counter: &mut Option<CacheCount>,
105+
modules: IdentifierSet,
106+
) -> Result<()> {
107+
let chunk_graph = &self.chunk_graph;
108+
let module_graph = self.get_module_graph();
109+
let mut jobs = Vec::new();
110+
for module in modules {
111+
let mut map: HashMap<RspackHashDigest, CodeGenerationJob> = HashMap::default();
112+
for runtime in chunk_graph.get_module_runtimes_iter(module, &self.chunk_by_ukey) {
113+
let hash = ChunkGraph::get_module_hash(self, module, runtime)
114+
.expect("should have cgm.hash in code generation");
115+
let scope = self
116+
.plugin_driver
117+
.compilation_hooks
118+
.concatenation_scope
119+
.call(self, module)
120+
.await?;
121+
if let Some(job) = map.get_mut(hash) {
122+
job.runtimes.push(runtime.clone());
123+
} else {
124+
map.insert(
125+
hash.clone(),
126+
CodeGenerationJob {
127+
module,
128+
hash: hash.clone(),
129+
runtime: runtime.clone(),
130+
runtimes: vec![runtime.clone()],
131+
scope,
132+
},
133+
);
134+
}
135+
}
136+
jobs.extend(map.into_values());
137+
}
138+
139+
let results = rspack_futures::scope::<_, _>(|token| {
140+
jobs.into_iter().for_each(|job| {
141+
// SAFETY: await immediately and trust caller to poll future entirely
142+
let s = unsafe { token.used((&self, &module_graph, job)) };
143+
144+
s.spawn(|(this, module_graph, job)| async {
145+
let options = &this.options;
146+
let old_cache = &this.old_cache;
147+
148+
let module = module_graph
149+
.module_by_identifier(&job.module)
150+
.expect("should have module");
151+
let codegen_res = old_cache
152+
.code_generate_occasion
153+
.use_cache(&job, || async {
154+
module
155+
.code_generation(this, Some(&job.runtime), job.scope.clone())
156+
.await
157+
.map(|mut codegen_res| {
158+
codegen_res.set_hash(
159+
&options.output.hash_function,
160+
&options.output.hash_digest,
161+
&options.output.hash_salt,
162+
);
163+
codegen_res
164+
})
165+
})
166+
.await;
167+
168+
(job.module, job.runtimes, codegen_res)
169+
})
170+
})
171+
})
172+
.await;
173+
let results = results
174+
.into_iter()
175+
.map(|res| res.to_rspack_result())
176+
.collect::<Result<Vec<_>>>()?;
177+
178+
for (module, runtimes, (codegen_res, from_cache)) in results {
179+
if let Some(counter) = cache_counter {
180+
if from_cache {
181+
counter.hit();
182+
} else {
183+
counter.miss();
184+
}
185+
}
186+
let codegen_res = match codegen_res {
187+
Ok(codegen_res) => codegen_res,
188+
Err(err) => {
189+
let mut diagnostic = Diagnostic::from(err);
190+
diagnostic.module_identifier = Some(module);
191+
self.push_diagnostic(diagnostic);
192+
let mut codegen_res = CodeGenerationResult::default();
193+
codegen_res.set_hash(
194+
&self.options.output.hash_function,
195+
&self.options.output.hash_digest,
196+
&self.options.output.hash_salt,
197+
);
198+
codegen_res
199+
}
200+
};
201+
self
202+
.code_generation_results
203+
.insert(module, codegen_res, runtimes);
204+
self.code_generated_modules.insert(module);
205+
}
206+
Ok(())
207+
}
208+
}

0 commit comments

Comments
 (0)