Try to decommit new chunks.

Always leave decommit disabled on non-Windows systems.
This commit is contained in:
Jason Evans 2015-08-12 10:26:54 -07:00
parent 1f27abc1b1
commit 03bf5b67be
4 changed files with 27 additions and 15 deletions

View File

@ -145,7 +145,8 @@ chunk_alloc_dss(arena_t *arena, void *new_addr, size_t size, size_t alignment,
ret, size); ret, size);
memset(ret, 0, size); memset(ret, 0, size);
} }
*commit = true; if (!*commit)
*commit = pages_decommit(ret, size);
return (ret); return (ret);
} }
} while (dss_prev != (void *)-1); } while (dss_prev != (void *)-1);

View File

@ -24,7 +24,8 @@ chunk_alloc_mmap_slow(size_t size, size_t alignment, bool *zero, bool *commit)
assert(ret != NULL); assert(ret != NULL);
*zero = true; *zero = true;
*commit = true; if (!*commit)
*commit = pages_decommit(ret, size);
return (ret); return (ret);
} }
@ -61,7 +62,8 @@ chunk_alloc_mmap(size_t size, size_t alignment, bool *zero, bool *commit)
assert(ret != NULL); assert(ret != NULL);
*zero = true; *zero = true;
*commit = true; if (!*commit)
*commit = pages_decommit(ret, size);
return (ret); return (ret);
} }

View File

@ -102,7 +102,13 @@ pages_commit_impl(void *addr, size_t size, bool commit)
{ {
#ifndef _WIN32 #ifndef _WIN32
if (config_debug) { /*
* The following decommit/commit implementation is functional, but
* always disabled because it doesn't add value beyong improved
* debugging (at the cost of extra system calls) on systems that
* overcommit.
*/
if (false) {
int prot = commit ? (PROT_READ | PROT_WRITE) : PROT_NONE; int prot = commit ? (PROT_READ | PROT_WRITE) : PROT_NONE;
void *result = mmap(addr, size, prot, MAP_PRIVATE | MAP_ANON | void *result = mmap(addr, size, prot, MAP_PRIVATE | MAP_ANON |
MAP_FIXED, -1, 0); MAP_FIXED, -1, 0);

View File

@ -49,25 +49,30 @@ bool
chunk_commit(void *chunk, size_t size, size_t offset, size_t length, chunk_commit(void *chunk, size_t size, size_t offset, size_t length,
unsigned arena_ind) unsigned arena_ind)
{ {
bool err;
TRACE_HOOK("%s(chunk=%p, size=%zu, offset=%zu, length=%zu, " TRACE_HOOK("%s(chunk=%p, size=%zu, offset=%zu, length=%zu, "
"arena_ind=%u)\n", __func__, chunk, size, offset, length, "arena_ind=%u)\n", __func__, chunk, size, offset, length,
arena_ind); arena_ind);
did_commit = true; err = old_hooks.commit(chunk, size, offset, length, arena_ind);
memset((void *)((uintptr_t)chunk + offset), 0, length); did_commit = !err;
return (false); return (err);
} }
bool bool
chunk_decommit(void *chunk, size_t size, size_t offset, size_t length, chunk_decommit(void *chunk, size_t size, size_t offset, size_t length,
unsigned arena_ind) unsigned arena_ind)
{ {
bool err;
TRACE_HOOK("%s(chunk=%p, size=%zu, offset=%zu, length=%zu, " TRACE_HOOK("%s(chunk=%p, size=%zu, offset=%zu, length=%zu, "
"arena_ind=%u)\n", __func__, chunk, size, offset, length, "arena_ind=%u)\n", __func__, chunk, size, offset, length,
arena_ind); arena_ind);
did_decommit = true; if (!do_decommit)
return (!do_decommit); return (true);
err = old_hooks.decommit(chunk, size, offset, length, arena_ind);
did_decommit = !err;
return (err);
} }
bool bool
@ -167,7 +172,7 @@ TEST_BEGIN(test_chunk)
assert_d_eq(mallctl("arena.0.purge", NULL, NULL, NULL, 0), 0, assert_d_eq(mallctl("arena.0.purge", NULL, NULL, NULL, 0), 0,
"Unexpected arena.0.purge error"); "Unexpected arena.0.purge error");
assert_true(did_dalloc, "Expected dalloc"); assert_true(did_dalloc, "Expected dalloc");
assert_true(did_decommit, "Expected decommit"); assert_false(did_decommit, "Unexpected decommit");
assert_true(did_purge, "Expected purge"); assert_true(did_purge, "Expected purge");
dallocx(p, 0); dallocx(p, 0);
do_dalloc = true; do_dalloc = true;
@ -185,12 +190,11 @@ TEST_BEGIN(test_chunk)
"Unexpected xallocx() failure"); "Unexpected xallocx() failure");
assert_d_eq(mallctl("arena.0.purge", NULL, NULL, NULL, 0), 0, assert_d_eq(mallctl("arena.0.purge", NULL, NULL, NULL, 0), 0,
"Unexpected arena.0.purge error"); "Unexpected arena.0.purge error");
assert_true(did_decommit, "Expected decommit");
assert_true(did_split, "Expected split"); assert_true(did_split, "Expected split");
assert_zu_eq(xallocx(p, huge0 * 2, 0, 0), huge0 * 2, assert_zu_eq(xallocx(p, huge0 * 2, 0, 0), huge0 * 2,
"Unexpected xallocx() failure"); "Unexpected xallocx() failure");
assert_true(did_commit, "Expected commit"); assert_b_eq(did_decommit, did_commit, "Expected decommit/commit match");
assert_true(did_commit, "Expected merge"); assert_true(did_merge, "Expected merge");
dallocx(p, 0); dallocx(p, 0);
do_dalloc = true; do_dalloc = true;
do_decommit = false; do_decommit = false;
@ -222,11 +226,10 @@ TEST_BEGIN(test_chunk)
"Unexpected xallocx() failure"); "Unexpected xallocx() failure");
assert_d_eq(mallctl("arena.0.purge", NULL, NULL, NULL, 0), 0, assert_d_eq(mallctl("arena.0.purge", NULL, NULL, NULL, 0), 0,
"Unexpected arena.0.purge error"); "Unexpected arena.0.purge error");
assert_true(did_decommit, "Expected decommit");
did_commit = false; did_commit = false;
assert_zu_eq(xallocx(p, large1, 0, 0), large1, assert_zu_eq(xallocx(p, large1, 0, 0), large1,
"Unexpected xallocx() failure"); "Unexpected xallocx() failure");
assert_true(did_commit, "Expected commit"); assert_b_eq(did_decommit, did_commit, "Expected decommit/commit match");
dallocx(p, 0); dallocx(p, 0);
do_decommit = false; do_decommit = false;