Executes the command.
(mut self)
| 93 | impl HotBlocksCommand { |
| 94 | /// Executes the command. |
| 95 | pub fn execute(mut self) -> Result<()> { |
| 96 | self.run.common.init_logging()?; |
| 97 | |
| 98 | if !(0.0..=100.0).contains(&self.percent) { |
| 99 | bail!("--percent must be between 0 and 100 inclusive"); |
| 100 | } |
| 101 | |
| 102 | // Ensure address maps are enabled (error if explicitly disabled). |
| 103 | if self.run.common.debug.address_map == Some(false) { |
| 104 | bail!( |
| 105 | "address maps must be enabled for hot-blocks profiling; do not pass -Daddress-map=n" |
| 106 | ); |
| 107 | } |
| 108 | self.run.common.debug.address_map = Some(true); |
| 109 | |
| 110 | let tmp_dir = tempdir().context("failed to create temp directory")?; |
| 111 | |
| 112 | // Compile the input Wasm to a .cwasm, emitting CLIF to the temp dir. |
| 113 | let clif_dir = tmp_dir.path().join("clif"); |
| 114 | std::fs::create_dir(&clif_dir)?; |
| 115 | let cwasm_path = tmp_dir.path().join("module.cwasm"); |
| 116 | |
| 117 | let wasm_bytes = |
| 118 | Cow::Owned(std::fs::read(&self.module).with_context(|| { |
| 119 | format!("failed to read Wasm module: {}", self.module.display()) |
| 120 | })?); |
| 121 | #[cfg(feature = "wat")] |
| 122 | let wasm_bytes = wat::parse_bytes(&wasm_bytes).map_err(|mut e| { |
| 123 | e.set_path(&self.module); |
| 124 | e |
| 125 | })?; |
| 126 | |
| 127 | let engine = self.compile_to_cwasm(&clif_dir, &cwasm_path, &wasm_bytes)?; |
| 128 | |
| 129 | // Run perf record. |
| 130 | let perf_data_path = tmp_dir.path().join("perf.data"); |
| 131 | self.run_perf_record(&cwasm_path, &perf_data_path)?; |
| 132 | |
| 133 | // Run perf script and parse samples. |
| 134 | let (samples, total_samples) = self.run_perf_script(&perf_data_path)?; |
| 135 | |
| 136 | let target = match self.run.common.target.as_deref() { |
| 137 | None => target_lexicon::Triple::host(), |
| 138 | Some(t) => target_lexicon::Triple::from_str(t)?, |
| 139 | }; |
| 140 | |
| 141 | // Build the WAT offset map using wasmprinter. |
| 142 | let wat_map = build_wat_offset_map(&wasm_bytes); |
| 143 | |
| 144 | // Deserialize the cwasm to extract functions, text, and address map. |
| 145 | self.run.allow_precompiled = true; |
| 146 | let run_target = self.run.load_module(&engine, &cwasm_path, None)?; |
| 147 | let (functions, text, address_map) = match &run_target { |
| 148 | RunTarget::Core(module) => ( |
| 149 | module.functions().collect::<Vec<_>>(), |
| 150 | module.text(), |
| 151 | module |
| 152 | .address_map() |
nothing calls this directly
no test coverage detected