We already have a stop-the-world pause elsewhere in this code path
(type_set_bases) and this makes will make it easier to avoid contention
on the TYPE_LOCK when looking up names in the MRO hierarchy.
Also use deferred reference counting for non-immortal MROs.
static inline PyObject *
lookup_tp_mro(PyTypeObject *self)
{
- ASSERT_NEW_TYPE_OR_LOCKED(self);
return self->tp_mro;
}
/* Other checks are done via set_tp_bases. */
_Py_SetImmortal(mro);
}
+ else {
+ PyUnstable_Object_EnableDeferredRefcount(mro);
+ }
+ }
+ if (!initial) {
+ type_lock_prevent_release();
+ types_stop_world();
}
self->tp_mro = mro;
+ if (!initial) {
+ types_start_world();
+ type_lock_allow_release();
+ }
}
static inline void
type_get_mro(PyObject *tp, void *Py_UNUSED(closure))
{
PyTypeObject *type = PyTypeObject_CAST(tp);
- PyObject *mro;
-
- BEGIN_TYPE_LOCK();
- mro = lookup_tp_mro(type);
+ PyObject *mro = lookup_tp_mro(type);
if (mro == NULL) {
- mro = Py_None;
- } else {
- Py_INCREF(mro);
+ Py_RETURN_NONE;
}
-
- END_TYPE_LOCK();
- return mro;
+ return Py_NewRef(mro);
}
static PyTypeObject *find_best_base(PyObject *);