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:
2026-08-15 09:08:05 +08:00
parent f8dacb192a
commit 9b2e33916a
10 changed files with 423 additions and 0 deletions
+7
View File
@@ -450,6 +450,12 @@ define_opcodes! {
SET_PROP_BATCH = 0x92 => "SET_PROP_BATCH",
def = None, uses = [SlotSpec::Slot(Slot::Rd), SlotSpec::Slot(Slot::A), SlotSpec::Slot(Slot::B)],
pure = false, jump = false, term = false, ic = false,
// 多操作数拼接(连续 `+` 左结合链摊平):rd=结果,a=首操作数,ext=[n, op2..opn],
// n=操作数总数,ext 字数 = 1+(n-1) = n;op 字无高位标记(纯 vreg,≤255),
// SpreadArgs 直接解析。与 ADD 同标纯(含 ToPrimitive 副作用仍静态可删,语义同 ADD)。
CONCAT_N = 0x93 => "CONCAT_N",
def = Some(SlotSpec::Slot(Slot::Rd)), uses = [SlotSpec::Slot(Slot::A), SlotSpec::SpreadArgs],
pure = true, jump = false, term = false, ic = false,
// ── 成员更新 (0x59-0x62) ──
MEMBER_INC = 0x59 => "MEMBER_INC", // 结果写 a 槽(val 槽原地更新)
@@ -783,6 +789,7 @@ mod tests {
assert_eq!(OpCode::CREATE_REST_ARRAY as u8, 0x6E);
assert_eq!(OpCode::DEFINE_ACCESSOR_DYNAMIC as u8, 0x7F);
assert_eq!(OpCode::SET_PROP_BATCH as u8, 0x92);
assert_eq!(OpCode::CONCAT_N as u8, 0x93);
assert_eq!(OpCode::ADD.to_string(), "ADD");
assert_eq!(OpCode::COMPOUND_MEMBER_EXP.to_string(), "COMPOUND_MEMBER_EXP");
assert_eq!(OpCode::MOV.to_string(), "MOV");