aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Python/executor_cases.c.h
diff options
context:
space:
mode:
Diffstat (limited to 'Python/executor_cases.c.h')
-rw-r--r--Python/executor_cases.c.h79
1 files changed, 76 insertions, 3 deletions
diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h
index 8886564cded..fb5b2240436 100644
--- a/Python/executor_cases.c.h
+++ b/Python/executor_cases.c.h
@@ -4171,10 +4171,23 @@
case _ITER_CHECK_LIST: {
_PyStackRef iter;
iter = stack_pointer[-1];
- if (Py_TYPE(PyStackRef_AsPyObjectBorrow(iter)) != &PyListIter_Type) {
+ PyObject *iter_o = PyStackRef_AsPyObjectBorrow(iter);
+ if (Py_TYPE(iter_o) != &PyListIter_Type) {
UOP_STAT_INC(uopcode, miss);
JUMP_TO_JUMP_TARGET();
}
+ #ifdef Py_GIL_DISABLED
+ if (!_PyObject_IsUniquelyReferenced(iter_o)) {
+ UOP_STAT_INC(uopcode, miss);
+ JUMP_TO_JUMP_TARGET();
+ }
+ _PyListIterObject *it = (_PyListIterObject *)iter_o;
+ if (!_Py_IsOwnedByCurrentThread((PyObject *)it->it_seq) ||
+ !_PyObject_GC_IS_SHARED(it->it_seq)) {
+ UOP_STAT_INC(uopcode, miss);
+ JUMP_TO_JUMP_TARGET();
+ }
+ #endif
break;
}
@@ -4183,6 +4196,7 @@
case _GUARD_NOT_EXHAUSTED_LIST: {
_PyStackRef iter;
iter = stack_pointer[-1];
+ #ifndef Py_GIL_DISABLED
PyObject *iter_o = PyStackRef_AsPyObjectBorrow(iter);
_PyListIterObject *it = (_PyListIterObject *)iter_o;
assert(Py_TYPE(iter_o) == &PyListIter_Type);
@@ -4198,10 +4212,13 @@
JUMP_TO_JUMP_TARGET();
}
}
+ #endif
break;
}
- case _ITER_NEXT_LIST: {
+ /* _ITER_NEXT_LIST is not a viable micro-op for tier 2 because it is replaced */
+
+ case _ITER_NEXT_LIST_TIER_TWO: {
_PyStackRef iter;
_PyStackRef next;
iter = stack_pointer[-1];
@@ -4210,8 +4227,32 @@
assert(Py_TYPE(iter_o) == &PyListIter_Type);
PyListObject *seq = it->it_seq;
assert(seq);
+ #ifdef Py_GIL_DISABLED
+ assert(_PyObject_IsUniquelyReferenced(iter_o));
+ assert(_Py_IsOwnedByCurrentThread((PyObject *)seq) ||
+ _PyObject_GC_IS_SHARED(seq));
+ STAT_INC(FOR_ITER, hit);
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+ int result = _PyList_GetItemRefNoLock(seq, it->it_index, &next);
+ stack_pointer = _PyFrame_GetStackPointer(frame);
+ // A negative result means we lost a race with another thread
+ // and we need to take the slow path.
+ if (result < 0) {
+ UOP_STAT_INC(uopcode, miss);
+ JUMP_TO_JUMP_TARGET();
+ }
+ if (result == 0) {
+ it->it_index = -1;
+ if (1) {
+ UOP_STAT_INC(uopcode, miss);
+ JUMP_TO_JUMP_TARGET();
+ }
+ }
+ it->it_index++;
+ #else
assert(it->it_index < PyList_GET_SIZE(seq));
next = PyStackRef_FromPyObjectNew(PyList_GET_ITEM(seq, it->it_index++));
+ #endif
stack_pointer[0] = next;
stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
@@ -4221,10 +4262,17 @@
case _ITER_CHECK_TUPLE: {
_PyStackRef iter;
iter = stack_pointer[-1];
- if (Py_TYPE(PyStackRef_AsPyObjectBorrow(iter)) != &PyTupleIter_Type) {
+ PyObject *iter_o = PyStackRef_AsPyObjectBorrow(iter);
+ if (Py_TYPE(iter_o) != &PyTupleIter_Type) {
+ UOP_STAT_INC(uopcode, miss);
+ JUMP_TO_JUMP_TARGET();
+ }
+ #ifdef Py_GIL_DISABLED
+ if (!_PyObject_IsUniquelyReferenced(iter_o)) {
UOP_STAT_INC(uopcode, miss);
JUMP_TO_JUMP_TARGET();
}
+ #endif
break;
}
@@ -4236,6 +4284,9 @@
PyObject *iter_o = PyStackRef_AsPyObjectBorrow(iter);
_PyTupleIterObject *it = (_PyTupleIterObject *)iter_o;
assert(Py_TYPE(iter_o) == &PyTupleIter_Type);
+ #ifdef Py_GIL_DISABLED
+ assert(_PyObject_IsUniquelyReferenced(iter_o));
+ #endif
PyTupleObject *seq = it->it_seq;
if (seq == NULL) {
UOP_STAT_INC(uopcode, miss);
@@ -4256,6 +4307,9 @@
_PyTupleIterObject *it = (_PyTupleIterObject *)iter_o;
assert(Py_TYPE(iter_o) == &PyTupleIter_Type);
PyTupleObject *seq = it->it_seq;
+ #ifdef Py_GIL_DISABLED
+ assert(_PyObject_IsUniquelyReferenced(iter_o));
+ #endif
assert(seq);
assert(it->it_index < PyTuple_GET_SIZE(seq));
next = PyStackRef_FromPyObjectNew(PyTuple_GET_ITEM(seq, it->it_index++));
@@ -4273,6 +4327,12 @@
UOP_STAT_INC(uopcode, miss);
JUMP_TO_JUMP_TARGET();
}
+ #ifdef Py_GIL_DISABLED
+ if (!_PyObject_IsUniquelyReferenced((PyObject *)r)) {
+ UOP_STAT_INC(uopcode, miss);
+ JUMP_TO_JUMP_TARGET();
+ }
+ #endif
break;
}
@@ -4296,6 +4356,9 @@
iter = stack_pointer[-1];
_PyRangeIterObject *r = (_PyRangeIterObject *)PyStackRef_AsPyObjectBorrow(iter);
assert(Py_TYPE(r) == &PyRangeIter_Type);
+ #ifdef Py_GIL_DISABLED
+ assert(_PyObject_IsUniquelyReferenced((PyObject *)r));
+ #endif
assert(r->len > 0);
long value = r->start;
r->start = value + r->step;
@@ -4321,6 +4384,16 @@
UOP_STAT_INC(uopcode, miss);
JUMP_TO_JUMP_TARGET();
}
+ #ifdef Py_GIL_DISABLED
+ // Since generators can't be used by multiple threads anyway we
+ // don't need to deopt here, but this lets us work on making
+ // generators thread-safe without necessarily having to
+ // specialize them thread-safely as well.
+ if (!_PyObject_IsUniquelyReferenced((PyObject *)gen)) {
+ UOP_STAT_INC(uopcode, miss);
+ JUMP_TO_JUMP_TARGET();
+ }
+ #endif
if (gen->gi_frame_state >= FRAME_EXECUTING) {
UOP_STAT_INC(uopcode, miss);
JUMP_TO_JUMP_TARGET();