Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Make next function version per-interpreter
  • Loading branch information
markshannon committed Aug 28, 2023
commit 0bed3bc99eb14223010b531d203139f04bb95a9d
2 changes: 0 additions & 2 deletions Include/internal/pycore_code.h
Original file line number Diff line number Diff line change
Expand Up @@ -462,8 +462,6 @@ adaptive_counter_backoff(uint16_t counter) {
return adaptive_counter_bits(value, backoff);
}

extern uint32_t _Py_next_func_version;


/* Comparison bit masks. */

Expand Down
1 change: 1 addition & 0 deletions Include/internal/pycore_interp.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ struct _is {
_PyOptimizerObject *optimizer;
uint16_t optimizer_resume_threshold;
uint16_t optimizer_backedge_threshold;
uint32_t next_func_version;

_Py_Monitors monitors;
bool f_opcode_trace_set;
Expand Down
9 changes: 4 additions & 5 deletions Objects/codeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -427,9 +427,10 @@ init_code(PyCodeObject *co, struct _PyCodeConstructor *con)
co->co_framesize = nlocalsplus + con->stacksize + FRAME_SPECIALS_SIZE;
co->co_ncellvars = ncellvars;
co->co_nfreevars = nfreevars;
co->co_version = _Py_next_func_version;
if (_Py_next_func_version != 0) {
_Py_next_func_version++;
PyInterpreterState *interp = _PyInterpreterState_GET();
co->co_version = interp->next_func_version;
if (interp->next_func_version != 0) {
interp->next_func_version++;
}
co->_co_monitoring = NULL;
co->_co_instrumentation_version = 0;
Expand Down Expand Up @@ -2368,6 +2369,4 @@ _PyStaticCode_Init(PyCodeObject *co)
return 0;
}

uint32_t _Py_next_func_version = 1;

#define MAX_CODE_UNITS_PER_LOC_ENTRY 8
9 changes: 3 additions & 6 deletions Objects/funcobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

#include "Python.h"
#include "pycore_ceval.h" // _PyEval_BuiltinsFromGlobals()
#include "pycore_code.h" // _Py_next_func_version
#include "pycore_object.h" // _PyObject_GC_UNTRACK()
#include "pycore_pyerrors.h" // _PyErr_Occurred()

Expand Down Expand Up @@ -252,11 +251,9 @@ When the function version is 0, the `CALL` bytecode is not specialized.
Code object versions
--------------------

So where to code objects get their `co_version`? There is a single
static global counter, `_Py_next_func_version`. This is initialized in
the generated (!) file `Python/deepfreeze/deepfreeze.c`, to 1 plus the
number of deep-frozen function objects in that file.
(In `_bootstrap_python.c` and `freeze_module.c` it is initialized to 1.)
So where to code objects get their `co_version`?
There is a per-interpreter counter, `next_func_version`.
This is initialized to 1 when the interpreter is created.

Code objects get a new `co_version` allocated from this counter upon
creation. Since code objects are nominally immutable, `co_version` can
Expand Down
1 change: 1 addition & 0 deletions Python/pystate.c
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,7 @@ init_interpreter(PyInterpreterState *interp,
interp->optimizer = &_PyOptimizer_Default;
interp->optimizer_backedge_threshold = _PyOptimizer_Default.backedge_threshold;
interp->optimizer_resume_threshold = _PyOptimizer_Default.backedge_threshold;
interp->next_func_version = 1;
if (interp != &runtime->_main_interpreter) {
/* Fix the self-referential, statically initialized fields. */
interp->dtoa = (struct _dtoa_state)_dtoa_state_INIT(interp);
Expand Down