perf: 数组元素访问 dispatch 内联 fast path + length_si 缓存

GET_PROP_DYNAMIC/SET_PROP_DYNAMIC 开头内联数组元素 fast path:整数键 +
真数组 + 无元素 meta + 界内时直读/直写元素区,免 primitive_property_get /
ordinary_get/set 调用链与 __proto__ 每次 RwLock 查询;越界与有 meta
场景回退原路径(CreateDataProperty + length 扩展 / accessor/hole 协议)。
GET 侧 is_object() 快检先于 checked_object_ptr,保持原始值 receiver
不抛错。length_si 缓存为 Vm 字段(builtin 绑定后取 id,稳定非 0),
普通属性路径 5 处 hot spot 改读缓存,消除每次 intern 的共享锁开销。
This commit is contained in:
2026-08-15 04:58:57 +08:00
parent 63d549aec2
commit ee4a12668f
7 changed files with 222 additions and 16 deletions
+2 -2
View File
@@ -21,7 +21,7 @@ impl Vm {
&mut self, obj: &JsObject, prop_name_si: u32, receiver: JsValue, target_reg: Option<u8>,
) -> Result<JsValue, String> {
vm_trace!("ordinary_get_inner: shape={} prop_si={}", obj.shape_id(), prop_name_si);
let length_si = self.kernel_core.perm_interner().intern("length").0;
let length_si = self.length_si;
let mut current = Some(obj);
let mut depth = 0usize;
while let Some(obj) = current {
@@ -186,7 +186,7 @@ impl Vm {
// 数组 length 赋值:ArraySetLength 语义(ToUint32 + 调整元素区)。
// 旧行为会把 length 存成影子命名属性,导致 `arr.length = N` 后
// prop_count/迭代/内置方法看到的长度不一致。
let length_si = self.kernel_core.perm_interner().intern("length").0;
let length_si = self.length_si;
if obj.is_array() && prop_name_si == length_si {
let pc_before = self.pc;
let number_len = self.coerce_number_bounded(val)?;