GH-113710: Fix updating of dict version tag and add watched dict stats (GH-115221)

This commit is contained in:
Mark Shannon 2024-02-12 16:07:38 +00:00 committed by GitHub
parent 93ac78ac3e
commit 8144661017
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 22 additions and 23 deletions

View file

@ -28,25 +28,23 @@ increment_mutations(PyObject* dict) {
d->ma_version_tag += (1 << DICT_MAX_WATCHERS);
}
/* The first two dict watcher IDs are reserved for CPython,
* so we don't need to check that they haven't been used */
#define BUILTINS_WATCHER_ID 0
#define GLOBALS_WATCHER_ID 1
static int
globals_watcher_callback(PyDict_WatchEvent event, PyObject* dict,
PyObject* key, PyObject* new_value)
{
if (event == PyDict_EVENT_CLONED) {
return 0;
}
uint64_t watched_mutations = get_mutations(dict);
if (watched_mutations < _Py_MAX_ALLOWED_GLOBALS_MODIFICATIONS) {
_Py_Executors_InvalidateDependency(_PyInterpreterState_GET(), dict);
increment_mutations(dict);
}
else {
PyDict_Unwatch(1, dict);
}
RARE_EVENT_STAT_INC(watched_globals_modification);
assert(get_mutations(dict) < _Py_MAX_ALLOWED_GLOBALS_MODIFICATIONS);
_Py_Executors_InvalidateDependency(_PyInterpreterState_GET(), dict);
increment_mutations(dict);
PyDict_Unwatch(GLOBALS_WATCHER_ID, dict);
return 0;
}
static void
global_to_const(_PyUOpInstruction *inst, PyObject *obj)
{
@ -82,11 +80,6 @@ incorrect_keys(_PyUOpInstruction *inst, PyObject *obj)
return 0;
}
/* The first two dict watcher IDs are reserved for CPython,
* so we don't need to check that they haven't been used */
#define BUILTINS_WATCHER_ID 0
#define GLOBALS_WATCHER_ID 1
/* Returns 1 if successfully optimized
* 0 if the trace is not suitable for optimization (yet)
* -1 if there was an error. */
@ -117,8 +110,8 @@ remove_globals(_PyInterpreterFrame *frame, _PyUOpInstruction *buffer,
uint32_t builtins_watched = 0;
uint32_t globals_checked = 0;
uint32_t globals_watched = 0;
if (interp->dict_state.watchers[1] == NULL) {
interp->dict_state.watchers[1] = globals_watcher_callback;
if (interp->dict_state.watchers[GLOBALS_WATCHER_ID] == NULL) {
interp->dict_state.watchers[GLOBALS_WATCHER_ID] = globals_watcher_callback;
}
for (int pc = 0; pc < buffer_size; pc++) {
_PyUOpInstruction *inst = &buffer[pc];

View file

@ -611,7 +611,7 @@ static int
builtins_dict_watcher(PyDict_WatchEvent event, PyObject *dict, PyObject *key, PyObject *new_value)
{
PyInterpreterState *interp = _PyInterpreterState_GET();
if (event != PyDict_EVENT_CLONED && interp->rare_events.builtin_dict < _Py_MAX_ALLOWED_BUILTINS_MODIFICATIONS) {
if (interp->rare_events.builtin_dict < _Py_MAX_ALLOWED_BUILTINS_MODIFICATIONS) {
_Py_Executors_InvalidateAll(interp);
}
RARE_EVENT_INTERP_INC(interp, builtin_dict);

View file

@ -275,6 +275,8 @@ print_rare_event_stats(FILE *out, RareEventStats *stats)
fprintf(out, "Rare event (set_eval_frame_func): %" PRIu64 "\n", stats->set_eval_frame_func);
fprintf(out, "Rare event (builtin_dict): %" PRIu64 "\n", stats->builtin_dict);
fprintf(out, "Rare event (func_modification): %" PRIu64 "\n", stats->func_modification);
fprintf(out, "Rare event (watched_dict_modification): %" PRIu64 "\n", stats->watched_dict_modification);
fprintf(out, "Rare event (watched_globals_modification): %" PRIu64 "\n", stats->watched_globals_modification);
}
static void