Skip to content

Commit a757649

Browse files
authored
bpo-35230: dict: Remove some macros (GH-10513)
Remove _Py_REF_DEBUG_COMMA, DK_DEBUG_INCREF, and DK_DEBUG_DECREF. Convert DK_INCREF and DK_DECREF to static inline functions.
1 parent 8e0b05e commit a757649

File tree

2 files changed

+59
-44
lines changed

2 files changed

+59
-44
lines changed

Include/object.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -734,7 +734,6 @@ PyAPI_FUNC(void) _Py_NegativeRefcount(const char *filename, int lineno,
734734
PyAPI_FUNC(Py_ssize_t) _Py_GetRefTotal(void);
735735
#define _Py_INC_REFTOTAL _Py_RefTotal++
736736
#define _Py_DEC_REFTOTAL _Py_RefTotal--
737-
#define _Py_REF_DEBUG_COMMA ,
738737

739738
/* Py_REF_DEBUG also controls the display of refcounts and memory block
740739
* allocations at the interactive prompt and at interpreter shutdown
@@ -743,7 +742,6 @@ PyAPI_FUNC(void) _PyDebug_PrintTotalRefs(void);
743742
#else
744743
#define _Py_INC_REFTOTAL
745744
#define _Py_DEC_REFTOTAL
746-
#define _Py_REF_DEBUG_COMMA
747745
#endif /* Py_REF_DEBUG */
748746

749747
#ifdef COUNT_ALLOCS

Objects/dictobject.c

Lines changed: 59 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -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)]))
304304

305-
#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)
312307

