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 */

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)

341355342356

/* 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)

464478465479

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

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)

690705

size_t i = (size_t)hash & mask;

691706692707

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;

744759745760

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;

804819805820

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;

847862848863

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;

892907893908

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)

983998984999

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

}

117311881174-

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);

2954297129552972

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

}