mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-25 19:21:11 +08:00
refactor: Symbol/Iter/Profiling 子结构方法下沉,IC helper 完成提取
This commit is contained in:
@@ -1,15 +1,26 @@
|
||||
//! Inline-cache (IC) bytecode-stream helpers.
|
||||
//!
|
||||
//! These operate purely on the bytecode `Instr` slice — they read/clear/write
|
||||
//! the IC extension words embedded after IC-bearing opcodes. They take no `Vm`
|
||||
//! state, so they live outside `Vm` for clearer ownership and to ease the future
|
||||
//! IC side-table migration.
|
||||
//! Contains ALL IC read/write/clear logic — property dispatch and member
|
||||
//! update handlers route through here, so IC format changes (like the future
|
||||
//! side-table migration) require editing only this file.
|
||||
|
||||
use oxide_bytecode::opcode::{self, Instr};
|
||||
use oxide_types::object::JsObject;
|
||||
use oxide_types::value::JsValue;
|
||||
|
||||
/// Read the three IC extension words at `pc` (the bytes following an
|
||||
/// IC-bearing opcode), advance `pc` past them, and return the decoded
|
||||
/// `(shape_id, slot)`.
|
||||
pub(crate) fn read_ic_entry(bytecode: &[Instr], pc: &mut usize) -> (u32, u32) {
|
||||
let ext0 = bytecode[*pc];
|
||||
let ext1 = bytecode[*pc + 1];
|
||||
*pc += 3;
|
||||
(ext0 & 0x00FF_FFFF, ext1)
|
||||
}
|
||||
|
||||
/// Write a resolved `(shape_id, slot)` back into the three IC extension words
|
||||
/// that precede the current `pc`. Called on an IC miss after resolving a
|
||||
/// property, so the next execution of this site hits the cache.
|
||||
/// at `pc - 3` (they precede the current instruction). Called on an IC miss
|
||||
/// after resolving a property, so the next execution of this site hits the cache.
|
||||
pub(crate) fn write_ic_back(bytecode: &mut [Instr], pc: usize, shape_id: u32, slot_index: u32) {
|
||||
debug_assert!(pc >= 3, "IC write-back requires 3 extension words before pc");
|
||||
bytecode[pc - 3] = shape_id & 0x00FF_FFFF;
|
||||
@@ -35,3 +46,22 @@ pub(crate) fn clear_ic_caches(bytecode: &mut [Instr]) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn ic_get_hit(obj: &JsObject, shape_id: u32, slot_index: u32) -> Option<JsValue> {
|
||||
if shape_id != 0 && obj.shape_id() == shape_id && slot_index < obj.prop_vec_len() as u32 {
|
||||
Some(obj.get_prop_at(slot_index))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn ic_set_hit(obj: &mut JsObject, shape_id: u32, slot_index: u32, value: JsValue) -> bool {
|
||||
if shape_id != 0 && obj.shape_id() == shape_id && slot_index < obj.prop_vec_len() as u32 {
|
||||
obj.set_prop_at(slot_index, value);
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user