Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-123990: Good bye WITH_FREELISTS macro #124358

Merged
merged 7 commits into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can move the { up to the same line as the else now

#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
Loading