Skip to content

Commit

Permalink
pythongh-123990: Good bye WITH_FREELISTS macro (pythongh-124358)
Browse files Browse the repository at this point in the history
  • Loading branch information
corona10 authored Sep 24, 2024
1 parent be76e3f commit ad7c778
Show file tree
Hide file tree
Showing 16 changed files with 4 additions and 100 deletions.
6 changes: 0 additions & 6 deletions Doc/using/configure.rst
Original file line number Diff line number Diff line change
Expand Up @@ -183,12 +183,6 @@ General Options

See :envvar:`PYTHONCOERCECLOCALE` and the :pep:`538`.

.. option:: --without-freelists

Disable all freelists except the empty tuple singleton.

.. versionadded:: 3.11

.. option:: --with-platlibdir=DIRNAME

Python library directory name (default is ``lib``).
Expand Down
2 changes: 1 addition & 1 deletion Doc/whatsnew/3.11.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2168,7 +2168,7 @@ Build Changes
(Contributed by Donghee Na and Brett Holman in :issue:`44340`.)

* Freelists for object structs can now be disabled. A new :program:`configure`
option :option:`--without-freelists` can be used to disable all freelists
option ``--without-freelists`` can be used to disable all freelists
except empty tuple singleton.
(Contributed by Christian Heimes in :issue:`45522`.)

Expand Down
8 changes: 0 additions & 8 deletions Include/internal/pycore_freelist.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,6 @@ _Py_freelists_GET(void)
#endif
}

#ifndef WITH_FREELISTS
#define _Py_FREELIST_FREE(NAME, op, freefunc) freefunc(op)
#define _Py_FREELIST_PUSH(NAME, op, limit) (0)
#define _Py_FREELIST_POP(TYPE, NAME) (NULL)
#define _Py_FREELIST_POP_MEM(NAME) (NULL)
#define _Py_FREELIST_SIZE(NAME) (0)
#else
// Pushes `op` to the freelist, calls `freefunc` if the freelist is full
#define _Py_FREELIST_FREE(NAME, op, freefunc) \
_PyFreeList_Free(&_Py_freelists_GET()->NAME, _PyObject_CAST(op), \
Expand Down Expand Up @@ -108,7 +101,6 @@ _PyFreeList_PopMem(struct _Py_freelist *fl)
}
return op;
}
#endif

extern void _PyObject_ClearFreeLists(struct _Py_freelists *freelists, int is_finalization);

Expand Down
9 changes: 0 additions & 9 deletions Include/internal/pycore_freelist_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif

