docs: 清理寄存器分配注释并重命名样例测试

This commit is contained in:
2026-09-17 16:05:45 +00:00
parent 0b33f4253a
commit d81777e8b2
4 changed files with 9 additions and 8 deletions
+7 -6
View File
@@ -3,7 +3,7 @@
//! - n_registers = map.phys_peak(≤254;最高合法物理槽 253 对应窗口大小 254;
//! 不含参数窗口——窗口是调用点暂存槽,
//! CALL handler 在 push 前收集 args 进 Vec,n_registers 只控 save_stack 窗口)
//! - builtin_reg_map:Phys → 新号;Spill → spilled_builtin_bindings 的自由色 R(与 rewrite 同源)
//! - builtin_reg_map:Phys → 新号;Spill → spilled_builtin_bindings 的自由色 R(与 rewrite 取同一 AllocMap 分配结果)
//! - param_layout 按参数首槽物理色回写;upvalue_captures 不动(escaped 预着色恒等)
use crate::alloc_map::{Alloc, AllocMap};
@@ -12,11 +12,12 @@ use oxide_ir::IRFunction;
/// 回写 IRFunction 元数据(不动 insts——rewrite 已完成改写)。
pub(super) fn run(f: &mut IRFunction, map: &AllocMap) {
// (a) n_registers = phys_peak
// 先写 n_registers = phys_peak(最高物理槽数,恒 ≤ 254)。
debug_assert!(map.phys_peak <= 254, "phys_peak 超 254");
f.n_registers = map.phys_peak;
// (b) builtin_reg_map 回写
// 再回写 builtin_reg_map:Phys 直接换新号;Spill 取入口
// spilled_builtin_bindings 的自由色 R(与 rewrite 取同一 AllocMap 分配结果)。
let spilled = spilled_builtin_bindings(f, map);
let mut rewritten_builtins = Vec::with_capacity(f.builtin_reg_map.len());
for (name, vreg) in &f.builtin_reg_map {
@@ -38,7 +39,7 @@ pub(super) fn run(f: &mut IRFunction, map: &AllocMap) {
}
f.builtin_reg_map = rewritten_builtins;
// (c) 参数段保持连续,但继承父上下文产生的高虚拟段会整体移动到低位物理段。
// 参数段保持连续,但继承父上下文产生的高虚拟段会整体移动到低位物理段。
let pl = f.param_layout;
if pl.count > 0 {
if let Some(Alloc::Phys(base)) = map.map.get(&pl.base) {
@@ -52,7 +53,7 @@ pub(super) fn run(f: &mut IRFunction, map: &AllocMap) {
f.param_layout.base = 0;
}
// (d) upvalue_captures 不动。enclosing_reg 是编译期产物(MAKE_CELL 定位用),VM 运行时
// upvalue_captures 不动。enclosing_reg 是编译期产物(MAKE_CELL 定位用),VM 运行时
// 不读(CREATE_CLOSURE 走 cell_idx,cell 捕获后值在 cell 中)——无需跨函数同步。
// 直接槽引用(class field 计算键等)的 escaped vreg 已由预着色恒等保留。
// 注:cell 捕获变量的父 vreg 可被 RegAlloc 移动(MAKE_CELL 后值入 cell,与寄存器无关),
@@ -107,7 +108,7 @@ mod tests {
let binds = spilled_builtin_bindings(&f, &map);
run(&mut f, &map);
assert_eq!(f.builtin_reg_map[0].0, "Math");
assert_eq!(f.builtin_reg_map[0].1, binds[0].1, "回写 R 与入口 SPILL 同源");
assert_eq!(f.builtin_reg_map[0].1, binds[0].1, "回写 R 与入口 SPILL 取同一 AllocMap 分配结果");
}
#[test]
+1 -1
View File
@@ -187,7 +187,7 @@ pub(super) fn build(
// builtin use 前执行写入 → 覆写全局值。
// 恒等号 v 在 ≤253 且不落入参数 MOV 窗口时保持恒等;大函数晚引用 builtin 的槽号
// >253(或 ≥arg_window_base 与 MOV 桥冲突)时恒等号不可编码 → 改分配确定性自由色
// R(算法与 spilled_builtin_bindings 同源:1..arg_window_base 中最小未占用)。
// R(与 spilled_builtin_bindings 取同一 AllocMap 分配结果:1..arg_window_base 中最小未占用)。
let mut builtin_entries: Vec<(String, u32)> = f
.builtin_reg_map
.iter()
+1 -1
View File
@@ -277,7 +277,7 @@ fn rewrite_inst(
}
let _ = f;
// 防御:imm16 编码位的操作数必须是 Imm/None,不得是 Reg——
// 否则会被上面的 Reg 重写改号,VM 侧 imm16 读到错值(历史 B020 根因)。
// 上面的 Reg 重写会改号,若该槽被改写,VM 侧按 imm16 读取会拿到错误值。
match inst.op {
OpCode::LOAD_UPVALUE | OpCode::CREATE_CLOSURE => {
debug_assert!(