308+
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 */
314328
static 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
{
317331
Py_ssize_t s = DK_SIZE(keys);
318332
Py_ssize_t ix;
@@ -341,7 +355,7 @@ dk_get_index(PyDictKeysObject *keys, Py_ssize_t i)
341355

342356
/* write to indices. */
343357
static 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
{
346360
Py_ssize_t s = DK_SIZE(keys);
347361

@@ -464,7 +478,7 @@ _PyDict_CheckConsistency(PyDictObject *mp)
464478

465479
#ifdef DEBUG_PYDICT
466480
for (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);
468482
ASSERT(DKIX_DUMMY <= ix && ix <= usable);
469483
}
470484

@@ -543,7 +557,8 @@ static PyDictKeysObject *new_keys_object(Py_ssize_t size)
543557
return NULL;
544558
}
545559
}
546-
DK_DEBUG_INCREF dk->dk_refcnt = 1;
560+
_Py_INC_REFTOTAL;
561+
dk->dk_refcnt = 1;
547562
dk->dk_size = size;
548563
dk->dk_usable = usable;
549564
dk->dk_lookup = lookdict_unicode_nodummy;
@@ -587,7 +602,7 @@ new_dict(PyDictKeysObject *keys, PyObject **values)
587602
else {
588603
mp = PyObject_GC_New(PyDictObject, &PyDict_Type);
589604
if (mp == NULL) {
590-
DK_DECREF(keys);
605+
dictkeys_decref(keys);
591606
free_values(values);
592607
return NULL;
593608
}
@@ -610,7 +625,7 @@ new_dict_with_shared_keys(PyDictKeysObject *keys)
610625
size = USABLE_FRACTION(DK_SIZE(keys));
611626
values = new_values(size);
612627
if (values == NULL) {
613-
DK_DECREF(keys);
628+
dictkeys_decref(keys);
614629
return PyErr_NoMemory();
615630
}
616631
for (i = 0; i < size; i++) {
@@ -665,7 +680,7 @@ clone_combined_dict(PyDictObject *orig)
665680

666681
/* 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)
690705
size_t i = (size_t)hash & mask;
691706

692707
for (;;) {
693-
Py_ssize_t ix = dk_get_index(k, i);
708+
Py_ssize_t ix = dictkeys_get_index(k, i);
694709
if (ix == index) {
695710
return i;
696711
}
@@ -743,7 +758,7 @@ lookdict(PyDictObject *mp, PyObject *key,
743758
i = (size_t)hash & mask;
744759

745760
for (;;) {
746-
Py_ssize_t ix = dk_get_index(dk, i);
761+
Py_ssize_t ix = dictkeys_get_index(dk, i);
747762
if (ix == DKIX_EMPTY) {
748763
*value_addr = NULL;
749764
return ix;
@@ -803,7 +818,7 @@ lookdict_unicode(PyDictObject *mp, PyObject *key,
803818
size_t i = (size_t)hash & mask;
804819

805820
for (;;) {
806-
Py_ssize_t ix = dk_get_index(mp->ma_keys, i);
821+
Py_ssize_t ix = dictkeys_get_index(mp->ma_keys, i);
807822
if (ix == DKIX_EMPTY) {
808823
*value_addr = NULL;
809824
return DKIX_EMPTY;
@@ -846,7 +861,7 @@ lookdict_unicode_nodummy(PyDictObject *mp, PyObject *key,
846861
size_t i = (size_t)hash & mask;
847862

848863
for (;;) {
849-
Py_ssize_t ix = dk_get_index(mp->ma_keys, i);
864+
Py_ssize_t ix = dictkeys_get_index(mp->ma_keys, i);
850865
assert (ix != DKIX_DUMMY);
851866
if (ix == DKIX_EMPTY) {
852867
*value_addr = NULL;
@@ -891,7 +906,7 @@ lookdict_split(PyDictObject *mp, PyObject *key,
891906
size_t i = (size_t)hash & mask;
892907

893908
for (;;) {
894-
Py_ssize_t ix = dk_get_index(mp->ma_keys, i);
909+
Py_ssize_t ix = dictkeys_get_index(mp->ma_keys, i);
895910
assert (ix != DKIX_DUMMY);
896911
if (ix == DKIX_EMPTY) {
897912
*value_addr = NULL;
@@ -983,11 +998,11 @@ find_empty_slot(PyDictKeysObject *keys, Py_hash_t hash)
983998

984999
const size_t mask = DK_MASK(keys);
9851000
size_t i = hash & mask;
986-
Py_ssize_t ix = dk_get_index(keys, i);
1001+
Py_ssize_t ix = dictkeys_get_index(keys, i);
9871002
for (size_t perturb = hash; ix >= 0;) {
9881003
perturb >>= PERTURB_SHIFT;
9891004
i = (i*5 + perturb + 1) & mask;
990-
ix = dk_get_index(keys, i);
1005+
ix = dictkeys_get_index(keys, i);
9911006
}
9921007
return i;
9931008
}
@@ -1044,7 +1059,7 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value)
10441059
}
10451060
Py_ssize_t hashpos = find_empty_slot(mp->ma_keys, hash);
10461061
ep = &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);
10481063
ep->me_key = key;
10491064
ep->me_hash = hash;
10501065
if (mp->ma_values) {
@@ -1098,11 +1113,11 @@ build_indices(PyDictKeysObject *keys, PyDictKeyEntry *ep, Py_ssize_t n)
10981113
for (Py_ssize_t ix = 0; ix != n; ix++, ep++) {
10991114
Py_hash_t hash = ep->me_hash;
11001115
size_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;) {
11021117
perturb >>= PERTURB_SHIFT;
11031118
i = 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)
11711186
newentries[i].me_value = oldvalues[i];
11721187
}
11731188

1174-
DK_DECREF(oldkeys);
1189+
dictkeys_decref(oldkeys);
11751190
mp->ma_values = NULL;
11761191
if (oldvalues != empty_values) {
11771192
free_values(oldvalues);
@@ -1194,10 +1209,12 @@ dictresize(PyDictObject *mp, Py_ssize_t minsize)
11941209
assert(oldkeys->dk_refcnt == 1);
11951210
if (oldkeys->dk_size == PyDict_MINSIZE &&
11961211
numfreekeys < PyDict_MAXFREELIST) {
1197-
DK_DEBUG_DECREF keys_free_list[numfreekeys++] = oldkeys;
1212+
_Py_DEC_REFTOTAL;
1213+
keys_free_list[numfreekeys++] = oldkeys;
11981214
}
11991215
else {
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)
12471264
mp->ma_keys->dk_lookup = lookdict_split;
12481265
mp->ma_values = values;
12491266
}
1250-
DK_INCREF(mp->ma_keys);
1267+
dictkeys_incref(mp->ma_keys);
12511268
return mp->ma_keys;
12521269
}
12531270

@@ -1499,7 +1516,7 @@ delitem_common(PyDictObject *mp, Py_hash_t hash, Py_ssize_t ix,
14991516
mp->ma_used--;
15001517
mp->ma_version_tag = DICT_NEXT_VERSION();
15011518
ep = &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);
15031520
ENSURE_ALLOWS_DELETIONS(mp);
15041521
old_key = ep->me_key;
15051522
ep->me_key = NULL;
@@ -1630,7 +1647,7 @@ PyDict_Clear(PyObject *op)
16301647
if (oldvalues == empty_values)
16311648
return;
16321649
/* Empty the dict... */
1633-
DK_INCREF(Py_EMPTY_KEYS);
1650+
dictkeys_incref(Py_EMPTY_KEYS);
16341651
mp->ma_keys = Py_EMPTY_KEYS;
16351652
mp->ma_values = empty_values;
16361653
mp->ma_used = 0;
@@ -1641,11 +1658,11 @@ PyDict_Clear(PyObject *op)
16411658
for (i = 0; i < n; i++)
16421659
Py_CLEAR(oldvalues[i]);
16431660
free_values(oldvalues);
1644-
DK_DECREF(oldkeys);
1661+
dictkeys_decref(oldkeys);
16451662
}
16461663
else {
16471664
assert(oldkeys->dk_refcnt == 1);
1648-
DK_DECREF(oldkeys);
1665+
dictkeys_decref(oldkeys);
16491666
}
16501667
assert(_PyDict_CheckConsistency(mp));
16511668
}
@@ -1769,7 +1786,7 @@ _PyDict_Pop_KnownHash(PyObject *dict, PyObject *key, Py_hash_t hash, PyObject *d
17691786
assert(old_value != NULL);
17701787
mp->ma_used--;
17711788
mp->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);
17731790
ep = &DK_ENTRIES(mp->ma_keys)[ix];
17741791
ENSURE_ALLOWS_DELETIONS(mp);
17751792
old_key = ep->me_key;
@@ -1910,11 +1927,11 @@ dict_dealloc(PyDictObject *mp)
19101927
}
19111928
free_values(values);
19121929
}
1913-
DK_DECREF(keys);
1930+
dictkeys_decref(keys);
19141931
}
19151932
else if (keys != NULL) {
19161933
assert(keys->dk_refcnt == 1);
1917-
DK_DECREF(keys);
1934+
dictkeys_decref(keys);
19181935
}
19191936
if (numfree < PyDict_MAXFREELIST && Py_TYPE(mp) == &PyDict_Type)
19201937
free_list[numfree++] = mp;
@@ -2563,7 +2580,7 @@ PyDict_Copy(PyObject *o)
25632580
split_copy->ma_keys = mp->ma_keys;
25642581
split_copy->ma_used = mp->ma_used;
25652582
split_copy->ma_version_tag = DICT_NEXT_VERSION();
2566-
DK_INCREF(mp->ma_keys);
2583+
dictkeys_incref(mp->ma_keys);
25672584
for (i = 0, n = size; i < n; i++) {
25682585
PyObject *value = mp->ma_values[i];
25692586
Py_XINCREF(value);
@@ -2828,7 +2845,7 @@ PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *defaultobj)
28282845
Py_ssize_t hashpos = find_empty_slot(mp->ma_keys, hash);
28292846
ep0 = DK_ENTRIES(mp->ma_keys);
28302847
ep = &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);
28322849
Py_INCREF(key);
28332850
Py_INCREF(value);
28342851
MAINTAIN_TRACKING(mp, key, value);
@@ -2949,8 +2966,8 @@ dict_popitem(PyDictObject *mp, PyObject *Py_UNUSED(ignored))
29492966
ep = &ep0[i];
29502967
j = lookdict_index(mp->ma_keys, ep->me_hash, i);
29512968
assert(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);
29542971