#ifdef WITH_FREELISTS
// with freelists
# define PyTuple_MAXSAVESIZE 20 // Largest tuple to save on freelist
# define Py_tuple_MAXFREELIST 2000 // Maximum number of tuples of each size to save
# define Py_lists_MAXFREELIST 80
Expand All @@ -22,9 +20,6 @@ extern "C" {
# define Py_async_gen_asends_MAXFREELIST 80
# define Py_futureiters_MAXFREELIST 255
# define Py_object_stack_chunks_MAXFREELIST 4
#else
# define PyTuple_MAXSAVESIZE 0
#endif

// A generic freelist of either PyObjects or other data structures.
struct _Py_freelist {
Expand All @@ -38,7 +33,6 @@ struct _Py_freelist {
};

struct _Py_freelists {
#ifdef WITH_FREELISTS
struct _Py_freelist floats;
struct _Py_freelist tuples[PyTuple_MAXSAVESIZE];
struct _Py_freelist lists;
Expand All @@ -50,9 +44,6 @@ struct _Py_freelists {
struct _Py_freelist async_gen_asends;
struct _Py_freelist futureiters;
struct _Py_freelist object_stack_chunks;
#else
char _unused; // Empty structs are not allowed.
#endif
};

#ifdef __cplusplus
Expand Down
1 change: 0 additions & 1 deletion Lib/test/pythoninfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,6 @@ def collect_sysconfig(info_add):
for name in (
'WITH_DOC_STRINGS',
'WITH_DTRACE',
'WITH_FREELISTS',
'WITH_MIMALLOC',
'WITH_PYMALLOC',
'WITH_VALGRIND',
Expand Down
6 changes: 1 addition & 5 deletions Lib/test/test_sys.py
Original file line number Diff line number Diff line change
Expand Up @@ -1042,14 +1042,10 @@ def test_debugmallocstats(self):
# Output of sys._debugmallocstats() depends on configure flags.
# The sysconfig vars are not available on Windows.
if sys.platform != "win32":
with_freelists = sysconfig.get_config_var("WITH_FREELISTS")
with_pymalloc = sysconfig.get_config_var("WITH_PYMALLOC")
if with_freelists:
self.assertIn(b"free PyDictObjects", err)
self.assertIn(b"free PyDictObjects", err)
if with_pymalloc:
self.assertIn(b'Small block threshold', err)
if not with_freelists and not with_pymalloc:
self.assertFalse(err)

# The function has no parameter
self.assertRaises(TypeError, sys._debugmallocstats, True)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Remove ``WITH_FREELISTS`` macro and ``--without-freelists`` build configuration
2 changes: 0 additions & 2 deletions Objects/dictobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -406,14 +406,12 @@ unicode_get_hash(PyObject *o)
void
_PyDict_DebugMallocStats(FILE *out)
{
#ifdef WITH_FREELISTS
_PyDebugAllocatorStats(out, "free PyDictObject",
_Py_FREELIST_SIZE(dicts),
sizeof(PyDictObject));
_PyDebugAllocatorStats(out, "free PyDictKeysObject",
_Py_FREELIST_SIZE(dictkeys),
sizeof(PyDictKeysObject));
#endif
}

#define DK_MASK(dk) (DK_SIZE(dk)-1)
Expand Down
9 changes: 1 addition & 8 deletions Objects/floatobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,15 +235,10 @@ static void
float_dealloc(PyObject *op)
{
assert(PyFloat_Check(op));
#ifdef WITH_FREELISTS
if (PyFloat_CheckExact(op)) {
if (PyFloat_CheckExact(op))
_PyFloat_ExactDealloc(op);
}
else
#endif
{
Py_TYPE(op)->tp_free(op);
}
}

double
Expand Down Expand Up @@ -1975,12 +1970,10 @@ _PyFloat_FiniType(PyInterpreterState *interp)
void
_PyFloat_DebugMallocStats(FILE *out)
{
#ifdef WITH_FREELISTS
_PyDebugAllocatorStats(out,
"free PyFloatObject",
_Py_FREELIST_SIZE(floats),
sizeof(PyFloatObject));
#endif
}


Expand Down
2 changes: 0 additions & 2 deletions Objects/listobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,12 +200,10 @@ list_preallocate_exact(PyListObject *self, Py_ssize_t size)
void
_PyList_DebugMallocStats(FILE *out)
{
#ifdef WITH_FREELISTS
_PyDebugAllocatorStats(out,
"free PyListObject",
_Py_FREELIST_SIZE(lists),
sizeof(PyListObject));
#endif
}

PyObject *
Expand Down
5 changes: 0 additions & 5 deletions Objects/object.c
Original file line number Diff line number Diff line change
Expand Up @@ -816,7 +816,6 @@ PyObject_Bytes(PyObject *v)
return PyBytes_FromObject(v);
}

#ifdef WITH_FREELISTS
static void
clear_freelist(struct _Py_freelist *freelist, int is_finalization,
freefunc dofree)
Expand All @@ -841,12 +840,9 @@ free_object(void *obj)
Py_DECREF(tp);
}

#endif

void
_PyObject_ClearFreeLists(struct _Py_freelists *freelists, int is_finalization)
{
#ifdef WITH_FREELISTS
// In the free-threaded build, freelists are per-PyThreadState and cleared in PyThreadState_Clear()
// In the default build, freelists are per-interpreter and cleared in finalize_interp_types()
clear_freelist(&freelists->floats, is_finalization, free_object);
Expand All @@ -866,7 +862,6 @@ _PyObject_ClearFreeLists(struct _Py_freelists *freelists, int is_finalization)
// stacks during GC, so emptying the free-list is counterproductive.
clear_freelist(&freelists->object_stack_chunks, 1, PyMem_RawFree);
}
#endif
}

/*
Expand Down
2 changes: 0 additions & 2 deletions Objects/tupleobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -1146,7 +1146,6 @@ maybe_freelist_push(PyTupleObject *op)
void
_PyTuple_DebugMallocStats(FILE *out)
{
#ifdef WITH_FREELISTS
for (int i = 0; i < PyTuple_MAXSAVESIZE; i++) {
int len = i + 1;
char buf[128];
Expand All @@ -1155,5 +1154,4 @@ _PyTuple_DebugMallocStats(FILE *out)
_PyDebugAllocatorStats(out, buf, _Py_FREELIST_SIZE(tuples[i]),
_PyObject_VAR_SIZE(&PyTuple_Type, len));
}
#endif
}
3 changes: 0 additions & 3 deletions PC/pyconfig.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -531,9 +531,6 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */
/* Define if you want to compile in mimalloc memory allocator. */
#define WITH_MIMALLOC 1

/* Define if you want to compile in object freelists optimization */
#define WITH_FREELISTS 1

/* Define if you have clock. */
/* #define HAVE_CLOCK */

Expand Down
27 changes: 0 additions & 27 deletions configure

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 0 additions & 18 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -4977,24 +4977,6 @@ then
fi
AC_MSG_RESULT([$with_pymalloc])

# Check whether objects such as float, tuple and dict are using
# freelists to optimization memory allocation.
AC_MSG_CHECKING([for --with-freelists])
AC_ARG_WITH(
[freelists],
[AS_HELP_STRING([--with-freelists], [enable object freelists (default is yes)])])

if test -z "$with_freelists"
then
with_freelists="yes"
fi
if test "$with_freelists" != "no"
then
AC_DEFINE([WITH_FREELISTS], [1],
[Define if you want to compile in object freelists optimization])
fi
AC_MSG_RESULT([$with_freelists])

# Check for --with-c-locale-coercion
AC_MSG_CHECKING([for --with-c-locale-coercion])
AC_ARG_WITH(
Expand Down
3 changes: 0 additions & 3 deletions pyconfig.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -1901,9 +1901,6 @@
/* Define to build the readline module against libedit. */
#undef WITH_EDITLINE

/* Define if you want to compile in object freelists optimization */
#undef WITH_FREELISTS

/* Define to 1 if libintl is needed for locale functions. */
#undef WITH_LIBINTL

Expand Down

0 comments on commit ad7c778

Please sign in to comment.