From d7f54e331a037f2ac1985eeffe3e763711940b5a Mon Sep 17 00:00:00 2001 From: pjh456 <147148383@qq.com> Date: Thu, 1 Oct 2026 09:37:54 +0000 Subject: [PATCH] =?UTF-8?q?style:=20=E6=8A=98=E5=8F=A0=E7=AD=BE=E5=90=8D?= =?UTF-8?q?=E4=B8=8E=E8=B0=83=E7=94=A8=E6=8A=98=E8=A1=8C=E5=AF=B9=E9=BD=90?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E6=A3=80=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/oxide_vm/src/session_gc.rs | 19 ++++----- crates/oxide_vm/src/session_gc/tests.rs | 5 +-- crates/oxide_vm/src/suspended.rs | 28 ++++++++------ crates/oxide_vm/src/vm_dispatch_misc.rs | 3 +- crates/oxide_vm/src/vm_props.rs | 51 +++++++++++++++---------- crates/oxide_vm/src/vm_support/tests.rs | 18 +++------ 6 files changed, 62 insertions(+), 62 deletions(-) diff --git a/crates/oxide_vm/src/session_gc.rs b/crates/oxide_vm/src/session_gc.rs index bdd2f720..7268a863 100644 --- a/crates/oxide_vm/src/session_gc.rs +++ b/crates/oxide_vm/src/session_gc.rs @@ -134,8 +134,7 @@ impl SessionGc { /// 单趟替代原 `object_edges` + `record_object_string_edges` 双遍模式:消除每对象 /// Vec 分配与重复字段遍历。 fn scan_edges_for_mark( - obj: &JsObject, stack: &mut Vec<*mut JsObject>, - live_strings: &mut HashSet<*mut JsString, FxBuildHasher>, + obj: &JsObject, stack: &mut Vec<*mut JsObject>, live_strings: &mut HashSet<*mut JsString, FxBuildHasher>, live_bigints: &mut HashSet<*mut num_bigint::BigInt, FxBuildHasher>, live_cells: &mut HashSet<*mut Cell, FxBuildHasher>, ) { @@ -197,8 +196,7 @@ impl SessionGc { #[inline] fn process_edge( - value: JsValue, stack: &mut Vec<*mut JsObject>, - live_strings: &mut HashSet<*mut JsString, FxBuildHasher>, + value: JsValue, stack: &mut Vec<*mut JsObject>, live_strings: &mut HashSet<*mut JsString, FxBuildHasher>, live_bigints: &mut HashSet<*mut num_bigint::BigInt, FxBuildHasher>, ) { if value.is_object() { @@ -624,11 +622,7 @@ impl SessionGc { if obj.is_gc_marked() && obj.is_weak_map_obj() { // SAFETY: 弱表 native 盒独占,整表重建在定夺期间无并发读者。 unsafe { - weak_map::rewrite_weak_map_native( - &mut *ptr, - |key| resolve_weak_key_sweep(key), - |value| value, - ); + weak_map::rewrite_weak_map_native(&mut *ptr, |key| resolve_weak_key_sweep(key), |value| value); } } } @@ -1004,8 +998,11 @@ impl SessionGc { string_bytes += size_of::() + unsafe { (*ptr).payload_bytes() }; } let bigint_bytes = vm.gc_state.session_bigint_ptrs.borrow().len() * size_of::(); - vm.gc_state.session_bytes_allocated = - vm.gc_state.session_bytes_allocated.saturating_add(string_bytes).saturating_add(bigint_bytes); + vm.gc_state.session_bytes_allocated = vm + .gc_state + .session_bytes_allocated + .saturating_add(string_bytes) + .saturating_add(bigint_bytes); // 抬高下次触发水位:当前分配包络 + 阈值增量——存活包络超阈值时不每指令 // 重复触发无死对象可回收的白跑。 diff --git a/crates/oxide_vm/src/session_gc/tests.rs b/crates/oxide_vm/src/session_gc/tests.rs index 2be0b822..601ef660 100644 --- a/crates/oxide_vm/src/session_gc/tests.rs +++ b/crates/oxide_vm/src/session_gc/tests.rs @@ -1702,10 +1702,7 @@ fn active_and_suspended_for_in_do_not_block_in_run_collection() { // 迭代器键经根收集标活。 let mut vm = vm_with_threshold(65536); let dead = plain_object(&mut vm); - let iter = Box::into_raw(Box::new(crate::vm::ForInIter { - keys: Vec::new(), - index: 0, - })); + let iter = Box::into_raw(Box::new(crate::vm::ForInIter { keys: Vec::new(), index: 0 })); vm.iters.push_for_in(iter); vm.maybe_collect_in_run(); diff --git a/crates/oxide_vm/src/suspended.rs b/crates/oxide_vm/src/suspended.rs index f52b6c92..9aa6ccc0 100644 --- a/crates/oxide_vm/src/suspended.rs +++ b/crates/oxide_vm/src/suspended.rs @@ -362,18 +362,22 @@ impl SuspendedFrame { save_stack: self.save_stack.iter().copied().map(&mut rewrite).collect(), cell_stack: self.cell_stack.clone(), try_stack: self.try_stack.clone(), - for_in_iters: self.for_in_iters.iter().map(|&iter| { - if iter.is_null() { - return iter; - } - // SAFETY: 指针是堆上迭代器体,原件状态盒独占持有;克隆新建 - // 独立体,原件与克隆各持自有体,恰好各释放一次。 - let body = unsafe { &*iter }; - Box::into_raw(Box::new(ForInIter { - keys: body.keys.iter().map(|(v, si)| (rewrite(*v), *si)).collect(), - index: body.index, - })) - }).collect(), + for_in_iters: self + .for_in_iters + .iter() + .map(|&iter| { + if iter.is_null() { + return iter; + } + // SAFETY: 指针是堆上迭代器体,原件状态盒独占持有;克隆新建 + // 独立体,原件与克隆各持自有体,恰好各释放一次。 + let body = unsafe { &*iter }; + Box::into_raw(Box::new(ForInIter { + keys: body.keys.iter().map(|(v, si)| (rewrite(*v), *si)).collect(), + index: body.index, + })) + }) + .collect(), for_of_iters: self .for_of_iters .iter() diff --git a/crates/oxide_vm/src/vm_dispatch_misc.rs b/crates/oxide_vm/src/vm_dispatch_misc.rs index 4452b94e..4d5a8369 100644 --- a/crates/oxide_vm/src/vm_dispatch_misc.rs +++ b/crates/oxide_vm/src/vm_dispatch_misc.rs @@ -1203,8 +1203,7 @@ impl Vm { // 免 promote 搬移——若按 epoch 分配,首次写入 session 根会把对象搬到新 // 地址,缓存中的旧指针与新实例分叉,同一 site 两次取值将返回不同对象。 let mut alloc_session_array = |n: usize| { - let clone = - JsObject::new_array(oxide_kernel::shape_forge::EMPTY_SHAPE_ID, proto_val, n, self.epoch.bump()); + let clone = JsObject::new_array(oxide_kernel::shape_forge::EMPTY_SHAPE_ID, proto_val, n, self.epoch.bump()); self.alloc_session_object(clone) }; let cooked = alloc_session_array(n); diff --git a/crates/oxide_vm/src/vm_props.rs b/crates/oxide_vm/src/vm_props.rs index 933e95e7..bdce5798 100644 --- a/crates/oxide_vm/src/vm_props.rs +++ b/crates/oxide_vm/src/vm_props.rs @@ -958,8 +958,7 @@ impl Vm { // 新元素(越界或 hole 空洞)要求对象可扩展;已有元素覆盖不受限制。 // 常规入口(ordinary_set)已预先拦截,此处为 REST/SPREAD/builtin // 内部等直调方的兜底。 - let is_new = - index >= obj.array_prop_count || obj.prop_meta_at(index).is_some_and(|m| m.is_hole()); + let is_new = index >= obj.array_prop_count || obj.prop_meta_at(index).is_some_and(|m| m.is_hole()); if is_new && !obj.is_extensible() { return; } @@ -1160,7 +1159,15 @@ impl Vm { } } } else { - return self.define_array_index_element(obj, index, JsValue::undefined(), attributes, true, get, set); + return self.define_array_index_element( + obj, + index, + JsValue::undefined(), + attributes, + true, + get, + set, + ); } } } @@ -1447,9 +1454,7 @@ impl Vm { } } names.reverse(); - let in_range = |name: u32| { - self.array_index_from_property_key(name).is_some_and(|i| i >= from && i < to) - }; + let in_range = |name: u32| self.array_index_from_property_key(name).is_some_and(|i| i >= from && i < to); // 无命中键时零重建。 if !names.iter().any(|&name| in_range(name)) { return; @@ -1711,7 +1716,8 @@ mod tests { (*a.as_js_object_ptr()).set_prop_at(0, JsValue::int(1)); } let si = array_index_si(&mut vm, 2_000_000); - vm.ordinary_set(unsafe { &mut *a.as_js_object_ptr() }, si, JsValue::int(9), a, true).expect("set"); + vm.ordinary_set(unsafe { &mut *a.as_js_object_ptr() }, si, JsValue::int(9), a, true) + .expect("set"); let obj = unsafe { &*a.as_js_object_ptr() }; assert_eq!(obj.logical_len(), 2_000_001, "length 扩到 index+1"); @@ -1727,7 +1733,8 @@ mod tests { let mut vm = Vm::new(); let b = new_array_val(&mut vm, 0); let si = array_index_si(&mut vm, u32::MAX); - vm.ordinary_set(unsafe { &mut *b.as_js_object_ptr() }, si, JsValue::int(9), b, true).expect("set"); + vm.ordinary_set(unsafe { &mut *b.as_js_object_ptr() }, si, JsValue::int(9), b, true) + .expect("set"); let obj = unsafe { &*b.as_js_object_ptr() }; assert_eq!(obj.logical_len(), 0, "2^32-1 不扩展 length"); @@ -1741,7 +1748,8 @@ mod tests { let c = new_array_val(&mut vm, 0); // "4294967296" 非规范数组下标(u32 解析失败),走字符串键路径。 let si = vm.kernel_core.perm_interner().intern("4294967296").0; - vm.ordinary_set(unsafe { &mut *c.as_js_object_ptr() }, si, JsValue::int(1), c, true).expect("set"); + vm.ordinary_set(unsafe { &mut *c.as_js_object_ptr() }, si, JsValue::int(1), c, true) + .expect("set"); let obj = unsafe { &*c.as_js_object_ptr() }; assert_eq!(obj.logical_len(), 0); @@ -1758,7 +1766,8 @@ mod tests { (*arr).set_prop_at(1, JsValue::int(2)); } let si = array_index_si(&mut vm, 3_000_000); - vm.ordinary_set(unsafe { &mut *d.as_js_object_ptr() }, si, JsValue::int(7), d, true).expect("set"); + vm.ordinary_set(unsafe { &mut *d.as_js_object_ptr() }, si, JsValue::int(7), d, true) + .expect("set"); vm.set_array_length_value(unsafe { &mut *d.as_js_object_ptr() }, JsValue::int(5), true, true) .expect("length"); @@ -1776,7 +1785,8 @@ mod tests { (*a.as_js_object_ptr()).set_prop_at(0, JsValue::int(1)); } let si = array_index_si(&mut vm, 2_000_000); - vm.ordinary_set(unsafe { &mut *a.as_js_object_ptr() }, si, JsValue::int(9), a, true).expect("set"); + vm.ordinary_set(unsafe { &mut *a.as_js_object_ptr() }, si, JsValue::int(9), a, true) + .expect("set"); // Object.defineProperty(a, "2000000", {value: 1, configurable: false})。 let attrs = PropAttributes::new(true, true, false); @@ -1811,7 +1821,8 @@ mod tests { // 命名阻挡点 N=2000000:大索引写后改为不可配置。 let si = array_index_si(&mut vm, 2_000_000); - vm.ordinary_set(unsafe { &mut *a.as_js_object_ptr() }, si, JsValue::int(9), a, true).expect("set"); + vm.ordinary_set(unsafe { &mut *a.as_js_object_ptr() }, si, JsValue::int(9), a, true) + .expect("set"); vm.define_data_property(unsafe { &mut *a.as_js_object_ptr() }, si, JsValue::int(9), attrs) .expect("define named"); @@ -1834,13 +1845,11 @@ mod tests { (*a.as_js_object_ptr()).set_prop_at(0, JsValue::int(1)); } let si = array_index_si(&mut vm, 2_000_000); - vm.ordinary_set(unsafe { &mut *a.as_js_object_ptr() }, si, JsValue::int(9), a, true).expect("set"); + vm.ordinary_set(unsafe { &mut *a.as_js_object_ptr() }, si, JsValue::int(9), a, true) + .expect("set"); - let outcome = oxide_builtins::object::delete_own_property_outcome( - &mut vm, - unsafe { &mut *a.as_js_object_ptr() }, - si, - ); + let outcome = + oxide_builtins::object::delete_own_property_outcome(&mut vm, unsafe { &mut *a.as_js_object_ptr() }, si); assert_eq!(outcome, oxide_builtins::object::DeleteOutcome::Deleted); let obj = unsafe { &*a.as_js_object_ptr() }; assert_eq!(obj.logical_len(), 2_000_001, "length 不变"); @@ -1855,8 +1864,10 @@ mod tests { (*a.as_js_object_ptr()).set_prop_at(0, JsValue::int(1)); } let si = array_index_si(&mut vm, 2_000_000); - vm.ordinary_set(unsafe { &mut *a.as_js_object_ptr() }, si, JsValue::int(5), a, true).expect("set"); - vm.ordinary_set(unsafe { &mut *a.as_js_object_ptr() }, si, JsValue::int(9), a, true).expect("set"); + vm.ordinary_set(unsafe { &mut *a.as_js_object_ptr() }, si, JsValue::int(5), a, true) + .expect("set"); + vm.ordinary_set(unsafe { &mut *a.as_js_object_ptr() }, si, JsValue::int(9), a, true) + .expect("set"); let obj = unsafe { &*a.as_js_object_ptr() }; assert_eq!(obj.logical_len(), 2_000_001); diff --git a/crates/oxide_vm/src/vm_support/tests.rs b/crates/oxide_vm/src/vm_support/tests.rs index b89764fb..072dc6ab 100644 --- a/crates/oxide_vm/src/vm_support/tests.rs +++ b/crates/oxide_vm/src/vm_support/tests.rs @@ -820,10 +820,9 @@ fn reset_clears_runtime_state_like_rerun() { upvalues: std::ptr::slice_from_raw_parts(std::ptr::null(), 0), }); vm.save_stack.push(JsValue::undefined()); - vm.iters.for_in_iters.push(Box::into_raw(Box::new(crate::vm::ForInIter { - keys: Vec::new(), - index: 0, - }))); + vm.iters + .for_in_iters + .push(Box::into_raw(Box::new(crate::vm::ForInIter { keys: Vec::new(), index: 0 }))); vm.iters.for_of_iters.push(crate::vm_state::ForOfEntry { iterator: JsValue::undefined(), last_result: JsValue::undefined(), @@ -888,15 +887,8 @@ fn inline_for_in_escape_restores_snapshot_and_releases_residual_body() { assert!(result.is_err(), "未捕获异常应返回 Err"); // 回调 for-in 体经内联路径执行过一轮(hits 记 1),证明场景落在内联调用 // 路径且残留体确曾入表;restore 后表须还原为快照(顶层为空)。 - assert_eq!( - global_prop(&vm, "hits").as_int(), - 1, - "回调 for-in 体应执行过一轮" - ); - assert!( - vm.iters.for_in_iters.is_empty(), - "restore 后 for-in 表应与快照一致(顶层为空)" - ); + assert_eq!(global_prop(&vm, "hits").as_int(), 1, "回调 for-in 体应执行过一轮"); + assert!(vm.iters.for_in_iters.is_empty(), "restore 后 for-in 表应与快照一致(顶层为空)"); } /// 既有 own 属性值覆盖须推进世代:`Array.prototype.push = 9`(P 对象既有槽、