29552972
PyTuple_SET_ITEM(res, 0, ep->me_key);
29562973
PyTuple_SET_ITEM(res, 1, ep->me_value);
@@ -4460,7 +4477,7 @@ PyObject_GenericGetDict(PyObject *obj, void *context)
44604477
if (dict == NULL) {
44614478
PyTypeObject *tp = Py_TYPE(obj);
44624479
if ((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
}
44664483
else {
@@ -4484,7 +4501,7 @@ _PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr,
44844501
assert(dictptr != NULL);
44854502
dict = *dictptr;
44864503
if (dict == NULL) {
4487-
DK_INCREF(cached);
4504+
dictkeys_incref(cached);
44884505
dict = new_dict_with_shared_keys(cached);
44894506
if (dict == NULL)
44904507
return -1;
@@ -4496,7 +4513,7 @@ _PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr,
44964513
// always converts dict to combined form.
44974514
if ((cached = CACHED_KEYS(tp)) != NULL) {
44984515
CACHED_KEYS(tp) = NULL;
4499-
DK_DECREF(cached);
4516+
dictkeys_decref(cached);
45004517
}
45014518
}
45024519
else {
@@ -4525,7 +4542,7 @@ _PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr,
45254542
else {
45264543
CACHED_KEYS(tp) = NULL;
45274544
}
4528-
DK_DECREF(cached);
4545+
dictkeys_decref(cached);
45294546
if (CACHED_KEYS(tp) == NULL && PyErr_Occurred())
45304547
return -1;
45314548
}
@@ -4550,5 +4567,5 @@ _PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr,
45504567
void
45514568
_PyDictKeys_DecRef(PyDictKeysObject *keys)
45524569
{
4553-
DK_DECREF(keys);
4570+
dictkeys_decref(keys);
45544571
}

0 commit comments

Comments
 (0)