55 lines
2.2 KiB
Rust
55 lines
2.2 KiB
Rust
/*!
|
|
* VM Stats & Diagnostics - prints per-instruction counters and timing
|
|
*
|
|
* Responsibility:
|
|
* - Aggregate instruction counts (by MIR opcode)
|
|
* - Print text or JSON summary based on env vars
|
|
* - Stay side-effect free w.r.t. VM execution semantics
|
|
*/
|
|
|
|
use super::vm::VM;
|
|
|
|
impl VM {
|
|
/// Print simple VM execution statistics when enabled via env var
|
|
pub(super) fn maybe_print_stats(&mut self) {
|
|
let enabled = std::env::var("NYASH_VM_STATS").ok().map(|v| v != "0").unwrap_or(false);
|
|
if !enabled { return; }
|
|
|
|
let elapsed_ms = self.exec_start.map(|t| t.elapsed().as_secs_f64() * 1000.0).unwrap_or(0.0);
|
|
let mut items: Vec<(&str, usize)> = self.instr_counter.iter().map(|(k,v)| (*k, *v)).collect();
|
|
items.sort_by(|a,b| b.1.cmp(&a.1).then_with(|| a.0.cmp(&b.0)));
|
|
let total: usize = items.iter().map(|(_,v)| *v).sum();
|
|
|
|
let json_enabled = std::env::var("NYASH_VM_STATS_JSON").ok().map(|v| v != "0").unwrap_or(false)
|
|
|| std::env::var("NYASH_VM_STATS_FORMAT").map(|v| v == "json").unwrap_or(false);
|
|
|
|
if json_enabled {
|
|
let counts_obj: std::collections::BTreeMap<&str, usize> = self.instr_counter.iter().map(|(k,v)| (*k, *v)).collect();
|
|
let top20: Vec<_> = items.iter().take(20).map(|(op,cnt)| {
|
|
serde_json::json!({ "op": op, "count": cnt })
|
|
}).collect();
|
|
let now_ms = {
|
|
use std::time::{SystemTime, UNIX_EPOCH};
|
|
SystemTime::now().duration_since(UNIX_EPOCH).map(|d| d.as_millis() as u64).unwrap_or(0)
|
|
};
|
|
let payload = serde_json::json!({
|
|
"total": total,
|
|
"elapsed_ms": elapsed_ms,
|
|
"counts": counts_obj,
|
|
"top20": top20,
|
|
"timestamp_ms": now_ms
|
|
});
|
|
match serde_json::to_string_pretty(&payload) {
|
|
Ok(s) => println!("{}", s),
|
|
Err(_) => println!("{{\"total\":{},\"elapsed_ms\":{:.3}}}", total, elapsed_ms),
|
|
}
|
|
} else {
|
|
println!("\n🧮 VM Stats: {} instructions in {:.3} ms", total, elapsed_ms);
|
|
for (k, v) in items.into_iter().take(20) {
|
|
println!(" {:>10}: {:>8}", k, v);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|