Skip to content

Commit ff0d788

Browse files
committed
merge specialize_binary_op_subscr into _Py_Specialize_BinaryOp and binary_op_fail_kind
1 parent 875bc77 commit ff0d788

File tree

1 file changed

+92
-98
lines changed

1 file changed

+92
-98
lines changed

Python/specialize.c

Lines changed: 92 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,7 @@ _PyCode_Quicken(_Py_CODEUNIT *instructions, Py_ssize_t size, int enable_counters
591591
#define SPEC_FAIL_BINARY_OP_OR_DIFFERENT_TYPES 30
592592
#define SPEC_FAIL_BINARY_OP_XOR_INT 31
593593
#define SPEC_FAIL_BINARY_OP_XOR_DIFFERENT_TYPES 32
594+
#define SPEC_FAIL_BINARY_OP_SUBSCR 33
594595

595596
/* Calls */
596597

@@ -1835,102 +1836,6 @@ function_get_version(PyObject *o, int opcode)
18351836
return version;
18361837
}
18371838

1838-
static int
1839-
specialize_binary_op_subscr(
1840-
PyObject *container, PyObject *sub, _Py_CODEUNIT *instr)
1841-
{
1842-
PyTypeObject *container_type = Py_TYPE(container);
1843-
uint8_t specialized_op;
1844-
if (container_type == &PyList_Type) {
1845-
if (PyLong_CheckExact(sub)) {
1846-
if (_PyLong_IsNonNegativeCompact((PyLongObject *)sub)) {
1847-
specialized_op = BINARY_OP_SUBSCR_LIST_INT;
1848-
goto success;
1849-
}
1850-
SPECIALIZATION_FAIL(BINARY_OP, SPEC_FAIL_OUT_OF_RANGE);
1851-
goto fail;
1852-
}
1853-
SPECIALIZATION_FAIL(BINARY_OP,
1854-
PySlice_Check(sub) ? SPEC_FAIL_SUBSCR_LIST_SLICE : SPEC_FAIL_OTHER);
1855-
goto fail;
1856-
}
1857-
if (container_type == &PyTuple_Type) {
1858-
if (PyLong_CheckExact(sub)) {
1859-
if (_PyLong_IsNonNegativeCompact((PyLongObject *)sub)) {
1860-
specialized_op = BINARY_OP_SUBSCR_TUPLE_INT;
1861-
goto success;
1862-
}
1863-
SPECIALIZATION_FAIL(BINARY_OP, SPEC_FAIL_OUT_OF_RANGE);
1864-
goto fail;
1865-
}
1866-
SPECIALIZATION_FAIL(BINARY_OP,
1867-
PySlice_Check(sub) ? SPEC_FAIL_SUBSCR_TUPLE_SLICE : SPEC_FAIL_OTHER);
1868-
goto fail;
1869-
}
1870-
if (container_type == &PyUnicode_Type) {
1871-
if (PyLong_CheckExact(sub)) {
1872-
if (_PyLong_IsNonNegativeCompact((PyLongObject *)sub)) {
1873-
specialized_op = BINARY_OP_SUBSCR_STR_INT;
1874-
goto success;
1875-
}
1876-
SPECIALIZATION_FAIL(BINARY_OP, SPEC_FAIL_OUT_OF_RANGE);
1877-
goto fail;
1878-
}
1879-
SPECIALIZATION_FAIL(BINARY_OP,
1880-
PySlice_Check(sub) ? SPEC_FAIL_SUBSCR_STRING_SLICE : SPEC_FAIL_OTHER);
1881-
goto fail;
1882-
}
1883-
if (container_type == &PyDict_Type) {
1884-
specialized_op = BINARY_OP_SUBSCR_DICT;
1885-
goto success;
1886-
}
1887-
unsigned int tp_version;
1888-
PyObject *descriptor = _PyType_LookupRefAndVersion(container_type, &_Py_ID(__getitem__), &tp_version);
1889-
if (descriptor && Py_TYPE(descriptor) == &PyFunction_Type) {
1890-
if (!(container_type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
1891-
SPECIALIZATION_FAIL(BINARY_OP, SPEC_FAIL_SUBSCR_NOT_HEAP_TYPE);
1892-
Py_DECREF(descriptor);
1893-
goto fail;
1894-
}
1895-
PyFunctionObject *func = (PyFunctionObject *)descriptor;
1896-
PyCodeObject *fcode = (PyCodeObject *)func->func_code;
1897-
int kind = function_kind(fcode);
1898-
if (kind != SIMPLE_FUNCTION) {
1899-
SPECIALIZATION_FAIL(BINARY_OP, kind);
1900-
Py_DECREF(descriptor);
1901-
goto fail;
1902-
}
1903-
if (fcode->co_argcount != 2) {
1904-
SPECIALIZATION_FAIL(BINARY_OP, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS);
1905-
Py_DECREF(descriptor);
1906-
goto fail;
1907-
}
1908-
1909-
PyHeapTypeObject *ht = (PyHeapTypeObject *)container_type;
1910-
/* Don't specialize if PEP 523 is active */
1911-
if (_PyInterpreterState_GET()->eval_frame) {
1912-
SPECIALIZATION_FAIL(BINARY_OP, SPEC_FAIL_OTHER);
1913-
Py_DECREF(descriptor);
1914-
goto fail;
1915-
}
1916-
if (_PyType_CacheGetItemForSpecialization(ht, descriptor, (uint32_t)tp_version)) {
1917-
specialized_op = BINARY_OP_SUBSCR_GETITEM;
1918-
Py_DECREF(descriptor);
1919-
goto success;
1920-
}
1921-
}
1922-
Py_XDECREF(descriptor);
1923-
SPECIALIZATION_FAIL(BINARY_OP,
1924-
binary_subscr_fail_kind(container_type, sub));
1925-
fail:
1926-
unspecialize(instr);
1927-
return 0;
1928-
success:
1929-
specialize(instr, specialized_op);
1930-
return 1;
1931-
}
1932-
1933-
19341839
#ifdef Py_STATS
19351840
static int
19361841
store_subscr_fail_kind(PyObject *container, PyObject *sub)
@@ -2424,6 +2329,59 @@ binary_op_fail_kind(int oparg, PyObject *lhs, PyObject *rhs)
24242329
return SPEC_FAIL_BINARY_OP_XOR_INT;
24252330
}
24262331
return SPEC_FAIL_BINARY_OP_XOR;
2332+
case NB_SUBSCR:
2333+
if (PyList_CheckExact(lhs)) {
2334+
if (PyLong_CheckExact(rhs) && !_PyLong_IsNonNegativeCompact((PyLongObject *)rhs)) {
2335+
return SPEC_FAIL_OUT_OF_RANGE;
2336+
}
2337+
if (PySlice_Check(rhs)) {
2338+
return SPEC_FAIL_SUBSCR_LIST_SLICE;
2339+
}
2340+
}
2341+
if (PyTuple_CheckExact(lhs)) {
2342+
if (PyLong_CheckExact(rhs) && !_PyLong_IsNonNegativeCompact((PyLongObject *)rhs)) {
2343+
return SPEC_FAIL_OUT_OF_RANGE;
2344+
}
2345+
if (PySlice_Check(rhs)) {
2346+
return SPEC_FAIL_SUBSCR_TUPLE_SLICE;
2347+
}
2348+
}
2349+
if (PyUnicode_CheckExact(lhs)) {
2350+
if (PyLong_CheckExact(rhs) && !_PyLong_IsNonNegativeCompact((PyLongObject *)rhs)) {
2351+
return SPEC_FAIL_OUT_OF_RANGE;
2352+
}
2353+
if (PySlice_Check(rhs)) {
2354+
return SPEC_FAIL_SUBSCR_STRING_SLICE;
2355+
}
2356+
}
2357+
unsigned int tp_version;
2358+
PyTypeObject *container_type = Py_TYPE(lhs);
2359+
PyObject *descriptor = _PyType_LookupRefAndVersion(container_type, &_Py_ID(__getitem__), &tp_version);
2360+
if (descriptor && Py_TYPE(descriptor) == &PyFunction_Type) {
2361+
if (!(container_type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
2362+
Py_DECREF(descriptor);
2363+
return SPEC_FAIL_SUBSCR_NOT_HEAP_TYPE;
2364+
}
2365+
PyFunctionObject *func = (PyFunctionObject *)descriptor;
2366+
PyCodeObject *fcode = (PyCodeObject *)func->func_code;
2367+
int kind = function_kind(fcode);
2368+
if (kind != SIMPLE_FUNCTION) {
2369+
Py_DECREF(descriptor);
2370+
return kind;
2371+
}
2372+
if (fcode->co_argcount != 2) {
2373+
Py_DECREF(descriptor);
2374+
return SPEC_FAIL_WRONG_NUMBER_ARGUMENTS;
2375+
}
2376+
2377+
if (_PyInterpreterState_GET()->eval_frame) {
2378+
/* Don't specialize if PEP 523 is active */
2379+
Py_DECREF(descriptor);
2380+
return SPEC_FAIL_OTHER;
2381+
}
2382+
}
2383+
Py_XDECREF(descriptor);
2384+
return SPEC_FAIL_BINARY_OP_SUBSCR;
24272385
}
24282386
Py_UNREACHABLE();
24292387
}
@@ -2634,10 +2592,46 @@ _Py_Specialize_BinaryOp(_PyStackRef lhs_st, _PyStackRef rhs_st, _Py_CODEUNIT *in
26342592
}
26352593
break;
26362594
case NB_SUBSCR:
2637-
if (specialize_binary_op_subscr(lhs, rhs, instr)) {
2595+
if (PyLong_CheckExact(rhs) && _PyLong_IsNonNegativeCompact((PyLongObject *)rhs)) {
2596+
if (PyList_CheckExact(lhs)) {
2597+
specialize(instr, BINARY_OP_SUBSCR_LIST_INT);
2598+
return;
2599+
}
2600+
if (PyTuple_CheckExact(lhs)) {
2601+
specialize(instr, BINARY_OP_SUBSCR_TUPLE_INT);
2602+
return;
2603+
}
2604+
if (PyUnicode_CheckExact(lhs)) {
2605+
specialize(instr, BINARY_OP_SUBSCR_STR_INT);
2606+
return;
2607+
}
2608+
}
2609+
if (PyDict_CheckExact(lhs)) {
2610+
specialize(instr, BINARY_OP_SUBSCR_DICT);
26382611
return;
26392612
}
2640-
return;
2613+
unsigned int tp_version;
2614+
PyTypeObject *container_type = Py_TYPE(lhs);
2615+
PyObject *descriptor = _PyType_LookupRefAndVersion(container_type, &_Py_ID(__getitem__), &tp_version);
2616+
if (descriptor && Py_TYPE(descriptor) == &PyFunction_Type &&
2617+
container_type->tp_flags & Py_TPFLAGS_HEAPTYPE)
2618+
{
2619+
PyFunctionObject *func = (PyFunctionObject *)descriptor;
2620+
PyCodeObject *fcode = (PyCodeObject *)func->func_code;
2621+
int kind = function_kind(fcode);
2622+
PyHeapTypeObject *ht = (PyHeapTypeObject *)container_type;
2623+
if (kind == SIMPLE_FUNCTION &&
2624+
fcode->co_argcount == 2 &&
2625+
!_PyInterpreterState_GET()->eval_frame && /* Don't specialize if PEP 523 is active */
2626+
_PyType_CacheGetItemForSpecialization(ht, descriptor, (uint32_t)tp_version))
2627+
{
2628+
specialize(instr, BINARY_OP_SUBSCR_GETITEM);
2629+
Py_DECREF(descriptor);
2630+
return;
2631+
}
2632+
}
2633+
Py_XDECREF(descriptor);
2634+
break;
26412635
}
26422636

26432637
_PyBinaryOpSpecializationDescr *descr;

0 commit comments

Comments
 (0)