Skip to content

Commit 1710e24

Browse files
committed
pythongh-111968: Split _Py_dictkeys_freelist out of _Py_dict_freelist
1 parent 18343c0 commit 1710e24

File tree

2 files changed

+36
-14
lines changed

2 files changed

+36
-14
lines changed

Include/internal/pycore_freelist.h

+9
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,14 @@ struct _Py_dict_freelist {
7171
#ifdef WITH_FREELISTS
7272
/* Dictionary reuse scheme to save calls to malloc and free */
7373
PyDictObject *free_list[PyDict_MAXFREELIST];
74+
int numfree;
75+
int keys_numfree;
76+
#endif
77+
};
78+
79+
struct _Py_dictkeys_freelist {
80+
#ifdef WITH_FREELISTS
81+
/* Dictionary keys reuse scheme to save calls to malloc and free */
7482
PyDictKeysObject *keys_free_list[PyDict_MAXFREELIST];
7583
int numfree;
7684
int keys_numfree;
@@ -119,6 +127,7 @@ struct _Py_object_freelists {
119127
struct _Py_tuple_freelist tuples;
120128
struct _Py_list_freelist lists;
121129
struct _Py_dict_freelist dicts;
130+
struct _Py_dictkeys_freelist dictkeys;
122131
struct _Py_slice_freelist slices;
123132
struct _Py_context_freelist contexts;
124133
struct _Py_async_gen_freelist async_gens;

Objects/dictobject.c

+27-14
Original file line numberDiff line numberDiff line change
@@ -276,25 +276,35 @@ get_dict_freelist(void)
276276
struct _Py_object_freelists *freelists = _Py_object_freelists_GET();
277277
return &freelists->dicts;
278278
}
279+
280+
static struct _Py_dictkeys_freelist *
281+
get_dictkeys_freelist(void)
282+
{
283+
struct _Py_object_freelists *freelists = _Py_object_freelists_GET();
284+
return &freelists->dictkeys;
285+
}
279286
#endif
280287

281288

282289
void
283290
_PyDict_ClearFreeList(struct _Py_object_freelists *freelists, int is_finalization)
284291
{
285292
#ifdef WITH_FREELISTS
286-
struct _Py_dict_freelist *state = &freelists->dicts;
287-
while (state->numfree > 0) {
288-
PyDictObject *op = state->free_list[--state->numfree];
293+
struct _Py_dict_freelist *dict_freelist = &freelists->dicts;
294+
while (dict_freelist->numfree > 0) {
295+
PyDictObject *op = dict_freelist->free_list[--dict_freelist->numfree];
289296
assert(PyDict_CheckExact(op));
290297
PyObject_GC_Del(op);
291298
}
292-
while (state->keys_numfree > 0) {
293-
PyMem_Free(state->keys_free_list[--state->keys_numfree]);
299+
struct _Py_dictkeys_freelist *dictkeys_freelist = &freelists->dictkeys;
300+
while (dictkeys_freelist->keys_numfree > 0) {
301+
PyMem_Free(dictkeys_freelist->keys_free_list[--dictkeys_freelist->keys_numfree]);
294302
}
295303
if (is_finalization) {
296-
state->numfree = -1;
297-
state->keys_numfree = -1;
304+
dict_freelist->numfree = -1;
305+
dict_freelist->keys_numfree = -1;
306+
dictkeys_freelist->numfree = -1;
307+
dictkeys_freelist->keys_numfree = -1;
298308
}
299309
#endif
300310
}
@@ -314,6 +324,9 @@ _PyDict_DebugMallocStats(FILE *out)
314324
struct _Py_dict_freelist *dict_freelist = get_dict_freelist();
315325
_PyDebugAllocatorStats(out, "free PyDictObject",
316326
dict_freelist->numfree, sizeof(PyDictObject));
327+
struct _Py_dictkeys_freelist *dictkeys_freelist = get_dictkeys_freelist();
328+
_PyDebugAllocatorStats(out, "free PyDictKeysObject",
329+
dictkeys_freelist->numfree, sizeof(PyDictKeysObject));
317330
#endif
318331
}
319332

@@ -663,9 +676,9 @@ new_keys_object(PyInterpreterState *interp, uint8_t log2_size, bool unicode)
663676
}
664677

665678
#ifdef WITH_FREELISTS
666-
struct _Py_dict_freelist *dict_freelist = get_dict_freelist();
667-
if (log2_size == PyDict_LOG_MINSIZE && unicode && dict_freelist->keys_numfree > 0) {
668-
dk = dict_freelist->keys_free_list[--dict_freelist->keys_numfree];
679+
struct _Py_dictkeys_freelist *dictkey_freelist = get_dictkeys_freelist();
680+
if (log2_size == PyDict_LOG_MINSIZE && unicode && dictkey_freelist->keys_numfree > 0) {
681+
dk = dictkey_freelist->keys_free_list[--dictkey_freelist->keys_numfree];
669682
OBJECT_STAT_INC(from_freelist);
670683
}
671684
else
@@ -698,12 +711,12 @@ static void
698711
free_keys_object(PyDictKeysObject *keys)
699712
{
700713
#ifdef WITH_FREELISTS
701-
struct _Py_dict_freelist *dict_freelist = get_dict_freelist();
714+
struct _Py_dictkeys_freelist *dictkey_freelist = get_dictkeys_freelist();
702715
if (DK_LOG_SIZE(keys) == PyDict_LOG_MINSIZE
703-
&& dict_freelist->keys_numfree < PyDict_MAXFREELIST
704-
&& dict_freelist->keys_numfree >= 0
716+
&& dictkey_freelist->keys_numfree < PyDict_MAXFREELIST
717+
&& dictkey_freelist->keys_numfree >= 0
705718
&& DK_IS_UNICODE(keys)) {
706-
dict_freelist->keys_free_list[dict_freelist->keys_numfree++] = keys;
719+
dictkey_freelist->keys_free_list[dictkey_freelist->keys_numfree++] = keys;
707720
OBJECT_STAT_INC(to_freelist);
708721
return;
709722
}

0 commit comments

Comments
 (0)