aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Python/bytecodes.c
diff options
context:
space:
mode:
authorSam Gross <colesbury@gmail.com>2024-11-26 21:46:06 +0000
committerGitHub <noreply@github.com>2024-11-26 16:46:06 -0500
commit71ede1142ddad2d31cc966b8fe4a5aff664f4d53 (patch)
treec8e17fd89be977bf04ffd1c01b352c4bbcb191f5 /Python/bytecodes.c
parentf0d3f10c43c9029378adba11a65b3d1287e4be32 (diff)
downloadcpython-71ede1142ddad2d31cc966b8fe4a5aff664f4d53.tar.gz
cpython-71ede1142ddad2d31cc966b8fe4a5aff664f4d53.zip
gh-115999: Add free-threaded specialization for `STORE_SUBSCR` (#127169)
The specialization only depends on the type, so no special thread-safety considerations there. STORE_SUBSCR_LIST_INT needs to lock the list before modifying it. `_PyDict_SetItem_Take2` already internally locks the dictionary using a critical section.
Diffstat (limited to 'Python/bytecodes.c')
-rw-r--r--Python/bytecodes.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index 88e96afe415..a14b32b8108 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -910,7 +910,7 @@ dummy_func(
};
specializing op(_SPECIALIZE_STORE_SUBSCR, (counter/1, container, sub -- container, sub)) {
- #if ENABLE_SPECIALIZATION
+ #if ENABLE_SPECIALIZATION_FT
if (ADAPTIVE_COUNTER_TRIGGERS(counter)) {
next_instr = this_instr;
_Py_Specialize_StoreSubscr(container, sub, next_instr);
@@ -918,7 +918,7 @@ dummy_func(
}
OPCODE_DEFERRED_INC(STORE_SUBSCR);
ADVANCE_ADAPTIVE_COUNTER(this_instr[1].counter);
- #endif /* ENABLE_SPECIALIZATION */
+ #endif /* ENABLE_SPECIALIZATION_FT */
}
op(_STORE_SUBSCR, (v, container, sub -- )) {
@@ -940,13 +940,18 @@ dummy_func(
// Ensure nonnegative, zero-or-one-digit ints.
DEOPT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject *)sub));
Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0];
+ DEOPT_IF(!LOCK_OBJECT(list));
// Ensure index < len(list)
- DEOPT_IF(index >= PyList_GET_SIZE(list));
+ if (index >= PyList_GET_SIZE(list)) {
+ UNLOCK_OBJECT(list);
+ DEOPT_IF(true);
+ }
STAT_INC(STORE_SUBSCR, hit);
PyObject *old_value = PyList_GET_ITEM(list, index);
PyList_SET_ITEM(list, index, PyStackRef_AsPyObjectSteal(value));
assert(old_value != NULL);
+ UNLOCK_OBJECT(list); // unlock before decrefs!
Py_DECREF(old_value);
PyStackRef_CLOSE_SPECIALIZED(sub_st, (destructor)PyObject_Free);
DEAD(sub_st);