From 595eab7fac1c64b8a25352d0dd40f1e7b62ee58a Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 2 May 2014 22:31:14 +0200 Subject: Issue #21233: Add new C functions: PyMem_RawCalloc(), PyMem_Calloc(), PyObject_Calloc(), _PyObject_GC_Calloc(). bytes(int) and bytearray(int) are now using ``calloc()`` instead of ``malloc()`` for large objects which is faster and use less memory (until the bytearray buffer is filled with data). --- Modules/_tracemalloc.c | 57 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 10 deletions(-) (limited to 'Modules/_tracemalloc.c') diff --git a/Modules/_tracemalloc.c b/Modules/_tracemalloc.c index 780e8eda82..e254a9029d 100644 --- a/Modules/_tracemalloc.c +++ b/Modules/_tracemalloc.c @@ -476,17 +476,22 @@ tracemalloc_remove_trace(void *ptr) } static void* -tracemalloc_malloc(void *ctx, size_t size) +tracemalloc_alloc(int use_calloc, void *ctx, size_t nelem, size_t elsize) { PyMemAllocator *alloc = (PyMemAllocator *)ctx; void *ptr; - ptr = alloc->malloc(alloc->ctx, size); + assert(nelem <= PY_SIZE_MAX / elsize); + + if (use_calloc) + ptr = alloc->calloc(alloc->ctx, nelem, elsize); + else + ptr = alloc->malloc(alloc->ctx, nelem * elsize); if (ptr == NULL) return NULL; TABLES_LOCK(); - if (tracemalloc_add_trace(ptr, size) < 0) { + if (tracemalloc_add_trace(ptr, nelem * elsize) < 0) { /* Failed to allocate a trace for the new memory block */ TABLES_UNLOCK(); alloc->free(alloc->ctx, ptr); @@ -560,13 +565,16 @@ tracemalloc_free(void *ctx, void *ptr) } static void* -tracemalloc_malloc_gil(void *ctx, size_t size) +tracemalloc_alloc_gil(int use_calloc, void *ctx, size_t nelem, size_t elsize) { void *ptr; if (get_reentrant()) { PyMemAllocator *alloc = (PyMemAllocator *)ctx; - return alloc->malloc(alloc->ctx, size); + if (use_calloc) + return alloc->calloc(alloc->ctx, nelem, elsize); + else + return alloc->malloc(alloc->ctx, nelem * elsize); } /* Ignore reentrant call. PyObjet_Malloc() calls PyMem_Malloc() for @@ -574,12 +582,24 @@ tracemalloc_malloc_gil(void *ctx, size_t size) allocation twice. */ set_reentrant(1); - ptr = tracemalloc_malloc(ctx, size); + ptr = tracemalloc_alloc(use_calloc, ctx, nelem, elsize); set_reentrant(0); return ptr; } +static void* +tracemalloc_malloc_gil(void *ctx, size_t size) +{ + return tracemalloc_alloc_gil(0, ctx, 1, size); +} + +static void* +tracemalloc_calloc_gil(void *ctx, size_t nelem, size_t elsize) +{ + return tracemalloc_alloc_gil(1, ctx, nelem, elsize); +} + static void* tracemalloc_realloc_gil(void *ctx, void *ptr, size_t new_size) { @@ -614,7 +634,7 @@ tracemalloc_realloc_gil(void *ctx, void *ptr, size_t new_size) #ifdef TRACE_RAW_MALLOC static void* -tracemalloc_raw_malloc(void *ctx, size_t size) +tracemalloc_raw_alloc(int use_calloc, void *ctx, size_t nelem, size_t elsize) { #ifdef WITH_THREAD PyGILState_STATE gil_state; @@ -623,7 +643,10 @@ tracemalloc_raw_malloc(void *ctx, size_t size) if (get_reentrant()) { PyMemAllocator *alloc = (PyMemAllocator *)ctx; - return alloc->malloc(alloc->ctx, size); + if (use_calloc) + return alloc->calloc(alloc->ctx, nelem, elsize); + else + return alloc->malloc(alloc->ctx, nelem * elsize); } /* Ignore reentrant call. PyGILState_Ensure() may call PyMem_RawMalloc() @@ -633,16 +656,28 @@ tracemalloc_raw_malloc(void *ctx, size_t size) #ifdef WITH_THREAD gil_state = PyGILState_Ensure(); - ptr = tracemalloc_malloc(ctx, size); + ptr = tracemalloc_alloc(use_calloc, ctx, nelem, elsize); PyGILState_Release(gil_state); #else - ptr = tracemalloc_malloc(ctx, size); + ptr = tracemalloc_alloc(use_calloc, ctx, nelem, elsize); #endif set_reentrant(0); return ptr; } +static void* +tracemalloc_raw_malloc(void *ctx, size_t size) +{ + return tracemalloc_raw_alloc(0, ctx, 1, size); +} + +static void* +tracemalloc_raw_calloc(void *ctx, size_t nelem, size_t elsize) +{ + return tracemalloc_raw_alloc(1, ctx, nelem, elsize); +} + static void* tracemalloc_raw_realloc(void *ctx, void *ptr, size_t new_size) { @@ -856,6 +891,7 @@ tracemalloc_start(int max_nframe) #ifdef TRACE_RAW_MALLOC alloc.malloc = tracemalloc_raw_malloc; + alloc.calloc = tracemalloc_raw_calloc; alloc.realloc = tracemalloc_raw_realloc; alloc.free = tracemalloc_free; @@ -865,6 +901,7 @@ tracemalloc_start(int max_nframe) #endif alloc.malloc = tracemalloc_malloc_gil; + alloc.calloc = tracemalloc_calloc_gil; alloc.realloc = tracemalloc_realloc_gil; alloc.free = tracemalloc_free; -- cgit v1.2.1 From e409cb0905a799d6de9b91b82b0bb5648b12aaec Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 14 May 2014 17:24:35 +0200 Subject: Issue #21490: Add new C macros: Py_ABS() and Py_STRINGIFY() Keep _Py_STRINGIZE() in PC/pyconfig.h to not introduce a dependency between pyconfig.h and pymacros.h. --- Modules/_tracemalloc.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'Modules/_tracemalloc.c') diff --git a/Modules/_tracemalloc.c b/Modules/_tracemalloc.c index e254a9029d..429b209c02 100644 --- a/Modules/_tracemalloc.c +++ b/Modules/_tracemalloc.c @@ -16,9 +16,6 @@ static void raw_free(void *ptr); # define TRACE_DEBUG #endif -#define _STR(VAL) #VAL -#define STR(VAL) _STR(VAL) - /* Protected by the GIL */ static struct { PyMemAllocator mem; -- cgit v1.2.1 From 1be655495f46dd956c0df2bb04f237e1d127e762 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 2 Jun 2014 21:57:10 +0200 Subject: Issue #21233: Rename the C structure "PyMemAllocator" to "PyMemAllocatorEx" to make sure that the code using it will be adapted for the new "calloc" field (instead of crashing). --- Modules/_tracemalloc.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'Modules/_tracemalloc.c') diff --git a/Modules/_tracemalloc.c b/Modules/_tracemalloc.c index 1e454144de..257ae1b57a 100644 --- a/Modules/_tracemalloc.c +++ b/Modules/_tracemalloc.c @@ -18,9 +18,9 @@ static void raw_free(void *ptr); /* Protected by the GIL */ static struct { - PyMemAllocator mem; - PyMemAllocator raw; - PyMemAllocator obj; + PyMemAllocatorEx mem; + PyMemAllocatorEx raw; + PyMemAllocatorEx obj; } allocators; static struct { @@ -475,7 +475,7 @@ tracemalloc_remove_trace(void *ptr) static void* tracemalloc_alloc(int use_calloc, void *ctx, size_t nelem, size_t elsize) { - PyMemAllocator *alloc = (PyMemAllocator *)ctx; + PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; void *ptr; assert(elsize == 0 || nelem <= PY_SIZE_MAX / elsize); @@ -501,7 +501,7 @@ tracemalloc_alloc(int use_calloc, void *ctx, size_t nelem, size_t elsize) static void* tracemalloc_realloc(void *ctx, void *ptr, size_t new_size) { - PyMemAllocator *alloc = (PyMemAllocator *)ctx; + PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; void *ptr2; ptr2 = alloc->realloc(alloc->ctx, ptr, new_size); @@ -546,7 +546,7 @@ tracemalloc_realloc(void *ctx, void *ptr, size_t new_size) static void tracemalloc_free(void *ctx, void *ptr) { - PyMemAllocator *alloc = (PyMemAllocator *)ctx; + PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; if (ptr == NULL) return; @@ -567,7 +567,7 @@ tracemalloc_alloc_gil(int use_calloc, void *ctx, size_t nelem, size_t elsize) void *ptr; if (get_reentrant()) { - PyMemAllocator *alloc = (PyMemAllocator *)ctx; + PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; if (use_calloc) return alloc->calloc(alloc->ctx, nelem, elsize); else @@ -607,7 +607,7 @@ tracemalloc_realloc_gil(void *ctx, void *ptr, size_t new_size) Example: PyMem_RawRealloc() is called internally by pymalloc (_PyObject_Malloc() and _PyObject_Realloc()) to allocate a new arena (new_arena()). */ - PyMemAllocator *alloc = (PyMemAllocator *)ctx; + PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; ptr2 = alloc->realloc(alloc->ctx, ptr, new_size); if (ptr2 != NULL && ptr != NULL) { @@ -639,7 +639,7 @@ tracemalloc_raw_alloc(int use_calloc, void *ctx, size_t nelem, size_t elsize) void *ptr; if (get_reentrant()) { - PyMemAllocator *alloc = (PyMemAllocator *)ctx; + PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; if (use_calloc) return alloc->calloc(alloc->ctx, nelem, elsize); else @@ -685,7 +685,7 @@ tracemalloc_raw_realloc(void *ctx, void *ptr, size_t new_size) if (get_reentrant()) { /* Reentrant call to PyMem_RawRealloc(). */ - PyMemAllocator *alloc = (PyMemAllocator *)ctx; + PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; ptr2 = alloc->realloc(alloc->ctx, ptr, new_size); @@ -863,7 +863,7 @@ tracemalloc_deinit(void) static int tracemalloc_start(int max_nframe) { - PyMemAllocator alloc; + PyMemAllocatorEx alloc; size_t size; if (tracemalloc_init() < 0) -- cgit v1.2.1