perf: 优化调用原型链的 IC 命中加速

This commit is contained in:
爱特每羊队
2026-06-30 21:41:05 +08:00
parent b6ce0f95bf
commit 7291fb237e
4 changed files with 145 additions and 50 deletions
+26 -11
View File
@@ -169,7 +169,7 @@ impl Vm {
let obj = unsafe { &*obj_ptr };
let prop_name_si = self.property_key_si(self.regs[b]);
let (cached_shape_id, cached_slot) = ic_helper::read_ic_entry(&self.bytecode, &mut self.pc);
let (cached_shape_id, cached_slot, cached_depth) = ic_helper::read_ic_entry(&self.bytecode, &mut self.pc);
if obj.has_prop_meta() {
let val = self.ordinary_get_with_target(obj, prop_name_si, val, a as u8)?;
if self.accessor_frame_target_reg.take().is_none() {
@@ -178,16 +178,16 @@ impl Vm {
return Ok(());
}
if let Some(value) = ic_get_hit(obj, cached_shape_id, cached_slot) {
if let Some(value) = ic_get_hit(obj, cached_shape_id, cached_slot, cached_depth) {
self.regs[a] = value;
self.profiling.record_ic_hit();
ic_trace!("IC_GET hit shape={} slot={}", cached_shape_id, cached_slot);
ic_trace!("IC_GET hit shape={} slot={} depth={}", cached_shape_id, cached_slot, cached_depth);
} else if let Some(template) = self.kernel_core.prop_forge().get_template(obj.shape_id()) {
self.profiling.record_ic_miss();
prop_cache_miss();
if template.prop_name == prop_name_si {
if template.position < obj.prop_vec_len() as u32 {
ic_helper::write_ic_back(&mut self.bytecode, self.pc, obj.shape_id(), template.position);
ic_helper::write_ic_back(&mut self.bytecode, self.pc, obj.shape_id(), template.position, 0);
ic_debug!(
"IC_GET propforge hit shape={} prop={} slot={}",
obj.shape_id(),
@@ -207,8 +207,23 @@ impl Vm {
prop_cache_miss();
ic_debug!("IC_GET miss shape={} prop={}", obj.shape_id(), prop_name_si);
let resolved = self.ordinary_get(obj, prop_name_si, val)?;
if let Some(pos) = self.kernel_core.shape_forge().lookup_position(obj.shape_id(), prop_name_si) {
ic_helper::write_ic_back(&mut self.bytecode, self.pc, obj.shape_id(), pos);
// Walk proto chain to find which object actually owns this property.
let mut cursor = obj_ptr;
let mut depth = 0u8;
loop {
let co = unsafe { &*cursor };
if let Some(pos) = self.kernel_core.shape_forge().lookup_position(co.shape_id(), prop_name_si) {
if !co.is_accessor_meta(pos) {
ic_helper::write_ic_back(&mut self.bytecode, self.pc, co.shape_id(), pos, depth);
ic_debug!("IC_GET write-back shape={} slot={} depth={}", co.shape_id(), pos, depth);
}
break;
}
if !co.proto().is_object() {
break;
}
cursor = co.proto().as_js_object_ptr();
depth += 1;
}
self.regs[a] = resolved;
}
@@ -235,7 +250,7 @@ impl Vm {
return Ok(());
}
let (cached_shape_id, cached_slot) = ic_helper::read_ic_entry(&self.bytecode, &mut self.pc);
let (cached_shape_id, cached_slot, cached_depth) = ic_helper::read_ic_entry(&self.bytecode, &mut self.pc);
let value = self.promote_if_needed_for_write_ptr(obj_ptr, self.regs[a]);
let receiver = self.regs[rd];
let obj = unsafe { &mut *obj_ptr };
@@ -244,14 +259,14 @@ impl Vm {
return Ok(());
}
if ic_set_hit(obj, cached_shape_id, cached_slot, value) {
if ic_set_hit(obj, cached_shape_id, cached_slot, cached_depth, value) {
self.profiling.record_ic_hit();
ic_trace!("IC_SET hit shape={} slot={}", cached_shape_id, cached_slot);
ic_trace!("IC_SET hit shape={} slot={} depth={}", cached_shape_id, cached_slot, cached_depth);
} else if let Some(pos) = self.kernel_core.shape_forge().lookup_position(obj.shape_id(), prop_name_si) {
self.profiling.record_ic_miss();
prop_cache_miss();
obj.set_prop_at(pos, value);
ic_helper::write_ic_back(&mut self.bytecode, self.pc, obj.shape_id(), pos);
ic_helper::write_ic_back(&mut self.bytecode, self.pc, obj.shape_id(), pos, 0);
ic_debug!("IC_SET write-back shape={} slot={}", obj.shape_id(), pos);
} else {
self.profiling.record_ic_miss();
@@ -260,7 +275,7 @@ impl Vm {
self.ordinary_set_dispatch(obj, prop_name_si, value, receiver)?;
if old_shape != obj.shape_id() {
if let Some(pos) = self.kernel_core.shape_forge().lookup_position(obj.shape_id(), prop_name_si) {
ic_helper::write_ic_back(&mut self.bytecode, self.pc, obj.shape_id(), pos);
ic_helper::write_ic_back(&mut self.bytecode, self.pc, obj.shape_id(), pos, 0);
ic_debug!("IC_SET write-back shape={} slot={}", obj.shape_id(), pos);
self.kernel_core.prop_forge().upsert(
obj.shape_id(),