Skip to content

Commit ec8d797

Browse files
committed
Restrict specialization in free-threaded build
1 parent ed89950 commit ec8d797

File tree

4 files changed

+16
-21
lines changed

4 files changed

+16
-21
lines changed

Python/bytecodes.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3286,9 +3286,6 @@ dummy_func(
32863286
PyObject *iter_o = PyStackRef_AsPyObjectBorrow(iter);
32873287
EXIT_IF(Py_TYPE(iter_o) != &PyTuple_Type);
32883288
assert(PyStackRef_IsTaggedInt(null_or_index));
3289-
#ifdef Py_GIL_DISABLED
3290-
EXIT_IF(!_PyObject_IsUniquelyReferenced(iter_o));
3291-
#endif
32923289
}
32933290

32943291
replaced op(_ITER_JUMP_TUPLE, (iter, null_or_index -- iter, null_or_index)) {

Python/executor_cases.c.h

Lines changed: 0 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/generated_cases.c.h

Lines changed: 0 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/specialize.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2904,13 +2904,18 @@ _Py_Specialize_ForIter(_PyStackRef iter, _PyStackRef null_or_index, _Py_CODEUNIT
29042904
assert(_PyOpcode_Caches[FOR_ITER] == INLINE_CACHE_ENTRIES_FOR_ITER);
29052905
PyObject *iter_o = PyStackRef_AsPyObjectBorrow(iter);
29062906
PyTypeObject *tp = Py_TYPE(iter_o);
2907+
2908+
if (PyStackRef_IsNull(null_or_index)) {
29072909
#ifdef Py_GIL_DISABLED
2908-
// Only specialize for lists owned by this thread or shared
2909-
if (!_Py_IsOwnedByCurrentThread(iter_o) && !_PyObject_GC_IS_SHARED(iter_o)) {
2910-
goto failure;
2911-
}
2910+
// Only specialize for uniquely referenced iterators, so that we know
2911+
// they're only referenced by this one thread. This is more limiting
2912+
// than we need (even `it = iter(mylist); for item in it:` won't get
2913+
// specialized) but we don't have a way to check whether we're the only
2914+
// _thread_ who has access to the object.
2915+
if (!_PyObject_IsUniquelyReferenced(iter_o)) {
2916+
goto failure;
2917+
}
29122918
#endif
2913-
if (PyStackRef_IsNull(null_or_index)) {
29142919
if (tp == &PyRangeIter_Type) {
29152920
specialize(instr, FOR_ITER_RANGE);
29162921
return;
@@ -2930,6 +2935,12 @@ _Py_Specialize_ForIter(_PyStackRef iter, _PyStackRef null_or_index, _Py_CODEUNIT
29302935
}
29312936
else {
29322937
if (tp == &PyList_Type) {
2938+
#ifdef Py_GIL_DISABLED
2939+
// Only specialize for lists owned by this thread or shared
2940+
if (!_Py_IsOwnedByCurrentThread(iter_o) && !_PyObject_GC_IS_SHARED(iter_o)) {
2941+
goto failure;
2942+
}
2943+
#endif
29332944
specialize(instr, FOR_ITER_LIST);
29342945
return;
29352946
}

0 commit comments

Comments
 (0)