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-81057: Move the Allocators to _PyRuntimeState #99217

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
9a44e7a
Look up the current interpreter in PyObject_Malloc().
ericsnowcurrently Oct 5, 2022
16cd128
Move the low-level allocator implementations to a header file.
ericsnowcurrently Oct 6, 2022
737877c
Move the top-level allocators state.
ericsnowcurrently Oct 6, 2022
6dd7ba5
Move the allocators to the runtime state.
ericsnowcurrently Oct 6, 2022
56251cb
Drop debug code.
ericsnowcurrently Oct 6, 2022
007eed4
Move the top-level object allocator to the runtime state.
ericsnowcurrently Oct 6, 2022
38a80d8
Move the arenas state to the runtime state.
ericsnowcurrently Oct 7, 2022
83d397f
Pass the context to initializers explicitly.
ericsnowcurrently Oct 7, 2022
991dfc8
Move the allocator groupings to pycore_allocators.h.
ericsnowcurrently Nov 8, 2022
ac5cfb0
Move the arena allocator to pycore_pymem_init.h.
ericsnowcurrently Nov 8, 2022
9f32218
Add a NEWS entry.
ericsnowcurrently Nov 7, 2022
e5fc139
Move the object allocator definitions to pycore_obmalloc*.h.
ericsnowcurrently Nov 8, 2022
d61b410
pycore_allocators.h -> pycore_pymem_allocators.h
ericsnowcurrently Nov 8, 2022
0efcef7
Move the arena allocator impl to its own file.
ericsnowcurrently Nov 8, 2022
ec01f99
Move _Py_GetAllocatedBlocks() over.
ericsnowcurrently Nov 8, 2022
a1ff9b0
Move _PyObject_DebugMallocStat() over.
ericsnowcurrently Nov 8, 2022
3172cbe
Restore uint for obmalloc.
ericsnowcurrently Nov 8, 2022
adc60e2
Do not define the functions in header files.
ericsnowcurrently Nov 9, 2022
5262207
Drop pycore_*_allocators.h.
ericsnowcurrently Nov 9, 2022
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
Prev Previous commit
Next Next commit
Move the low-level allocator implementations to a header file.
  • Loading branch information
