fix: 执行期字符串 GC 触发点移到指令边界,消除 builtin 局部活串悬垂

分配点触发会把仅存于 builtin 函数栈上局部 JsValue 与构造中未登记对象的
存活串判死释放(temporal 槽、regexp exec 构造中数组、replace 回调参数
Vec),长会话超阈值即悬垂。触发改在 dispatch 指令边界,此时所有局部值已
落地为执行根;分配点只留账目。水位采用上次收集存活字节加阈值增量,活串
超阈值时不会每指令重复白跑;reset 完整收集仍按阈值直接比较。debug 构建下
收集后断言存活对象字符串边已登记。补低阈值回归:regexp exec 旧行为直接
SIGABRT,temporal 与 replace 结果断言守护。
This commit is contained in:
2026-08-15 13:20:04 +08:00
parent f4c58d5dd9
commit 81f54f280d
5 changed files with 136 additions and 17 deletions
+4
View File
@@ -34,6 +34,10 @@ pub(crate) struct GcState {
/// mark/sweep 回收(值量少),只在 full_reset 统一释放。
pub(crate) session_bigint_ptrs: RefCell<Vec<*mut num_bigint::BigInt>>,
pub(crate) session_bytes_allocated: usize,
/// 执行期字符串 GC 的触发水位:本次收集后的存活字节 + 阈值增量。
/// 仅当账目超过水位才在指令边界触发回收——活串超阈值时不会每指令重复
/// 触发无死串可回收的白跑,且保证触发点恒在无 builtin 局部活值的边界。
pub(crate) string_gc_watermark: usize,
pub(crate) forwarding: HashMap<*mut JsObject, *mut JsObject, FxBuildHasher>,
}