From b5a05828437ed85356445ad495f5271be42a1a90 Mon Sep 17 00:00:00 2001 From: pjh456 <147148383@qq.com> Date: Sat, 3 Oct 2026 10:10:20 +0000 Subject: [PATCH] =?UTF-8?q?refactor:=20=E9=80=80=E5=BD=B9=20Vm=20epoch=20?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E9=9D=A2=E4=B8=8E=20doc=20epoch=20=E8=A1=A8?= =?UTF-8?q?=E8=BF=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/oxide_builtins/src/disposable_stack.rs | 3 ++- crates/oxide_builtins/src/map.rs | 14 +++++++------- crates/oxide_builtins/src/set.rs | 10 +++++----- crates/oxide_runtime_api/src/host.rs | 2 -- crates/oxide_types/src/object.rs | 6 +++--- crates/oxide_vm/src/vm/mod.rs | 8 +------- crates/oxide_vm/src/vm/vmhost.rs | 4 ---- crates/oxide_vm/src/vm_support.rs | 4 +--- 8 files changed, 19 insertions(+), 32 deletions(-) diff --git a/crates/oxide_builtins/src/disposable_stack.rs b/crates/oxide_builtins/src/disposable_stack.rs index 0a7f3df2..60ec79a8 100644 --- a/crates/oxide_builtins/src/disposable_stack.rs +++ b/crates/oxide_builtins/src/disposable_stack.rs @@ -54,7 +54,8 @@ pub fn require_dispose_capability( if obj_ptr.is_null() { return Err(crate::error::create_type_error(vm, "DisposableStack internal state invalid")); } - // SAFETY: obj_ptr 是当前 epoch 分配的 JsObject 非空指针;native 执行期间 epoch 不重置。 + // SAFETY: obj_ptr 是 JsObject 的非空、对齐指针;对象在 native 执行期间 + // 被根保持、不被回收,指针在本调用内有效。 let obj = unsafe { &*obj_ptr }; if obj.type_tag != type_tag { return Err(crate::error::create_type_error( diff --git a/crates/oxide_builtins/src/map.rs b/crates/oxide_builtins/src/map.rs index 6d7e7115..6e284c34 100644 --- a/crates/oxide_builtins/src/map.rs +++ b/crates/oxide_builtins/src/map.rs @@ -106,11 +106,11 @@ impl MapInner { /// /// # 调用方维护的安全性契约 /// -/// 指针在 Map `JsObject` 存活期间有效:`JsObject` 分配于当前 `Epoch` arena, -/// native builtin 执行期间不会调用 `Epoch::reset()`。持有分配的 -/// `Box` 由 `new_map_inner()` 创建,进程退出前不释放(生命周期与 -/// epoch 绑定,属有意为之)。native 调用为单线程,同一 Map 对象同时至多 -/// 存在一个活 `*mut` 别名。 +/// 指针在 Map `JsObject` 存活期间有效:`JsObject` 经统一入口分配,session GC +/// 回收界定其生命周期,native builtin 执行期间对象被根保持、不被回收。 +/// 持有分配的 `Box` 由 `new_map_inner()` 创建,进程退出前不释放 +/// (属有意为之)。native 调用为单线程,同一 Map 对象同时至多存在一个活 +/// `*mut` 别名。 fn get_map_inner(vm: &mut H, this_val: JsValue) -> Result<*mut MapInner, JsValue> { if !this_val.is_object() { return Err(crate::error::create_type_error(vm, "called on non-Map object")); @@ -119,8 +119,8 @@ fn get_map_inner(vm: &mut H, this_val: JsValue) -> Result<*mut MapInn if map_ptr.is_null() { return Err(crate::error::create_type_error(vm, "Map internal state invalid")); } - // SAFETY: map_ptr 是当前 Epoch bump 分配的 JsObject 的非空、对齐指针; - // native 执行期间 epoch 不重置,指针在本调用内有效。 + // SAFETY: map_ptr 是 JsObject 的非空、对齐指针;对象在 native 执行期间 + // 被根保持、不被回收,指针在本调用内有效。 let map_obj = unsafe { &*map_ptr }; if !map_obj.is_map() { return Err(crate::error::create_type_error( diff --git a/crates/oxide_builtins/src/set.rs b/crates/oxide_builtins/src/set.rs index d7dacd9d..e744172e 100644 --- a/crates/oxide_builtins/src/set.rs +++ b/crates/oxide_builtins/src/set.rs @@ -87,9 +87,9 @@ pub(crate) type SetInner = indexmap::IndexSet; /// /// # 调用方维护的安全性契约 /// -/// 指针在 Set `JsObject` 存活期间有效:`JsObject` 分配于当前 `Epoch` arena, -/// native builtin 执行期间不会调用 `Epoch::reset()`。持有分配的 -/// `Box` 由 `new_set_inner()` 创建,Set 生命周期内不释放。 +/// 指针在 Set `JsObject` 存活期间有效:`JsObject` 经统一入口分配,session GC +/// 回收界定其生命周期,native builtin 执行期间对象被根保持、不被回收。 +/// 持有分配的 `Box` 由 `new_set_inner()` 创建,Set 生命周期内不释放。 /// native 调用为单线程,同一 Set 对象同时至多存在一个活 `*mut` 别名。 fn get_set_inner(vm: &mut H, this_val: JsValue) -> Result<*mut SetInner, JsValue> { if !this_val.is_object() { @@ -99,8 +99,8 @@ fn get_set_inner(vm: &mut H, this_val: JsValue) -> Result<*mut SetInn if set_ptr.is_null() { return Err(crate::error::create_type_error(vm, "Set internal state invalid")); } - // SAFETY: set_ptr 是当前 Epoch bump 分配的 JsObject 的非空、对齐指针, - // 本调用期间有效。 + // SAFETY: set_ptr 是 JsObject 的非空、对齐指针;对象在 native 执行期间 + // 被根保持、不被回收,指针在本调用内有效。 let set_obj = unsafe { &*set_ptr }; if !set_obj.is_set() { return Err(crate::error::create_type_error(vm, "Set.prototype.add called on incompatible receiver")); diff --git a/crates/oxide_runtime_api/src/host.rs b/crates/oxide_runtime_api/src/host.rs index 376279c3..7d555eb0 100644 --- a/crates/oxide_runtime_api/src/host.rs +++ b/crates/oxide_runtime_api/src/host.rs @@ -3,7 +3,6 @@ use std::sync::Arc; use oxide_kernel::kernel::{KernelCore, KernelSession}; -use oxide_types::mem::Epoch; use oxide_types::object::{Cell, JsObject, PropAttributes}; use oxide_types::value::JsValue; @@ -97,7 +96,6 @@ pub trait VmHost { // 内核访问器 fn kernel_core(&self) -> &Arc; fn session(&self) -> &KernelSession; - fn epoch(&self) -> &Epoch; // 属性解析 fn property_key_si(&mut self, val: JsValue) -> u32; diff --git a/crates/oxide_types/src/object.rs b/crates/oxide_types/src/object.rs index dd7ebfbd..06eafcff 100644 --- a/crates/oxide_types/src/object.rs +++ b/crates/oxide_types/src/object.rs @@ -43,9 +43,9 @@ pub const MAX_DENSE_PROPS: usize = 1_000_000; /// /// 内联字段:`header`(shape_id + 一组标志位)、`type_tag`(外来对象种类)、 /// `proto`、`generation` 等;命名属性区(`hash_props`)、属性元数据、 -/// native payload 与 upvalue cell 列表以裸指针挂在堆上,由 VM / GC 维护。对象可分配在 -/// session arena(`Epoch`)或全局堆(`Arc`),通过 -/// `is_session_epoch` 位区分。 +/// native payload 与 upvalue cell 列表以裸指针挂在堆上,由 VM / GC 维护。对象统一 +/// 经统一入口分配,session GC 回收界定 session 对象生命周期, +/// 通过 `is_session_epoch` 位区分。 /// /// 布局: /// header: u32 位 diff --git a/crates/oxide_vm/src/vm/mod.rs b/crates/oxide_vm/src/vm/mod.rs index a4abe6e3..f8e30e1f 100644 --- a/crates/oxide_vm/src/vm/mod.rs +++ b/crates/oxide_vm/src/vm/mod.rs @@ -21,7 +21,7 @@ use crate::vm_debug; use crate::vm_state::{GcState, IterState, ProfilingState, SymbolState}; use oxide_kernel::kernel::{KernelCore, KernelSession}; use oxide_types::error::JsErrorKind; -use oxide_types::mem::{Epoch, P}; +use oxide_types::mem::P; use oxide_types::object::{Cell, JsObject, NativeFnPtr}; use oxide_types::private_key::INT_KEY_COUNT; use oxide_types::value::JsValue; @@ -179,7 +179,6 @@ pub struct Vm { /// KernelCore 不重建),属性 get/set 热路径免每次 intern(hash64 + DashMap + /// RwLock 读锁)。 pub(crate) length_si: u32, - pub epoch: Epoch, pub object_prototype: P, /// `%GeneratorPrototype%`:生成器实例的原型(next/return/throw 方法挂此)。 pub generator_proto: P, @@ -456,11 +455,6 @@ impl Vm { self.pc_watch = path; } - /// 只读访问 VM 的 epoch arena。 - pub fn epoch(&self) -> &Epoch { - &self.epoch - } - /// 若 `val` 是字符串,返回其内容的 `String` 副本;否则返回 `None`。 pub fn lookup_str(&self, val: JsValue) -> Option { if !val.is_string() { diff --git a/crates/oxide_vm/src/vm/vmhost.rs b/crates/oxide_vm/src/vm/vmhost.rs index f6d8b5b9..3574d5d5 100644 --- a/crates/oxide_vm/src/vm/vmhost.rs +++ b/crates/oxide_vm/src/vm/vmhost.rs @@ -3,7 +3,6 @@ use std::sync::Arc; use oxide_kernel::kernel::{KernelCore, KernelSession}; -use oxide_types::mem::Epoch; use oxide_types::object::{Cell, JsObject, PropAttributes}; use oxide_types::value::JsValue; @@ -46,9 +45,6 @@ impl oxide_runtime_api::VmHost for Vm { fn session(&self) -> &KernelSession { self.session() } - fn epoch(&self) -> &Epoch { - self.epoch() - } fn pc(&self) -> usize { self.pc } diff --git a/crates/oxide_vm/src/vm_support.rs b/crates/oxide_vm/src/vm_support.rs index 26fb4a1d..7b441c81 100644 --- a/crates/oxide_vm/src/vm_support.rs +++ b/crates/oxide_vm/src/vm_support.rs @@ -11,7 +11,7 @@ use crate::vm_info; use crate::vm_state::{GcState, IterState, ProfilingState, SymbolState}; use oxide_kernel::kernel::{KernelConfig, KernelCore, KernelSession}; use oxide_kernel::shape_forge::EMPTY_SHAPE_ID; -use oxide_types::mem::{Epoch, P}; +use oxide_types::mem::P; use oxide_types::object::{JsObject, JsString, PropAttributes}; use oxide_types::value::JsValue; @@ -55,7 +55,6 @@ impl Vm { kernel_core: core, session, length_si, - epoch: Epoch::new(), object_prototype: obj_proto, generator_proto: P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())), generator_function_proto: P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())), @@ -189,7 +188,6 @@ impl Vm { kernel_core: core, session, length_si, - epoch: Epoch::new(), object_prototype: obj_proto, generator_proto: P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())), generator_function_proto: P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())),