ericsnowcurrently committed Nov 8, 2022
commit 16cd128dd79ac95b67bef8cf684dcb6e864c9601
124 changes: 124 additions & 0 deletions Include/internal/pycore_allocators.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#ifndef Py_INTERNAL_ALLOCATORS_H
#define Py_INTERNAL_ALLOCATORS_H
#ifdef __cplusplus
extern "C" {
#endif

#ifndef Py_BUILD_CORE
# error "this header requires Py_BUILD_CORE define"
#endif

#include <stdlib.h> // malloc()


/*************************************/
/* the (raw) malloc allocator */

static void *
_PyMem_RawMalloc(void *Py_UNUSED(ctx), size_t size)
{
/* PyMem_RawMalloc(0) means malloc(1). Some systems would return NULL
for malloc(0), which would be treated as an error. Some platforms would
return a pointer with no memory behind it, which would break pymalloc.
To solve these problems, allocate an extra byte. */
if (size == 0)
size = 1;
return malloc(size);
}

static void *
_PyMem_RawCalloc(void *Py_UNUSED(ctx), size_t nelem, size_t elsize)
{
/* PyMem_RawCalloc(0, 0) means calloc(1, 1). Some systems would return NULL
for calloc(0, 0), which would be treated as an error. Some platforms
would return a pointer with no memory behind it, which would break
pymalloc. To solve these problems, allocate an extra byte. */
if (nelem == 0 || elsize == 0) {
nelem = 1;
elsize = 1;
}
return calloc(nelem, elsize);
}

static void *
_PyMem_RawRealloc(void *Py_UNUSED(ctx), void *ptr, size_t size)
{
if (size == 0)
size = 1;
return realloc(ptr, size);
}

static void
_PyMem_RawFree(void *Py_UNUSED(ctx), void *ptr)
{
free(ptr);
}


/*************************************/
/* the object allocator */

#ifdef WITH_PYMALLOC
# ifdef MS_WINDOWS
# include <windows.h>
# elif defined(HAVE_MMAP)
# include <sys/mman.h>
# ifdef MAP_ANONYMOUS
# define ARENAS_USE_MMAP
# endif
# endif
#endif

#ifdef MS_WINDOWS
static void *
_PyObject_ArenaVirtualAlloc(void *Py_UNUSED(ctx), size_t size)
{
return VirtualAlloc(NULL, size,
MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
}

static void
_PyObject_ArenaVirtualFree(void *Py_UNUSED(ctx), void *ptr,
size_t Py_UNUSED(size))
{
VirtualFree(ptr, 0, MEM_RELEASE);
}

#elif defined(ARENAS_USE_MMAP)
static void *
_PyObject_ArenaMmap(void *Py_UNUSED(ctx), size_t size)
{
void *ptr;
ptr = mmap(NULL, size, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
if (ptr == MAP_FAILED)
return NULL;
assert(ptr != NULL);
return ptr;
}

static void
_PyObject_ArenaMunmap(void *Py_UNUSED(ctx), void *ptr, size_t size)
{
munmap(ptr, size);
}

#else
static void *
_PyObject_ArenaMalloc(void *Py_UNUSED(ctx), size_t size)
{
return malloc(size);
}

static void
_PyObject_ArenaFree(void *Py_UNUSED(ctx), void *ptr, size_t Py_UNUSED(size))
{
free(ptr);
}
#endif


#ifdef __cplusplus
}
#endif
#endif /* !Py_INTERNAL_ALLOCATORS_H */
1 change: 1 addition & 0 deletions Makefile.pre.in
Original file line number Diff line number Diff line change
Expand Up @@ -1612,6 +1612,7 @@ PYTHON_HEADERS= \
$(srcdir)/Include/cpython/weakrefobject.h \
\
$(srcdir)/Include/internal/pycore_abstract.h \
$(srcdir)/Include/internal/pycore_allocators.h \
$(srcdir)/Include/internal/pycore_asdl.h \
$(srcdir)/Include/internal/pycore_ast.h \
$(srcdir)/Include/internal/pycore_ast_state.h \
Expand Down
100 changes: 1 addition & 99 deletions Objects/obmalloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "pycore_pymem.h" // _PyTraceMalloc_Config
#include "pycore_code.h" // stats
#include "pycore_pystate.h" // _PyInterpreterState_GET
#include "pycore_allocators.h"

#include <stdbool.h>
#include <stdlib.h> // malloc()
Expand Down Expand Up @@ -66,16 +67,6 @@ static void _PyMem_SetupDebugHooksDomain(PyMemAllocatorDomain domain);
#endif

#ifdef WITH_PYMALLOC

#ifdef MS_WINDOWS
# include <windows.h>
#elif defined(HAVE_MMAP)
# include <sys/mman.h>
# ifdef MAP_ANONYMOUS
# define ARENAS_USE_MMAP
# endif
#endif

/* Forward declaration */
static void* _PyObject_Malloc(void *ctx, size_t size);
static void* _PyObject_Calloc(void *ctx, size_t nelem, size_t elsize);
Expand All @@ -90,95 +81,6 @@ static void* _PyObject_Realloc(void *ctx, void *ptr, size_t size);
struct _PyTraceMalloc_Config _Py_tracemalloc_config = _PyTraceMalloc_Config_INIT;


static void *
_PyMem_RawMalloc(void *Py_UNUSED(ctx), size_t size)
{
/* PyMem_RawMalloc(0) means malloc(1). Some systems would return NULL
for malloc(0), which would be treated as an error. Some platforms would
return a pointer with no memory behind it, which would break pymalloc.
To solve these problems, allocate an extra byte. */
if (size == 0)
size = 1;
return malloc(size);
}

static void *
_PyMem_RawCalloc(void *Py_UNUSED(ctx), size_t nelem, size_t elsize)
{
/* PyMem_RawCalloc(0, 0) means calloc(1, 1). Some systems would return NULL
for calloc(0, 0), which would be treated as an error. Some platforms
would return a pointer with no memory behind it, which would break
pymalloc. To solve these problems, allocate an extra byte. */
if (nelem == 0 || elsize == 0) {
nelem = 1;
elsize = 1;
}
return calloc(nelem, elsize);
}

static void *
_PyMem_RawRealloc(void *Py_UNUSED(ctx), void *ptr, size_t size)
{
if (size == 0)
size = 1;
return realloc(ptr, size);
}

static void
_PyMem_RawFree(void *Py_UNUSED(ctx), void *ptr)
{
free(ptr);
}


#ifdef MS_WINDOWS
static void *
_PyObject_ArenaVirtualAlloc(void *Py_UNUSED(ctx), size_t size)
{
return VirtualAlloc(NULL, size,
MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
}

static void
_PyObject_ArenaVirtualFree(void *Py_UNUSED(ctx), void *ptr,
size_t Py_UNUSED(size))
{
VirtualFree(ptr, 0, MEM_RELEASE);
}

#elif defined(ARENAS_USE_MMAP)
static void *
_PyObject_ArenaMmap(void *Py_UNUSED(ctx), size_t size)
{
void *ptr;
ptr = mmap(NULL, size, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
if (ptr == MAP_FAILED)
return NULL;
assert(ptr != NULL);
return ptr;
}

static void
_PyObject_ArenaMunmap(void *Py_UNUSED(ctx), void *ptr, size_t size)
{
munmap(ptr, size);
}

#else
static void *
_PyObject_ArenaMalloc(void *Py_UNUSED(ctx), size_t size)
{
return malloc(size);
}

static void
_PyObject_ArenaFree(void *Py_UNUSED(ctx), void *ptr, size_t Py_UNUSED(size))
{
free(ptr);
}
#endif

#define MALLOC_ALLOC {NULL, _PyMem_RawMalloc, _PyMem_RawCalloc, _PyMem_RawRealloc, _PyMem_RawFree}
#ifdef WITH_PYMALLOC
# define PYMALLOC_ALLOC {NULL, _PyObject_Malloc, _PyObject_Calloc, _PyObject_Realloc, _PyObject_Free}
Expand Down
1 change: 1 addition & 0 deletions PCbuild/pythoncore.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@
<ClInclude Include="..\Include\frameobject.h" />
<ClInclude Include="..\Include\import.h" />
<ClInclude Include="..\Include\internal\pycore_abstract.h" />
<ClInclude Include="..\Include\internal\pycore_allocators.h" />
<ClInclude Include="..\Include\internal\pycore_asdl.h" />
<ClInclude Include="..\Include\internal\pycore_ast.h" />
<ClInclude Include="..\Include\internal\pycore_ast_state.h" />
Expand Down
3 changes: 3 additions & 0 deletions PCbuild/pythoncore.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,9 @@
<ClInclude Include="..\Include\internal\pycore_abstract.h">
<Filter>Include\internal</Filter>
</ClInclude>
<ClInclude Include="..\Include\internal\pycore_allocators.h">
<Filter>Include\internal</Filter>
</ClInclude>
<ClInclude Include="..\Include\internal\pycore_asdl.h">
<Filter>Include\internal</Filter>
</ClInclude>
Expand Down