summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Evans <je@fb.com>2016-02-25 01:18:44 (GMT)
committerJason Evans <je@fb.com>2016-02-25 01:23:18 (GMT)
commitc7a9a6c86b483d4aebb51bd62d902f4022a7367b (patch)
tree5a9022af8ddf5cbcbcf2d1571155570fe004f491
parent5ec703dd33b60924ec39534d3fbc234dfa01b15a (diff)
downloadjemalloc-c7a9a6c86b483d4aebb51bd62d902f4022a7367b.zip
jemalloc-c7a9a6c86b483d4aebb51bd62d902f4022a7367b.tar.gz
jemalloc-c7a9a6c86b483d4aebb51bd62d902f4022a7367b.tar.bz2
Attempt mmap-based in-place huge reallocation.
Attempt mmap-based in-place huge reallocation by plumbing new_addr into chunk_alloc_mmap(). This can dramatically speed up incremental huge reallocation. This resolves #335.
-rw-r--r--include/jemalloc/internal/chunk_mmap.h4
-rw-r--r--src/chunk.c11
-rw-r--r--src/chunk_mmap.c10
3 files changed, 12 insertions, 13 deletions
diff --git a/include/jemalloc/internal/chunk_mmap.h b/include/jemalloc/internal/chunk_mmap.h
index 7d8014c..6f2d0ac 100644
--- a/include/jemalloc/internal/chunk_mmap.h
+++ b/include/jemalloc/internal/chunk_mmap.h
@@ -9,8 +9,8 @@
/******************************************************************************/
#ifdef JEMALLOC_H_EXTERNS
-void *chunk_alloc_mmap(size_t size, size_t alignment, bool *zero,
- bool *commit);
+void *chunk_alloc_mmap(void *new_addr, size_t size, size_t alignment,
+ bool *zero, bool *commit);
bool chunk_dalloc_mmap(void *chunk, size_t size);
#endif /* JEMALLOC_H_EXTERNS */
diff --git a/src/chunk.c b/src/chunk.c
index 9de36eb..6a107e1 100644
--- a/src/chunk.c
+++ b/src/chunk.c
@@ -350,12 +350,9 @@ chunk_alloc_core(arena_t *arena, void *new_addr, size_t size, size_t alignment,
chunk_alloc_dss(arena, new_addr, size, alignment, zero, commit)) !=
NULL)
return (ret);
- /*
- * mmap. Requesting an address is not implemented for
- * chunk_alloc_mmap(), so only call it if (new_addr == NULL).
- */
- if (new_addr == NULL && (ret = chunk_alloc_mmap(size, alignment, zero,
- commit)) != NULL)
+ /* mmap. */
+ if ((ret = chunk_alloc_mmap(new_addr, size, alignment, zero, commit)) !=
+ NULL)
return (ret);
/* "secondary" dss. */
if (have_dss && dss_prec == dss_prec_secondary && (ret =
@@ -380,7 +377,7 @@ chunk_alloc_base(size_t size)
*/
zero = true;
commit = true;
- ret = chunk_alloc_mmap(size, chunksize, &zero, &commit);
+ ret = chunk_alloc_mmap(NULL, size, chunksize, &zero, &commit);
if (ret == NULL)
return (NULL);
if (config_valgrind)
diff --git a/src/chunk_mmap.c b/src/chunk_mmap.c
index b9ba741..56b2ee4 100644
--- a/src/chunk_mmap.c
+++ b/src/chunk_mmap.c
@@ -32,7 +32,8 @@ chunk_alloc_mmap_slow(size_t size, size_t alignment, bool *zero, bool *commit)
}
void *
-chunk_alloc_mmap(size_t size, size_t alignment, bool *zero, bool *commit)
+chunk_alloc_mmap(void *new_addr, size_t size, size_t alignment, bool *zero,
+ bool *commit)
{
void *ret;
size_t offset;
@@ -53,9 +54,10 @@ chunk_alloc_mmap(size_t size, size_t alignment, bool *zero, bool *commit)
assert(alignment != 0);
assert((alignment & chunksize_mask) == 0);
- ret = pages_map(NULL, size);
- if (ret == NULL)
- return (NULL);
+ ret = pages_map(new_addr, size);
+ if (ret == NULL || ret == new_addr)
+ return (ret);
+ assert(new_addr == NULL);
offset = ALIGNMENT_ADDR2OFFSET(ret, alignment);
if (offset != 0) {
pages_unmap(ret, size);