GH-104584: Assorted fixes for the optimizer API. (GH-105683) · python/cpython@5816199 · GitHub
Skip to content

Commit 5816199

Browse files
authored
GH-104584: Assorted fixes for the optimizer API. (GH-105683)
* Add test for long loops * Clear ENTER_EXECUTOR when deopting code objects.
1 parent 4426279 commit 5816199

6 files changed

Lines changed: 297 additions & 203 deletions

File tree

Lib/test/test_capi/test_misc.py

Lines changed: 57 additions & 8 deletions

Modules/_testinternalcapi.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -840,6 +840,15 @@ set_optimizer(PyObject *self, PyObject *opt)
840840
Py_RETURN_NONE;
841841
}
842842

843+
static PyObject *
844+
get_optimizer(PyObject *self, PyObject *Py_UNUSED(ignored))
845+
{
846+
PyObject *opt = (PyObject *)PyUnstable_GetOptimizer();
847+
if (opt == NULL) {
848+
Py_RETURN_NONE;
849+
}
850+
return opt;
851+
}
843852

844853
static int _pending_callback(void *arg)
845854
{
@@ -982,6 +991,7 @@ static PyMethodDef module_functions[] = {
982991
{"iframe_getcode", iframe_getcode, METH_O, NULL},
983992
{"iframe_getline", iframe_getline, METH_O, NULL},
984993
{"iframe_getlasti", iframe_getlasti, METH_O, NULL},
994+
{"get_optimizer", get_optimizer, METH_NOARGS, NULL},
985995
{"set_optimizer", set_optimizer, METH_O, NULL},
986996
{"get_counter_optimizer", get_counter_optimizer, METH_NOARGS, NULL},
987997
{"pending_threadfunc", _PyCFunction_CAST(pending_threadfunc),

Objects/codeobject.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1465,12 +1465,28 @@ PyCode_GetFreevars(PyCodeObject *code)
14651465
return _PyCode_GetFreevars(code);
14661466
}
14671467

1468+
static void
1469+
clear_executors(PyCodeObject *co)
1470+
{
1471+
for (int i = 0; i < co->co_executors->size; i++) {
1472+
Py_CLEAR(co->co_executors->executors[i]);
1473+
}
1474+
PyMem_Free(co->co_executors);
1475+
co->co_executors = NULL;
1476+
}
1477+
14681478
static void
14691479
deopt_code(PyCodeObject *code, _Py_CODEUNIT *instructions)
14701480
{
14711481
Py_ssize_t len = Py_SIZE(code);
14721482
for (int i = 0; i < len; i++) {
14731483
int opcode = _Py_GetBaseOpcode(code, i);
1484+
if (opcode == ENTER_EXECUTOR) {
1485+
_PyExecutorObject *exec = code->co_executors->executors[instructions[i].op.arg];
1486+
opcode = exec->vm_data.opcode;
1487+
instructions[i].op.arg = exec->vm_data.oparg;
1488+
}
1489+
assert(opcode != ENTER_EXECUTOR);
14741490
int caches = _PyOpcode_Caches[opcode];
14751491
instructions[i].op.code = opcode;
14761492
for (int j = 1; j <= caches; j++) {
@@ -1679,10 +1695,7 @@ code_dealloc(PyCodeObject *co)
16791695
PyMem_Free(co_extra);
16801696
}
16811697
if (co->co_executors != NULL) {
1682-
for (int i = 0; i < co->co_executors->size; i++) {
1683-
Py_CLEAR(co->co_executors->executors[i]);
1684-
}
1685-
PyMem_Free(co->co_executors);
1698+
clear_executors(co);
16861699
}
16871700

16881701
Py_XDECREF(co->co_consts);
@@ -2278,6 +2291,9 @@ void
22782291
_PyStaticCode_Fini(PyCodeObject *co)
22792292
{
22802293
deopt_code(co, _PyCode_CODE(co));
2294+
if (co->co_executors != NULL) {
2295+
clear_executors(co);
2296+
}
22812297
PyMem_Free(co->co_extra);
22822298
if (co->_co_cached != NULL) {
22832299
Py_CLEAR(co->_co_cached->_co_code);

Python/bytecodes.c

Lines changed: 2 additions & 1 deletion

0 commit comments

Comments
 (0)