@@ -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 */
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{
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. */
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{
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,
45504567void
45514568_PyDictKeys_DecRef (PyDictKeysObject * keys )
45524569{
4553- DK_DECREF (keys );
4570+ dictkeys_decref (keys );
45544571}
0 commit comments