summaryrefslogtreecommitdiffstats
path: root/Objects/dictobject.c
diff options
context:
space:
mode:
Diffstat (limited to 'Objects/dictobject.c')
-rw-r--r--Objects/dictobject.c37
1 files changed, 33 insertions, 4 deletions
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index 9c35f3c..fa35d16 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -250,16 +250,26 @@ static uint64_t pydict_global_version = 0;
#ifndef PyDict_MAXFREELIST
#define PyDict_MAXFREELIST 80
#endif
+
+/* bpo-40521: dict free lists are shared by all interpreters. */
+#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
+# undef PyDict_MAXFREELIST
+# define PyDict_MAXFREELIST 0
+#endif
+
+#if PyDict_MAXFREELIST > 0
static PyDictObject *free_list[PyDict_MAXFREELIST];
static int numfree = 0;
static PyDictKeysObject *keys_free_list[PyDict_MAXFREELIST];
static int numfreekeys = 0;
+#endif
#include "clinic/dictobject.c.h"
void
_PyDict_ClearFreeList(void)
{
+#if PyDict_MAXFREELIST > 0
while (numfree) {
PyDictObject *op = free_list[--numfree];
assert(PyDict_CheckExact(op));
@@ -268,14 +278,17 @@ _PyDict_ClearFreeList(void)
while (numfreekeys) {
PyObject_FREE(keys_free_list[--numfreekeys]);
}
+#endif
}
/* Print summary info about the state of the optimized allocator */
void
_PyDict_DebugMallocStats(FILE *out)
{
+#if PyDict_MAXFREELIST > 0
_PyDebugAllocatorStats(out,
"free PyDictObject", numfree, sizeof(PyDictObject));
+#endif
}
@@ -553,10 +566,13 @@ static PyDictKeysObject *new_keys_object(Py_ssize_t size)
es = sizeof(Py_ssize_t);
}
+#if PyDict_MAXFREELIST > 0
if (size == PyDict_MINSIZE && numfreekeys > 0) {
dk = keys_free_list[--numfreekeys];
}
- else {
+ else
+#endif
+ {
dk = PyObject_MALLOC(sizeof(PyDictKeysObject)
+ es * size
+ sizeof(PyDictKeyEntry) * usable);
@@ -587,10 +603,12 @@ free_keys_object(PyDictKeysObject *keys)
Py_XDECREF(entries[i].me_key);
Py_XDECREF(entries[i].me_value);
}
+#if PyDict_MAXFREELIST > 0
if (keys->dk_size == PyDict_MINSIZE && numfreekeys < PyDict_MAXFREELIST) {
keys_free_list[numfreekeys++] = keys;
return;
}
+#endif
PyObject_FREE(keys);
}
@@ -603,13 +621,16 @@ new_dict(PyDictKeysObject *keys, PyObject **values)
{
PyDictObject *mp;
assert(keys != NULL);
+#if PyDict_MAXFREELIST > 0
if (numfree) {
mp = free_list[--numfree];
assert (mp != NULL);
assert (Py_IS_TYPE(mp, &PyDict_Type));
_Py_NewReference((PyObject *)mp);
}
- else {
+ else
+#endif
+ {
mp = PyObject_GC_New(PyDictObject, &PyDict_Type);
if (mp == NULL) {
dictkeys_decref(keys);
@@ -1258,12 +1279,15 @@ dictresize(PyDictObject *mp, Py_ssize_t minsize)
#ifdef Py_REF_DEBUG
_Py_RefTotal--;
#endif
+#if PyDict_MAXFREELIST > 0
if (oldkeys->dk_size == PyDict_MINSIZE &&
numfreekeys < PyDict_MAXFREELIST)
{
keys_free_list[numfreekeys++] = oldkeys;
}
- else {
+ else
+#endif
+ {
PyObject_FREE(oldkeys);
}
}
@@ -2005,10 +2029,15 @@ dict_dealloc(PyDictObject *mp)
assert(keys->dk_refcnt == 1);
dictkeys_decref(keys);
}
- if (numfree < PyDict_MAXFREELIST && Py_IS_TYPE(mp, &PyDict_Type))
+#if PyDict_MAXFREELIST > 0
+ if (numfree < PyDict_MAXFREELIST && Py_IS_TYPE(mp, &PyDict_Type)) {
free_list[numfree++] = mp;
+ }
else
+#endif
+ {
Py_TYPE(mp)->tp_free((PyObject *)mp);
+ }
Py_TRASHCAN_END
}