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
Next Next commit
Make sure watched modification count is preserved when update dict ve…
…rsion tag.
  • Loading branch information
markshannon committed Feb 9, 2024
commit 247cd3bbb3db179b9706ac8d9dc07732d16a4a68
4 changes: 2 additions & 2 deletions Include/internal/pycore_dict.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ static inline PyDictUnicodeEntry* DK_UNICODE_ENTRIES(PyDictKeysObject *dk) {

#define DICT_VERSION_INCREMENT (1 << (DICT_MAX_WATCHERS + DICT_WATCHED_MUTATION_BITS))
#define DICT_WATCHER_MASK ((1 << DICT_MAX_WATCHERS) - 1)
#define DICT_WATCHER_AND_MODIFICATION_MASK ((1 << (DICT_MAX_WATCHERS + DICT_WATCHED_MUTATION_BITS)) - 1)

#ifdef Py_GIL_DISABLED
#define DICT_NEXT_VERSION(INTERP) \
Expand Down Expand Up @@ -238,9 +239,8 @@ _PyDict_NotifyEvent(PyInterpreterState *interp,
if (watcher_bits) {
RARE_EVENT_STAT_INC(watched_dict_modification);
_PyDict_SendEvent(watcher_bits, event, mp, key, value);
return DICT_NEXT_VERSION(interp) | watcher_bits;
}
return DICT_NEXT_VERSION(interp);
return DICT_NEXT_VERSION(interp) | (mp->ma_version_tag & DICT_WATCHER_AND_MODIFICATION_MASK);
}

extern PyObject *_PyObject_MakeDictFromInstanceAttributes(PyObject *obj, PyDictValues *values);
Expand Down
17 changes: 10 additions & 7 deletions Python/optimizer_analysis.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,16 @@ static int
globals_watcher_callback(PyDict_WatchEvent event, PyObject* dict,
PyObject* key, PyObject* new_value)
{
uint64_t watched_mutations = get_mutations(dict);
assert(((PyDictObject *)dict)->ma_version_tag & 2);
int watched_mutations = get_mutations(dict);
printf("globals_watcher_callback called. dict %p, %d\n", dict, watched_mutations);
RARE_EVENT_STAT_INC(watched_globals_modification);
if (watched_mutations < _Py_MAX_ALLOWED_GLOBALS_MODIFICATIONS) {
_Py_Executors_InvalidateDependency(_PyInterpreterState_GET(), dict);
increment_mutations(dict);
}
assert(watched_mutations < _Py_MAX_ALLOWED_GLOBALS_MODIFICATIONS);
_Py_Executors_InvalidateDependency(_PyInterpreterState_GET(), dict);
PyDict_Unwatch(GLOBALS_WATCHER_ID, dict);
assert((((PyDictObject *)dict)->ma_version_tag & DICT_WATCHER_MASK) == 0);
increment_mutations(dict);
assert(get_mutations(dict) == watched_mutations + 1);
return 0;
}

Expand Down Expand Up @@ -112,8 +115,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];
Expand Down