Skip to content

Commit 375399d

Browse files
committed
Make the free-threaded FOR_ITER work in the tier 2 interpreter/jit.
1 parent 4326376 commit 375399d

File tree

8 files changed

+122
-87
lines changed

8 files changed

+122
-87
lines changed

Include/internal/pycore_opcode_metadata.h

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_uop_ids.h

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

Include/internal/pycore_uop_metadata.h

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

Python/bytecodes.c

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3094,6 +3094,7 @@ dummy_func(
30943094
// invalid by the time we actually try to fetch the item.
30953095
#ifdef Py_GIL_DISABLED
30963096
assert(_PyObject_IsUniquelyReferenced(iter_o));
3097+
(void)iter_o;
30973098
#else
30983099
_PyListIterObject *it = (_PyListIterObject *)iter_o;
30993100
STAT_INC(FOR_ITER, hit);
@@ -3126,7 +3127,7 @@ dummy_func(
31263127
#endif
31273128
}
31283129

3129-
op(_ITER_NEXT_LIST, (iter -- iter, next)) {
3130+
replaced op(_ITER_NEXT_LIST, (iter -- iter, next)) {
31303131
PyObject *iter_o = PyStackRef_AsPyObjectBorrow(iter);
31313132
_PyListIterObject *it = (_PyListIterObject *)iter_o;
31323133
assert(Py_TYPE(iter_o) == &PyListIter_Type);
@@ -3154,6 +3155,33 @@ dummy_func(
31543155
#endif
31553156
}
31563157

3158+
// Only used by Tier 2
3159+
op(_ITER_NEXT_LIST_TIER_TWO, (iter -- iter, next)) {
3160+
PyObject *iter_o = PyStackRef_AsPyObjectBorrow(iter);
3161+
_PyListIterObject *it = (_PyListIterObject *)iter_o;
3162+
assert(Py_TYPE(iter_o) == &PyListIter_Type);
3163+
PyListObject *seq = it->it_seq;
3164+
assert(seq);
3165+
#ifdef Py_GIL_DISABLED
3166+
assert(_PyObject_IsUniquelyReferenced(iter_o));
3167+
assert(_Py_IsOwnedByCurrentThread((PyObject *)seq) ||
3168+
_PyObject_GC_IS_SHARED(seq));
3169+
STAT_INC(FOR_ITER, hit);
3170+
int result = _PyList_GetItemRefNoLock(seq, it->it_index, &next);
3171+
// A negative result means we lost a race with another thread
3172+
// and we need to take the slow path.
3173+
EXIT_IF(result < 0);
3174+
if (result == 0) {
3175+
it->it_index = -1;
3176+
EXIT_IF(1);
3177+
}
3178+
it->it_index++;
3179+
#else
3180+
assert(it->it_index < PyList_GET_SIZE(seq));
3181+
next = PyStackRef_FromPyObjectNew(PyList_GET_ITEM(seq, it->it_index++));
3182+
#endif
3183+
}
3184+
31573185
macro(FOR_ITER_LIST) =
31583186
unused/1 + // Skip over the counter
31593187
_ITER_CHECK_LIST +

Python/executor_cases.c.h

Lines changed: 7 additions & 5 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: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/optimizer.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,7 @@ _PyUOp_Replacements[MAX_UOP_ID + 1] = {
363363
[_ITER_JUMP_LIST] = _GUARD_NOT_EXHAUSTED_LIST,
364364
[_ITER_JUMP_TUPLE] = _GUARD_NOT_EXHAUSTED_TUPLE,
365365
[_FOR_ITER] = _FOR_ITER_TIER_TWO,
366+
[_ITER_NEXT_LIST] = _ITER_NEXT_LIST_TIER_TWO,
366367
};
367368

368369
static const uint8_t

Python/optimizer_cases.c.h

Lines changed: 3 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)