mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-25 19:21:11 +08:00
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:
@@ -21,6 +21,9 @@ impl Vm {
|
||||
let core = KernelCore::new(KernelConfig::minimal());
|
||||
let mut session = KernelSession::new(&core);
|
||||
bindings::init_kernel_builtins(&core, &mut session);
|
||||
// 在 builtin 绑定之后取 id:绑定过程已 intern "length",此处命中缓存得到
|
||||
// 非 0 的稳定 id(保持枚举层"id 0 哨兵"的既有约定,见 walk_own_keys)。
|
||||
let length_si = core.perm_interner().intern("length").0;
|
||||
let obj_proto = P::clone(&session.builtin_world().object_proto);
|
||||
let mut vm = Self {
|
||||
regs: [JsValue::undefined(); 256],
|
||||
@@ -31,6 +34,7 @@ impl Vm {
|
||||
frames: smallvec::SmallVec::new(),
|
||||
kernel_core: core,
|
||||
session,
|
||||
length_si,
|
||||
epoch: Epoch::new(),
|
||||
object_prototype: obj_proto,
|
||||
generator_proto: P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())),
|
||||
@@ -115,6 +119,9 @@ impl Vm {
|
||||
pub fn with_kernel_core(core: Arc<KernelCore>) -> Self {
|
||||
let mut session = KernelSession::new(&core);
|
||||
bindings::init_kernel_builtins(&core, &mut session);
|
||||
// 在 builtin 绑定之后取 id:绑定过程已 intern "length",此处命中缓存得到
|
||||
// 非 0 的稳定 id(保持枚举层"id 0 哨兵"的既有约定,见 walk_own_keys)。
|
||||
let length_si = core.perm_interner().intern("length").0;
|
||||
let obj_proto = P::clone(&session.builtin_world().object_proto);
|
||||
let mut vm = Self {
|
||||
regs: [JsValue::undefined(); 256],
|
||||
@@ -125,6 +132,7 @@ impl Vm {
|
||||
frames: smallvec::SmallVec::new(),
|
||||
kernel_core: core,
|
||||
session,
|
||||
length_si,
|
||||
epoch: Epoch::new(),
|
||||
object_prototype: obj_proto,
|
||||
generator_proto: P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())),
|
||||
@@ -637,10 +645,7 @@ mod tests {
|
||||
// wrapper 是跨重置存活对象,其原型链必须仍能解析出 call/apply/bind:
|
||||
// 任何一条路径失效都说明 wrapper 原型指向了已释放的旧 Function 原型。
|
||||
assert_eq!(run_source(&mut vm, "Array.prototype.push.call([1], 2)"), JsValue::int(2));
|
||||
assert_eq!(
|
||||
run_source(&mut vm, "Array.prototype.push.apply([], [1, 2, 3])"),
|
||||
JsValue::int(3)
|
||||
);
|
||||
assert_eq!(run_source(&mut vm, "Array.prototype.push.apply([], [1, 2, 3])"), JsValue::int(3));
|
||||
let replaced = run_source(&mut vm, "String.prototype.replace.call('a', 'a', 'b')");
|
||||
assert_eq!(vm.lookup_str(replaced).as_deref(), Some("b"));
|
||||
let has = run_source(&mut vm, "Object.prototype.hasOwnProperty.call({x: 1}, 'x')");
|
||||
|
||||
Reference in New Issue
Block a user