From b8167d4d8474ee9153802ab56f194d566b86e6ce Mon Sep 17 00:00:00 2001 From: pjh456 <147148383@qq.com> Date: Fri, 11 Sep 2026 20:20:00 +0000 Subject: [PATCH] =?UTF-8?q?perf:=20kernel=20=E5=AF=BF=E5=91=BD=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E5=8C=96=E2=80=94=E2=80=94=E9=9B=B6=E6=B6=88=E8=B4=B9?= =?UTF-8?q?=E8=80=85=E6=AD=BB=E6=97=8B=E9=92=AE=20max=5Fdead=5Fstrings=20?= =?UTF-8?q?=E6=8D=A2=20advisory=20=E9=87=8D=E5=BB=BA=E9=98=88=E5=80=BC=20p?= =?UTF-8?q?erm=5Finterner=5Fmax=5Fentries=EF=BC=88=E9=A2=84=E8=AE=BE?= =?UTF-8?q?=E5=85=A8=20None=20=E9=9B=B6=E6=BC=82=E7=A7=BB=EF=BC=89+=20Kern?= =?UTF-8?q?elCore::should=5Frebuild=5Fperm=20=E5=AE=BF=E4=B8=BB=E8=BE=B9?= =?UTF-8?q?=E7=95=8C=E6=9F=A5=E8=AF=A2=EF=BC=8C3=20=E5=8D=95=E6=B5=8B?= =?UTF-8?q?=E9=92=89=E9=BB=98=E8=AE=A4=E9=9D=A2/=E9=98=88=E5=80=BC?= =?UTF-8?q?=E9=9D=A2/=E6=9C=AA=E8=BE=BE=E9=98=88=E5=80=BC=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/oxide_kernel/src/kernel.rs | 78 ++++++++++++++++++++++++++++--- 1 file changed, 71 insertions(+), 7 deletions(-) diff --git a/crates/oxide_kernel/src/kernel.rs b/crates/oxide_kernel/src/kernel.rs index 242b1e13..8f214614 100644 --- a/crates/oxide_kernel/src/kernel.rs +++ b/crates/oxide_kernel/src/kernel.rs @@ -17,13 +17,17 @@ use oxide_log; use oxide_log::{Level, SUBSYSTEM_COUNT}; /// kernel 运行配置:VM 池规模、步数/调用深度/单 run 分配上限、session GC 阈值、 -/// 日志级别与内置对象预热开关。由三个预设构造器([`KernelConfig::minimal`] / -/// [`KernelConfig::standard`] / [`KernelConfig::full`])或默认值创建。 +/// perm interner 重建阈值、日志级别与内置对象预热开关。由三个预设构造器 +/// ([`KernelConfig::minimal`] / [`KernelConfig::standard`] / [`KernelConfig::full`]) +/// 或默认值创建。 #[derive(Clone)] pub struct KernelConfig { pub min_pool_size: usize, pub max_pool_size: Option, - pub max_dead_strings: Option, + /// perm interner advisory 重建阈值:唯一键数 `entry_count` 达到该值时, + /// 宿主应在安全边界(无存活 VM)整体重建 kernel;None = 无阈值(三个预设 + /// 默认值,行为与无旋钮一致)。见 [`KernelCore::should_rebuild_perm`]。 + pub perm_interner_max_entries: Option, pub max_steps: Option, /// 单次 run 的分配上限(epoch + session arena + session 堆账目字节): /// 超限的 run 以 `VM memory limit exceeded` 失败,防单测试 arena 高水位 @@ -44,7 +48,7 @@ impl KernelConfig { Self { min_pool_size: 4, max_pool_size: Some(8), - max_dead_strings: Some(10_000), + perm_interner_max_entries: None, max_steps: None, max_alloc_bytes: None, max_call_depth: 1024, @@ -62,7 +66,7 @@ impl KernelConfig { Self { min_pool_size: 8, max_pool_size: Some(32), - max_dead_strings: Some(10_000), + perm_interner_max_entries: None, max_steps: None, max_alloc_bytes: None, max_call_depth: 1024, @@ -80,7 +84,7 @@ impl KernelConfig { Self { min_pool_size: 16, max_pool_size: None, - max_dead_strings: Some(5_000), + perm_interner_max_entries: None, max_steps: None, max_alloc_bytes: None, max_call_depth: 1024, @@ -121,7 +125,9 @@ impl Default for KernelConfig { } /// 不可变、跨所有 VM 实例永久共享的状态。 -/// 构造后从不重建——forge 表为 append-only。 +/// 构造后从不原地重建——forge 表为 append-only;宿主可经 +/// [`KernelCore::should_rebuild_perm`] 阈值在安全边界(无存活 VM)整体 +/// 重建(换 `Arc`,非原地清表)。 pub struct KernelCore { pub config: KernelConfig, pub perm_interner: Arc, @@ -217,6 +223,33 @@ impl KernelCore { self.prop_forge.clear(); } } + + /// 宿主是否应整体重建本 kernel(advisory 信号)。 + /// + /// perm interner 唯一键数达到配置的 + /// [`KernelConfig::perm_interner_max_entries`] 阈值时返回 true。纯 + /// advisory 契约:引擎不自动重建——重建须由宿主在"无存活 VM"边界驱动: + /// 归还全部 `VmGuard`(池排空)→ 旧 `Arc` 归零整体释放 + /// (PermInterner/ShapeForge/CodeForge/PropForge,含全部泄漏键文本与 + /// 物化串)→ 新建 kernel + 新池/VM。存活 VM 的 `immutables_cache` 与 + /// P 对象持有旧 kernel 的物化串裸指针与 shape id,VM 存活期间重建 + /// 会使其悬垂。三个预设默认 None = 永不触发(有意裁定:CLI eval/run/ + /// REPL/bench/test262 宿主均未接重建边界,None 保证零行为漂移)。 + /// + /// # 边界与前提 + /// - 仅在宿主边界(run 间 / 测试间 / 迭代间)调用,勿入 dispatch 热路径: + /// `entry_count` 为 O(1) 读锁,intern 路径零加码; + /// - 仅具备安全重建边界的宿主(test262 runner 批边界、嵌入宿主迭代 + /// 之间)应启用旋钮;REPL 类宿主(单持久 VM,重建 = 丢失顶层状态) + /// 不应启用。 + /// + /// # 副作用 + /// 无:只读查询。 + pub fn should_rebuild_perm(&self) -> bool { + self.config + .perm_interner_max_entries + .is_some_and(|n| self.perm_interner.entry_count() >= n) + } } /// 每会话可变状态:内置原型对象与全局对象。 @@ -804,6 +837,37 @@ mod tests { assert_eq!(KernelConfig::full().max_pool_size, None); } + #[test] + fn should_rebuild_perm_default_off() { + // 预设默认 None = 无阈值:任意键数下永不触发,钉死零漂移默认面。 + let core = KernelCore::new(KernelConfig::minimal()); + for i in 0..10 { + core.perm_interner().intern(&format!("key{i}")); + } + assert!(!core.should_rebuild_perm()); + } + + #[test] + fn should_rebuild_perm_threshold_reached() { + let mut config = KernelConfig::minimal(); + config.perm_interner_max_entries = Some(2); + let core = KernelCore::new(config); + core.perm_interner().intern("a"); + assert!(!core.should_rebuild_perm()); + core.perm_interner().intern("b"); + assert!(core.should_rebuild_perm()); + } + + #[test] + fn should_rebuild_perm_below_threshold() { + let mut config = KernelConfig::minimal(); + config.perm_interner_max_entries = Some(100); + let core = KernelCore::new(config); + core.perm_interner().intern("a"); + core.perm_interner().intern("b"); + assert!(!core.should_rebuild_perm()); + } + #[test] fn test_session_rebuild_shares_forges() { let core = KernelCore::new(KernelConfig::minimal());