mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-24 02:31:13 +08:00
perf: CONCAT_N 多操作数拼接单趟精确预分配替代逐次 ADD
新增 CONCAT_N opcode(0x93):连续加号左结合链摊平为单条指令, 字符串模式单趟精确总长预分配,消除 N-2 次中间串分配与逐次整串重拷贝。 - emit 只下钻 left 链、right 括号不拆(a+(b+c) 退化 ADD),求值序与 f64 结合性保持左结合原义;摊平上限 14 防超长链寄存器压力 - dispatch 两阶段:数值前缀逐项复用 ADD 判定序列(int 溢出升 double、 BigInt 混合 TypeError、对象 ToPrimitive 副作用序),遇字符串转入 字符串模式单趟预分配拼接(concat_n_strings) - RegAlloc graph/rewrite 登记 CONCAT_N ext 操作数(漏收集即错值); ic_helper ext_word_count 登记(clear_ic_caches 字节定位) - contract golden 显式 CONCAT_N 分支(规避 canonical_inst _ 兜底)
This commit is contained in:
@@ -86,6 +86,16 @@ pub(super) fn collect_real_vregs(f: &IRFunction) -> BTreeSet<u32> {
|
||||
real.insert(r);
|
||||
}
|
||||
}
|
||||
// CONCAT_N:ext[1..] 每个字是完整操作数 vreg(无高位标记)——漏收集则
|
||||
// RegAlloc 不分配该 vreg,物理号冲突 → 错值。
|
||||
if inst.op == OpCode::CONCAT_N {
|
||||
for &w in inst.ext.iter().skip(1) {
|
||||
let r = w & 0x7FFF_FFFF;
|
||||
if r != 0 {
|
||||
real.insert(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
real
|
||||
}
|
||||
@@ -474,4 +484,21 @@ mod tests {
|
||||
assert!(g.nodes.contains_key(&254), "vreg 254 建节点");
|
||||
assert_eq!(g.nodes[&254].pre_color, None, "254 非预着色");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn concat_n_ext_operands_collected_as_real() {
|
||||
// CONCAT_N 的 ext 操作数 vreg 必须进入真实集合(漏收集 → 未染色 → 错值)
|
||||
let mut f = empty_function();
|
||||
f.insts.push(Inst::concat_n(Operand::Reg(1), &[2, 5, 9, 300]));
|
||||
f.insts
|
||||
.push(Inst::new(OpCode::RETURN, Operand::Reg(1), Operand::None, Operand::None));
|
||||
let real = collect_real_vregs(&f);
|
||||
for r in [1u32, 2, 5, 9, 300] {
|
||||
assert!(real.contains(&r), "vreg {r} 应被 CONCAT_N 收集");
|
||||
}
|
||||
let g = build_graph(&f);
|
||||
for r in [1u32, 2, 5, 9, 300] {
|
||||
assert!(g.nodes.contains_key(&r), "vreg {r} 建节点");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user