gh-90815: Add mimalloc memory allocator (#109914)

* Add mimalloc v2.12

Modified src/alloc.c to remove include of alloc-override.c and not
compile new handler.

Did not include the following files:

 - include/mimalloc-new-delete.h
 - include/mimalloc-override.h
 - src/alloc-override-osx.c
 - src/alloc-override.c
 - src/static.c
 - src/region.c

mimalloc is thread safe and shares a single heap across all runtimes,
therefore finalization and getting global allocated blocks across all
runtimes is different.

* mimalloc: minimal changes for use in Python:

 - remove debug spam for freeing large allocations
 - use same bytes (0xDD) for freed allocations in CPython and mimalloc
   This is important for the test_capi debug memory tests

* Don't export mimalloc symbol in libpython.
* Enable mimalloc as Python allocator option.
* Add mimalloc MIT license.
* Log mimalloc in Lib/test/pythoninfo.py.
* Document new mimalloc support.
* Use macro defs for exports as done in:
  https://github.com/python/cpython/pull/31164/

Co-authored-by: Sam Gross <colesbury@gmail.com>
Co-authored-by: Christian Heimes <christian@python.org>
Co-authored-by: Victor Stinner <vstinner@python.org>
This commit is contained in:
Dino Viehland 2023-10-30 08:43:11 -07:00 • committed by GitHub
parent 4ebf2fae96
commit 05f2f0ac92
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
61 changed files with 16792 additions and 161 deletions

View file

@ -11,6 +11,11 @@ ALLOWED_PREFIXES = ('Py', '_Py')
if sys.platform == 'darwin':
ALLOWED_PREFIXES += ('__Py',)
# mimalloc doesn't use static, but it's symbols are not exported
# from the shared library. They do show up in the static library
# before its linked into an executable.
ALLOWED_STATIC_PREFIXES = ('mi_', '_mi_')
# "Legacy": some old symbols are prefixed by "PY_".
EXCEPTIONS = frozenset({
'PY_TIMEOUT_MAX',
@ -59,7 +64,7 @@ def get_exported_symbols(library, dynamic=False):
return stdout
def get_smelly_symbols(stdout):
def get_smelly_symbols(stdout, dynamic=False):
smelly_symbols = []
python_symbols = []
local_symbols = []
@ -77,7 +82,9 @@ def get_smelly_symbols(stdout):
symbol = parts[-1]
result = '%s (type: %s)' % (symbol, symtype)
if symbol.startswith(ALLOWED_PREFIXES) or symbol in EXCEPTIONS:
if (symbol.startswith(ALLOWED_PREFIXES) or
symbol in EXCEPTIONS or
(not dynamic and symbol.startswith(ALLOWED_STATIC_PREFIXES))):
python_symbols.append(result)
continue
@ -95,7 +102,7 @@ def get_smelly_symbols(stdout):
def check_library(library, dynamic=False):
nm_output = get_exported_symbols(library, dynamic)
smelly_symbols, python_symbols = get_smelly_symbols(nm_output)
smelly_symbols, python_symbols = get_smelly_symbols(nm_output, dynamic)
if not smelly_symbols:
print(f"OK: no smelly symbol found ({len(python_symbols)} Python symbols)")

View file

@ -9,6 +9,7 @@ GLOBS = [
# Technically, this is covered by "Include/*.h":
#'Include/cpython/*.h',
'Include/internal/*.h',
'Include/internal/mimalloc/**/*.h',
'Modules/**/*.h',
'Modules/**/*.c',
'Objects/**/*.h',

View file

@ -89,6 +89,11 @@ Python/abstract_interp_cases.c.h
# not actually source
Python/bytecodes.c
# mimalloc
Objects/mimalloc/*.c
Include/internal/mimalloc/*.h
Include/internal/mimalloc/mimalloc/*.h
# @end=conf@
''')
@ -109,6 +114,7 @@ glob dirname
* .
* ./Include
* ./Include/internal
* ./Include/internal/mimalloc
Modules/_decimal/**/*.c Modules/_decimal/libmpdec
Modules/_elementtree.c Modules/expat