Add support for sized deallocation.

This adds a new `sdallocx` function to the external API, allowing the
size to be passed by the caller.  It avoids some extra reads in the
thread cache fast path.  In the case where stats are enabled, this
avoids the work of calculating the size from the pointer.

An assertion validates the size that's passed in, so enabling debugging
will allow users of the API to debug cases where an incorrect size is
passed in.

The performance win for a contrived microbenchmark doing an allocation
and immediately freeing it is ~10%.  It may have a different impact on a
real workload.

Closes #28
This commit is contained in:
Daniel Micay
2014-08-28 15:41:48 -04:00
committed by Jason Evans
parent c3f8650749
commit 4cfe55166e
10 changed files with 201 additions and 5 deletions

View File

@@ -1223,6 +1223,24 @@ ifree(void *ptr, bool try_tcache)
JEMALLOC_VALGRIND_FREE(ptr, rzsize);
}
JEMALLOC_INLINE_C void
isfree(void *ptr, size_t usize, bool try_tcache)
{
UNUSED size_t rzsize JEMALLOC_CC_SILENCE_INIT(0);
assert(ptr != NULL);
assert(malloc_initialized || IS_INITIALIZER);
if (config_prof && opt_prof)
prof_free(ptr, usize);
if (config_stats)
thread_allocated_tsd_get()->deallocated += usize;
if (config_valgrind && in_valgrind)
rzsize = p2rz(ptr);
isqalloc(ptr, usize, try_tcache);
JEMALLOC_VALGRIND_FREE(ptr, rzsize);
}
void *
je_realloc(void *ptr, size_t size)
{
@@ -1820,6 +1838,32 @@ je_dallocx(void *ptr, int flags)
ifree(ptr, try_tcache);
}
void
je_sdallocx(void *ptr, size_t size, int flags)
{
bool try_tcache;
assert(ptr != NULL);
assert(malloc_initialized || IS_INITIALIZER);
assert(size == isalloc(ptr, config_prof));
if ((flags & MALLOCX_LG_ALIGN_MASK) == 0)
size = s2u(size);
else
size = sa2u(size, MALLOCX_ALIGN_GET_SPECIFIED(flags));
if ((flags & MALLOCX_ARENA_MASK) != 0) {
unsigned arena_ind = MALLOCX_ARENA_GET(flags);
arena_chunk_t *chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
try_tcache = (chunk == ptr || chunk->arena !=
arenas[arena_ind]);
} else
try_tcache = true;
UTRACE(ptr, 0, 0);
isfree(ptr, size, try_tcache);
}
size_t
je_nallocx(size_t size, int flags)
{