gh-112075: Use PyMem_* for allocating dict keys objects (#114543)
Use PyMem_* for keys allocation
This commit is contained in:
parent
2c089b09ac
commit
3d716655d2
@ -262,7 +262,7 @@ _PyDict_ClearFreeList(PyInterpreterState *interp)
|
|||||||
PyObject_GC_Del(op);
|
PyObject_GC_Del(op);
|
||||||
}
|
}
|
||||||
while (state->keys_numfree) {
|
while (state->keys_numfree) {
|
||||||
PyObject_Free(state->keys_free_list[--state->keys_numfree]);
|
PyMem_Free(state->keys_free_list[--state->keys_numfree]);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -332,6 +332,22 @@ dictkeys_decref(PyInterpreterState *interp, PyDictKeysObject *dk)
|
|||||||
_Py_DecRefTotal(_PyInterpreterState_GET());
|
_Py_DecRefTotal(_PyInterpreterState_GET());
|
||||||
#endif
|
#endif
|
||||||
if (--dk->dk_refcnt == 0) {
|
if (--dk->dk_refcnt == 0) {
|
||||||
|
if (DK_IS_UNICODE(dk)) {
|
||||||
|
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dk);
|
||||||
|
Py_ssize_t i, n;
|
||||||
|
for (i = 0, n = dk->dk_nentries; i < n; i++) {
|
||||||
|
Py_XDECREF(entries[i].me_key);
|
||||||
|
Py_XDECREF(entries[i].me_value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PyDictKeyEntry *entries = DK_ENTRIES(dk);
|
||||||
|
Py_ssize_t i, n;
|
||||||
|
for (i = 0, n = dk->dk_nentries; i < n; i++) {
|
||||||
|
Py_XDECREF(entries[i].me_key);
|
||||||
|
Py_XDECREF(entries[i].me_value);
|
||||||
|
}
|
||||||
|
}
|
||||||
free_keys_object(interp, dk);
|
free_keys_object(interp, dk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -640,9 +656,9 @@ new_keys_object(PyInterpreterState *interp, uint8_t log2_size, bool unicode)
|
|||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
dk = PyObject_Malloc(sizeof(PyDictKeysObject)
|
dk = PyMem_Malloc(sizeof(PyDictKeysObject)
|
||||||
+ ((size_t)1 << log2_bytes)
|
+ ((size_t)1 << log2_bytes)
|
||||||
+ entry_size * usable);
|
+ entry_size * usable);
|
||||||
if (dk == NULL) {
|
if (dk == NULL) {
|
||||||
PyErr_NoMemory();
|
PyErr_NoMemory();
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -666,23 +682,6 @@ new_keys_object(PyInterpreterState *interp, uint8_t log2_size, bool unicode)
|
|||||||
static void
|
static void
|
||||||
free_keys_object(PyInterpreterState *interp, PyDictKeysObject *keys)
|
free_keys_object(PyInterpreterState *interp, PyDictKeysObject *keys)
|
||||||
{
|
{
|
||||||
assert(keys != Py_EMPTY_KEYS);
|
|
||||||
if (DK_IS_UNICODE(keys)) {
|
|
||||||
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(keys);
|
|
||||||
Py_ssize_t i, n;
|
|
||||||
for (i = 0, n = keys->dk_nentries; i < n; i++) {
|
|
||||||
Py_XDECREF(entries[i].me_key);
|
|
||||||
Py_XDECREF(entries[i].me_value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
PyDictKeyEntry *entries = DK_ENTRIES(keys);
|
|
||||||
Py_ssize_t i, n;
|
|
||||||
for (i = 0, n = keys->dk_nentries; i < n; i++) {
|
|
||||||
Py_XDECREF(entries[i].me_key);
|
|
||||||
Py_XDECREF(entries[i].me_value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#if PyDict_MAXFREELIST > 0
|
#if PyDict_MAXFREELIST > 0
|
||||||
struct _Py_dict_state *state = get_dict_state(interp);
|
struct _Py_dict_state *state = get_dict_state(interp);
|
||||||
#ifdef Py_DEBUG
|
#ifdef Py_DEBUG
|
||||||
@ -697,7 +696,7 @@ free_keys_object(PyInterpreterState *interp, PyDictKeysObject *keys)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
PyObject_Free(keys);
|
PyMem_Free(keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline PyDictValues*
|
static inline PyDictValues*
|
||||||
@ -798,7 +797,7 @@ clone_combined_dict_keys(PyDictObject *orig)
|
|||||||
assert(orig->ma_keys->dk_refcnt == 1);
|
assert(orig->ma_keys->dk_refcnt == 1);
|
||||||
|
|
||||||
size_t keys_size = _PyDict_KeysSize(orig->ma_keys);
|
size_t keys_size = _PyDict_KeysSize(orig->ma_keys);
|
||||||
PyDictKeysObject *keys = PyObject_Malloc(keys_size);
|
PyDictKeysObject *keys = PyMem_Malloc(keys_size);
|
||||||
if (keys == NULL) {
|
if (keys == NULL) {
|
||||||
PyErr_NoMemory();
|
PyErr_NoMemory();
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1544,32 +1543,13 @@ dictresize(PyInterpreterState *interp, PyDictObject *mp,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We can not use free_keys_object here because key's reference
|
|
||||||
// are moved already.
|
|
||||||
if (oldkeys != Py_EMPTY_KEYS) {
|
if (oldkeys != Py_EMPTY_KEYS) {
|
||||||
#ifdef Py_REF_DEBUG
|
#ifdef Py_REF_DEBUG
|
||||||
_Py_DecRefTotal(_PyInterpreterState_GET());
|
_Py_DecRefTotal(_PyInterpreterState_GET());
|
||||||
#endif
|
#endif
|
||||||
assert(oldkeys->dk_kind != DICT_KEYS_SPLIT);
|
assert(oldkeys->dk_kind != DICT_KEYS_SPLIT);
|
||||||
assert(oldkeys->dk_refcnt == 1);
|
assert(oldkeys->dk_refcnt == 1);
|
||||||
#if PyDict_MAXFREELIST > 0
|
free_keys_object(interp, oldkeys);
|
||||||
struct _Py_dict_state *state = get_dict_state(interp);
|
|
||||||
#ifdef Py_DEBUG
|
|
||||||
// dictresize() must not be called after _PyDict_Fini()
|
|
||||||
assert(state->keys_numfree != -1);
|
|
||||||
#endif
|
|
||||||
if (DK_LOG_SIZE(oldkeys) == PyDict_LOG_MINSIZE &&
|
|
||||||
DK_IS_UNICODE(oldkeys) &&
|
|
||||||
state->keys_numfree < PyDict_MAXFREELIST)
|
|
||||||
{
|
|
||||||
state->keys_free_list[state->keys_numfree++] = oldkeys;
|
|
||||||
OBJECT_STAT_INC(to_freelist);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
PyObject_Free(oldkeys);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user