wamex_cli/analysis/
debug.rs1use std::fmt::Debug;
2
3use crate::{
4 analysis::{
5 self,
6 dep_graph::{DepGraph, DepSet},
7 split_point::OutputModuleInfo,
8 symbols::{SymbolKind, SymbolRecord},
9 },
10 helpers::debug_fmt_mostly_filled,
11 index::SymbolId,
12};
13
14pub(crate) fn print_deps_inner(
15 module_name: &str,
16 info: &analysis::ModuleInfo,
17 reachable: &DepSet,
18 graph: &DepGraph,
19) {
20 let size_fn = |symbol: &SymbolRecord| match symbol.kind {
21 SymbolKind::DataDefined { length, .. } => length,
22 SymbolKind::Func { input_id } => {
23 if let Some(defined_id) = info.as_defined_function_id(input_id) {
24 info.wasm.code.defined_funcs[defined_id].body.range().len()
25 } else {
26 0
27 }
28 }
29 _ => unreachable!(),
30 };
31 let format_dep = |dep: SymbolId| {
32 let symbol = info.symbols.get(dep).expect("dep should be valid");
33 let name = crate::helpers::demangle_full(&symbol.name);
34 match symbol.kind {
35 SymbolKind::Func { input_id } => {
36 format!(
37 "{dep} func[{input_id}] <{name:?}> (size={})",
38 size_fn(symbol)
39 )
40 }
41 SymbolKind::DataDefined {
42 segment_id,
43 offset,
44 length,
45 ..
46 } => {
47 let segment_name = info
48 .wasm
49 .names
50 .data_segments
51 .get(segment_id)
52 .cloned()
53 .unwrap_or_default();
54 format!(
55 "{dep} data[{segment_name}({segment_id}):{start}..{end}] <{name:?}> (size={})",
56 size_fn(symbol),
57 start = offset,
58 end = offset + length
59 )
60 }
61 _ => unreachable!(),
62 }
63 };
64
65 println!("SPLIT: ============== {module_name}");
66 for (node, children) in graph.iter_childs() {
67 if !reachable.contains(&node) {
68 continue;
69 }
70
71 println!("---{}---", format_dep(node));
72 for parent in graph.get_parents(node).into_iter().flatten() {
73 println!("<=={} (parent)", format_dep(*parent));
74 }
75 println!("-------------");
76 for child in children {
77 println!("==>{}", format_dep(*child));
78 }
79 }
80
81 let mut total_size: usize = 0;
82 for r in reachable.iter() {
83 let symbol = info.symbols.get(*r).expect("dep should be valid");
84 total_size += size_fn(symbol);
85 }
86 println!("SPLIT: ============== {module_name} : total size: {total_size}");
87}
88
89impl Debug for OutputModuleInfo {
90 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
91 let mut defined_symbols = self.defined_symbols.iter().copied().collect::<Vec<_>>();
92
93 let mut imported_symbols = self.imports.iter().copied().collect::<Vec<_>>();
94
95 let mut exported_symbols = self.exports.iter().copied().collect::<Vec<_>>();
96
97 defined_symbols.sort_unstable();
98 imported_symbols.sort_unstable();
99 exported_symbols.sort_unstable();
100
101 f.debug_struct("OutputModuleInfo")
102 .field(
103 "imported_symbols",
104 &debug_fmt_mostly_filled(&imported_symbols, 3, 7, "...", |a, b| a.next() != *b),
105 )
106 .field(
107 "exported_symbols",
108 &debug_fmt_mostly_filled(&exported_symbols, 3, 7, "...", |a, b| a.next() != *b),
109 )
110 .field(
111 "defined_symbols",
112 &debug_fmt_mostly_filled(&defined_symbols, 3, 7, "...", |a, b| a.next() != *b),
113 )
114 .finish()
115 }
116}
117
118impl OutputModuleInfo {
119 pub fn print(&self, module_name: &str, info: &analysis::ModuleInfo, graph: &DepGraph) {
120 print_deps_inner(module_name, info, &self.defined_symbols, graph);
121 }
122}