perf: 消除热路径冗余检查

This commit is contained in:
爱特每羊队
2026-06-30 21:02:45 +08:00
parent 4fdbb667da
commit 7877aad75d
6 changed files with 31 additions and 14 deletions
+8 -2
View File
@@ -7,8 +7,14 @@ impl Vm {
#[inline(always)]
pub(crate) fn dispatch_add(&mut self, rd: usize, a: usize, b: usize) -> Result<(), String> {
vm_trace!("ADD rd={} r{}={:?} r{}={:?}", rd, a, self.regs[a], b, self.regs[b]);
let lhs = self.coerce_primitive_bounded(self.regs[a], false)?;
let rhs = self.coerce_primitive_bounded(self.regs[b], false)?;
let lv = self.regs[a];
let rv = self.regs[b];
if lv.is_int() && rv.is_int() {
self.regs[rd] = JsValue::float(lv.as_int() as f64 + rv.as_int() as f64);
return Ok(());
}
let lhs = self.coerce_primitive_bounded(lv, false)?;
let rhs = self.coerce_primitive_bounded(rv, false)?;
if lhs.is_string() || rhs.is_string() {
let mut buf = std::mem::take(&mut self.string_buf);
buf.clear();
+11 -5
View File
@@ -17,7 +17,7 @@ use oxide_runtime_api::NativeResult;
use oxide_types::error::{JsError, JsErrorKind};
use oxide_types::mem::{Epoch, P};
use oxide_types::object::{Cell, JsObject, NativeFnPtr, PropAttributes};
use oxide_types::value::JsValue;
use oxide_types::value::{JsValue, PTR_MASK};
pub(crate) const MAX_PROTO_CHAIN_DEPTH: usize = 1024;
@@ -77,9 +77,15 @@ macro_rules! throw_err {
macro_rules! binary_arith {
($self:ident, $a:expr, $b:expr, $rd:expr, $op:tt) => {{
let l = $self.coerce_number_bounded($self.regs[$a])?;
let r = $self.coerce_number_bounded($self.regs[$b])?;
$self.regs[$rd] = JsValue::float(l $op r);
let lv = $self.regs[$a];
let rv = $self.regs[$b];
if lv.is_int() && rv.is_int() {
$self.regs[$rd] = JsValue::float(lv.as_int() as f64 $op rv.as_int() as f64);
} else {
let l = $self.coerce_number_bounded(lv)?;
let r = $self.coerce_number_bounded(rv)?;
$self.regs[$rd] = JsValue::float(l $op r);
}
}}
}
@@ -440,7 +446,7 @@ impl Vm {
self.raise_type_error(error_msg)?;
return Ok(None);
}
let ptr = val.as_js_object_ptr();
let ptr = (val.to_bits() & PTR_MASK) as *mut JsObject;
let addr = ptr as usize;
if ptr.is_null() || addr < 0x10000 || addr % std::mem::align_of::<JsObject>() != 0 {
self.raise_type_error(error_msg)?;
+1
View File
@@ -583,6 +583,7 @@ impl Vm {
{
let val = src_obj.get_prop_at(pos);
let rest = unsafe { &mut *rest_ptr };
let val = self.promote_if_needed_for_write_ptr(rest_ptr, val);
self.set_or_create_prop_value(rest, shape.property_name, val);
}
}
+2 -2
View File
@@ -120,9 +120,11 @@ impl Vm {
pub(crate) fn ordinary_set(
&mut self, obj: &mut JsObject, prop_name_si: u32, val: JsValue, receiver: JsValue,
) -> Result<(), String> {
let val = self.promote_if_needed_for_write_ptr(obj as *mut JsObject, val);
self.ordinary_set_inner(obj, prop_name_si, val, receiver, false)
}
/// Dispatch-time entry: caller (dispatch_set_prop etc.) already promoted the value.
pub(crate) fn ordinary_set_dispatch(
&mut self, obj: &mut JsObject, prop_name_si: u32, val: JsValue, receiver: JsValue,
) -> Result<(), String> {
@@ -138,7 +140,6 @@ impl Vm {
prop_name_si,
use_frame_push
);
let val = self.promote_if_needed_for_write_ptr(obj as *mut JsObject, val);
if let Some(pos) = self.get_own_property_slot(obj, prop_name_si) {
if let Some(meta) = obj.prop_meta_at(pos) {
if meta.is_accessor {
@@ -260,7 +261,6 @@ impl Vm {
pub(crate) fn set_or_create_prop_value(&mut self, obj: &mut JsObject, prop_name_si: u32, val: JsValue) {
vm_trace!("set_or_create_prop_value: shape_id={} prop_name_si={}", obj.shape_id(), prop_name_si);
let val = self.promote_if_needed_for_write_ptr(obj as *mut JsObject, val);
if let Some(pos) = self.kernel_core.shape_forge().lookup_position(obj.shape_id(), prop_name_si) {
obj.set_prop_at(pos, val);
} else {