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.
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_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 @@
*/
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 @@
}
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 @@
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);