From eb6c441d62d7b5c9269debd651c010d7c49dbf8d Mon Sep 17 00:00:00 2001 From: pjh456 <147148383@qq.com> Date: Thu, 17 Sep 2026 04:29:24 +0000 Subject: [PATCH] =?UTF-8?q?docs:=20kernel=20session=20=E7=BB=84=E6=B3=A8?= =?UTF-8?q?=E9=87=8A=E6=94=B9=E5=86=99=E4=B8=8E=E6=96=AD=E9=93=BE=E6=B6=88?= =?UTF-8?q?=E8=A7=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/oxide_kernel/src/kernel/builtin_id.rs | 6 ++--- crates/oxide_kernel/src/kernel/config.rs | 6 ++--- crates/oxide_kernel/src/kernel/core.rs | 25 +++++++++++--------- crates/oxide_kernel/src/kernel/session.rs | 24 +++++++++++-------- crates/oxide_kernel/tests/kernel_tests.rs | 2 +- 5 files changed, 35 insertions(+), 28 deletions(-) diff --git a/crates/oxide_kernel/src/kernel/builtin_id.rs b/crates/oxide_kernel/src/kernel/builtin_id.rs index ba8c8078..d53b8c15 100644 --- a/crates/oxide_kernel/src/kernel/builtin_id.rs +++ b/crates/oxide_kernel/src/kernel/builtin_id.rs @@ -219,8 +219,8 @@ impl BuiltinId { ]; } -// 顺序钉:ALL 与判别值 0..NUM_BUILTINS 严格同序(无换序、无重复、无遗漏); -// 错位即快照/脏检查按下标误读,钉成编译失败。 +// 编译期自检:ALL 必须与判别值 0..NUM_BUILTINS 严格同序(无换序、无重复、无遗漏); +// 错位即快照/脏检查按下标误读,const 求值使错位直接成为编译错误。 const _: () = { let mut i = 0; while i < BuiltinId::ALL.len() { @@ -233,7 +233,7 @@ const _: () = { /// 内置对象世代(generation)快照:记录构造时各对象及其 stub 的世代号与数量。 /// -/// 供 [`KernelSession::dirty_since_snapshot`] 对比,判断哪些 builtin 家族在运行期被污染。 +/// 供 [`crate::kernel::KernelSession::dirty_since_snapshot`] 对比,判断哪些 builtin 家族在运行期被污染。 #[derive(Clone, Debug)] pub struct BuiltinSnapshot { pub generations: [u32; NUM_BUILTINS], diff --git a/crates/oxide_kernel/src/kernel/config.rs b/crates/oxide_kernel/src/kernel/config.rs index 5d054989..d4337ebe 100644 --- a/crates/oxide_kernel/src/kernel/config.rs +++ b/crates/oxide_kernel/src/kernel/config.rs @@ -11,11 +11,11 @@ use oxide_log::{Level, SUBSYSTEM_COUNT}; pub struct KernelConfig { pub min_pool_size: usize, pub max_pool_size: Option, - /// perm interner advisory 重建阈值:唯一键数 `entry_count` **超过**该值时, + /// perm interner 建议重建阈值:唯一键数 `entry_count` **超过**该值时, /// 宿主应在安全边界(无存活 VM)整体重建 kernel,并把 - /// [`KernelCore::should_rebuild_perm`] 返回的建议上限写入新 kernel 配置; + /// [`crate::kernel::KernelCore::should_rebuild_perm`] 返回的建议上限写入新 kernel 配置; /// None = 无阈值(三个预设默认值,行为与无旋钮一致)。 - /// 见 [`KernelCore::should_rebuild_perm`]。 + /// 见 [`crate::kernel::KernelCore::should_rebuild_perm`]。 pub perm_interner_max_entries: Option, pub max_steps: Option, /// 单次 run 的分配上限(epoch + session arena + session 堆账目字节): diff --git a/crates/oxide_kernel/src/kernel/core.rs b/crates/oxide_kernel/src/kernel/core.rs index 56be5450..78fad1ff 100644 --- a/crates/oxide_kernel/src/kernel/core.rs +++ b/crates/oxide_kernel/src/kernel/core.rs @@ -1,5 +1,5 @@ //! 跨所有 VM 实例永久共享的不可变核心:持有 perm/shape/code/prop 四张 forge -//! Arc、VM 边界守卫计数(active_vms)、批边界 sweep 与 perm interner advisory +//! Arc、VM 边界守卫计数(active_vms)、批边界 sweep 与 perm interner 建议 //! 重建信号。 use std::num::NonZeroUsize; @@ -136,28 +136,31 @@ impl KernelCore { } } - /// 宿主是否应整体重建本 kernel,并返回重建后的建议上限(advisory 信号)。 + /// 判断宿主是否应整体重建本 kernel,并返回重建后建议写入新配置的阈值。 /// /// perm interner 唯一键数 `entry_count` **超过**配置的 /// [`KernelConfig::perm_interner_max_entries`] 阈值时返回 /// `Some(建议上限)`——建议上限 = 阈值取 2 的幂后加倍,宿主应在整体重建 /// 后把它写入新 kernel 的 `perm_interner_max_entries`(增长不立即再次 - /// 触顶);阈值未设或键数未超阈值时返回 `None`。纯 advisory 契约:引擎 - /// 不自动重建——重建须由宿主在"无存活 VM"边界驱动:归还全部 `VmGuard` - /// (池排空)→ 旧 `Arc` 归零整体释放(PermInterner/ShapeForge/ - /// CodeForge/PropForge,含全部泄漏键文本与物化串)→ 新建 kernel + 新池/ - /// VM。存活 VM 的代际表注册表(`immutables`)与 P 对象持有旧 kernel 的物化串裸 - /// 指针与 shape id,VM 存活期间重建会使其悬垂。三个预设默认 None = 永不 - /// 触发(有意裁定:CLI eval/run/REPL/bench/test262 宿主均未接重建边界, - /// None 保证零行为漂移)。 + /// 触顶);阈值未设或键数未超阈值时返回 `None`。 /// /// # 边界与前提 /// - 仅在宿主边界(run 间 / 测试间 / 迭代间)调用,勿入 dispatch 热路径: - /// `entry_count` 为 O(1) 读锁,intern 路径零加码; + /// `entry_count` 为一次读锁的 O(1) 查询,intern 路径零加码; /// - 仅具备安全重建边界的宿主(test262 runner 批边界、嵌入宿主迭代 /// 之间)应启用旋钮;REPL 类宿主(单持久 VM,重建 = 丢失顶层状态) /// 不应启用。 /// + /// # 注意事项 + /// - 纯建议、只读查询:引擎不自动重建。重建须由宿主在"无存活 VM"边界 + /// 驱动:归还全部 `VmGuard`(池排空)→ 旧 `Arc` 归零整体 + /// 释放(PermInterner / ShapeForge / CodeForge / PropForge,含全部键 + /// 文本与物化串)→ 新建 kernel 与新池 / VM。存活 VM 持有的模块代际表 + /// 注册表与 P 对象引用旧 kernel 的物化串裸指针与 shape id,VM 存活 + /// 期间重建会使它们悬垂。 + /// - 三个预设默认 `None`(永不触发):现有 CLI eval/run/REPL/bench/test262 + /// 宿主均未接重建边界,`None` 保证零行为漂移。 + /// /// # 副作用 /// 无:只读查询。 pub fn should_rebuild_perm(&self) -> Option { diff --git a/crates/oxide_kernel/src/kernel/session.rs b/crates/oxide_kernel/src/kernel/session.rs index dbc49050..4a2f0514 100644 --- a/crates/oxide_kernel/src/kernel/session.rs +++ b/crates/oxide_kernel/src/kernel/session.rs @@ -12,7 +12,9 @@ use crate::shape_forge::EMPTY_SHAPE_ID; use super::{BuiltinDirtySet, BuiltinId, BuiltinSnapshot, KernelCore}; /// 每会话可变状态:内置原型对象与全局对象。 -/// 在 full_reset() 时重建,实现 JS 执行之间的完全隔离。 +/// 两条重建路径:full_reset() 整体重建,实现 JS 执行之间的完全隔离; +/// selective_reset() 按世代快照的家族位脏集合只重建被污染的家族,保留 +/// 未污染的内置指针与世代。 pub struct KernelSession { pub builtin_world: Arc, pub global_object: P, @@ -59,7 +61,7 @@ impl KernelSession { } /// 从 KernelCore 构建一个全新 session。所有 string/shape intern 调用在 - /// 第二次及后续调用时命中缓存——净开销 < 0.5 ms。 + /// 第二次及后续调用时命中缓存。 pub fn new(core: &KernelCore) -> Self { let builtin_world = Arc::new(BuiltinWorld::new(&core.perm_interner, &core.shape_forge)); let global_object = Self::new_global_object(core); @@ -205,12 +207,12 @@ impl KernelSession { self.dirty_since_snapshot().any() } - /// 收尾释放 session 拥有的手工堆数据:builtin world(方法 wrapper 登记表 + + /// 收尾释放 session 拥有的手工堆数据:builtin world(方法 wrapper 释放登记表 + /// 全部 P 对象属性区)与 global 对象属性区。对象本体随 Arc 引用归零释放。 /// /// # 注意事项 - /// 幂等(登记表按值取走、属性区释放后置空),session 生命周期内可安全重入; - /// 仅应在 session 真正终止时调用——选择性重置换出的旧 world/global 不走本路径。 + /// 幂等(释放登记表按值取走、属性区释放后置空),session 生命周期内可安全重入; + /// 仅应在 session 真正终止时调用——选择性重置替换的旧 world/global 不走本路径。 pub fn teardown_builtins(&mut self) { self.builtin_world.teardown_heap_data(); // SAFETY: global 归本 session 所有,收尾时恰好释放其属性区一次。 @@ -237,12 +239,14 @@ impl KernelSession { core.shape_forge.as_ref(), &dirty, ); - // 旧 world 的登记表并入新 world:存活 wrapper(未污染家族别名)仍须在 - // session 收尾统一释放;已弃 wrapper 随之恰好释放一次,不二次持有。 + // 旧 world 的释放登记表并入新 world:存活 wrapper(未污染家族别名) + // 仍须在 session 收尾统一释放;已弃 wrapper 随之恰好释放一次, + // 不二次持有。 new_world.inherit_leaked_objects(&old_world); - // 重建收尾:保留对象(登记表 wrapper + 共用保留 P 字段)proto 槽 - // 重指新指针,随后被替换旧对象属性区恰好释放一次(含保活钉住 - // 对的属性区,本体钉保留);重指须先于释放、先于换出完成。 + // 选择性重建收尾:保留对象(释放登记表 wrapper + 共用保留 P 字段) + // 原型槽改写到新指针,随后被替换旧 P 对象属性区恰好释放一次 + // (Function/Object 4 个对象本体永久保留、属性区同批释放);原型 + // 槽改写须先于释放、先于旧 world 被替换完成。 new_world.retire_replaced(&old_world); self.builtin_world = Arc::new(new_world); } diff --git a/crates/oxide_kernel/tests/kernel_tests.rs b/crates/oxide_kernel/tests/kernel_tests.rs index 35d992aa..7e89bb3f 100644 --- a/crates/oxide_kernel/tests/kernel_tests.rs +++ b/crates/oxide_kernel/tests/kernel_tests.rs @@ -52,7 +52,7 @@ fn test_kernel_config_presets() { #[test] fn should_rebuild_perm_default_off() { - // 预设默认 None = 无阈值:任意键数下永不触发,钉死零漂移默认面。 + // 预设默认 None = 无阈值:任意键数下永不触发,默认配置行为与无旋钮时一致。 let core = KernelCore::new(KernelConfig::minimal()); for i in 0..10 { core.perm_interner().intern(&format!("key{i}"));