Skip to content

Commit 3d71665

Browse files
authored
gh-112075: Use PyMem_* for allocating dict keys objects (#114543)
Use PyMem_* for keys allocation
1 parent 2c089b0 commit 3d71665

File tree

1 file changed

+23
-43
lines changed

1 file changed

+23
-43
lines changed

Objects/dictobject.c

Lines changed: 23 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ _PyDict_ClearFreeList(PyInterpreterState *interp)
262262
PyObject_GC_Del(op);
263263
}
264264
while (state->keys_numfree) {
265-
PyObject_Free(state->keys_free_list[--state->keys_numfree]);
265+
PyMem_Free(state->keys_free_list[--state->keys_numfree]);
266266
}
267267
#endif
268268
}
@@ -332,6 +332,22 @@ dictkeys_decref(PyInterpreterState *interp, PyDictKeysObject *dk)
332332
_Py_DecRefTotal(_PyInterpreterState_GET());
333333
#endif
334334
if (--dk->dk_refcnt == 0) {
335+
if (DK_IS_UNICODE(dk)) {
336+
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dk);
337+
Py_ssize_t i, n;
338+
for (i = 0, n = dk->dk_nentries; i < n; i++) {
339+
Py_XDECREF(entries[i].me_key);
340+
Py_XDECREF(entries[i].me_value);
341+
}
342+
}
343+
else {
344+
PyDictKeyEntry *entries = DK_ENTRIES(dk);
345+
Py_ssize_t i, n;
346+
for (i = 0, n = dk->dk_nentries; i < n; i++) {
347+
Py_XDECREF(entries[i].me_key);
348+
Py_XDECREF(entries[i].me_value);
349+
}
350+
}
335351
free_keys_object(interp, dk);
336352
}
337353
}
@@ -640,9 +656,9 @@ new_keys_object(PyInterpreterState *interp, uint8_t log2_size, bool unicode)
640656
else
641657
#endif
642658
{
643-
dk = PyObject_Malloc(sizeof(PyDictKeysObject)
644-
+ ((size_t)1 << log2_bytes)
645-
+ entry_size * usable);
659+
dk = PyMem_Malloc(sizeof(PyDictKeysObject)
660+
+ ((size_t)1 << log2_bytes)
661+
+ entry_size * usable);
646662
if (dk == NULL) {
647663
PyErr_NoMemory();
648664
return NULL;
@@ -666,23 +682,6 @@ new_keys_object(PyInterpreterState *interp, uint8_t log2_size, bool unicode)
666682
static void
667683
free_keys_object(PyInterpreterState *interp, PyDictKeysObject *keys)
668684
{
669-
assert(keys != Py_EMPTY_KEYS);
670-
if (DK_IS_UNICODE(keys)) {
671-
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(keys);
672-
Py_ssize_t i, n;
673-
for (i = 0, n = keys->dk_nentries; i < n; i++) {
674-
Py_XDECREF(entries[i].me_key);
675-
Py_XDECREF(entries[i].me_value);
676-
}
677-
}
678-
else {
679-
PyDictKeyEntry *entries = DK_ENTRIES(keys);
680-
Py_ssize_t i, n;
681-
for (i = 0, n = keys->dk_nentries; i < n; i++) {
682-
Py_XDECREF(entries[i].me_key);
683-
Py_XDECREF(entries[i].me_value);
684-
}
685-
}
686685
#if PyDict_MAXFREELIST > 0
687686
struct _Py_dict_state *state = get_dict_state(interp);
688687
#ifdef Py_DEBUG
@@ -697,7 +696,7 @@ free_keys_object(PyInterpreterState *interp, PyDictKeysObject *keys)
697696
return;
698697
}
699698
#endif
700-
PyObject_Free(keys);
699+
PyMem_Free(keys);
701700
}
702701

703702
static inline PyDictValues*
@@ -798,7 +797,7 @@ clone_combined_dict_keys(PyDictObject *orig)
798797
assert(orig->ma_keys->dk_refcnt == 1);
799798

800799
size_t keys_size = _PyDict_KeysSize(orig->ma_keys);
801-
PyDictKeysObject *keys = PyObject_Malloc(keys_size);
800+
PyDictKeysObject *keys = PyMem_Malloc(keys_size);
802801
if (keys == NULL) {
803802
PyErr_NoMemory();
804803
return NULL;
@@ -1544,32 +1543,13 @@ dictresize(PyInterpreterState *interp, PyDictObject *mp,
15441543
}
15451544
}
15461545

1547-
// We can not use free_keys_object here because key's reference
1548-
// are moved already.
15491546
if (oldkeys != Py_EMPTY_KEYS) {
15501547
#ifdef Py_REF_DEBUG
15511548
_Py_DecRefTotal(_PyInterpreterState_GET());
15521549
#endif
15531550
assert(oldkeys->dk_kind != DICT_KEYS_SPLIT);
15541551
assert(oldkeys->dk_refcnt == 1);
1555-
#if PyDict_MAXFREELIST > 0
1556-
struct _Py_dict_state *state = get_dict_state(interp);
1557-
#ifdef Py_DEBUG
1558-
// dictresize() must not be called after _PyDict_Fini()
1559-
assert(state->keys_numfree != -1);
1560-
#endif
1561-
if (DK_LOG_SIZE(oldkeys) == PyDict_LOG_MINSIZE &&
1562-
DK_IS_UNICODE(oldkeys) &&
1563-
state->keys_numfree < PyDict_MAXFREELIST)
1564-
{
1565-
state->keys_free_list[state->keys_numfree++] = oldkeys;
1566-
OBJECT_STAT_INC(to_freelist);
1567-
}
1568-
else
1569-
#endif
1570-
{
1571-
PyObject_Free(oldkeys);
1572-
}
1552+
free_keys_object(interp, oldkeys);
15731553
}
15741554
}
15751555

0 commit comments

Comments
 (0)