mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-25 11:11:11 +08:00
perf: member 复合写路径接入 IC 写命中(depth 0)消除每次 DashMap 查询与回写
set_member_prop 增加 ic_set_hit_own(仅接受 depth==0 槽,跳过读侧学习的 原型条目防原型污染)命中直写槽,ext_pc 由 read_member_prop 显式带出消除 隐式 pc 契约;写新属性 miss 分支(IC_SET 分发 + member 写)统一改 CreateDataProperty 快路径(保留原型链 setter/readonly 检查),砍掉 ordinary_set 全链路的重复查询与 shape 转换开销。
This commit is contained in:
@@ -239,3 +239,51 @@ pub(crate) fn ic_set_hit_poly(obj: &mut JsObject, bytecode: &[Instr], ext_pc: us
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// member 复合写(读改写共用同一扩展字组)的写侧命中判定:顺序遍历 4 槽,只接受
|
||||
/// depth==0 的数据槽并直写。
|
||||
///
|
||||
/// 读侧会把继承属性解析结果以 depth>0 条目写回同一扩展字组;写侧若命中这些条目
|
||||
/// 会把新值直写原型对象(原型污染,规范要求 shadow 到接收者 own 属性)——因此
|
||||
/// 原型条目一律跳过,落到慢路径走完整 [[Set]] 语义。
|
||||
///
|
||||
/// `pc` 为越过该 IC 指令全部扩展字后的位置(与 [`write_ic_back`] 同一约定),
|
||||
/// 命中遍历从 `pc - IC_EXT_WORDS` 起的扩展字开始。
|
||||
#[inline(always)]
|
||||
pub(crate) fn ic_set_hit_own(obj: &mut JsObject, bytecode: &[Instr], pc: usize, value: JsValue) -> bool {
|
||||
let base = pc - IC_EXT_WORDS;
|
||||
let shape_id = bytecode[base] & 0x00FF_FFFF;
|
||||
if shape_id == 0 {
|
||||
return false;
|
||||
}
|
||||
let proto_depth = (bytecode[base] >> 24) as u8;
|
||||
let slot_index = bytecode[base + 1];
|
||||
if proto_depth == 0 && obj.shape_id() == shape_id && slot_index < obj.prop_vec_len() as u32 {
|
||||
obj.set_prop_shape(slot_index, value);
|
||||
return true;
|
||||
}
|
||||
ic_set_hit_own_poly(obj, bytecode, base, value)
|
||||
}
|
||||
|
||||
/// 写侧多态槽(1..3)遍历,depth==0 only;`inline(never)` 防主循环代码膨胀。
|
||||
/// `ext_pc` 为扩展字起始位置(首个扩展字处)。
|
||||
#[inline(never)]
|
||||
fn ic_set_hit_own_poly(obj: &mut JsObject, bytecode: &[Instr], ext_pc: usize, value: JsValue) -> bool {
|
||||
for i in 1..IC_SLOTS {
|
||||
let base = ext_pc + i * 2;
|
||||
let shape_id = bytecode[base] & 0x00FF_FFFF;
|
||||
if shape_id == 0 {
|
||||
break;
|
||||
}
|
||||
let proto_depth = (bytecode[base] >> 24) as u8;
|
||||
if proto_depth != 0 {
|
||||
continue;
|
||||
}
|
||||
let slot_index = bytecode[base + 1];
|
||||
if obj.shape_id() == shape_id && slot_index < obj.prop_vec_len() as u32 {
|
||||
obj.set_prop_shape(slot_index, value);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user