]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-116916: Remove separate next_func_version counter (#116918)
authorGuido van Rossum <guido@python.org>
Mon, 18 Mar 2024 18:11:10 +0000 (11:11 -0700)
committerGitHub <noreply@github.com>
Mon, 18 Mar 2024 18:11:10 +0000 (11:11 -0700)
Somehow we ended up with two separate counter variables tracking "the next function version".
Most likely this was a historical accident where an old branch was updated incorrectly.
This PR merges the two counters into a single one: `interp->func_state.next_version`.

Include/internal/pycore_interp.h
Objects/codeobject.c
Objects/funcobject.c
Python/pystate.c

index d79fd3b6039ef536955a697cb33a97bc37eb2457..942f47340b3966c7ba9da570b1e548740d8c7ef8 100644 (file)
@@ -245,7 +245,6 @@ struct _is {
 
     uint16_t optimizer_side_threshold;
 
-    uint32_t next_func_version;
     _rare_events rare_events;
     PyDict_WatchCallback builtins_dict_watcher;
 
index 30336fa86111a7127e72dada7b311eb6255c2868..3df733eb4ee578f79b43b3c2917fa23da257b0bd 100644 (file)
@@ -415,9 +415,9 @@ init_code(PyCodeObject *co, struct _PyCodeConstructor *con)
     co->co_ncellvars = ncellvars;
     co->co_nfreevars = nfreevars;
     PyInterpreterState *interp = _PyInterpreterState_GET();
-    co->co_version = interp->next_func_version;
-    if (interp->next_func_version != 0) {
-        interp->next_func_version++;
+    co->co_version = interp->func_state.next_version;
+    if (interp->func_state.next_version != 0) {
+        interp->func_state.next_version++;
     }
     co->_co_monitoring = NULL;
     co->_co_instrumentation_version = 0;
index 08b2823d8cf024efac96457edf63de036afc3214..a506166916de4864b539f68842494132aaadd9f8 100644 (file)
@@ -236,8 +236,9 @@ How does a function's `func_version` field get initialized?
 - A new version is allocated by `_PyFunction_GetVersionForCurrentState`
   when the specializer needs a version and the version is 0.
 
-The latter allocates versions using a counter in the interpreter state;
-when the counter wraps around to 0, no more versions are allocated.
+The latter allocates versions using a counter in the interpreter state,
+`interp->func_state.next_version`.
+When the counter wraps around to 0, no more versions are allocated.
 There is one other special case: functions with a non-standard
 `vectorcall` field are not given a version.
 
@@ -247,8 +248,7 @@ Code object versions
 --------------------
 
 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.
+They share the same counter, `interp->func_state.next_version`.
 
 Code objects get a new `co_version` allocated from this counter upon
 creation. Since code objects are nominally immutable, `co_version` can
index 9f142223aff340f01c3d7b7b00af764182b3aaa4..eedcb920cd1cf26126a3be8cf3e90602d47c2f87 100644 (file)
@@ -630,7 +630,6 @@ init_interpreter(PyInterpreterState *interp,
     interp->sys_profile_initialized = false;
     interp->sys_trace_initialized = false;
     (void)_Py_SetOptimizer(interp, NULL);
-    interp->next_func_version = 1;
     interp->executor_list_head = NULL;
     if (interp != &runtime->_main_interpreter) {
         /* Fix the self-referential, statically initialized fields. */