fix: 执行期字符串 GC 触发点移到指令边界,消除 builtin 局部活串悬垂
分配点触发会把仅存于 builtin 函数栈上局部 JsValue 与构造中未登记对象的 存活串判死释放(temporal 槽、regexp exec 构造中数组、replace 回调参数 Vec),长会话超阈值即悬垂。触发改在 dispatch 指令边界,此时所有局部值已 落地为执行根;分配点只留账目。水位采用上次收集存活字节加阈值增量,活串 超阈值时不会每指令重复白跑;reset 完整收集仍按阈值直接比较。debug 构建下 收集后断言存活对象字符串边已登记。补低阈值回归:regexp exec 旧行为直接 SIGABRT,temporal 与 replace 结果断言守护。
This commit is contained in:
@@ -1320,6 +1320,12 @@ impl Vm {
|
||||
let mut steps: u64 = 0;
|
||||
loop {
|
||||
steps += 1;
|
||||
// 执行期字符串 GC 安全点:指令边界上无 builtin 局部活值(分配点触发
|
||||
// 会释放仅存于 Rust 局部/构造中未登记对象的串),此处触发保证回收
|
||||
// 时所有存活串都已落地为执行根。账目未超水位时仅 2 次字段比较。
|
||||
if self.gc_state.session_bytes_allocated >= self.gc_state.string_gc_watermark {
|
||||
self.maybe_collect_session_strings();
|
||||
}
|
||||
if let Some(max_steps) = max_steps {
|
||||
if steps > max_steps {
|
||||
vm_warn!("dispatch: step limit {} exceeded at pc={}", max_steps, self.pc);
|
||||
|
||||
Reference in New Issue
Block a user