mirror of
https://github.com/python/cpython.git
synced 2025-08-03 16:39:00 +00:00
GH-98831: Refactor and fix cases generator (#99526)
Also complete cache effects for BINARY_SUBSCR family.
This commit is contained in:
parent
b629fdd88a
commit
4f5e1cb00a
6 changed files with 403 additions and 306 deletions
|
@ -71,7 +71,7 @@ do { \
|
|||
|
||||
#define inst(name, ...) case name:
|
||||
#define super(name) static int SUPER_##name
|
||||
#define family(name) static int family_##name
|
||||
#define family(name, ...) static int family_##name
|
||||
|
||||
#define NAME_ERROR_MSG \
|
||||
"name '%.200s' is not defined"
|
||||
|
@ -79,6 +79,7 @@ do { \
|
|||
// Dummy variables for stack effects.
|
||||
static PyObject *value, *value1, *value2, *left, *right, *res, *sum, *prod, *sub;
|
||||
static PyObject *container, *start, *stop, *v, *lhs, *rhs;
|
||||
static PyObject *list, *tuple, *dict;
|
||||
|
||||
static PyObject *
|
||||
dummy_func(
|
||||
|
@ -322,7 +323,15 @@ dummy_func(
|
|||
ERROR_IF(sum == NULL, error);
|
||||
}
|
||||
|
||||
inst(BINARY_SUBSCR, (container, sub -- res)) {
|
||||
family(binary_subscr, INLINE_CACHE_ENTRIES_BINARY_SUBSCR) = {
|
||||
BINARY_SUBSCR,
|
||||
BINARY_SUBSCR_DICT,
|
||||
BINARY_SUBSCR_GETITEM,
|
||||
BINARY_SUBSCR_LIST_INT,
|
||||
BINARY_SUBSCR_TUPLE_INT,
|
||||
};
|
||||
|
||||
inst(BINARY_SUBSCR, (container, sub, unused/4 -- res)) {
|
||||
_PyBinarySubscrCache *cache = (_PyBinarySubscrCache *)next_instr;
|
||||
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
|
||||
assert(cframe.use_tracing == 0);
|
||||
|
@ -336,7 +345,6 @@ dummy_func(
|
|||
Py_DECREF(container);
|
||||
Py_DECREF(sub);
|
||||
ERROR_IF(res == NULL, error);
|
||||
JUMPBY(INLINE_CACHE_ENTRIES_BINARY_SUBSCR);
|
||||
}
|
||||
|
||||
inst(BINARY_SLICE, (container, start, stop -- res)) {
|
||||
|
@ -369,11 +377,8 @@ dummy_func(
|
|||
ERROR_IF(err, error);
|
||||
}
|
||||
|
||||
// stack effect: (__0 -- )
|
||||
inst(BINARY_SUBSCR_LIST_INT) {
|
||||
inst(BINARY_SUBSCR_LIST_INT, (list, sub, unused/4 -- res)) {
|
||||
assert(cframe.use_tracing == 0);
|
||||
PyObject *sub = TOP();
|
||||
PyObject *list = SECOND();
|
||||
DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR);
|
||||
DEOPT_IF(!PyList_CheckExact(list), BINARY_SUBSCR);
|
||||
|
||||
|
@ -384,21 +389,15 @@ dummy_func(
|
|||
Py_ssize_t index = ((PyLongObject*)sub)->ob_digit[0];
|
||||
DEOPT_IF(index >= PyList_GET_SIZE(list), BINARY_SUBSCR);
|
||||
STAT_INC(BINARY_SUBSCR, hit);
|
||||
PyObject *res = PyList_GET_ITEM(list, index);
|
||||
res = PyList_GET_ITEM(list, index);
|
||||
assert(res != NULL);
|
||||
Py_INCREF(res);
|
||||
STACK_SHRINK(1);
|
||||
_Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free);
|
||||
SET_TOP(res);
|
||||
Py_DECREF(list);
|
||||
JUMPBY(INLINE_CACHE_ENTRIES_BINARY_SUBSCR);
|
||||
}
|
||||
|
||||
// stack effect: (__0 -- )
|
||||
inst(BINARY_SUBSCR_TUPLE_INT) {
|
||||
inst(BINARY_SUBSCR_TUPLE_INT, (tuple, sub, unused/4 -- res)) {
|
||||
assert(cframe.use_tracing == 0);
|
||||
PyObject *sub = TOP();
|
||||
PyObject *tuple = SECOND();
|
||||
DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR);
|
||||
DEOPT_IF(!PyTuple_CheckExact(tuple), BINARY_SUBSCR);
|
||||
|
||||
|
@ -409,51 +408,39 @@ dummy_func(
|
|||
Py_ssize_t index = ((PyLongObject*)sub)->ob_digit[0];
|
||||
DEOPT_IF(index >= PyTuple_GET_SIZE(tuple), BINARY_SUBSCR);
|
||||
STAT_INC(BINARY_SUBSCR, hit);
|
||||
PyObject *res = PyTuple_GET_ITEM(tuple, index);
|
||||
res = PyTuple_GET_ITEM(tuple, index);
|
||||
assert(res != NULL);
|
||||
Py_INCREF(res);
|
||||
STACK_SHRINK(1);
|
||||
_Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free);
|
||||
SET_TOP(res);
|
||||
Py_DECREF(tuple);
|
||||
JUMPBY(INLINE_CACHE_ENTRIES_BINARY_SUBSCR);
|
||||
}
|
||||
|
||||
// stack effect: (__0 -- )
|
||||
inst(BINARY_SUBSCR_DICT) {
|
||||
inst(BINARY_SUBSCR_DICT, (dict, sub, unused/4 -- res)) {
|
||||
assert(cframe.use_tracing == 0);
|
||||
PyObject *dict = SECOND();
|
||||
DEOPT_IF(!PyDict_CheckExact(SECOND()), BINARY_SUBSCR);
|
||||
DEOPT_IF(!PyDict_CheckExact(dict), BINARY_SUBSCR);
|
||||
STAT_INC(BINARY_SUBSCR, hit);
|
||||
PyObject *sub = TOP();
|
||||
PyObject *res = PyDict_GetItemWithError(dict, sub);
|
||||
res = PyDict_GetItemWithError(dict, sub);
|
||||
if (res == NULL) {
|
||||
if (!_PyErr_Occurred(tstate)) {
|
||||
_PyErr_SetKeyError(sub);
|
||||
}
|
||||
goto error;
|
||||
Py_DECREF(dict);
|
||||
Py_DECREF(sub);
|
||||
ERROR_IF(1, error);
|
||||
}
|
||||
Py_INCREF(res);
|
||||
STACK_SHRINK(1);
|
||||
Py_DECREF(sub);
|
||||
SET_TOP(res);
|
||||
Py_INCREF(res); // Do this before DECREF'ing dict, sub
|
||||
Py_DECREF(dict);
|
||||
JUMPBY(INLINE_CACHE_ENTRIES_BINARY_SUBSCR);
|
||||
Py_DECREF(sub);
|
||||
}
|
||||
|
||||
// stack effect: (__0 -- )
|
||||
inst(BINARY_SUBSCR_GETITEM) {
|
||||
PyObject *sub = TOP();
|
||||
PyObject *container = SECOND();
|
||||
_PyBinarySubscrCache *cache = (_PyBinarySubscrCache *)next_instr;
|
||||
uint32_t type_version = read_u32(cache->type_version);
|
||||
inst(BINARY_SUBSCR_GETITEM, (container, sub, unused/1, type_version/2, func_version/1 -- unused)) {
|
||||
PyTypeObject *tp = Py_TYPE(container);
|
||||
DEOPT_IF(tp->tp_version_tag != type_version, BINARY_SUBSCR);
|
||||
assert(tp->tp_flags & Py_TPFLAGS_HEAPTYPE);
|
||||
PyObject *cached = ((PyHeapTypeObject *)tp)->_spec_cache.getitem;
|
||||
assert(PyFunction_Check(cached));
|
||||
PyFunctionObject *getitem = (PyFunctionObject *)cached;
|
||||
DEOPT_IF(getitem->func_version != cache->func_version, BINARY_SUBSCR);
|
||||
DEOPT_IF(getitem->func_version != func_version, BINARY_SUBSCR);
|
||||
PyCodeObject *code = (PyCodeObject *)getitem->func_code;
|
||||
assert(code->co_argcount == 2);
|
||||
DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), BINARY_SUBSCR);
|
||||
|
|
65
Python/generated_cases.c.h
generated
65
Python/generated_cases.c.h
generated
|
@ -1,4 +1,5 @@
|
|||
// This file is generated by Tools/cases_generator/generate_cases.py
|
||||
// from Python/bytecodes.c
|
||||
// Do not edit!
|
||||
|
||||
TARGET(NOP) {
|
||||
|
@ -300,6 +301,7 @@
|
|||
|
||||
TARGET(BINARY_SUBSCR) {
|
||||
PREDICTED(BINARY_SUBSCR);
|
||||
static_assert(INLINE_CACHE_ENTRIES_BINARY_SUBSCR == 4, "incorrect cache size");
|
||||
PyObject *sub = PEEK(1);
|
||||
PyObject *container = PEEK(2);
|
||||
PyObject *res;
|
||||
|
@ -316,9 +318,9 @@
|
|||
Py_DECREF(container);
|
||||
Py_DECREF(sub);
|
||||
if (res == NULL) goto pop_2_error;
|
||||
JUMPBY(INLINE_CACHE_ENTRIES_BINARY_SUBSCR);
|
||||
STACK_SHRINK(1);
|
||||
POKE(1, res);
|
||||
next_instr += 4;
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
|
@ -366,9 +368,10 @@
|
|||
}
|
||||
|
||||
TARGET(BINARY_SUBSCR_LIST_INT) {
|
||||
PyObject *sub = PEEK(1);
|
||||
PyObject *list = PEEK(2);
|
||||
PyObject *res;
|
||||
assert(cframe.use_tracing == 0);
|
||||
PyObject *sub = TOP();
|
||||
PyObject *list = SECOND();
|
||||
DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR);
|
||||
DEOPT_IF(!PyList_CheckExact(list), BINARY_SUBSCR);
|
||||
|
||||
|
@ -379,21 +382,22 @@
|
|||
Py_ssize_t index = ((PyLongObject*)sub)->ob_digit[0];
|
||||
DEOPT_IF(index >= PyList_GET_SIZE(list), BINARY_SUBSCR);
|
||||
STAT_INC(BINARY_SUBSCR, hit);
|
||||
PyObject *res = PyList_GET_ITEM(list, index);
|
||||
res = PyList_GET_ITEM(list, index);
|
||||
assert(res != NULL);
|
||||
Py_INCREF(res);
|
||||
STACK_SHRINK(1);
|
||||
_Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free);
|
||||
SET_TOP(res);
|
||||
Py_DECREF(list);
|
||||
JUMPBY(INLINE_CACHE_ENTRIES_BINARY_SUBSCR);
|
||||
STACK_SHRINK(1);
|
||||
POKE(1, res);
|
||||
next_instr += 4;
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
TARGET(BINARY_SUBSCR_TUPLE_INT) {
|
||||
PyObject *sub = PEEK(1);
|
||||
PyObject *tuple = PEEK(2);
|
||||
PyObject *res;
|
||||
assert(cframe.use_tracing == 0);
|
||||
PyObject *sub = TOP();
|
||||
PyObject *tuple = SECOND();
|
||||
DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR);
|
||||
DEOPT_IF(!PyTuple_CheckExact(tuple), BINARY_SUBSCR);
|
||||
|
||||
|
@ -404,51 +408,54 @@
|
|||
Py_ssize_t index = ((PyLongObject*)sub)->ob_digit[0];
|
||||
DEOPT_IF(index >= PyTuple_GET_SIZE(tuple), BINARY_SUBSCR);
|
||||
STAT_INC(BINARY_SUBSCR, hit);
|
||||
PyObject *res = PyTuple_GET_ITEM(tuple, index);
|
||||
res = PyTuple_GET_ITEM(tuple, index);
|
||||
assert(res != NULL);
|
||||
Py_INCREF(res);
|
||||
STACK_SHRINK(1);
|
||||
_Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free);
|
||||
SET_TOP(res);
|
||||
Py_DECREF(tuple);
|
||||
JUMPBY(INLINE_CACHE_ENTRIES_BINARY_SUBSCR);
|
||||
STACK_SHRINK(1);
|
||||
POKE(1, res);
|
||||
next_instr += 4;
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
TARGET(BINARY_SUBSCR_DICT) {
|
||||
PyObject *sub = PEEK(1);
|
||||
PyObject *dict = PEEK(2);
|
||||
PyObject *res;
|
||||
assert(cframe.use_tracing == 0);
|
||||
PyObject *dict = SECOND();
|
||||
DEOPT_IF(!PyDict_CheckExact(SECOND()), BINARY_SUBSCR);
|
||||
DEOPT_IF(!PyDict_CheckExact(dict), BINARY_SUBSCR);
|
||||
STAT_INC(BINARY_SUBSCR, hit);
|
||||
PyObject *sub = TOP();
|
||||
PyObject *res = PyDict_GetItemWithError(dict, sub);
|
||||
res = PyDict_GetItemWithError(dict, sub);
|
||||
if (res == NULL) {
|
||||
if (!_PyErr_Occurred(tstate)) {
|
||||
_PyErr_SetKeyError(sub);
|
||||
}
|
||||
goto error;
|
||||
Py_DECREF(dict);
|
||||
Py_DECREF(sub);
|
||||
if (1) goto pop_2_error;
|
||||
}
|
||||
Py_INCREF(res);
|
||||
STACK_SHRINK(1);
|
||||
Py_DECREF(sub);
|
||||
SET_TOP(res);
|
||||
Py_INCREF(res); // Do this before DECREF'ing dict, sub
|
||||
Py_DECREF(dict);
|
||||
JUMPBY(INLINE_CACHE_ENTRIES_BINARY_SUBSCR);
|
||||
Py_DECREF(sub);
|
||||
STACK_SHRINK(1);
|
||||
POKE(1, res);
|
||||
next_instr += 4;
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
TARGET(BINARY_SUBSCR_GETITEM) {
|
||||
PyObject *sub = TOP();
|
||||
PyObject *container = SECOND();
|
||||
_PyBinarySubscrCache *cache = (_PyBinarySubscrCache *)next_instr;
|
||||
uint32_t type_version = read_u32(cache->type_version);
|
||||
uint32_t type_version = read_u32(next_instr + 1);
|
||||
uint16_t func_version = *(next_instr + 3);
|
||||
PyObject *sub = PEEK(1);
|
||||
PyObject *container = PEEK(2);
|
||||
PyTypeObject *tp = Py_TYPE(container);
|
||||
DEOPT_IF(tp->tp_version_tag != type_version, BINARY_SUBSCR);
|
||||
assert(tp->tp_flags & Py_TPFLAGS_HEAPTYPE);
|
||||
PyObject *cached = ((PyHeapTypeObject *)tp)->_spec_cache.getitem;
|
||||
assert(PyFunction_Check(cached));
|
||||
PyFunctionObject *getitem = (PyFunctionObject *)cached;
|
||||
DEOPT_IF(getitem->func_version != cache->func_version, BINARY_SUBSCR);
|
||||
DEOPT_IF(getitem->func_version != func_version, BINARY_SUBSCR);
|
||||
PyCodeObject *code = (PyCodeObject *)getitem->func_code;
|
||||
assert(code->co_argcount == 2);
|
||||
DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), BINARY_SUBSCR);
|
||||
|
@ -3656,7 +3663,7 @@
|
|||
|
||||
TARGET(BINARY_OP) {
|
||||
PREDICTED(BINARY_OP);
|
||||
assert(INLINE_CACHE_ENTRIES_BINARY_OP == 1);
|
||||
static_assert(INLINE_CACHE_ENTRIES_BINARY_OP == 1, "incorrect cache size");
|
||||
PyObject *rhs = PEEK(1);
|
||||
PyObject *lhs = PEEK(2);
|
||||
PyObject *res;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue