summaryrefslogtreecommitdiffstats
path: root/contrib/jemalloc/src
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/jemalloc/src')
-rw-r--r--contrib/jemalloc/src/chunk.c39
-rw-r--r--contrib/jemalloc/src/chunk_dss.c5
-rw-r--r--contrib/jemalloc/src/chunk_mmap.c110
-rw-r--r--contrib/jemalloc/src/huge.c10
-rw-r--r--contrib/jemalloc/src/jemalloc.c7
5 files changed, 65 insertions, 106 deletions
diff --git a/contrib/jemalloc/src/chunk.c b/contrib/jemalloc/src/chunk.c
index bcaedea..5426b02 100644
--- a/contrib/jemalloc/src/chunk.c
+++ b/contrib/jemalloc/src/chunk.c
@@ -98,7 +98,10 @@ chunk_recycle(size_t size, size_t alignment, bool *zero)
if (node != NULL)
base_node_dealloc(node);
-#ifdef JEMALLOC_PURGE_MADVISE_FREE
+#ifdef JEMALLOC_PURGE_MADVISE_DONTNEED
+ /* Pages are zeroed as a side effect of pages_purge(). */
+ *zero = true;
+#else
if (*zero) {
VALGRIND_MAKE_MEM_UNDEFINED(ret, size);
memset(ret, 0, size);
@@ -125,16 +128,16 @@ chunk_alloc(size_t size, size_t alignment, bool base, bool *zero)
ret = chunk_recycle(size, alignment, zero);
if (ret != NULL)
goto label_return;
+
+ ret = chunk_alloc_mmap(size, alignment, zero);
+ if (ret != NULL)
+ goto label_return;
+
if (config_dss) {
ret = chunk_alloc_dss(size, alignment, zero);
if (ret != NULL)
goto label_return;
}
- ret = chunk_alloc_mmap(size, alignment);
- if (ret != NULL) {
- *zero = true;
- goto label_return;
- }
/* All strategies for allocation failed. */
ret = NULL;
@@ -161,7 +164,13 @@ label_return:
if (config_prof && opt_prof && opt_prof_gdump && gdump)
prof_gdump();
}
+ if (config_debug && *zero && ret != NULL) {
+ size_t i;
+ size_t *p = (size_t *)(uintptr_t)ret;
+ for (i = 0; i < size / sizeof(size_t); i++)
+ assert(p[i] == 0);
+ }
assert(CHUNK_ADDR2BASE(ret) == ret);
return (ret);
}
@@ -258,14 +267,14 @@ chunk_dealloc(void *chunk, size_t size, bool unmap)
}
if (unmap) {
- if (chunk_dealloc_mmap(chunk, size) == false)
- return;
- chunk_record(chunk, size);
+ if ((config_dss && chunk_in_dss(chunk)) ||
+ chunk_dealloc_mmap(chunk, size))
+ chunk_record(chunk, size);
}
}
bool
-chunk_boot0(void)
+chunk_boot(void)
{
/* Set variables according to the value of opt_lg_chunk. */
@@ -292,13 +301,3 @@ chunk_boot0(void)
return (false);
}
-
-bool
-chunk_boot1(void)
-{
-
- if (chunk_mmap_boot())
- return (true);
-
- return (false);
-}
diff --git a/contrib/jemalloc/src/chunk_dss.c b/contrib/jemalloc/src/chunk_dss.c
index b05509a..2d68e48 100644
--- a/contrib/jemalloc/src/chunk_dss.c
+++ b/contrib/jemalloc/src/chunk_dss.c
@@ -89,7 +89,10 @@ chunk_alloc_dss(size_t size, size_t alignment, bool *zero)
malloc_mutex_unlock(&dss_mtx);
if (cpad_size != 0)
chunk_dealloc(cpad, cpad_size, true);
- *zero = true;
+ if (*zero) {
+ VALGRIND_MAKE_MEM_UNDEFINED(ret, size);
+ memset(ret, 0, size);
+ }
return (ret);
}
} while (dss_prev != (void *)-1);
diff --git a/contrib/jemalloc/src/chunk_mmap.c b/contrib/jemalloc/src/chunk_mmap.c
index 9dea831..9ff7480 100644
--- a/contrib/jemalloc/src/chunk_mmap.c
+++ b/contrib/jemalloc/src/chunk_mmap.c
@@ -2,23 +2,12 @@
#include "jemalloc/internal/jemalloc_internal.h"
/******************************************************************************/
-/* Data. */
-
-/*
- * Used by chunk_alloc_mmap() to decide whether to attempt the fast path and
- * potentially avoid some system calls.
- */
-malloc_tsd_data(static, mmap_unaligned, bool, false)
-malloc_tsd_funcs(JEMALLOC_INLINE, mmap_unaligned, bool, false,
- malloc_tsd_no_cleanup)
-
-/******************************************************************************/
/* Function prototypes for non-inline static functions. */
static void *pages_map(void *addr, size_t size);
static void pages_unmap(void *addr, size_t size);
static void *chunk_alloc_mmap_slow(size_t size, size_t alignment,
- bool unaligned);
+ bool unaligned, bool *zero);
/******************************************************************************/
@@ -87,7 +76,7 @@ pages_purge(void *addr, size_t length)
}
static void *
-chunk_alloc_mmap_slow(size_t size, size_t alignment, bool unaligned)
+chunk_alloc_mmap_slow(size_t size, size_t alignment, bool unaligned, bool *zero)
{
void *ret, *pages;
size_t alloc_size, leadsize, trailsize;
@@ -112,23 +101,16 @@ chunk_alloc_mmap_slow(size_t size, size_t alignment, bool unaligned)
if (trailsize != 0)
pages_unmap((void *)((uintptr_t)ret + size), trailsize);
- /*
- * If mmap() returned an aligned mapping, reset mmap_unaligned so that
- * the next chunk_alloc_mmap() execution tries the fast allocation
- * method.
- */
- if (unaligned == false && mmap_unaligned_booted) {
- bool mu = false;
- mmap_unaligned_tsd_set(&mu);
- }
-
+ assert(ret != NULL);
+ *zero = true;
return (ret);
}
void *
-chunk_alloc_mmap(size_t size, size_t alignment)
+chunk_alloc_mmap(size_t size, size_t alignment, bool *zero)
{
void *ret;
+ size_t offset;
/*
* Ideally, there would be a way to specify alignment to mmap() (like
@@ -150,45 +132,37 @@ chunk_alloc_mmap(size_t size, size_t alignment)
*
* Another possible confounding factor is address space layout
* randomization (ASLR), which causes mmap(2) to disregard the
- * requested address. mmap_unaligned tracks whether the previous
- * chunk_alloc_mmap() execution received any unaligned or relocated
- * mappings, and if so, the current execution will immediately fall
- * back to the slow method. However, we keep track of whether the fast
- * method would have succeeded, and if so, we make a note to try the
- * fast method next time.
+ * requested address. As such, repeatedly trying to extend unaligned
+ * mappings could result in an infinite loop, so if extension fails,
+ * immediately fall back to the reliable method of over-allocation
+ * followed by trimming.
*/
- if (mmap_unaligned_booted && *mmap_unaligned_tsd_get() == false) {
- size_t offset;
-
- ret = pages_map(NULL, size);
- if (ret == NULL)
- return (NULL);
-
- offset = ALIGNMENT_ADDR2OFFSET(ret, alignment);
- if (offset != 0) {
- bool mu = true;
- mmap_unaligned_tsd_set(&mu);
- /* Try to extend chunk boundary. */
- if (pages_map((void *)((uintptr_t)ret + size),
- chunksize - offset) == NULL) {
- /*
- * Extension failed. Clean up, then revert to
- * the reliable-but-expensive method.
- */
- pages_unmap(ret, size);
- ret = chunk_alloc_mmap_slow(size, alignment,
- true);
- } else {
- /* Clean up unneeded leading space. */
- pages_unmap(ret, chunksize - offset);
- ret = (void *)((uintptr_t)ret + (chunksize -
- offset));
- }
+ ret = pages_map(NULL, size);
+ if (ret == NULL)
+ return (NULL);
+
+ offset = ALIGNMENT_ADDR2OFFSET(ret, alignment);
+ if (offset != 0) {
+ /* Try to extend chunk boundary. */
+ if (pages_map((void *)((uintptr_t)ret + size), chunksize -
+ offset) == NULL) {
+ /*
+ * Extension failed. Clean up, then fall back to the
+ * reliable-but-expensive method.
+ */
+ pages_unmap(ret, size);
+ return (chunk_alloc_mmap_slow(size, alignment, true,
+ zero));
+ } else {
+ /* Clean up unneeded leading space. */
+ pages_unmap(ret, chunksize - offset);
+ ret = (void *)((uintptr_t)ret + (chunksize - offset));
}
- } else
- ret = chunk_alloc_mmap_slow(size, alignment, false);
+ }
+ assert(ret != NULL);
+ *zero = true;
return (ret);
}
@@ -201,21 +175,3 @@ chunk_dealloc_mmap(void *chunk, size_t size)
return (config_munmap == false);
}
-
-bool
-chunk_mmap_boot(void)
-{
-
- /*
- * XXX For the non-TLS implementation of tsd, the first access from
- * each thread causes memory allocation. The result is a bootstrapping
- * problem for this particular use case, so for now just disable it by
- * leaving it in an unbooted state.
- */
-#ifdef JEMALLOC_TLS
- if (mmap_unaligned_tsd_boot())
- return (true);
-#endif
-
- return (false);
-}
diff --git a/contrib/jemalloc/src/huge.c b/contrib/jemalloc/src/huge.c
index daf0c62..23eb074 100644
--- a/contrib/jemalloc/src/huge.c
+++ b/contrib/jemalloc/src/huge.c
@@ -28,6 +28,7 @@ huge_palloc(size_t size, size_t alignment, bool zero)
void *ret;
size_t csize;
extent_node_t *node;
+ bool is_zeroed;
/* Allocate one or more contiguous chunks for this request. */
@@ -42,7 +43,12 @@ huge_palloc(size_t size, size_t alignment, bool zero)
if (node == NULL)
return (NULL);
- ret = chunk_alloc(csize, alignment, false, &zero);
+ /*
+ * Copy zero into is_zeroed and pass the copy to chunk_alloc(), so that
+ * it is possible to make correct junk/zero fill decisions below.
+ */
+ is_zeroed = zero;
+ ret = chunk_alloc(csize, alignment, false, &is_zeroed);
if (ret == NULL) {
base_node_dealloc(node);
return (NULL);
@@ -64,7 +70,7 @@ huge_palloc(size_t size, size_t alignment, bool zero)
if (config_fill && zero == false) {
if (opt_junk)
memset(ret, 0xa5, csize);
- else if (opt_zero)
+ else if (opt_zero && is_zeroed == false)
memset(ret, 0, csize);
}
diff --git a/contrib/jemalloc/src/jemalloc.c b/contrib/jemalloc/src/jemalloc.c
index 729f4e1..8e24a5a 100644
--- a/contrib/jemalloc/src/jemalloc.c
+++ b/contrib/jemalloc/src/jemalloc.c
@@ -638,7 +638,7 @@ malloc_init_hard(void)
return (true);
}
- if (chunk_boot0()) {
+ if (chunk_boot()) {
malloc_mutex_unlock(&init_lock);
return (true);
}
@@ -715,11 +715,6 @@ malloc_init_hard(void)
ncpus = malloc_ncpus();
malloc_mutex_lock(&init_lock);
- if (chunk_boot1()) {
- malloc_mutex_unlock(&init_lock);
- return (true);
- }
-
if (mutex_boot()) {
malloc_mutex_unlock(&init_lock);
return (true);
OpenPOWER on IntegriCloud