8000 bpo-44338: Port LOAD_GLOBAL to PEP 659 adaptive interpreter by markshannon · Pull Request #26638 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

bpo-44338: Port LOAD_GLOBAL to PEP 659 adaptive interpreter #26638

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Jun 14, 2021
Merged
Prev Previous commit
Next Next commit
Remove old opcache; it is no longer used.
  • Loading branch information
markshannon committed Jun 10, 2021
commit 2b7aad15891e2d0a90549732f2e3fc8a7f30faf3
14 changes: 0 additions & 14 deletions Include/cpython/code.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,20 +106,6 @@ struct PyCodeObject {
interpreter. */
union _cache_or_instruction *co_quickened;

/* Per opcodes just-in-time cache
*
* To reduce cache size, we use indirect mapping from opcode index to
* cache object:
* cache = co_opcache[co_opcache_map[next_instr - first_instr] - 1]
*/

// co_opcache_map is indexed by (next_instr - first_instr).
// * 0 means there is no cache for this opcode.
// * n > 0 means there is cache in co_opcache[n-1].
unsigned char *co_opcache_map;
_PyOpcache *co_opcache;
int co_opcache_flag; // used to determine when create a cache.
unsigned char co_opcache_size; // length of co_opcache.
};

/* Masks for co_flags above */
Expand Down
2 changes: 0 additions & 2 deletions Include/internal/pycore_code.h
Original file line number Diff line number Diff line change
Expand Up @@ -260,8 +260,6 @@ PyAPI_FUNC(PyCodeObject *) _PyCode_New(struct _PyCodeConstructor *);

/* Private API */

int _PyCode_InitOpcache(PyCodeObject *co);

/* Getters for internal PyCodeObject data. */
PyAPI_FUNC(PyObject *) _PyCode_GetVarnames(PyCodeObject *);
PyAPI_FUNC(PyObject *) _PyCode_GetCellvars(PyCodeObject *);
Expand Down
72 changes: 4 additions & 68 deletions Objects/codeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -350,10 +350,7 @@ init_code(PyCodeObject *co, struct _PyCodeConstructor *con)
/* not set */
co->co_weakreflist = NULL;
co->co_extra = NULL;
co->co_opcache_map = NULL;
co->co_opcache = NULL;
co->co_opcache_flag = 0;
co->co_opcache_size = 0;

co->co_warmup = QUICKENING_INITIAL_WARMUP_VALUE;
co->co_quickened = NULL;
}
Expand Down Expand Up @@ -912,55 +909,6 @@ new_linesiterator(PyCodeObject *code)
return li;
}


/******************
* the opcache
******************/

int
_PyCode_InitOpcache(PyCodeObject *co)
{
Py_ssize_t co_size = PyBytes_Size(co->co_code) / sizeof(_Py_CODEUNIT);
co->co_opcache_map = (unsigned char *)PyMem_Calloc(co_size, 1);
if (co->co_opcache_map == NULL) {
return -1;
}

_Py_CODEUNIT *opcodes = (_Py_CODEUNIT*)PyBytes_AS_STRING(co->co_code);
Py_ssize_t opts = 0;

for (Py_ssize_t i = 0; i < co_size;) {
unsigned char opcode = _Py_OPCODE(opcodes[i]);
i++; // 'i' is now aligned to (next_instr - first_instr)

// TODO: LOAD_METHOD
if (opcode == LOAD_GLOBAL || opcode == LOAD_ATTR) {
opts++;
co->co_opcache_map[i] = (unsigned char)opts;
if (opts > 254) {
break;
}
}
}

if (opts) {
co->co_opcache = (_PyOpcache *)PyMem_Calloc(opts, sizeof(_PyOpcache));
if (co->co_opcache == NULL) {
PyMem_Free(co->co_opcache_map);
return -1;
}
}
else {
PyMem_Free(co->co_opcache_map);
co->co_opcache_map = NULL;
co->co_opcache = NULL;
}

co->co_opcache_size = (unsigned char)opts;
return 0;
}


