Skip to content

Commit

Permalink
pythonGH-98831: Refactor and fix cases generator (python#99526)
Browse files Browse the repository at this point in the history
Also complete cache effects for BINARY_SUBSCR family.
  • Loading branch information
gvanrossum committed Nov 18, 2022
1 parent b629fdd commit 4f5e1cb
Show file tree
Hide file tree
Showing 6 changed files with 405 additions and 308 deletions.
63 changes: 25 additions & 38 deletions Python/bytecodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,15 @@ 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"

// 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(
Expand Down Expand Up @@ -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);
Expand All @@ -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)) {
Expand Down Expand Up @@ -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);

Expand All @@ -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);

Expand All @@ -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);
Expand Down
65 changes: 36 additions & 29 deletions Python/generated_cases.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 4f5e1cb

Please sign in to comment.