MCPcopy Create free account
hub / github.com/bytecodealliance/wasmtime / build_basic_blocks

Function build_basic_blocks

src/commands/hot_blocks.rs:614–683  ·  view source on GitHub ↗

Build basic blocks for a function by disassembling its code and splitting at control flow boundaries.

(
    func_body: &[u8],
    func_offset: usize,
    address_map: &[(usize, Option<u32>)],
    clif_lines: &[(Option<u32>, String)],
    wat_map: &BTreeMap<u32, String>,
    target: &target_lexicon::Tr

Source from the content-addressed store, hash-verified

612/// Build basic blocks for a function by disassembling its code and splitting
613/// at control flow boundaries.
614fn build_basic_blocks(
615 func_body: &[u8],
616 func_offset: usize,
617 address_map: &[(usize, Option<u32>)],
618 clif_lines: &[(Option<u32>, String)],
619 wat_map: &BTreeMap<u32, String>,
620 target: &target_lexicon::Triple,
621) -> Result<Vec<BasicBlock>> {
622 let cs = build_capstone(target)?;
623 let insts =
624 crate::disas::disas_with_capstone(&cs, func_body, u64::try_from(func_offset).unwrap())?;
625
626 // Build a map from code offset -> wasm offset for instructions in this function.
627 let mut offset_to_wasm: BTreeMap<usize, Option<u32>> = BTreeMap::new();
628 for &(code_offset, wasm_offset) in address_map {
629 if code_offset >= func_offset && code_offset < func_offset + func_body.len() {
630 offset_to_wasm.insert(code_offset, wasm_offset);
631 }
632 }
633
634 // Build a map from wasm offset -> CLIF text.
635 let mut wasm_to_clif: BTreeMap<u32, Vec<&str>> = BTreeMap::new();
636 for (wasm_off, clif_text) in clif_lines {
637 if let Some(off) = wasm_off {
638 wasm_to_clif.entry(*off).or_default().push(clif_text);
639 }
640 }
641
642 // Build annotated instructions and split into basic blocks.
643 let mut blocks = Vec::new();
644 let mut current_block = Vec::new();
645
646 for inst in &insts {
647 let addr = usize::try_from(inst.address).unwrap();
648 let offset_in_func = addr - func_offset;
649
650 // Find wasm offset for this instruction.
651 let wasm_offset = find_wasm_offset_for_address(&offset_to_wasm, addr);
652
653 // Find CLIF text for this wasm offset.
654 let clif = wasm_offset
655 .and_then(|wo| wasm_to_clif.get(&wo))
656 .map(|lines| lines.join("; "));
657
658 // Find Wasm text for this wasm offset from the WAT map.
659 let wasm = wasm_offset.and_then(|wo| wat_map.get(&wo).cloned());
660
661 current_block.push(BlockInstruction {
662 offset_in_func,
663 assembly: inst.disassembly.clone(),
664 clif,
665 wasm_offset,
666 wasm,
667 });
668
669 if inst.is_jump || inst.is_return {
670 blocks.push(BasicBlock {
671 instructions: std::mem::take(&mut current_block),

Callers 3

format_hot_blocksMethod · 0.85
test_mocked_hot_blocksFunction · 0.85
test_ditto_marksFunction · 0.85

Calls 15

build_capstoneFunction · 0.85
disas_with_capstoneFunction · 0.85
OkFunction · 0.85
or_defaultMethod · 0.80
newFunction · 0.50
unwrapMethod · 0.45
lenMethod · 0.45
insertMethod · 0.45
pushMethod · 0.45
entryMethod · 0.45
mapMethod · 0.45

Tested by 2

test_mocked_hot_blocksFunction · 0.68
test_ditto_marksFunction · 0.68