/******************
* "extra" frame eval info (see PEP 523)
******************/
Expand Down Expand Up @@ -1207,15 +1155,6 @@ code_new_impl(PyTypeObject *type, int argcount, int posonlyargcount,
static void
code_dealloc(PyCodeObject *co)
{
if (co->co_opcache != NULL) {
PyMem_Free(co->co_opcache);
}
if (co->co_opcache_map != NULL) {
PyMem_Free(co->co_opcache_map);
}
co->co_opcache_flag = 0;
co->co_opcache_size = 0;

if (co->co_extra != NULL) {
PyInterpreterState *interp = _PyInterpreterState_GET();
_PyCodeObjectExtra *co_extra = co->co_extra;
Expand Down Expand Up @@ -1442,12 +1381,9 @@ code_sizeof(PyCodeObject *co, PyObject *Py_UNUSED(args))
res += co->co_ncellvars * sizeof(Py_ssize_t);
}

if (co->co_opcache != NULL) {
assert(co->co_opcache_map != NULL);
// co_opcache_map
res += PyBytes_GET_SIZE(co->co_code) / sizeof(_Py_CODEUNIT);
// co_opcache
res += co->co_opcache_size * sizeof(_PyOpcache);
if (co->co_quickened != NULL) {
res += co->co_quickened[0].entry.zero.cache_count * sizeof(SpecializedCacheEntry);
res += PyBytes_GET_SIZE(co->co_code);
}

return PyLong_FromSsize_t(res);
Expand Down
115 changes: 1 addition & 114 deletions Python/ceval.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#include "pycore_abstract.h" // _PyIndex_Check()
#include "pycore_call.h" // _PyObject_FastCallDictTstate()
#include "pycore_ceval.h" // _PyEval_SignalAsyncExc()
#include "pycore_code.h" // _PyCode_InitOpcache()
#include "pycore_code.h"
#include "pycore_initconfig.h" // _PyStatus_OK()
#include "pycore_object.h" // _PyObject_GC_TRACK()
#include "pycore_moduleobject.h"
Expand Down Expand Up @@ -1448,108 +1448,11 @@ eval_frame_handle_pending(PyThreadState *tstate)
GETLOCAL(i) = value; \
Py_XDECREF(tmp); } while (0)

/* macros for opcode cache */
#define OPCACHE_CHECK() \
do { \
co_opcache = NULL; \
if (co->co_opcache != NULL) { \
unsigned char co_opcache_offset = \
co->co_opcache_map[next_instr - first_instr]; \
if (co_opcache_offset > 0) { \
assert(co_opcache_offset <= co->co_opcache_size); \
co_opcache = &co->co_opcache[co_opcache_offset - 1]; \
assert(co_opcache != NULL); \
} \
} \
} while (0)

#define OPCACHE_DEOPT() \
do { \
if (co_opcache != NULL) { \
co_opcache->optimized = -1; \
unsigned char co_opcache_offset = \
co->co_opcache_map[next_instr - first_instr]; \
assert(co_opcache_offset <= co->co_opcache_size); \
co->co_opcache_map[co_opcache_offset] = 0; \
co_opcache = NULL; \
} \
} while (0)

#define OPCACHE_DEOPT_LOAD_ATTR() \
do { \
if (co_opcache != NULL) { \
OPCACHE_STAT_ATTR_DEOPT(); \
OPCACHE_DEOPT(); \
} \
} while (0)

#define OPCACHE_MAYBE_DEOPT_LOAD_ATTR() \
do { \
if (co_opcache != NULL && --co_opcache->optimized <= 0) { \
OPCACHE_DEOPT_LOAD_ATTR(); \
} \
} while (0)

#if OPCACHE_STATS

#define OPCACHE_STAT_GLOBAL_HIT() \
do { \
if (co->co_opcache != NULL) opcache_global_hits++; \
} while (0)

#define OPCACHE_STAT_GLOBAL_MISS() \
do { \
if (co->co_opcache != NULL) opcache_global_misses++; \
} while (0)

#define OPCACHE_STAT_GLOBAL_OPT() \
do { \
if (co->co_opcache != NULL) opcache_global_opts++; \
} while (0)

#define OPCACHE_STAT_ATTR_HIT() \
do { \
if (co->co_opcache != NULL) opcache_attr_hits++; \
} while (0)

#define OPCACHE_STAT_ATTR_MISS() \
do { \
if (co->co_opcache != NULL) opcache_attr_misses++; \
} while (0)

#define OPCACHE_STAT_ATTR_OPT() \
do { \
if (co->co_opcache!= NULL) opcache_attr_opts++; \
} while (0)

#define OPCACHE_STAT_ATTR_DEOPT() \
do { \
if (co->co_opcache != NULL) opcache_attr_deopts++; \
} while (0)

#define OPCACHE_STAT_ATTR_TOTAL() \
do { \
if (co->co_opcache != NULL) opcache_attr_total++; \
} while (0)

#else /* OPCACHE_STATS */

#define OPCACHE_STAT_GLOBAL_HIT()
#define OPCACHE_STAT_GLOBAL_MISS()
#define OPCACHE_STAT_GLOBAL_OPT()

#define OPCACHE_STAT_ATTR_HIT()
#define OPCACHE_STAT_ATTR_MISS()
#define OPCACHE_STAT_ATTR_OPT()
#define OPCACHE_STAT_ATTR_DEOPT()
#define OPCACHE_STAT_ATTR_TOTAL()

#define JUMP_TO_INSTRUCTION(op) goto PREDICT_ID(op)

#define GET_CACHE() \
_GetSpecializedCacheEntryForInstruction(first_instr, INSTR_OFFSET(), oparg)

#endif

#define DEOPT_IF(cond, instname) if (cond) { goto instname ## _miss; }

Expand Down Expand Up @@ -1582,7 +1485,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
_Py_CODEUNIT *first_instr;
PyObject *names;
PyObject *consts;
_PyOpcache *co_opcache;

#ifdef LLTRACE
_Py_IDENTIFIER(__ltrace__);
Expand Down Expand Up @@ -1690,21 +1592,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
f->f_stackdepth = -1;
f->f_state = FRAME_EXECUTING;

if (co->co_opcache_flag < opcache_min_runs) {
co->co_opcache_flag++;
if (co->co_opcache_flag == opcache_min_runs) {
if (_PyCode_InitOpcache(co) < 0) {
goto exit_eval_frame;
}
#if OPCACHE_STATS
opcache_code_objects_extra_mem +=
PyBytes_Size(co->co_code) / sizeof(_Py_CODEUNIT) +
sizeof(_PyOpcache) * co->co_opcache_size;
opcache_code_objects++;
#endif
}
}

#ifdef LLTRACE
{
int r = _PyDict_ContainsId(GLOBALS(), &PyId___ltrace__);
Expand Down
0