perf: 优化调用原型链的 IC 命中加速
This commit is contained in:
@@ -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(),
|
||||
|
||||
Reference in New Issue
Block a user