summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorSam Gross <colesbury@gmail.com>2024-10-01 16:39:56 (GMT)
committerGitHub <noreply@github.com>2024-10-01 16:39:56 (GMT)
commit5aa91c56bf14c38b4c7f5ccaaa3cd24fe3fb0f04 (patch)
tree60b3e8d6790d7e54c3f507dc5ddb16ac548b076a /Objects
parent60ff67d010078eca15a74b1429caf779ac4f9c74 (diff)
downloadcpython-5aa91c56bf14c38b4c7f5ccaaa3cd24fe3fb0f04.zip
cpython-5aa91c56bf14c38b4c7f5ccaaa3cd24fe3fb0f04.tar.gz
cpython-5aa91c56bf14c38b4c7f5ccaaa3cd24fe3fb0f04.tar.bz2
gh-124296: Remove private dictionary version tag (PEP 699) (#124472)
Diffstat (limited to 'Objects')
-rw-r--r--Objects/dictobject.c63
1 files changed, 21 insertions, 42 deletions
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index ef9d23e..adfd91d 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -877,7 +877,7 @@ new_dict(PyInterpreterState *interp,
mp->ma_keys = keys;
mp->ma_values = values;
mp->ma_used = used;
- mp->ma_version_tag = DICT_NEXT_VERSION(interp);
+ mp->_ma_watcher_tag = 0;
ASSERT_CONSISTENT(mp);
return (PyObject *)mp;
}
@@ -1678,8 +1678,7 @@ insert_combined_dict(PyInterpreterState *interp, PyDictObject *mp,
}
}
- uint64_t new_version = _PyDict_NotifyEvent(
- interp, PyDict_EVENT_ADDED, mp, key, value);
+ _PyDict_NotifyEvent(interp, PyDict_EVENT_ADDED, mp, key, value);
mp->ma_keys->dk_version = 0;
Py_ssize_t hashpos = find_empty_slot(mp->ma_keys, hash);
@@ -1698,7 +1697,6 @@ insert_combined_dict(PyInterpreterState *interp, PyDictObject *mp,
STORE_VALUE(ep, value);
STORE_HASH(ep, hash);
}
- mp->ma_version_tag = new_version;
STORE_KEYS_USABLE(mp->ma_keys, mp->ma_keys->dk_usable - 1);
STORE_KEYS_NENTRIES(mp->ma_keys, mp->ma_keys->dk_nentries + 1);
assert(mp->ma_keys->dk_usable >= 0);
@@ -1744,16 +1742,14 @@ insert_split_value(PyInterpreterState *interp, PyDictObject *mp, PyObject *key,
MAINTAIN_TRACKING(mp, key, value);
PyObject *old_value = mp->ma_values->values[ix];
if (old_value == NULL) {
- uint64_t new_version = _PyDict_NotifyEvent(interp, PyDict_EVENT_ADDED, mp, key, value);
+ _PyDict_NotifyEvent(interp, PyDict_EVENT_ADDED, mp, key, value);
STORE_SPLIT_VALUE(mp, ix, Py_NewRef(value));
_PyDictValues_AddToInsertionOrder(mp->ma_values, ix);
STORE_USED(mp, mp->ma_used + 1);
- mp->ma_version_tag = new_version;
}
else {
- uint64_t new_version = _PyDict_NotifyEvent(interp, PyDict_EVENT_MODIFIED, mp, key, value);
+ _PyDict_NotifyEvent(interp, PyDict_EVENT_MODIFIED, mp, key, value);
STORE_SPLIT_VALUE(mp, ix, Py_NewRef(value));
- mp->ma_version_tag = new_version;
// old_value should be DECREFed after GC track checking is done, if not, it could raise a segmentation fault,
// when dict only holds the strong reference to value in ep->me_value.
Py_DECREF(old_value);
@@ -1815,8 +1811,7 @@ insertdict(PyInterpreterState *interp, PyDictObject *mp,
}
if (old_value != value) {
- uint64_t new_version = _PyDict_NotifyEvent(
- interp, PyDict_EVENT_MODIFIED, mp, key, value);
+ _PyDict_NotifyEvent(interp, PyDict_EVENT_MODIFIED, mp, key, value);
assert(old_value != NULL);
assert(!_PyDict_HasSplitTable(mp));
if (DK_IS_UNICODE(mp->ma_keys)) {
@@ -1827,7 +1822,6 @@ insertdict(PyInterpreterState *interp, PyDictObject *mp,
PyDictKeyEntry *ep = &DK_ENTRIES(mp->ma_keys)[ix];
STORE_VALUE(ep, value);
}
- mp->ma_version_tag = new_version;
}
Py_XDECREF(old_value); /* which **CAN** re-enter (see issue #22653) */
ASSERT_CONSISTENT(mp);
@@ -1857,8 +1851,7 @@ insert_to_emptydict(PyInterpreterState *interp, PyDictObject *mp,
Py_DECREF(value);
return -1;
}
- uint64_t new_version = _PyDict_NotifyEvent(
- interp, PyDict_EVENT_ADDED, mp, key, value);
+ _PyDict_NotifyEvent(interp, PyDict_EVENT_ADDED, mp, key, value);
/* We don't decref Py_EMPTY_KEYS here because it is immortal. */
assert(mp->ma_values == NULL);
@@ -1879,7 +1872,6 @@ insert_to_emptydict(PyInterpreterState *interp, PyDictObject *mp,
STORE_VALUE(ep, value);
}
STORE_USED(mp, mp->ma_used + 1);
- mp->ma_version_tag = new_version;
newkeys->dk_usable--;
newkeys->dk_nentries++;
// We store the keys last so no one can see them in a partially inconsistent
@@ -2612,7 +2604,7 @@ delete_index_from_values(PyDictValues *values, Py_ssize_t ix)
static void
delitem_common(PyDictObject *mp, Py_hash_t hash, Py_ssize_t ix,
- PyObject *old_value, uint64_t new_version)
+ PyObject *old_value)
{
PyObject *old_key;
@@ -2622,7 +2614,6 @@ delitem_common(PyDictObject *mp, Py_hash_t hash, Py_ssize_t ix,
assert(hashpos >= 0);
STORE_USED(mp, mp->ma_used - 1);
- mp->ma_version_tag = new_version;
if (_PyDict_HasSplitTable(mp)) {
assert(old_value == mp->ma_values->values[ix]);
STORE_SPLIT_VALUE(mp, ix, NULL);
@@ -2692,9 +2683,8 @@ delitem_knownhash_lock_held(PyObject *op, PyObject *key, Py_hash_t hash)
}
PyInterpreterState *interp = _PyInterpreterState_GET();
- uint64_t new_version = _PyDict_NotifyEvent(
- interp, PyDict_EVENT_DELETED, mp, key, NULL);
- delitem_common(mp, hash, ix, old_value, new_version);
+ _PyDict_NotifyEvent(interp, PyDict_EVENT_DELETED, mp, key, NULL);
+ delitem_common(mp, hash, ix, old_value);
return 0;
}
@@ -2740,9 +2730,8 @@ delitemif_lock_held(PyObject *op, PyObject *key,
if (res > 0) {
PyInterpreterState *interp = _PyInterpreterState_GET();
- uint64_t new_version = _PyDict_NotifyEvent(
- interp, PyDict_EVENT_DELETED, mp, key, NULL);
- delitem_common(mp, hash, ix, old_value, new_version);
+ _PyDict_NotifyEvent(interp, PyDict_EVENT_DELETED, mp, key, NULL);
+ delitem_common(mp, hash, ix, old_value);
return 1;
} else {
return 0;
@@ -2786,11 +2775,9 @@ clear_lock_held(PyObject *op)
}
/* Empty the dict... */
PyInterpreterState *interp = _PyInterpreterState_GET();
- uint64_t new_version = _PyDict_NotifyEvent(
- interp, PyDict_EVENT_CLEARED, mp, NULL, NULL);
+ _PyDict_NotifyEvent(interp, PyDict_EVENT_CLEARED, mp, NULL, NULL);
// We don't inc ref empty keys because they're immortal
ensure_shared_on_resize(mp);
- mp->ma_version_tag = new_version;
STORE_USED(mp, 0);
if (oldvalues == NULL) {
set_keys(mp, Py_EMPTY_KEYS);
@@ -2950,9 +2937,8 @@ _PyDict_Pop_KnownHash(PyDictObject *mp, PyObject *key, Py_hash_t hash,
assert(old_value != NULL);
PyInterpreterState *interp = _PyInterpreterState_GET();
- uint64_t new_version = _PyDict_NotifyEvent(
- interp, PyDict_EVENT_DELETED, mp, key, NULL);
- delitem_common(mp, hash, ix, Py_NewRef(old_value), new_version);
+ _PyDict_NotifyEvent(interp, PyDict_EVENT_DELETED, mp, key, NULL);
+ delitem_common(mp, hash, ix, Py_NewRef(old_value));
ASSERT_CONSISTENT(mp);
if (result) {
@@ -3717,8 +3703,7 @@ dict_dict_merge(PyInterpreterState *interp, PyDictObject *mp, PyDictObject *othe
(DK_LOG_SIZE(okeys) == PyDict_LOG_MINSIZE ||
USABLE_FRACTION(DK_SIZE(okeys)/2) < other->ma_used)
) {
- uint64_t new_version = _PyDict_NotifyEvent(
- interp, PyDict_EVENT_CLONED, mp, (PyObject *)other, NULL);
+ _PyDict_NotifyEvent(interp, PyDict_EVENT_CLONED, mp, (PyObject *)other, NULL);
PyDictKeysObject *keys = clone_combined_dict_keys(other);
if (keys == NULL)
return -1;
@@ -3727,7 +3712,6 @@ dict_dict_merge(PyInterpreterState *interp, PyDictObject *mp, PyDictObject *othe
dictkeys_decref(interp, mp->ma_keys, IS_DICT_SHARED(mp));
mp->ma_keys = keys;
STORE_USED(mp, other->ma_used);
- mp->ma_version_tag = new_version;
ASSERT_CONSISTENT(mp);
if (_PyObject_GC_IS_TRACKED(other) && !_PyObject_GC_IS_TRACKED(mp)) {
@@ -3982,7 +3966,7 @@ copy_lock_held(PyObject *o)
split_copy->ma_values = newvalues;
split_copy->ma_keys = mp->ma_keys;
split_copy->ma_used = mp->ma_used;
- split_copy->ma_version_tag = DICT_NEXT_VERSION(interp);
+ split_copy->_ma_watcher_tag = 0;
dictkeys_incref(mp->ma_keys);
if (_PyObject_GC_IS_TRACKED(mp))
_PyObject_GC_TRACK(split_copy);
@@ -4430,7 +4414,6 @@ dict_popitem_impl(PyDictObject *self)
{
Py_ssize_t i, j;
PyObject *res;
- uint64_t new_version;
PyInterpreterState *interp = _PyInterpreterState_GET();
ASSERT_DICT_LOCKED(self);
@@ -4473,8 +4456,7 @@ dict_popitem_impl(PyDictObject *self)
assert(i >= 0);
key = ep0[i].me_key;
- new_version = _PyDict_NotifyEvent(
- interp, PyDict_EVENT_DELETED, self, key, NULL);
+ _PyDict_NotifyEvent(interp, PyDict_EVENT_DELETED, self, key, NULL);
hash = unicode_get_hash(key);
value = ep0[i].me_value;
ep0[i].me_key = NULL;
@@ -4489,8 +4471,7 @@ dict_popitem_impl(PyDictObject *self)
assert(i >= 0);
key = ep0[i].me_key;
- new_version = _PyDict_NotifyEvent(
- interp, PyDict_EVENT_DELETED, self, key, NULL);
+ _PyDict_NotifyEvent(interp, PyDict_EVENT_DELETED, self, key, NULL);
hash = ep0[i].me_hash;
value = ep0[i].me_value;
ep0[i].me_key = NULL;
@@ -4508,7 +4489,6 @@ dict_popitem_impl(PyDictObject *self)
/* We can't dk_usable++ since there is DKIX_DUMMY in indices */
STORE_KEYS_NENTRIES(self->ma_keys, i);
STORE_USED(self, self->ma_used - 1);
- self->ma_version_tag = new_version;
ASSERT_CONSISTENT(self);
return res;
}
@@ -4759,8 +4739,7 @@ dict_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
PyDictObject *d = (PyDictObject *)self;
d->ma_used = 0;
- d->ma_version_tag = DICT_NEXT_VERSION(
- _PyInterpreterState_GET());
+ d->_ma_watcher_tag = 0;
dictkeys_incref(Py_EMPTY_KEYS);
d->ma_keys = Py_EMPTY_KEYS;
d->ma_values = NULL;
@@ -7384,7 +7363,7 @@ PyDict_Watch(int watcher_id, PyObject* dict)
if (validate_watcher_id(interp, watcher_id)) {
return -1;
}
- ((PyDictObject*)dict)->ma_version_tag |= (1LL << watcher_id);
+ ((PyDictObject*)dict)->_ma_watcher_tag |= (1LL << watcher_id);
return 0;
}
@@ -7399,7 +7378,7 @@ PyDict_Unwatch(int watcher_id, PyObject* dict)
if (validate_watcher_id(interp, watcher_id)) {
return -1;
}
- ((PyDictObject*)dict)->ma_version_tag &= ~(1LL << watcher_id);
+ ((PyDictObject*)dict)->_ma_watcher_tag &= ~(1LL << watcher_id);
return 0;
}