Skip to content
Prev Previous commit
Next Next commit
Cache builtins downcast in ExecutingFrame for LOAD_GLOBAL
Pre-compute builtins.downcast_ref::<PyDict>() at frame entry and reuse
the cached reference in load_global_or_builtin and LoadBuildClass.
Also add get_chain_exact to skip redundant exact_dict type checks.
  • Loading branch information
youknowone committed Mar 1, 2026
commit 98ea46e223baa579f3981087986dbb791e18c632
11 changes: 11 additions & 0 deletions crates/vm/src/builtins/dict.rs
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,17 @@ impl Py<PyDict> {
other.get_item_opt(key, vm)
}
}

/// Like `get_chain` but skips the exact_dict type checks. Use when both
/// dicts are known to be exact dict types (e.g. globals + builtins).
pub fn get_chain_exact<K: DictKey + ?Sized>(
&self,
other: &Self,
key: &K,
vm: &VirtualMachine,
) -> PyResult<Option<PyObjectRef>> {
self.entries.get_chain(&other.entries, vm, key)
}
}

// Implement IntoIterator so that we can easily iterate dictionaries from rust code.
Expand Down
13 changes: 9 additions & 4 deletions crates/vm/src/frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,7 @@ impl Py<Frame> {
locals: &self.locals,
globals: &self.globals,
builtins: &self.builtins,
builtins_dict: self.builtins.downcast_ref::<PyDict>(),
lasti: &self.lasti,
object: self,
state: &mut state,
Expand Down Expand Up @@ -484,6 +485,7 @@ impl Py<Frame> {
locals: &self.locals,
globals: &self.globals,
builtins: &self.builtins,
builtins_dict: self.builtins.downcast_ref::<PyDict>(),
lasti: &self.lasti,
object: self,
state: &mut state,
Expand Down Expand Up @@ -519,6 +521,9 @@ struct ExecutingFrame<'a> {
locals: &'a ArgMapping,
globals: &'a PyDictRef,
builtins: &'a PyObjectRef,
/// Cached downcast of builtins to PyDict. builtins never changes during
/// frame execution, so we avoid repeating the downcast on every LOAD_GLOBAL.
builtins_dict: Option<&'a Py<PyDict>>,
object: &'a Py<Frame>,
lasti: &'a PyAtomic<u32>,
state: &'a mut FrameState,
Expand Down Expand Up @@ -1670,7 +1675,7 @@ impl ExecutingFrame<'_> {
Instruction::LoadSuperAttr { arg: idx } => self.load_super_attr(vm, idx.get(arg)),
Instruction::LoadBuildClass => {
let build_class =
if let Some(builtins_dict) = self.builtins.downcast_ref::<PyDict>() {
if let Some(builtins_dict) = self.builtins_dict {
builtins_dict
.get_item_opt(identifier!(vm, __build_class__), vm)?
.ok_or_else(|| {
Expand Down Expand Up @@ -3014,10 +3019,10 @@ impl ExecutingFrame<'_> {

#[inline]
fn load_global_or_builtin(&self, name: &Py<PyStr>, vm: &VirtualMachine) -> PyResult {
if let Some(builtins_dict) = self.builtins.downcast_ref::<PyDict>() {
// Fast path: builtins is a dict
if let Some(builtins_dict) = self.builtins_dict {
// Fast path: both globals (PyDictRef) and builtins are exact dicts
self.globals
.get_chain(builtins_dict, name, vm)?
.get_chain_exact(builtins_dict, name, vm)?
.ok_or_else(|| {
vm.new_name_error(format!("name '{name}' is not defined"), name.to_owned())
})
Expand Down