Skip to content

Commit 6a29c4c

Browse files
committed
avoid get_class_attr for __hash__; read hash slot via mro_find_map
Reduce calls and lock acquisitions on hot paths by bypassing get_class_attr(__hash__) and directly resolving the hash implementation with mro_find_map(|cls| cls.slots.hash.load()).
1 parent 41a956a commit 6a29c4c

1 file changed

Lines changed: 6 additions & 17 deletions

File tree

‎vm/src/protocol/object.rs‎

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -642,25 +642,14 @@ impl PyObject {
642642
}
643643

644644
pub fn hash(&self, vm: &VirtualMachine) -> PyResult<PyHash> {
645-
// __hash__ function in str cannot be overwritten
646-
if let Some(pystr) = self.downcast_ref_if_exact::<PyStr>(vm) {
647-
return Ok(pystr.hash(vm));
645+
if let Some(hash) = self.class().mro_find_map(|cls| cls.slots.hash.load()) {
646+
return hash(self, vm);
648647
}
649648

650-
let hash = self.get_class_attr(identifier!(vm, __hash__)).unwrap();
651-
if vm.is_none(&hash) {
652-
return Err(vm.new_exception_msg(
653-
vm.ctx.exceptions.type_error.to_owned(),
654-
format!("unhashable type: '{}'", self.class().name()),
655-
));
656-
}
657-
658-
let hash = self
659-
.class()
660-
.mro_find_map(|cls| cls.slots.hash.load())
661-
.unwrap();
662-
663-
hash(self, vm)
649+
return Err(vm.new_exception_msg(
650+
vm.ctx.exceptions.type_error.to_owned(),
651+
format!("unhashable type: '{}'", self.class().name()),
652+
));
664653
}
665654

666655
// type protocol

0 commit comments

Comments
 (0)