Skip to content

Commit 5f07081

Browse files
committed
Make PyType.tp_name() more efficient
1 parent a1ca535 commit 5f07081

1 file changed

Lines changed: 18 additions & 13 deletions

File tree

vm/src/builtins/pytype.rs

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
use crate::common::lock::PyRwLock;
1+
use crate::common::lock::{
2+
PyMappedRwLockReadGuard, PyRwLock, PyRwLockReadGuard, PyRwLockUpgradableReadGuard,
3+
PyRwLockWriteGuard,
4+
};
25
use std::collections::{HashMap, HashSet};
36
use std::fmt;
47

@@ -57,21 +60,23 @@ impl PyValue for PyType {
5760
}
5861

5962
impl PyType {
60-
fn tp_name(&self, vm: &VirtualMachine) -> String {
61-
let opt_name = self.slots.name.read().clone();
62-
opt_name.unwrap_or_else(|| {
63+
pub fn tp_name<'s>(&'s self) -> PyMappedRwLockReadGuard<'s, str> {
64+
let opt_name = self.slots.name.upgradable_read();
65+
let read_guard = if opt_name.is_some() {
66+
PyRwLockUpgradableReadGuard::downgrade(opt_name)
67+
} else {
68+
let mut opt_name = PyRwLockUpgradableReadGuard::upgrade(opt_name);
6369
let module = self.attributes.read().get("__module__").cloned();
70+
let module: Option<PyStrRef> = module.and_then(|m| m.downcast().ok());
6471
let new_name = if let Some(module) = module {
65-
// FIXME: "unknown" case is a bug.
66-
let module_str = PyStrRef::try_from_object(vm, module)
67-
.map_or("<unknown>".to_owned(), |m| m.borrow_value().to_owned());
68-
format!("{}.{}", module_str, &self.name)
72+
format!("{}.{}", module, &self.name)
6973
} else {
7074
self.name.clone()
7175
};
72-
*self.slots.name.write() = Some(new_name.clone());
73-
new_name
74-
})
76+
*opt_name = Some(new_name);
77+
PyRwLockWriteGuard::downgrade(opt_name)
78+
};
79+
PyRwLockReadGuard::map(read_guard, |opt| opt.as_deref().unwrap())
7580
}
7681

7782
pub fn iter_mro(&self) -> impl Iterator<Item = &PyType> + DoubleEndedIterator {
@@ -272,8 +277,8 @@ impl PyType {
272277
}
273278

274279
#[pymethod(magic)]
275-
fn repr(&self, vm: &VirtualMachine) -> String {
276-
format!("<class '{}'>", self.tp_name(vm))
280+
fn repr(&self) -> String {
281+
format!("<class '{}'>", self.tp_name())
277282
}
278283

279284
#[pyproperty(magic)]

0 commit comments

Comments
 (0)