mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-25 03:01:12 +08:00
refactor: for-in 迭代器体脱离 epoch arena 改堆上 Box 独占释放
This commit is contained in:
@@ -87,11 +87,13 @@ pub struct CallFrame {
|
||||
|
||||
/// 一次 `for-in` 迭代的游标:已收集的 key 列表与当前下标。
|
||||
///
|
||||
/// 体是堆上 `Box`:迭代器表与挂起状态盒各独占持有体,出表/状态盒释放时
|
||||
/// 逐条释放。
|
||||
/// 每个 key 与它的 intern id 配对保存,使整型下标 key 无需重新 intern 即可排到字符串 key 之前。
|
||||
pub struct ForInIter<'bump> {
|
||||
pub struct ForInIter {
|
||||
/// 每个 key 与其字符串 intern id 配对,使 for-in 排序时整型下标 key 无需
|
||||
/// 重新 intern 即可排到字符串 key 之前。
|
||||
pub keys: bumpalo::collections::Vec<'bump, (JsValue, u32)>,
|
||||
pub keys: Vec<(JsValue, u32)>,
|
||||
pub index: usize,
|
||||
}
|
||||
|
||||
|
||||
@@ -96,7 +96,7 @@ impl Vm {
|
||||
if iter.is_null() {
|
||||
continue;
|
||||
}
|
||||
// SAFETY: for_in_iters 存放由当前 VM epoch 拥有的存活迭代器指针。
|
||||
// SAFETY: for_in_iters 存放堆上迭代器体,VM 表独占持有。
|
||||
unsafe {
|
||||
for (v, _si) in (*(*iter)).keys.iter() {
|
||||
f(*v);
|
||||
@@ -200,7 +200,7 @@ impl Vm {
|
||||
if iter.is_null() {
|
||||
continue;
|
||||
}
|
||||
// SAFETY: for_in_iters 存放由当前 VM epoch 拥有的存活迭代器指针。
|
||||
// SAFETY: for_in_iters 存放堆上迭代器体,VM 表独占持有。
|
||||
unsafe {
|
||||
for (v, _si) in (*(*iter)).keys.iter_mut() {
|
||||
*v = rewrite(*v);
|
||||
@@ -242,13 +242,13 @@ impl Vm {
|
||||
/// 门控子句二:三型状态盒(生成器/异步函数/异步生成器)的
|
||||
/// `suspended.for_in_iters` 是否非空。
|
||||
///
|
||||
/// ForInIter body 分配于 epoch arena,收集换新 Bump 即时失效在表迭代器;
|
||||
/// 门控是保守门:for-in 迭代器活跃/挂起期间拦下执行期收集;
|
||||
/// 挂起帧把迭代器搬入状态盒(`vm.iters` 不可见),故须逐状态盒扫描。
|
||||
///
|
||||
/// # 边界与前提
|
||||
/// - 扫描 epoch + session 两份对象表——挂起状态盒宿主对象可能尚未晋升;
|
||||
/// - 挂起帧的 keys 经状态盒边收为 GC 根(被枚举对象不误释放),悬的是
|
||||
/// 迭代器 body,故按指针扫 `for_in_iters`;
|
||||
/// - 挂起帧的 keys 经状态盒边收为 GC 根(被枚举对象不误释放),迭代器
|
||||
/// 体是堆上 Box,故按指针扫 `for_in_iters`;
|
||||
/// - 保守口径:死对象的状态盒同样计入(持挂起 for-in 的 run 放弃执行期
|
||||
/// 收集),正确性优先于收益;
|
||||
/// - 新增挂起态持有者须在此登记。
|
||||
|
||||
@@ -32,7 +32,7 @@ pub(crate) struct InlineSyncState {
|
||||
pub(crate) pending_exception: Option<JsValue>,
|
||||
pub(crate) pending_error_kind: Option<&'static str>,
|
||||
pub(crate) pending_completion: Option<Completion>,
|
||||
pub(crate) for_in_iters: Vec<*mut ForInIter<'static>>,
|
||||
pub(crate) for_in_iters: Vec<*mut ForInIter>,
|
||||
pub(crate) for_of_iters: Vec<ForOfEntry>,
|
||||
pub(crate) saved_bytecode_stack: Vec<Arc<[opcode::Instr]>>,
|
||||
pub(crate) saved_immutables_stack: Vec<*const [JsValue]>,
|
||||
@@ -62,3 +62,20 @@ pub(crate) struct InlineSyncState {
|
||||
pub(crate) active_flat_id: u32,
|
||||
pub(crate) active_table_gen: u32,
|
||||
}
|
||||
|
||||
impl Drop for InlineSyncState {
|
||||
/// 释放快照持有的 for-in 迭代器体:体是堆上 `Box`,快照独占持有自身体,
|
||||
/// drop 时逐条释放(null 跳过)。restore 是字段直移,移出后字段为空,
|
||||
/// Drop 不再触碰,无双放。
|
||||
fn drop(&mut self) {
|
||||
for iter in self.for_in_iters.drain(..) {
|
||||
if iter.is_null() {
|
||||
continue;
|
||||
}
|
||||
// SAFETY: 指针是堆上迭代器体,快照独占持有,释放恰好一次。
|
||||
unsafe {
|
||||
drop(Box::from_raw(iter));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user