MCPcopy Index your code
hub / github.com/RustPython/RustPython / specialize_load_attr

Method specialize_load_attr

crates/vm/src/frame.rs:7425–7706  ·  view source on GitHub ↗
(
        &mut self,
        _vm: &VirtualMachine,
        oparg: LoadAttr,
        instr_idx: usize,
        cache_base: usize,
    )

Source from the content-addressed store, hash-verified

7423 }
7424
7425 fn specialize_load_attr(
7426 &mut self,
7427 _vm: &VirtualMachine,
7428 oparg: LoadAttr,
7429 instr_idx: usize,
7430 cache_base: usize,
7431 ) {
7432 // Pre-check: bail if already specialized by another thread
7433 if !matches!(
7434 self.code.instructions.read_op(instr_idx),
7435 Instruction::LoadAttr { .. }
7436 ) {
7437 return;
7438 }
7439 let obj = self.top_value();
7440 let cls = obj.class();
7441
7442 // Check if this is a type object (class attribute access)
7443 if obj.downcast_ref::<PyType>().is_some() {
7444 self.specialize_class_load_attr(_vm, oparg, instr_idx, cache_base);
7445 return;
7446 }
7447
7448 // Only specialize if getattro is the default (PyBaseObject::getattro)
7449 let is_default_getattro = cls
7450 .slots
7451 .getattro
7452 .load()
7453 .is_some_and(|f| f as usize == PyBaseObject::getattro as *const () as usize);
7454 if !is_default_getattro {
7455 let mut type_version = cls.tp_version_tag.load(Acquire);
7456 if type_version == 0 {
7457 type_version = cls.assign_version_tag();
7458 }
7459 if type_version != 0
7460 && !oparg.is_method()
7461 && !self.specialization_eval_frame_active(_vm)
7462 && cls.get_attr(identifier!(_vm, __getattr__)).is_none()
7463 && let Some(getattribute) = cls.get_attr(identifier!(_vm, __getattribute__))
7464 && let Some(func) = getattribute.downcast_ref_if_exact::<PyFunction>(_vm)
7465 && func.can_specialize_call(2)
7466 {
7467 let func_version = func.get_version_for_current_state();
7468 if func_version != 0 {
7469 let func_ptr = &*getattribute as *const PyObject as usize;
7470 unsafe {
7471 self.code
7472 .instructions
7473 .write_cache_u32(cache_base + 3, func_version);
7474 self.write_cached_descriptor(cache_base, type_version, func_ptr);
7475 }
7476 self.specialize_at(
7477 instr_idx,
7478 cache_base,
7479 Instruction::LoadAttrGetattributeOverridden,
7480 );
7481 return;
7482 }

Callers 1

load_attrMethod · 0.80

Calls 15

adaptive_counter_backoffFunction · 0.85
top_valueMethod · 0.80
assign_version_tagMethod · 0.80
is_methodMethod · 0.80
can_specialize_callMethod · 0.80
write_cache_u32Method · 0.80
specialize_atMethod · 0.80

Tested by

no test coverage detected