perf: 内置函数跳过冗余哈希校验

This commit is contained in:
爱特每羊队
2026-06-30 22:03:07 +08:00
parent b944aa2832
commit aa7e67bd5a
2 changed files with 31 additions and 4 deletions
+4 -4
View File
@@ -245,7 +245,7 @@ pub fn array_pop<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
return NativeResult::Ok(JsValue::undefined());
}
let last = arr.get_prop_at(len - 1);
arr.set_prop_count(len - 1);
arr.set_prop_count_fast(len - 1);
NativeResult::Ok(last)
}
@@ -335,7 +335,7 @@ pub fn array_splice<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
}
let new_len = n + insert_count - delete_count;
arr.set_prop_count(new_len);
arr.set_prop_count_fast(new_len);
let removed_arr = create_new_array(vm, removed.len());
unsafe {
@@ -899,7 +899,7 @@ pub fn array_shift<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
let v = arr.get_prop_at(i);
arr.set_prop_at(i - 1, v);
}
arr.set_prop_count(len - 1);
arr.set_prop_count_fast(len - 1);
NativeResult::Ok(first)
}
@@ -917,7 +917,7 @@ pub fn array_unshift<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
arr.set_prop_at(j, vm.reg(arg_reg));
}
let new_len = len as usize + n_items;
arr.set_prop_count(new_len);
arr.set_prop_count_fast(new_len);
NativeResult::Ok(JsValue::int(new_len as i32))
}
+27
View File
@@ -571,6 +571,33 @@ impl JsObject {
!self.prop_meta.is_null()
}
/// Like `set_prop_count` but assumes `hash_props` is already allocated.
/// Caller must guarantee the object has at least one element (or was
/// created via `new_array`). Used in hot array builtins to skip the
/// redundant `ensure_hash_props` null check on each mutation.
#[inline]
pub fn set_prop_count_fast(&mut self, count: impl PropIndex) {
let target = count.to_u32() as usize;
// SAFETY: caller guarantees hash_props is non-null.
let vec = unsafe { &mut *(self.hash_props as *mut Vec<JsValue>) };
if target < vec.len() {
vec.truncate(target);
} else {
while vec.len() < target {
vec.push(JsValue::undefined());
}
}
if let Some(meta) = self.prop_meta_vec_mut() {
if target < meta.len() {
meta.truncate(target);
} else {
while meta.len() < target {
meta.push(None);
}
}
}
}
pub fn ensure_prop_meta(&mut self) -> &mut Vec<Option<PropMetaEntry>> {
if self.prop_meta.is_null() {
let len = self.prop_vec_len();