perf: 执行期 session 字符串 GC 阈值回收(超 32MiB 触发,跳过对象 sweep)
new_string_owned 分配前做廉价阈值检查(1 次 usize 比较 + 阈值读取), 超 session_gc_threshold 即调 collect_strings_only:clear_all_marks → 完整 mark(现成)→ sweep_session_strings(现成),跳过对象 sweep 搬移, builtin 层对象裸指针跨分配点零悬垂面。触发检查在登记之前——返回值 尚未根化,登记后回收会被本次 GC 判死致悬垂。分配前触发亦使 GC 期间 新串仍在栈上未登记,天然安全。 长循环字符串累积场景(REPL 常驻 / test262 长测试 / kernel_batch 复用) session 内存从无界变为有界(≤ 阈值 + 存活串);bench gc_trigger_count 恢复有效(string_build 由 0 → 2 次触发)。07.2 rope 死节点回收依赖本机制。
This commit is contained in:
@@ -363,8 +363,19 @@ impl Vm {
|
||||
}
|
||||
|
||||
/// 同 `new_string`,但以 move 接收 `String`,避免一次克隆。
|
||||
///
|
||||
/// # 副作用
|
||||
/// - 累计 session 字符串字节超阈值时,触发一次仅字符串的 GC(对象不搬移)。
|
||||
///
|
||||
/// # 注意事项
|
||||
/// - 触发检查在登记之前:返回值尚未写入任何执行根,若登记后回收会被本次 GC
|
||||
/// 判死并释放,返回即悬垂;此时 `s` 仍在栈上、未被登记,GC 不会触碰它。
|
||||
/// - 热路径仅 1 次 usize 比较 + 阈值读取,超限才进回收路径。
|
||||
pub fn new_string_owned(&mut self, s: String) -> JsValue {
|
||||
let len = s.len();
|
||||
if self.gc_state.session_bytes_allocated >= self.kernel_core.config().session_gc_threshold {
|
||||
self.maybe_collect_session_strings();
|
||||
}
|
||||
let ptr = Box::into_raw(Box::new(JsString::new(s)));
|
||||
self.gc_state.session_string_ptrs.push(ptr);
|
||||
self.gc_state.session_bytes_allocated += std::mem::size_of::<JsString>() + len;
|
||||
|
||||
Reference in New Issue
Block a user