Skip to content

Commit 1d091a3

Browse files
authored
gh-145566: Skip stop-the-world when reassigning __class__ on newly created objects (gh-145567)
1 parent b28e5f5 commit 1d091a3

File tree

2 files changed

+14
-3
lines changed

2 files changed

+14
-3
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
In the free threading build, skip the stop-the-world pause when reassigning
2+
``__class__`` on a newly created object.

Objects/typeobject.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7568,7 +7568,11 @@ object_set_class_world_stopped(PyObject *self, PyTypeObject *newto)
75687568

75697569
assert(_PyObject_GetManagedDict(self) == dict);
75707570

7571-
if (_PyDict_DetachFromObject(dict, self) < 0) {
7571+
int err;
7572+
Py_BEGIN_CRITICAL_SECTION(dict);
7573+
err = _PyDict_DetachFromObject(dict, self);
7574+
Py_END_CRITICAL_SECTION();
7575+
if (err < 0) {
75727576
return -1;
75737577
}
75747578

@@ -7608,10 +7612,15 @@ object_set_class(PyObject *self, PyObject *value, void *closure)
76087612
return -1;
76097613
}
76107614

7611-
types_stop_world();
7615+
int unique = _PyObject_IsUniquelyReferenced(self);
7616+
if (!unique) {
7617+
types_stop_world();
7618+
}
76127619
PyTypeObject *oldto = Py_TYPE(self);
76137620
int res = object_set_class_world_stopped(self, newto);
7614-
types_start_world();
7621+
if (!unique) {
7622+
types_start_world();
7623+
}
76157624
if (res == 0) {
76167625
if (oldto->tp_flags & Py_TPFLAGS_HEAPTYPE) {
76177626
Py_DECREF(oldto);

0 commit comments

Comments
 (0)