Avoid variable length arrays and remove declarations within code
MSVC doesn't support C99, and building as C++ to be able to use them is dangerous, as C++ and C99 are incompatible. Introduce a VARIABLE_ARRAY macro that either uses VLA when supported, or alloca() otherwise. Note that using alloca() inside loops doesn't quite work like VLAs, thus the use of VARIABLE_ARRAY there is discouraged. It might be worth investigating ways to check whether VARIABLE_ARRAY is used in such context at runtime in debug builds and bail out if that happens.
This commit is contained in:
parent
f278994029
commit
8b49971d0c
@ -319,6 +319,20 @@ static const bool config_ivsalloc =
|
|||||||
#define ALIGNMENT_CEILING(s, alignment) \
|
#define ALIGNMENT_CEILING(s, alignment) \
|
||||||
(((s) + (alignment - 1)) & (-(alignment)))
|
(((s) + (alignment - 1)) & (-(alignment)))
|
||||||
|
|
||||||
|
/* Declare a variable length array */
|
||||||
|
#if __STDC_VERSION__ < 199901L
|
||||||
|
# ifdef _MSC_VER
|
||||||
|
# include <malloc.h>
|
||||||
|
# define alloca _alloca
|
||||||
|
# else
|
||||||
|
# include <alloca.h>
|
||||||
|
# endif
|
||||||
|
# define VARIABLE_ARRAY(type, name, count) \
|
||||||
|
type *name = alloca(sizeof(type) * count)
|
||||||
|
#else
|
||||||
|
# define VARIABLE_ARRAY(type, name, count) type name[count]
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef JEMALLOC_VALGRIND
|
#ifdef JEMALLOC_VALGRIND
|
||||||
/*
|
/*
|
||||||
* The JEMALLOC_VALGRIND_*() macros must be macros rather than functions
|
* The JEMALLOC_VALGRIND_*() macros must be macros rather than functions
|
||||||
|
@ -542,8 +542,9 @@ prof_free(const void *ptr, size_t size)
|
|||||||
cassert(config_prof);
|
cassert(config_prof);
|
||||||
|
|
||||||
if ((uintptr_t)ctx > (uintptr_t)1) {
|
if ((uintptr_t)ctx > (uintptr_t)1) {
|
||||||
|
prof_thr_cnt_t *tcnt;
|
||||||
assert(size == isalloc(ptr, true));
|
assert(size == isalloc(ptr, true));
|
||||||
prof_thr_cnt_t *tcnt = prof_lookup(ctx->bt);
|
tcnt = prof_lookup(ctx->bt);
|
||||||
|
|
||||||
if (tcnt != NULL) {
|
if (tcnt != NULL) {
|
||||||
tcnt->epoch++;
|
tcnt->epoch++;
|
||||||
|
18
src/arena.c
18
src/arena.c
@ -640,14 +640,14 @@ arena_chunk_purge(arena_t *arena, arena_chunk_t *chunk)
|
|||||||
if (mapelm->bits & CHUNK_MAP_LARGE)
|
if (mapelm->bits & CHUNK_MAP_LARGE)
|
||||||
pageind += mapelm->bits >> LG_PAGE;
|
pageind += mapelm->bits >> LG_PAGE;
|
||||||
else {
|
else {
|
||||||
|
size_t binind;
|
||||||
|
arena_bin_info_t *bin_info;
|
||||||
arena_run_t *run = (arena_run_t *)((uintptr_t)
|
arena_run_t *run = (arena_run_t *)((uintptr_t)
|
||||||
chunk + (uintptr_t)(pageind << LG_PAGE));
|
chunk + (uintptr_t)(pageind << LG_PAGE));
|
||||||
|
|
||||||
assert((mapelm->bits >> LG_PAGE) == 0);
|
assert((mapelm->bits >> LG_PAGE) == 0);
|
||||||
size_t binind = arena_bin_index(arena,
|
binind = arena_bin_index(arena, run->bin);
|
||||||
run->bin);
|
bin_info = &arena_bin_info[binind];
|
||||||
arena_bin_info_t *bin_info =
|
|
||||||
&arena_bin_info[binind];
|
|
||||||
pageind += bin_info->run_size >> LG_PAGE;
|
pageind += bin_info->run_size >> LG_PAGE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1056,11 +1056,12 @@ arena_bin_runs_first(arena_bin_t *bin)
|
|||||||
if (mapelm != NULL) {
|
if (mapelm != NULL) {
|
||||||
arena_chunk_t *chunk;
|
arena_chunk_t *chunk;
|
||||||
size_t pageind;
|
size_t pageind;
|
||||||
|
arena_run_t *run;
|
||||||
|
|
||||||
chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(mapelm);
|
chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(mapelm);
|
||||||
pageind = ((((uintptr_t)mapelm - (uintptr_t)chunk->map) /
|
pageind = ((((uintptr_t)mapelm - (uintptr_t)chunk->map) /
|
||||||
sizeof(arena_chunk_map_t))) + map_bias;
|
sizeof(arena_chunk_map_t))) + map_bias;
|
||||||
arena_run_t *run = (arena_run_t *)((uintptr_t)chunk +
|
run = (arena_run_t *)((uintptr_t)chunk +
|
||||||
(uintptr_t)((pageind - (mapelm->bits >> LG_PAGE)) <<
|
(uintptr_t)((pageind - (mapelm->bits >> LG_PAGE)) <<
|
||||||
LG_PAGE));
|
LG_PAGE));
|
||||||
return (run);
|
return (run);
|
||||||
@ -1596,14 +1597,15 @@ arena_dalloc_bin(arena_t *arena, arena_chunk_t *chunk, void *ptr,
|
|||||||
size_t pageind;
|
size_t pageind;
|
||||||
arena_run_t *run;
|
arena_run_t *run;
|
||||||
arena_bin_t *bin;
|
arena_bin_t *bin;
|
||||||
size_t size;
|
arena_bin_info_t *bin_info;
|
||||||
|
size_t size, binind;
|
||||||
|
|
||||||
pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE;
|
pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE;
|
||||||
run = (arena_run_t *)((uintptr_t)chunk + (uintptr_t)((pageind -
|
run = (arena_run_t *)((uintptr_t)chunk + (uintptr_t)((pageind -
|
||||||
(mapelm->bits >> LG_PAGE)) << LG_PAGE));
|
(mapelm->bits >> LG_PAGE)) << LG_PAGE));
|
||||||
bin = run->bin;
|
bin = run->bin;
|
||||||
size_t binind = arena_bin_index(arena, bin);
|
binind = arena_bin_index(arena, bin);
|
||||||
arena_bin_info_t *bin_info = &arena_bin_info[binind];
|
bin_info = &arena_bin_info[binind];
|
||||||
if (config_fill || config_stats)
|
if (config_fill || config_stats)
|
||||||
size = bin_info->reg_size;
|
size = bin_info->reg_size;
|
||||||
|
|
||||||
|
@ -520,7 +520,7 @@ static void
|
|||||||
ctl_refresh(void)
|
ctl_refresh(void)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
arena_t *tarenas[narenas];
|
VARIABLE_ARRAY(arena_t *, tarenas, narenas);
|
||||||
|
|
||||||
if (config_stats) {
|
if (config_stats) {
|
||||||
malloc_mutex_lock(&chunks_mtx);
|
malloc_mutex_lock(&chunks_mtx);
|
||||||
@ -1232,7 +1232,7 @@ arenas_purge_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
|
|||||||
ret = EFAULT;
|
ret = EFAULT;
|
||||||
goto label_return;
|
goto label_return;
|
||||||
} else {
|
} else {
|
||||||
arena_t *tarenas[narenas];
|
VARIABLE_ARRAY(arena_t *, tarenas, narenas);
|
||||||
|
|
||||||
malloc_mutex_lock(&arenas_lock);
|
malloc_mutex_lock(&arenas_lock);
|
||||||
memcpy(tarenas, arenas, sizeof(arena_t *) * narenas);
|
memcpy(tarenas, arenas, sizeof(arena_t *) * narenas);
|
||||||
|
@ -498,7 +498,7 @@ stats_print(void (*write_cb)(void *, const char *), void *cbopaque,
|
|||||||
|
|
||||||
CTL_GET("arenas.narenas", &narenas, unsigned);
|
CTL_GET("arenas.narenas", &narenas, unsigned);
|
||||||
{
|
{
|
||||||
bool initialized[narenas];
|
VARIABLE_ARRAY(bool, initialized, narenas);
|
||||||
size_t isz;
|
size_t isz;
|
||||||
unsigned i, ninitialized;
|
unsigned i, ninitialized;
|
||||||
|
|
||||||
@ -527,7 +527,7 @@ stats_print(void (*write_cb)(void *, const char *), void *cbopaque,
|
|||||||
|
|
||||||
CTL_GET("arenas.narenas", &narenas, unsigned);
|
CTL_GET("arenas.narenas", &narenas, unsigned);
|
||||||
{
|
{
|
||||||
bool initialized[narenas];
|
VARIABLE_ARRAY(bool, initialized, narenas);
|
||||||
size_t isz;
|
size_t isz;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ JEMALLOC_ATTR(visibility("default"))
|
|||||||
void
|
void
|
||||||
_malloc_thread_cleanup(void)
|
_malloc_thread_cleanup(void)
|
||||||
{
|
{
|
||||||
bool pending[ncleanups], again;
|
bool pending[MALLOC_TSD_CLEANUPS_MAX], again;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
for (i = 0; i < ncleanups; i++)
|
for (i = 0; i < ncleanups; i++)
|
||||||
|
@ -30,11 +30,13 @@ test_bitmap_init(void)
|
|||||||
bitmap_info_init(&binfo, i);
|
bitmap_info_init(&binfo, i);
|
||||||
{
|
{
|
||||||
size_t j;
|
size_t j;
|
||||||
bitmap_t bitmap[bitmap_info_ngroups(&binfo)];
|
bitmap_t *bitmap = malloc(sizeof(bitmap_t) *
|
||||||
|
bitmap_info_ngroups(&binfo));
|
||||||
bitmap_init(bitmap, &binfo);
|
bitmap_init(bitmap, &binfo);
|
||||||
|
|
||||||
for (j = 0; j < i; j++)
|
for (j = 0; j < i; j++)
|
||||||
assert(bitmap_get(bitmap, &binfo, j) == false);
|
assert(bitmap_get(bitmap, &binfo, j) == false);
|
||||||
|
free(bitmap);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -50,12 +52,14 @@ test_bitmap_set(void)
|
|||||||
bitmap_info_init(&binfo, i);
|
bitmap_info_init(&binfo, i);
|
||||||
{
|
{
|
||||||
size_t j;
|
size_t j;
|
||||||
bitmap_t bitmap[bitmap_info_ngroups(&binfo)];
|
bitmap_t *bitmap = malloc(sizeof(bitmap_t) *
|
||||||
|
bitmap_info_ngroups(&binfo));
|
||||||
bitmap_init(bitmap, &binfo);
|
bitmap_init(bitmap, &binfo);
|
||||||
|
|
||||||
for (j = 0; j < i; j++)
|
for (j = 0; j < i; j++)
|
||||||
bitmap_set(bitmap, &binfo, j);
|
bitmap_set(bitmap, &binfo, j);
|
||||||
assert(bitmap_full(bitmap, &binfo));
|
assert(bitmap_full(bitmap, &binfo));
|
||||||
|
free(bitmap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -70,7 +74,8 @@ test_bitmap_unset(void)
|
|||||||
bitmap_info_init(&binfo, i);
|
bitmap_info_init(&binfo, i);
|
||||||
{
|
{
|
||||||
size_t j;
|
size_t j;
|
||||||
bitmap_t bitmap[bitmap_info_ngroups(&binfo)];
|
bitmap_t *bitmap = malloc(sizeof(bitmap_t) *
|
||||||
|
bitmap_info_ngroups(&binfo));
|
||||||
bitmap_init(bitmap, &binfo);
|
bitmap_init(bitmap, &binfo);
|
||||||
|
|
||||||
for (j = 0; j < i; j++)
|
for (j = 0; j < i; j++)
|
||||||
@ -81,6 +86,7 @@ test_bitmap_unset(void)
|
|||||||
for (j = 0; j < i; j++)
|
for (j = 0; j < i; j++)
|
||||||
bitmap_set(bitmap, &binfo, j);
|
bitmap_set(bitmap, &binfo, j);
|
||||||
assert(bitmap_full(bitmap, &binfo));
|
assert(bitmap_full(bitmap, &binfo));
|
||||||
|
free(bitmap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -95,7 +101,8 @@ test_bitmap_sfu(void)
|
|||||||
bitmap_info_init(&binfo, i);
|
bitmap_info_init(&binfo, i);
|
||||||
{
|
{
|
||||||
ssize_t j;
|
ssize_t j;
|
||||||
bitmap_t bitmap[bitmap_info_ngroups(&binfo)];
|
bitmap_t *bitmap = malloc(sizeof(bitmap_t) *
|
||||||
|
bitmap_info_ngroups(&binfo));
|
||||||
bitmap_init(bitmap, &binfo);
|
bitmap_init(bitmap, &binfo);
|
||||||
|
|
||||||
/* Iteratively set bits starting at the beginning. */
|
/* Iteratively set bits starting at the beginning. */
|
||||||
@ -125,6 +132,7 @@ test_bitmap_sfu(void)
|
|||||||
}
|
}
|
||||||
assert(bitmap_sfu(bitmap, &binfo) == i - 1);
|
assert(bitmap_sfu(bitmap, &binfo) == i - 1);
|
||||||
assert(bitmap_full(bitmap, &binfo));
|
assert(bitmap_full(bitmap, &binfo));
|
||||||
|
free(bitmap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user