fix: strings-only 收集结尾清对象 mark 位,恢复完整收集 mark 不变量
collect_strings_only 只清位开头、mark 后不还原,残留 marked 对象会让 后续 reset 完整收集的 mark DFS 短路漏标其字符串边,存活串被误释放、 存活对象持悬垂指针。结尾与 sweep 同点 clear_all_marks 收尾,并补 strings-only 后接完整收集的回归(单测 + 集成,覆盖 global 子树串跨 reset 存活)。
This commit is contained in:
@@ -62,6 +62,24 @@ fn reset_preserves_session_strings_after_runtime_gc() {
|
||||
assert_eq!(text, "xy");
|
||||
}
|
||||
|
||||
/// strings-only 收集后 reset 完整收集:global 子树中 session 对象属性里的串
|
||||
/// 跨两次收集存活(strings-only 残留 mark 位不得短路完整收集的 mark DFS)。
|
||||
#[test]
|
||||
fn strings_only_then_reset_keeps_global_subtree_strings() {
|
||||
let mut vm = vm_with_threshold(4096);
|
||||
let first = compile(
|
||||
"globalThis.kept = { s: 'he' + 'llo' }; var t; for (var i = 0; i < 500000; i++) { t = 'x' + i; } 0",
|
||||
);
|
||||
vm.run(&first).expect("run1");
|
||||
assert!(vm.session_gc_stats().total_collections > 0, "run1 应触发执行期字符串 GC");
|
||||
vm.reset();
|
||||
|
||||
let second = compile("globalThis.kept.s");
|
||||
let result = vm.run(&second).expect("run2");
|
||||
let text = vm.lookup_str(result).expect("kept.s 应为字符串").to_string();
|
||||
assert_eq!(text, "hello");
|
||||
}
|
||||
|
||||
/// full_reset 清空 session 内存:执行期回收释放过的死串不与完全重置的
|
||||
/// 整体释放路径重复释放(无双重释放崩溃),重置后引擎可继续运行。
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user