mirror of
https://github.com/python/cpython.git
synced 2026-01-04 06:22:20 +00:00
gh-115999: Add partial free-thread specialization for BINARY_SUBSCR (gh-127227)
This commit is contained in:
parent
7ea523f47c
commit
e2713409cf
10 changed files with 128 additions and 71 deletions
|
|
@ -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);
|
||||
|
|
|
|||
11
Python/executor_cases.c.h
generated
11
Python/executor_cases.c.h
generated
|
|
@ -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);
|
||||
|
|
|
|||
12
Python/generated_cases.c.h
generated
12
Python/generated_cases.c.h
generated
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue