bpo-35230: dict: Remove some macros (GH-10513) · python/cpython@a757649
@@ -302,17 +302,31 @@ PyDict_Fini(void)
302302#define DK_ENTRIES(dk) \
303303 ((PyDictKeyEntry*)(&((int8_t*)((dk)->dk_indices))[DK_SIZE(dk) * DK_IXSIZE(dk)]))
304304305-#define DK_DEBUG_INCREF _Py_INC_REFTOTAL _Py_REF_DEBUG_COMMA
306-#define DK_DEBUG_DECREF _Py_DEC_REFTOTAL _Py_REF_DEBUG_COMMA
307-308-#define DK_INCREF(dk) (DK_DEBUG_INCREF ++(dk)->dk_refcnt)
309-#define DK_DECREF(dk) if (DK_DEBUG_DECREF (--(dk)->dk_refcnt) == 0) free_keys_object(dk)
310305#define DK_MASK(dk) (((dk)->dk_size)-1)
311306#define IS_POWER_OF_2(x) (((x) & (x-1)) == 0)
312307308+static void free_keys_object(PyDictKeysObject *keys);
309+310+static inline void
311+dictkeys_incref(PyDictKeysObject *dk)
312+{
313+_Py_INC_REFTOTAL;
314+dk->dk_refcnt++;
315+}
316+317+static inline void
318+dictkeys_decref(PyDictKeysObject *dk)
319+{
320+assert(dk->dk_refcnt > 0);
321+_Py_DEC_REFTOTAL;
322+if (--dk->dk_refcnt == 0) {
323+free_keys_object(dk);
324+ }
325+}
326+313327/* lookup indices. returns DKIX_EMPTY, DKIX_DUMMY, or ix >=0 */
314328static inline Py_ssize_t
315-dk_get_index(PyDictKeysObject *keys, Py_ssize_t i)
329+dictkeys_get_index(PyDictKeysObject *keys, Py_ssize_t i)
316330{
317331Py_ssize_t s = DK_SIZE(keys);
318332Py_ssize_t ix;
@@ -341,7 +355,7 @@ dk_get_index(PyDictKeysObject *keys, Py_ssize_t i)
341355342356/* write to indices. */
343357static inline void
344-dk_set_index(PyDictKeysObject *keys, Py_ssize_t i, Py_ssize_t ix)
358+dictkeys_set_index(PyDictKeysObject *keys, Py_ssize_t i, Py_ssize_t ix)
345359{
346360Py_ssize_t s = DK_SIZE(keys);
347361@@ -464,7 +478,7 @@ _PyDict_CheckConsistency(PyDictObject *mp)
464478465479#ifdef DEBUG_PYDICT
466480for (i=0; i < keys->dk_size; i++) {
467-Py_ssize_t ix = dk_get_index(keys, i);
481+Py_ssize_t ix = dictkeys_get_index(keys, i);
468482ASSERT(DKIX_DUMMY <= ix && ix <= usable);
469483 }
470484@@ -543,7 +557,8 @@ static PyDictKeysObject *new_keys_object(Py_ssize_t size)
543557return NULL;
544558 }
545559 }
546-DK_DEBUG_INCREF dk->dk_refcnt = 1;
560+_Py_INC_REFTOTAL;
561+dk->dk_refcnt = 1;
547562dk->dk_size = size;
548563dk->dk_usable = usable;
549564dk->dk_lookup = lookdict_unicode_nodummy;
@@ -587,7 +602,7 @@ new_dict(PyDictKeysObject *keys, PyObject **values)
587602else {
588603mp = PyObject_GC_New(PyDictObject, &PyDict_Type);
589604if (mp == NULL) {
590-DK_DECREF(keys);
605+dictkeys_decref(keys);
591606free_values(values);
592607return NULL;
593608 }
@@ -610,7 +625,7 @@ new_dict_with_shared_keys(PyDictKeysObject *keys)
610625size = USABLE_FRACTION(DK_SIZE(keys));
611626values = new_values(size);
612627if (values == NULL) {
613-DK_DECREF(keys);
628+dictkeys_decref(keys);
614629return PyErr_NoMemory();
615630 }
616631for (i = 0; i < size; i++) {
@@ -665,7 +680,7 @@ clone_combined_dict(PyDictObject *orig)
665680666681/* Since we copied the keys table we now have an extra reference
667682 in the system. Manually call _Py_INC_REFTOTAL to signal that
668- we have it now; calling DK_INCREF would be an error as
683+ we have it now; calling dictkeys_incref would be an error as
669684 keys->dk_refcnt is already set to 1 (after memcpy). */
670685_Py_INC_REFTOTAL;
671686@@ -690,7 +705,7 @@ lookdict_index(PyDictKeysObject *k, Py_hash_t hash, Py_ssize_t index)
690705size_t i = (size_t)hash & mask;
691706692707for (;;) {
693-Py_ssize_t ix = dk_get_index(k, i);
708+Py_ssize_t ix = dictkeys_get_index(k, i);
694709if (ix == index) {
695710return i;
696711 }
@@ -743,7 +758,7 @@ lookdict(PyDictObject *mp, PyObject *key,
743758i = (size_t)hash & mask;
744759745760for (;;) {
746-Py_ssize_t ix = dk_get_index(dk, i);
761+Py_ssize_t ix = dictkeys_get_index(dk, i);
747762if (ix == DKIX_EMPTY) {
748763*value_addr = NULL;
749764return ix;
@@ -803,7 +818,7 @@ lookdict_unicode(PyDictObject *mp, PyObject *key,
803818size_t i = (size_t)hash & mask;
804819805820for (;;) {
806-Py_ssize_t ix = dk_get_index(mp->ma_keys, i);
821+Py_ssize_t ix = dictkeys_get_index(mp->ma_keys, i);
807822if (ix == DKIX_EMPTY) {
808823*value_addr = NULL;
809824return DKIX_EMPTY;
@@ -846,7 +861,7 @@ lookdict_unicode_nodummy(PyDictObject *mp, PyObject *key,
846861size_t i = (size_t)hash & mask;
847862848863for (;;) {
849-Py_ssize_t ix = dk_get_index(mp->ma_keys, i);
864+Py_ssize_t ix = dictkeys_get_index(mp->ma_keys, i);
850865assert (ix != DKIX_DUMMY);
851866if (ix == DKIX_EMPTY) {
852867*value_addr = NULL;
@@ -891,7 +906,7 @@ lookdict_split(PyDictObject *mp, PyObject *key,
891906size_t i = (size_t)hash & mask;
892907893908for (;;) {
894-Py_ssize_t ix = dk_get_index(mp->ma_keys, i);
909+Py_ssize_t ix = dictkeys_get_index(mp->ma_keys, i);
895910assert (ix != DKIX_DUMMY);
896911if (ix == DKIX_EMPTY) {
897912*value_addr = NULL;
@@ -983,11 +998,11 @@ find_empty_slot(PyDictKeysObject *keys, Py_hash_t hash)
983998984999const size_t mask = DK_MASK(keys);
9851000size_t i = hash & mask;
986-Py_ssize_t ix = dk_get_index(keys, i);
1001+Py_ssize_t ix = dictkeys_get_index(keys, i);
9871002for (size_t perturb = hash; ix >= 0;) {
9881003perturb >>= PERTURB_SHIFT;
9891004i = (i*5 + perturb + 1) & mask;
990-ix = dk_get_index(keys, i);
1005+ix = dictkeys_get_index(keys, i);
9911006 }
9921007return i;
9931008}
@@ -1044,7 +1059,7 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value)
10441059 }
10451060Py_ssize_t hashpos = find_empty_slot(mp->ma_keys, hash);
10461061ep = &DK_ENTRIES(mp->ma_keys)[mp->ma_keys->dk_nentries];
1047-dk_set_index(mp->ma_keys, hashpos, mp->ma_keys->dk_nentries);
1062+dictkeys_set_index(mp->ma_keys, hashpos, mp->ma_keys->dk_nentries);
10481063ep->me_key = key;
10491064ep->me_hash = hash;
10501065if (mp->ma_values) {
@@ -1098,11 +1113,11 @@ build_indices(PyDictKeysObject *keys, PyDictKeyEntry *ep, Py_ssize_t n)
10981113for (Py_ssize_t ix = 0; ix != n; ix++, ep++) {
10991114Py_hash_t hash = ep->me_hash;
11001115size_t i = hash & mask;
1101-for (size_t perturb = hash; dk_get_index(keys, i) != DKIX_EMPTY;) {
1116+for (size_t perturb = hash; dictkeys_get_index(keys, i) != DKIX_EMPTY;) {
11021117perturb >>= PERTURB_SHIFT;
11031118i = mask & (i*5 + perturb + 1);
11041119 }
1105-dk_set_index(keys, i, ix);
1120+dictkeys_set_index(keys, i, ix);
11061121 }
11071122}
11081123@@ -1171,7 +1186,7 @@ dictresize(PyDictObject *mp, Py_ssize_t minsize)
11711186newentries[i].me_value = oldvalues[i];
11721187 }
117311881174-DK_DECREF(oldkeys);
1189+dictkeys_decref(oldkeys);
11751190mp->ma_values = NULL;
11761191if (oldvalues != empty_values) {
11771192free_values(oldvalues);
@@ -1194,10 +1209,12 @@ dictresize(PyDictObject *mp, Py_ssize_t minsize)
11941209assert(oldkeys->dk_refcnt == 1);
11951210if (oldkeys->dk_size == PyDict_MINSIZE &&
11961211numfreekeys < PyDict_MAXFREELIST) {
1197-DK_DEBUG_DECREF keys_free_list[numfreekeys++] = oldkeys;
1212+_Py_DEC_REFTOTAL;
1213+keys_free_list[numfreekeys++] = oldkeys;
11981214 }
11991215else {
1200-DK_DEBUG_DECREF PyObject_FREE(oldkeys);
1216+_Py_DEC_REFTOTAL;
1217+PyObject_FREE(oldkeys);
12011218 }
12021219 }
12031220@@ -1247,7 +1264,7 @@ make_keys_shared(PyObject *op)
12471264mp->ma_keys->dk_lookup = lookdict_split;
12481265mp->ma_values = values;
12491266 }
1250-DK_INCREF(mp->ma_keys);
1267+dictkeys_incref(mp->ma_keys);
12511268return mp->ma_keys;
12521269}
12531270@@ -1499,7 +1516,7 @@ delitem_common(PyDictObject *mp, Py_hash_t hash, Py_ssize_t ix,
14991516mp->ma_used--;
15001517mp->ma_version_tag = DICT_NEXT_VERSION();
15011518ep = &DK_ENTRIES(mp->ma_keys)[ix];
1502-dk_set_index(mp->ma_keys, hashpos, DKIX_DUMMY);
1519+dictkeys_set_index(mp->ma_keys, hashpos, DKIX_DUMMY);
15031520ENSURE_ALLOWS_DELETIONS(mp);
15041521old_key = ep->me_key;
15051522ep->me_key = NULL;
@@ -1630,7 +1647,7 @@ PyDict_Clear(PyObject *op)
16301647if (oldvalues == empty_values)
16311648return;
16321649/* Empty the dict... */
1633-DK_INCREF(Py_EMPTY_KEYS);
1650+dictkeys_incref(Py_EMPTY_KEYS);
16341651mp->ma_keys = Py_EMPTY_KEYS;
16351652mp->ma_values = empty_values;
16361653mp->ma_used = 0;
@@ -1641,11 +1658,11 @@ PyDict_Clear(PyObject *op)
16411658for (i = 0; i < n; i++)
16421659Py_CLEAR(oldvalues[i]);
16431660free_values(oldvalues);
1644-DK_DECREF(oldkeys);
1661+dictkeys_decref(oldkeys);
16451662 }
16461663else {
16471664assert(oldkeys->dk_refcnt == 1);
1648-DK_DECREF(oldkeys);
1665+dictkeys_decref(oldkeys);
16491666 }
16501667assert(_PyDict_CheckConsistency(mp));
16511668}
@@ -1769,7 +1786,7 @@ _PyDict_Pop_KnownHash(PyObject *dict, PyObject *key, Py_hash_t hash, PyObject *d
17691786assert(old_value != NULL);
17701787mp->ma_used--;
17711788mp->ma_version_tag = DICT_NEXT_VERSION();
1772-dk_set_index(mp->ma_keys, hashpos, DKIX_DUMMY);
1789+dictkeys_set_index(mp->ma_keys, hashpos, DKIX_DUMMY);
17731790ep = &DK_ENTRIES(mp->ma_keys)[ix];
17741791ENSURE_ALLOWS_DELETIONS(mp);
17751792old_key = ep->me_key;
@@ -1910,11 +1927,11 @@ dict_dealloc(PyDictObject *mp)
19101927 }
19111928free_values(values);
19121929 }
1913-DK_DECREF(keys);
1930+dictkeys_decref(keys);
19141931 }
19151932else if (keys != NULL) {
19161933assert(keys->dk_refcnt == 1);
1917-DK_DECREF(keys);
1934+dictkeys_decref(keys);
19181935 }
19191936if (numfree < PyDict_MAXFREELIST && Py_TYPE(mp) == &PyDict_Type)
19201937free_list[numfree++] = mp;
@@ -2563,7 +2580,7 @@ PyDict_Copy(PyObject *o)
25632580split_copy->ma_keys = mp->ma_keys;
25642581split_copy->ma_used = mp->ma_used;
25652582split_copy->ma_version_tag = DICT_NEXT_VERSION();
2566-DK_INCREF(mp->ma_keys);
2583+dictkeys_incref(mp->ma_keys);
25672584for (i = 0, n = size; i < n; i++) {
25682585PyObject *value = mp->ma_values[i];
25692586Py_XINCREF(value);
@@ -2828,7 +2845,7 @@ PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *defaultobj)
28282845Py_ssize_t hashpos = find_empty_slot(mp->ma_keys, hash);
28292846ep0 = DK_ENTRIES(mp->ma_keys);
28302847ep = &ep0[mp->ma_keys->dk_nentries];
2831-dk_set_index(mp->ma_keys, hashpos, mp->ma_keys->dk_nentries);
2848+dictkeys_set_index(mp->ma_keys, hashpos, mp->ma_keys->dk_nentries);
28322849Py_INCREF(key);
28332850Py_INCREF(value);
28342851MAINTAIN_TRACKING(mp, key, value);
@@ -2949,8 +2966,8 @@ dict_popitem(PyDictObject *mp, PyObject *Py_UNUSED(ignored))
29492966ep = &ep0[i];
29502967j = lookdict_index(mp->ma_keys, ep->me_hash, i);
29512968assert(j >= 0);
2952-assert(dk_get_index(mp->ma_keys, j) == i);
2953-dk_set_index(mp->ma_keys, j, DKIX_DUMMY);
2969+assert(dictkeys_get_index(mp->ma_keys, j) == i);
2970+dictkeys_set_index(mp->ma_keys, j, DKIX_DUMMY);
2954297129552972PyTuple_SET_ITEM(res, 0, ep->me_key);
29562973PyTuple_SET_ITEM(res, 1, ep->me_value);
@@ -4460,7 +4477,7 @@ PyObject_GenericGetDict(PyObject *obj, void *context)
44604477if (dict == NULL) {
44614478PyTypeObject *tp = Py_TYPE(obj);
44624479if ((tp->tp_flags & Py_TPFLAGS_HEAPTYPE) && CACHED_KEYS(tp)) {
4463-DK_INCREF(CACHED_KEYS(tp));
4480+dictkeys_incref(CACHED_KEYS(tp));
44644481*dictptr = dict = new_dict_with_shared_keys(CACHED_KEYS(tp));
44654482 }
44664483else {
@@ -4484,7 +4501,7 @@ _PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr,
44844501assert(dictptr != NULL);
44854502dict = *dictptr;
44864503if (dict == NULL) {
4487-DK_INCREF(cached);
4504+dictkeys_incref(cached);
44884505dict = new_dict_with_shared_keys(cached);
44894506if (dict == NULL)
44904507return -1;
@@ -4496,7 +4513,7 @@ _PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr,
44964513// always converts dict to combined form.
44974514if ((cached = CACHED_KEYS(tp)) != NULL) {
44984515CACHED_KEYS(tp) = NULL;
4499-DK_DECREF(cached);
4516+dictkeys_decref(cached);
45004517 }
45014518 }
45024519else {
@@ -4525,7 +4542,7 @@ _PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr,
45254542else {
45264543CACHED_KEYS(tp) = NULL;
45274544 }
4528-DK_DECREF(cached);
4545+dictkeys_decref(cached);
45294546if (CACHED_KEYS(tp) == NULL && PyErr_Occurred())
45304547return -1;
45314548 }
@@ -4550,5 +4567,5 @@ _PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr,
45504567void
45514568_PyDictKeys_DecRef(PyDictKeysObject *keys)
45524569{
4553-DK_DECREF(keys);
4570+dictkeys_decref(keys);
45544571}