9bbe5ae67a
LiveInfo 四矩阵由逐位 Vec<bool>(1 字节/位,长度 = max_vreg+1)改为 u64 压缩位集(1 字 64 位,长度 ÷8),dataflow 不动点 out/input 缓冲 提为循环外复用(clear + 覆盖,免逐迭代逐块分配)。dce_precise / graph 建图 / call_window 三处消费方同步改为字内位移查询,越界语义 与旧 Vec<bool>::get 一致(越界 = 不 live)。位集遍历(call_window 存活上界)按 trailing_zeros 只走实际置位,活集小则近 O(活集) 而非 O(254)。 实测(debug,start-unicode-17.0.0.js):liveness 三趟合计 ~536ms → ~118ms(-78%),矩阵内存 ÷8;graph 全 node 扫描为剩余 瓶颈,另行跟进。
61 lines
2.2 KiB
Rust
61 lines
2.2 KiB
Rust
//! 集成冒烟:真实编译产物(parse→emit→build_cfg→liveness)跑不崩 + 维度一致性 + try/catch reg0 断言 + 确定性。
|
|
|
|
use oxide_cfg::build_cfg;
|
|
use oxide_liveness::{liveness, LiveInfo};
|
|
|
|
fn run_liveness(src: &str) -> (LiveInfo, oxide_cfg::Cfg, usize) {
|
|
let allocator = oxide_parser::Allocator::default();
|
|
let program = oxide_parser::parse(&allocator, src).expect("parse");
|
|
let ir = oxide_emit::Emitter::new().emit_program(&program).expect("emit");
|
|
let cfg = build_cfg(&ir);
|
|
let info = liveness(&ir, &cfg);
|
|
(info, cfg, ir.insts.len())
|
|
}
|
|
|
|
fn smoke(src: &str) {
|
|
let (info, cfg, inst_len) = run_liveness(src);
|
|
assert_eq!(info.block_live_in.len(), cfg.blocks.len(), "block 维度一致");
|
|
assert_eq!(info.block_live_out.len(), cfg.blocks.len(), "block 维度一致");
|
|
assert_eq!(info.inst_live_before.len(), inst_len, "inst 维度一致");
|
|
assert_eq!(info.inst_live_after.len(), inst_len, "inst 维度一致");
|
|
}
|
|
|
|
#[test]
|
|
fn smoke_simple_function() {
|
|
smoke("function f(a, b) { return a + b; } f(1, 2)");
|
|
}
|
|
|
|
#[test]
|
|
fn smoke_if_else() {
|
|
smoke("function f(x) { if (x > 0) { return 1; } else { return 2; } } f(5)");
|
|
}
|
|
|
|
#[test]
|
|
fn smoke_loop_with_variables() {
|
|
smoke("function f(n) { var s = 0; for (var i = 0; i < n; i++) { s = s + i; } return s; } f(10)");
|
|
}
|
|
|
|
#[test]
|
|
fn smoke_try_catch() {
|
|
let (info, cfg, _) =
|
|
run_liveness("function x() {} function y(e) {} function f() { try { x(); } catch (e) { y(e); } } f()");
|
|
// entry 块 liveIn 不含 reg 0(异常边 reg0 截断在真实产物上成立)
|
|
assert!(!oxide_liveness::bitset_get(&info.block_live_in[cfg.entry], 0), "entry 块 liveIn 不得含 reg0");
|
|
}
|
|
|
|
#[test]
|
|
fn smoke_nested_calls() {
|
|
smoke("function g(x) { return x + 1; } function f(x) { return g(x) + g(x + 1); } f(1)");
|
|
}
|
|
|
|
#[test]
|
|
fn liveness_is_deterministic() {
|
|
let src = "function f(n) { var s = 0; for (var i = 0; i < n; i++) { s = s + i; } return s; } f(10)";
|
|
let (a, _, _) = run_liveness(src);
|
|
let (b, _, _) = run_liveness(src);
|
|
assert_eq!(a.block_live_in, b.block_live_in);
|
|
assert_eq!(a.block_live_out, b.block_live_out);
|
|
assert_eq!(a.inst_live_before, b.inst_live_before);
|
|
assert_eq!(a.inst_live_after, b.inst_live_after);
|
|
}
|