Avoid NULL check in free() and malloc_usable_size().
Generalize isalloc() to handle NULL pointers in such a way that the NULL checking overhead is only paid when introspecting huge allocations (or NULL). This allows free() and malloc_usable_size() to no longer check for NULL. Submitted by Igor Bukanov and Mike Hommey.
This commit is contained in:
parent
80b25932ca
commit
96d4120ac0
@ -65,7 +65,7 @@ DOCS_HTML := $(DOCS_XML:@objroot@%.xml=@srcroot@%.html)
|
|||||||
DOCS_MAN3 := $(DOCS_XML:@objroot@%.xml=@srcroot@%.3)
|
DOCS_MAN3 := $(DOCS_XML:@objroot@%.xml=@srcroot@%.3)
|
||||||
DOCS := $(DOCS_HTML) $(DOCS_MAN3)
|
DOCS := $(DOCS_HTML) $(DOCS_MAN3)
|
||||||
CTESTS := @srcroot@test/aligned_alloc.c @srcroot@test/allocated.c \
|
CTESTS := @srcroot@test/aligned_alloc.c @srcroot@test/allocated.c \
|
||||||
@srcroot@test/bitmap.c @srcroot@test/mremap.c \
|
@srcroot@test/bitmap.c @srcroot@test/mremap.c @srcroot@test/null.c \
|
||||||
@srcroot@test/posix_memalign.c @srcroot@test/thread_arena.c \
|
@srcroot@test/posix_memalign.c @srcroot@test/thread_arena.c \
|
||||||
@srcroot@test/thread_tcache_enabled.c
|
@srcroot@test/thread_tcache_enabled.c
|
||||||
ifeq (@enable_experimental@, 1)
|
ifeq (@enable_experimental@, 1)
|
||||||
|
@ -633,8 +633,6 @@ isalloc(const void *ptr)
|
|||||||
size_t ret;
|
size_t ret;
|
||||||
arena_chunk_t *chunk;
|
arena_chunk_t *chunk;
|
||||||
|
|
||||||
assert(ptr != NULL);
|
|
||||||
|
|
||||||
chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
|
chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
|
||||||
if (chunk != ptr) {
|
if (chunk != ptr) {
|
||||||
/* Region. */
|
/* Region. */
|
||||||
@ -642,8 +640,10 @@ isalloc(const void *ptr)
|
|||||||
ret = arena_salloc_demote(ptr);
|
ret = arena_salloc_demote(ptr);
|
||||||
else
|
else
|
||||||
ret = arena_salloc(ptr);
|
ret = arena_salloc(ptr);
|
||||||
} else
|
} else if (ptr != NULL)
|
||||||
ret = huge_salloc(ptr);
|
ret = huge_salloc(ptr);
|
||||||
|
else
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
@ -664,12 +664,10 @@ idalloc(void *ptr)
|
|||||||
{
|
{
|
||||||
arena_chunk_t *chunk;
|
arena_chunk_t *chunk;
|
||||||
|
|
||||||
assert(ptr != NULL);
|
|
||||||
|
|
||||||
chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
|
chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
|
||||||
if (chunk != ptr)
|
if (chunk != ptr)
|
||||||
arena_dalloc(chunk->arena, chunk, ptr);
|
arena_dalloc(chunk->arena, chunk, ptr);
|
||||||
else
|
else if (ptr != NULL)
|
||||||
huge_dalloc(ptr, true);
|
huge_dalloc(ptr, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1100,22 +1100,18 @@ JEMALLOC_ATTR(visibility("default"))
|
|||||||
void
|
void
|
||||||
je_free(void *ptr)
|
je_free(void *ptr)
|
||||||
{
|
{
|
||||||
|
size_t usize;
|
||||||
|
|
||||||
if (ptr != NULL) {
|
assert(malloc_initialized || IS_INITIALIZER);
|
||||||
size_t usize;
|
|
||||||
|
|
||||||
assert(malloc_initialized || IS_INITIALIZER);
|
if (config_prof && opt_prof) {
|
||||||
|
usize = isalloc(ptr);
|
||||||
if (config_prof && opt_prof) {
|
prof_free(ptr, usize);
|
||||||
usize = isalloc(ptr);
|
} else if (config_stats)
|
||||||
prof_free(ptr, usize);
|
usize = isalloc(ptr);
|
||||||
} else if (config_stats) {
|
if (config_stats)
|
||||||
usize = isalloc(ptr);
|
thread_allocated_tsd_get()->deallocated += usize;
|
||||||
}
|
idalloc(ptr);
|
||||||
if (config_stats)
|
|
||||||
thread_allocated_tsd_get()->deallocated += usize;
|
|
||||||
idalloc(ptr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1200,7 +1196,7 @@ je_malloc_usable_size(const void *ptr)
|
|||||||
if (config_ivsalloc)
|
if (config_ivsalloc)
|
||||||
ret = ivsalloc(ptr);
|
ret = ivsalloc(ptr);
|
||||||
else
|
else
|
||||||
ret = (ptr != NULL) ? isalloc(ptr) : 0;
|
ret = isalloc(ptr);
|
||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
19
test/null.c
Normal file
19
test/null.c
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#define JEMALLOC_MANGLE
|
||||||
|
#include "jemalloc_test.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
main(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
fprintf(stderr, "Test begin\n");
|
||||||
|
|
||||||
|
free(malloc(1));
|
||||||
|
free(NULL);
|
||||||
|
assert(malloc_usable_size(NULL) == 0);
|
||||||
|
|
||||||
|
fprintf(stderr, "Test end\n");
|
||||||
|
return (0);
|
||||||
|
}
|
2
test/null.exp
Normal file
2
test/null.exp
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
Test begin
|
||||||
|
Test end
|
Loading…
Reference in New Issue
Block a user