perf: 对象统一入口 Box 化合并对象表退役晋升档

This commit is contained in:
2026-10-01 06:39:51 +00:00
parent 0e3992722e
commit 1711ae948b
13 changed files with 262 additions and 523 deletions
+19 -38
View File
@@ -13,14 +13,6 @@ use super::{native_fn_ptr_to_fn, Vm};
use crate::native::NativeFn;
use crate::{vm_debug, vm_trace};
/// 对象分配统一入口的后端:epoch arena(短命对象,晋升进 session)与
/// session arena(长命对象,session GC mark/sweep 回收)二选一。
#[derive(Clone, Copy)]
enum AllocBackend {
Epoch,
Session,
}
impl Vm {
fn pack_sync_native_call_args(
&mut self, receiver: JsValue, callee: JsValue, args: &[JsValue],
@@ -48,44 +40,33 @@ impl Vm {
unsafe { (*obj_ptr).is_session_epoch() }
}
/// 按指定后端分配对象并登记追踪表与堆账目,返回裸指针。
/// 对象分配统一入口:置 session 归属位与堆载体位,本体经 `Box::into_raw`
/// 堆分配,登记 session 对象表并计入堆账目,返回裸指针。
///
/// # 步骤
/// 1. Epoch 后端:epoch arena 分配并登记 `epoch_object_ptrs`。
/// 2. Session 后端:先置 session 归属位再分配,登记 `session_object_ptrs`,
/// 计入堆账目(与晋升同式:对象头 + 对象堆数据,读分配后的 arena 对象)。
///
/// # 注意事项
/// Session 后端先置位后分配,置位与登记顺序在两个后端内固定;
/// 换后端只改本函数内的分配原语,调用点不动。
fn alloc_with_backend(&mut self, mut obj: JsObject, backend: AllocBackend) -> *mut JsObject {
match backend {
AllocBackend::Epoch => {
let ptr = self.epoch.alloc(obj);
self.gc_state.track_epoch_object(ptr);
ptr
}
AllocBackend::Session => {
obj.set_session_epoch(true);
let ptr = self.gc_state.session_epoch.alloc(obj) as *mut JsObject;
self.gc_state.session_object_ptrs.push(ptr);
// 直 session 分配计入堆账目(与 promote 同式:对象头 + 对象堆数据)。
self.gc_state.session_bytes_allocated += std::mem::size_of::<JsObject>()
+ crate::session_gc::SessionGc::object_heap_data_bytes(unsafe { &*ptr }) as usize;
ptr
}
}
/// 1. 置 session 归属位与堆载体位(释放点据此 `Box::from_raw` 释放本体)。
/// 2. 本体堆分配,登记 `session_object_ptrs`。
/// 3. 计入堆账目(对象头 + 对象堆数据,读分配后的对象)。
fn alloc_object_box(&mut self, mut obj: JsObject) -> *mut JsObject {
obj.set_session_epoch(true);
obj.set_heap_alloc(true);
let ptr = Box::into_raw(Box::new(obj));
self.gc_state.session_object_ptrs.push(ptr);
// 直 session 分配计入堆账目(与 promote 同式:对象头 + 对象堆数据)。
self.gc_state.session_bytes_allocated += std::mem::size_of::<JsObject>()
+ crate::session_gc::SessionGc::object_heap_data_bytes(unsafe { &*ptr }) as usize;
ptr
}
/// 在当前 epoch arena 分配对象并登记 GC 追踪表,返回裸指针。
/// 分配对象并登记 GC 追踪表,返回裸指针。
pub(crate) fn alloc_object(&mut self, obj: JsObject) -> *mut JsObject {
self.alloc_with_backend(obj, AllocBackend::Epoch)
self.alloc_object_box(obj)
}
/// 在当前 session arena 分配对象:置 session 归属位、登记 session 对象表
/// 并计入堆账目,返回裸指针。
/// 分配对象:置 session 归属位与堆载体位、登记 session 对象表并计入
/// 堆账目,返回裸指针。
pub(crate) fn alloc_session_object(&mut self, obj: JsObject) -> *mut JsObject {
self.alloc_with_backend(obj, AllocBackend::Session)
self.alloc_object_box(obj)
}
/// native / 字节码函数的统一同步调用入口,返回结果或错误文本。