[3.14] gh-145566: Skip stop-the-world when reassigning __class__ on newly created objects (gh-145567) (#145605)

Co-authored-by: Sam Gross <colesbury@gmail.com>
This commit is contained in:
Sam Gross 2026-03-06 14:35:00 -05:00 committed by GitHub
parent 7b9508f4b0
commit 20438820ff
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 14 additions and 3 deletions

View file

@ -0,0 +1,2 @@
In the free threading build, skip the stop-the-world pause when reassigning
``__class__`` on a newly created object.

View file

@ -7120,7 +7120,11 @@ object_set_class_world_stopped(PyObject *self, PyTypeObject *newto)
assert(_PyObject_GetManagedDict(self) == dict);
if (_PyDict_DetachFromObject(dict, self) < 0) {
int err;
Py_BEGIN_CRITICAL_SECTION(dict);
err = _PyDict_DetachFromObject(dict, self);
Py_END_CRITICAL_SECTION();
if (err < 0) {
return -1;
}
@ -7162,12 +7166,17 @@ object_set_class(PyObject *self, PyObject *value, void *closure)
#ifdef Py_GIL_DISABLED
PyInterpreterState *interp = _PyInterpreterState_GET();
_PyEval_StopTheWorld(interp);
int unique = _PyObject_IsUniquelyReferenced(self);
if (!unique) {
_PyEval_StopTheWorld(interp);
}
#endif
PyTypeObject *oldto = Py_TYPE(self);
int res = object_set_class_world_stopped(self, newto);
#ifdef Py_GIL_DISABLED
_PyEval_StartTheWorld(interp);
if (!unique) {
_PyEval_StartTheWorld(interp);
}
#endif
if (res == 0) {
if (oldto->tp_flags & Py_TPFLAGS_HEAPTYPE) {