summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorDonghee Na <donghee.na@python.org>2024-12-02 01:38:17 (GMT)
committerGitHub <noreply@github.com>2024-12-02 01:38:17 (GMT)
commite2713409cff5b71b1176b0e3fa63dae447548672 (patch)
treed91c8e16052a44f78bbe075ad320fade4e907061 /Python
parent7ea523f47cdb4cf512a1e2ae1f93f5d19a48945d (diff)
downloadcpython-e2713409cff5b71b1176b0e3fa63dae447548672.zip
cpython-e2713409cff5b71b1176b0e3fa63dae447548672.tar.gz
cpython-e2713409cff5b71b1176b0e3fa63dae447548672.tar.bz2
gh-115999: Add partial free-thread specialization for BINARY_SUBSCR (gh-127227)
Diffstat (limited to 'Python')
-rw-r--r--Python/bytecodes.c10
-rw-r--r--Python/executor_cases.c.h11
-rw-r--r--Python/generated_cases.c.h12
-rw-r--r--Python/specialize.c25
4 files changed, 40 insertions, 18 deletions
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index a14b32b..c07ec42 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -704,7 +704,7 @@ dummy_func(
};
specializing op(_SPECIALIZE_BINARY_SUBSCR, (counter/1, container, sub -- container, sub)) {
- #if ENABLE_SPECIALIZATION
+ #if ENABLE_SPECIALIZATION_FT
assert(frame->stackpointer == NULL);
if (ADAPTIVE_COUNTER_TRIGGERS(counter)) {
next_instr = this_instr;
@@ -713,7 +713,7 @@ dummy_func(
}
OPCODE_DEFERRED_INC(BINARY_SUBSCR);
ADVANCE_ADAPTIVE_COUNTER(this_instr[1].counter);
- #endif /* ENABLE_SPECIALIZATION */
+ #endif /* ENABLE_SPECIALIZATION_FT */
}
op(_BINARY_SUBSCR, (container, sub -- res)) {
@@ -790,11 +790,17 @@ dummy_func(
// Deopt unless 0 <= sub < PyList_Size(list)
DEOPT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject *)sub));
Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0];
+#ifdef Py_GIL_DISABLED
+ PyObject *res_o = _PyList_GetItemRef((PyListObject*)list, index);
+ DEOPT_IF(res_o == NULL);
+ STAT_INC(BINARY_SUBSCR, hit);
+#else
DEOPT_IF(index >= PyList_GET_SIZE(list));
STAT_INC(BINARY_SUBSCR, hit);
PyObject *res_o = PyList_GET_ITEM(list, index);
assert(res_o != NULL);
Py_INCREF(res_o);
+#endif
PyStackRef_CLOSE_SPECIALIZED(sub_st, (destructor)PyObject_Free);
DEAD(sub_st);
PyStackRef_CLOSE(list_st);
diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h
index d46412a..c91257b 100644
--- a/Python/executor_cases.c.h
+++ b/Python/executor_cases.c.h
@@ -981,6 +981,16 @@
JUMP_TO_JUMP_TARGET();
}
Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0];
+ #ifdef Py_GIL_DISABLED
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+ PyObject *res_o = _PyList_GetItemRef((PyListObject*)list, index);
+ stack_pointer = _PyFrame_GetStackPointer(frame);
+ if (res_o == NULL) {
+ UOP_STAT_INC(uopcode, miss);
+ JUMP_TO_JUMP_TARGET();
+ }
+ STAT_INC(BINARY_SUBSCR, hit);
+ #else
if (index >= PyList_GET_SIZE(list)) {
UOP_STAT_INC(uopcode, miss);
JUMP_TO_JUMP_TARGET();
@@ -989,6 +999,7 @@
PyObject *res_o = PyList_GET_ITEM(list, index);
assert(res_o != NULL);
Py_INCREF(res_o);
+ #endif
PyStackRef_CLOSE_SPECIALIZED(sub_st, (destructor)PyObject_Free);
PyStackRef_CLOSE(list_st);
res = PyStackRef_FromPyObjectSteal(res_o);
diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h
index c9a5132..45bcc42 100644
--- a/Python/generated_cases.c.h
+++ b/Python/generated_cases.c.h
@@ -433,7 +433,7 @@
container = stack_pointer[-2];
uint16_t counter = read_u16(&this_instr[1].cache);
(void)counter;
- #if ENABLE_SPECIALIZATION
+ #if ENABLE_SPECIALIZATION_FT
assert(frame->stackpointer == NULL);
if (ADAPTIVE_COUNTER_TRIGGERS(counter)) {
next_instr = this_instr;
@@ -444,7 +444,7 @@
}
OPCODE_DEFERRED_INC(BINARY_SUBSCR);
ADVANCE_ADAPTIVE_COUNTER(this_instr[1].counter);
- #endif /* ENABLE_SPECIALIZATION */
+ #endif /* ENABLE_SPECIALIZATION_FT */
}
// _BINARY_SUBSCR
{
@@ -577,11 +577,19 @@
// Deopt unless 0 <= sub < PyList_Size(list)
DEOPT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject *)sub), BINARY_SUBSCR);
Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0];
+ #ifdef Py_GIL_DISABLED
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+ PyObject *res_o = _PyList_GetItemRef((PyListObject*)list, index);
+ stack_pointer = _PyFrame_GetStackPointer(frame);
+ DEOPT_IF(res_o == NULL, BINARY_SUBSCR);
+ STAT_INC(BINARY_SUBSCR, hit);
+ #else
DEOPT_IF(index >= PyList_GET_SIZE(list), BINARY_SUBSCR);
STAT_INC(BINARY_SUBSCR, hit);
PyObject *res_o = PyList_GET_ITEM(list, index);
assert(res_o != NULL);
Py_INCREF(res_o);
+ #endif
PyStackRef_CLOSE_SPECIALIZED(sub_st, (destructor)PyObject_Free);
PyStackRef_CLOSE(list_st);
res = PyStackRef_FromPyObjectSteal(res_o);
diff --git a/Python/specialize.c b/Python/specialize.c
index 172dae7..d03310d 100644
--- a/Python/specialize.c
+++ b/Python/specialize.c
@@ -1717,15 +1717,15 @@ _Py_Specialize_BinarySubscr(
PyObject *container = PyStackRef_AsPyObjectBorrow(container_st);
PyObject *sub = PyStackRef_AsPyObjectBorrow(sub_st);
- assert(ENABLE_SPECIALIZATION);
+ assert(ENABLE_SPECIALIZATION_FT);
assert(_PyOpcode_Caches[BINARY_SUBSCR] ==
INLINE_CACHE_ENTRIES_BINARY_SUBSCR);
- _PyBinarySubscrCache *cache = (_PyBinarySubscrCache *)(instr + 1);
PyTypeObject *container_type = Py_TYPE(container);
+ uint8_t specialized_op;
if (container_type == &PyList_Type) {
if (PyLong_CheckExact(sub)) {
if (_PyLong_IsNonNegativeCompact((PyLongObject *)sub)) {
- instr->op.code = BINARY_SUBSCR_LIST_INT;
+ specialized_op = BINARY_SUBSCR_LIST_INT;
goto success;
}
SPECIALIZATION_FAIL(BINARY_SUBSCR, SPEC_FAIL_OUT_OF_RANGE);
@@ -1738,7 +1738,7 @@ _Py_Specialize_BinarySubscr(
if (container_type == &PyTuple_Type) {
if (PyLong_CheckExact(sub)) {
if (_PyLong_IsNonNegativeCompact((PyLongObject *)sub)) {
- instr->op.code = BINARY_SUBSCR_TUPLE_INT;
+ specialized_op = BINARY_SUBSCR_TUPLE_INT;
goto success;
}
SPECIALIZATION_FAIL(BINARY_SUBSCR, SPEC_FAIL_OUT_OF_RANGE);
@@ -1751,7 +1751,7 @@ _Py_Specialize_BinarySubscr(
if (container_type == &PyUnicode_Type) {
if (PyLong_CheckExact(sub)) {
if (_PyLong_IsNonNegativeCompact((PyLongObject *)sub)) {
- instr->op.code = BINARY_SUBSCR_STR_INT;
+ specialized_op = BINARY_SUBSCR_STR_INT;
goto success;
}
SPECIALIZATION_FAIL(BINARY_SUBSCR, SPEC_FAIL_OUT_OF_RANGE);
@@ -1762,9 +1762,10 @@ _Py_Specialize_BinarySubscr(
goto fail;
}
if (container_type == &PyDict_Type) {
- instr->op.code = BINARY_SUBSCR_DICT;
+ specialized_op = BINARY_SUBSCR_DICT;
goto success;
}
+#ifndef Py_GIL_DISABLED
PyTypeObject *cls = Py_TYPE(container);
PyObject *descriptor = _PyType_Lookup(cls, &_Py_ID(__getitem__));
if (descriptor && Py_TYPE(descriptor) == &PyFunction_Type) {
@@ -1797,21 +1798,17 @@ _Py_Specialize_BinarySubscr(
// struct _specialization_cache):
ht->_spec_cache.getitem = descriptor;
ht->_spec_cache.getitem_version = version;
- instr->op.code = BINARY_SUBSCR_GETITEM;
+ specialized_op = BINARY_SUBSCR_GETITEM;
goto success;
}
+#endif // Py_GIL_DISABLED
SPECIALIZATION_FAIL(BINARY_SUBSCR,
binary_subscr_fail_kind(container_type, sub));
fail:
- STAT_INC(BINARY_SUBSCR, failure);
- assert(!PyErr_Occurred());
- instr->op.code = BINARY_SUBSCR;
- cache->counter = adaptive_counter_backoff(cache->counter);
+ unspecialize(instr);
return;
success:
- STAT_INC(BINARY_SUBSCR, success);
- assert(!PyErr_Occurred());
- cache->counter = adaptive_counter_cooldown();
+ specialize(instr, specialized_op);
}