gh-81057: Move the global Dict-Related Versions to _PyRuntimeState (gh-99497)

We also move the global func version.

https://github.com/python/cpython/issues/81057
This commit is contained in:
Eric Snow 2022-11-16 10:37:29 -07:00 committed by GitHub
parent 8211cf5d28
commit 9db1e17c80
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 89 additions and 48 deletions

View file

@ -1,6 +1,7 @@
#include "Python.h"
#include "pycore_call.h" // _PyObject_CallNoArgsTstate()
#include "pycore_ceval.h" // _Py_EnterRecursiveCallTstate()
#include "pycore_dict.h" // _PyDict_FromItems()
#include "pycore_object.h" // _PyCFunctionWithKeywords_TrampolineCall()
#include "pycore_pyerrors.h" // _PyErr_Occurred()
#include "pycore_pystate.h" // _PyThreadState_GET()

View file

@ -236,11 +236,6 @@ static int dictresize(PyDictObject *mp, uint8_t log_newsize, int unicode);
static PyObject* dict_iter(PyDictObject *dict);
/*Global counter used to set ma_version_tag field of dictionary.
* It is incremented each time that a dictionary is created and each
* time that a dictionary is modified. */
uint64_t _pydict_global_version = 0;
#include "clinic/dictobject.c.h"
@ -5658,17 +5653,15 @@ _PyDictKeys_DecRef(PyDictKeysObject *keys)
dictkeys_decref(keys);
}
static uint32_t next_dict_keys_version = 2;
uint32_t _PyDictKeys_GetVersionForCurrentState(PyDictKeysObject *dictkeys)
{
if (dictkeys->dk_version != 0) {
return dictkeys->dk_version;
}
if (next_dict_keys_version == 0) {
if (_PyRuntime.dict_state.next_keys_version == 0) {
return 0;
}
uint32_t v = next_dict_keys_version++;
uint32_t v = _PyRuntime.dict_state.next_keys_version++;
dictkeys->dk_version = v;
return v;
}
@ -5680,7 +5673,7 @@ validate_watcher_id(PyInterpreterState *interp, int watcher_id)
PyErr_Format(PyExc_ValueError, "Invalid dict watcher ID %d", watcher_id);
return -1;
}
if (!interp->dict_watchers[watcher_id]) {
if (!interp->dict_state.watchers[watcher_id]) {
PyErr_Format(PyExc_ValueError, "No dict watcher set for ID %d", watcher_id);
return -1;
}
@ -5723,8 +5716,8 @@ PyDict_AddWatcher(PyDict_WatchCallback callback)
PyInterpreterState *interp = _PyInterpreterState_GET();
for (int i = 0; i < DICT_MAX_WATCHERS; i++) {
if (!interp->dict_watchers[i]) {
interp->dict_watchers[i] = callback;
if (!interp->dict_state.watchers[i]) {
interp->dict_state.watchers[i] = callback;
return i;
}
}
@ -5740,7 +5733,7 @@ PyDict_ClearWatcher(int watcher_id)
if (validate_watcher_id(interp, watcher_id)) {
return -1;
}
interp->dict_watchers[watcher_id] = NULL;
interp->dict_state.watchers[watcher_id] = NULL;
return 0;
}
@ -5754,7 +5747,7 @@ _PyDict_SendEvent(int watcher_bits,
PyInterpreterState *interp = _PyInterpreterState_GET();
for (int i = 0; i < DICT_MAX_WATCHERS; i++) {
if (watcher_bits & 1) {
PyDict_WatchCallback cb = interp->dict_watchers[i];
PyDict_WatchCallback cb = interp->dict_state.watchers[i];
if (cb && (cb(event, (PyObject*)mp, key, value) < 0)) {
// some dict modification paths (e.g. PyDict_Clear) can't raise, so we
// can't propagate exceptions from dict watchers.

View file

@ -7,8 +7,6 @@
#include "pycore_pyerrors.h" // _PyErr_Occurred()
#include "structmember.h" // PyMemberDef
static uint32_t next_func_version = 1;
PyFunctionObject *
_PyFunction_FromConstructor(PyFrameConstructor *constr)
{
@ -128,10 +126,10 @@ uint32_t _PyFunction_GetVersionForCurrentState(PyFunctionObject *func)
if (func->vectorcall != _PyFunction_Vectorcall) {
return 0;
}
if (next_func_version == 0) {
if (_PyRuntime.func_state.next_version == 0) {
return 0;
}
uint32_t v = next_func_version++;
uint32_t v = _PyRuntime.func_state.next_version++;
func->func_version = v;
return v;
}

View file

@ -4,6 +4,7 @@
#include "pycore_call.h"
#include "pycore_code.h" // CO_FAST_FREE
#include "pycore_compile.h" // _Py_Mangle()
#include "pycore_dict.h" // _PyDict_KeysSize()
#include "pycore_initconfig.h" // _PyStatus_OK()
#include "pycore_moduleobject.h" // _PyModule_GetDef()
#include "pycore_object.h" // _PyType_HasFeature()