summaryrefslogtreecommitdiffstats
path: root/Modules/_tracemalloc.c
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2014-05-02 20:31:14 (GMT)
committerVictor Stinner <victor.stinner@gmail.com>2014-05-02 20:31:14 (GMT)
commitdb067af12a5ebb889874e47d8177f9c4a3dc9a68 (patch)
tree87cea7c1fb4a0905ac2632c03520c43f377b3584 /Modules/_tracemalloc.c
parentd50c3f3f3af54f3be46d26d53a1c10b7c15a7b2d (diff)
downloadcpython-db067af12a5ebb889874e47d8177f9c4a3dc9a68.zip
cpython-db067af12a5ebb889874e47d8177f9c4a3dc9a68.tar.gz
cpython-db067af12a5ebb889874e47d8177f9c4a3dc9a68.tar.bz2
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).
Diffstat (limited to 'Modules/_tracemalloc.c')
-rw-r--r--Modules/_tracemalloc.c57
1 files changed, 47 insertions, 10 deletions
diff --git a/Modules/_tracemalloc.c b/Modules/_tracemalloc.c
index 780e8ed..e254a90 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,13 +582,25 @@ 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)
{
void *ptr2;
@@ -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,10 +656,10 @@ 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);
@@ -644,6 +667,18 @@ tracemalloc_raw_malloc(void *ctx, size_t size)
}
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)
{
#ifdef WITH_THREAD
@@ -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;