|
1 | 1 | //! VM execution runner |
2 | 2 |
|
3 | | -use crate::HintExecutionContext; |
| 3 | +use crate::{CodeAddress, SourceLineNumber, HintExecutionContext}; |
4 | 4 | use crate::core::{ |
5 | 5 | DIMENSION, F, ONE_VEC_PTR, POSEIDON_16_NULL_HASH_PTR, POSEIDON_24_NULL_HASH_PTR, |
6 | 6 | PUBLIC_INPUT_START, VECTOR_LEN, ZERO_VEC_PTR, |
@@ -72,36 +72,82 @@ pub fn execute_bytecode( |
72 | 72 | ) -> ExecutionResult { |
73 | 73 | let mut std_out = String::new(); |
74 | 74 | let mut instruction_history = ExecutionHistory::new(); |
75 | | - execute_bytecode_helper( |
76 | | - bytecode, |
77 | | - public_input, |
78 | | - private_input, |
79 | | - no_vec_runtime_memory, |
80 | | - &mut std_out, |
81 | | - &mut instruction_history, |
82 | | - profiler, |
83 | | - function_locations, |
84 | | - ) |
85 | | - .unwrap_or_else(|err| { |
86 | | - let lines_history = &instruction_history.lines; |
87 | | - let latest_instructions = |
88 | | - &lines_history[lines_history.len().saturating_sub(STACK_TRACE_INSTRUCTIONS)..]; |
89 | | - println!( |
90 | | - "\n{}", |
91 | | - crate::diagnostics::pretty_stack_trace( |
92 | | - source_code, |
93 | | - latest_instructions, |
94 | | - function_locations |
95 | | - ) |
96 | | - ); |
97 | | - if !std_out.is_empty() { |
98 | | - println!("╔══════════════════════════════════════════════════════════════╗"); |
99 | | - println!("║ STD-OUT ║"); |
100 | | - println!("╚══════════════════════════════════════════════════════════════╝\n"); |
101 | | - print!("{std_out}"); |
| 75 | + let result = |
| 76 | + execute_bytecode_helper( |
| 77 | + bytecode, |
| 78 | + public_input, |
| 79 | + private_input, |
| 80 | + no_vec_runtime_memory, |
| 81 | + &mut std_out, |
| 82 | + &mut instruction_history, |
| 83 | + profiler, |
| 84 | + function_locations, |
| 85 | + ) |
| 86 | + .unwrap_or_else(|err| { |
| 87 | + let lines_history = &instruction_history.lines; |
| 88 | + let latest_instructions = |
| 89 | + &lines_history[lines_history.len().saturating_sub(STACK_TRACE_INSTRUCTIONS)..]; |
| 90 | + println!( |
| 91 | + "\n{}", |
| 92 | + crate::diagnostics::pretty_stack_trace( |
| 93 | + source_code, |
| 94 | + latest_instructions, |
| 95 | + function_locations |
| 96 | + ) |
| 97 | + ); |
| 98 | + if !std_out.is_empty() { |
| 99 | + println!("╔══════════════════════════════════════════════════════════════╗"); |
| 100 | + println!("║ STD-OUT ║"); |
| 101 | + println!("╚══════════════════════════════════════════════════════════════╝\n"); |
| 102 | + print!("{std_out}"); |
| 103 | + } |
| 104 | + panic!("Error during bytecode execution: {err}"); |
| 105 | + }); |
| 106 | + if profiler { |
| 107 | + print_line_cycle_counts(instruction_history); |
| 108 | + print_instruction_cycle_counts(bytecode, result.pcs.clone()); |
| 109 | + } |
| 110 | + result |
| 111 | +} |
| 112 | + |
| 113 | +fn print_line_cycle_counts(history: ExecutionHistory) { |
| 114 | + println!("Line by line cycle counts"); |
| 115 | + println!("=========================\n"); |
| 116 | + |
| 117 | + let mut gross_cycle_counts: BTreeMap<SourceLineNumber, usize> = BTreeMap::new(); |
| 118 | + for (line, cycle_count) in history.lines.iter().zip(history.lines_cycles.iter()) { |
| 119 | + let prev_count = gross_cycle_counts.get(line).unwrap_or(&0); |
| 120 | + gross_cycle_counts.insert(*line, *prev_count + cycle_count); |
| 121 | + } |
| 122 | + for (line, cycle_count) in gross_cycle_counts.iter() { |
| 123 | + println!("line {line}: {cycle_count} cycles"); |
| 124 | + } |
| 125 | + println!(""); |
| 126 | +} |
| 127 | + |
| 128 | +fn print_instruction_cycle_counts(bytecode: &Bytecode, pcs: Vec<CodeAddress>) { |
| 129 | + println!("Instruction level cycle counts"); |
| 130 | + println!("=============================="); |
| 131 | + |
| 132 | + let mut gross_cycle_counts: BTreeMap<CodeAddress, usize> = BTreeMap::new(); |
| 133 | + for pc in pcs.iter() { |
| 134 | + let prev_count = gross_cycle_counts.get(pc).unwrap_or(&0); |
| 135 | + gross_cycle_counts.insert(*pc, *prev_count + 1); |
| 136 | + } |
| 137 | + for (pc, cycle_count) in gross_cycle_counts.iter() { |
| 138 | + let instruction = &bytecode.instructions[*pc]; |
| 139 | + let hints = bytecode.hints.get(pc); |
| 140 | + match hints { |
| 141 | + Some(hints) => { |
| 142 | + for hint in hints { |
| 143 | + println!("hint: {hint}"); |
| 144 | + } |
| 145 | + }, |
| 146 | + None => {}, |
102 | 147 | } |
103 | | - panic!("Error during bytecode execution: {err}"); |
104 | | - }) |
| 148 | + println!("pc {pc}: {cycle_count} cycles: {instruction}"); |
| 149 | + } |
| 150 | + println!(""); |
105 | 151 | } |
106 | 152 |
|
107 | 153 | /// Helper function that performs the actual bytecode execution |
|
0 commit comments