Avoid overflow in arena_run_regind().
Fix a regression due to:
Remove an arena_bin_run_size_calc() constraint.
2a6f2af6e4
The removed constraint required that small run headers fit in one page,
which indirectly limited runs such that they would not cause overflow in
arena_run_regind(). Add an explicit constraint to
arena_bin_run_size_calc() based on the largest number of regions that
arena_run_regind() can handle (2^11 as currently configured).
This commit is contained in:
parent
1dcb4f86b2
commit
47e57f9bda
@ -58,6 +58,10 @@
|
|||||||
#define RUN_MAX_OVRHD 0x0000003dU
|
#define RUN_MAX_OVRHD 0x0000003dU
|
||||||
#define RUN_MAX_OVRHD_RELAX 0x00001800U
|
#define RUN_MAX_OVRHD_RELAX 0x00001800U
|
||||||
|
|
||||||
|
/* Maximum number of regions in one run. */
|
||||||
|
#define LG_RUN_MAXREGS 11
|
||||||
|
#define RUN_MAXREGS (1U << LG_RUN_MAXREGS)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The minimum ratio of active:dirty pages per arena is computed as:
|
* The minimum ratio of active:dirty pages per arena is computed as:
|
||||||
*
|
*
|
||||||
@ -556,7 +560,7 @@ arena_run_regind(arena_run_t *run, arena_bin_info_t *bin_info, const void *ptr)
|
|||||||
* divide by 0, and 1 and 2 are both powers of two, which are
|
* divide by 0, and 1 and 2 are both powers of two, which are
|
||||||
* handled above.
|
* handled above.
|
||||||
*/
|
*/
|
||||||
#define SIZE_INV_SHIFT 21
|
#define SIZE_INV_SHIFT ((sizeof(unsigned) << 3) - LG_RUN_MAXREGS)
|
||||||
#define SIZE_INV(s) (((1U << SIZE_INV_SHIFT) / (s)) + 1)
|
#define SIZE_INV(s) (((1U << SIZE_INV_SHIFT) / (s)) + 1)
|
||||||
static const unsigned size_invs[] = {
|
static const unsigned size_invs[] = {
|
||||||
SIZE_INV(3),
|
SIZE_INV(3),
|
||||||
|
@ -70,7 +70,9 @@ atomic_sub_uint64(uint64_t *p, uint64_t x)
|
|||||||
return (OSAtomicAdd64(-((int64_t)x), (int64_t *)p));
|
return (OSAtomicAdd64(-((int64_t)x), (int64_t *)p));
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
# if (LG_SIZEOF_PTR == 3)
|
||||||
# error "Missing implementation for 64-bit atomic operations"
|
# error "Missing implementation for 64-bit atomic operations"
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* 32-bit operations. */
|
/* 32-bit operations. */
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#ifdef JEMALLOC_H_TYPES
|
#ifdef JEMALLOC_H_TYPES
|
||||||
|
|
||||||
/* Maximum bitmap bit count is 2^LG_BITMAP_MAXBITS. */
|
/* Maximum bitmap bit count is 2^LG_BITMAP_MAXBITS. */
|
||||||
#define LG_BITMAP_MAXBITS 18
|
#define LG_BITMAP_MAXBITS LG_RUN_MAXREGS
|
||||||
|
|
||||||
typedef struct bitmap_level_s bitmap_level_t;
|
typedef struct bitmap_level_s bitmap_level_t;
|
||||||
typedef struct bitmap_info_s bitmap_info_t;
|
typedef struct bitmap_info_s bitmap_info_t;
|
||||||
|
@ -224,9 +224,9 @@ extern void (*JEMALLOC_P(malloc_message))(void *wcbopaque, const char *s);
|
|||||||
#include "jemalloc/internal/ctl.h"
|
#include "jemalloc/internal/ctl.h"
|
||||||
#include "jemalloc/internal/mutex.h"
|
#include "jemalloc/internal/mutex.h"
|
||||||
#include "jemalloc/internal/mb.h"
|
#include "jemalloc/internal/mb.h"
|
||||||
#include "jemalloc/internal/bitmap.h"
|
|
||||||
#include "jemalloc/internal/extent.h"
|
#include "jemalloc/internal/extent.h"
|
||||||
#include "jemalloc/internal/arena.h"
|
#include "jemalloc/internal/arena.h"
|
||||||
|
#include "jemalloc/internal/bitmap.h"
|
||||||
#include "jemalloc/internal/base.h"
|
#include "jemalloc/internal/base.h"
|
||||||
#include "jemalloc/internal/chunk.h"
|
#include "jemalloc/internal/chunk.h"
|
||||||
#include "jemalloc/internal/huge.h"
|
#include "jemalloc/internal/huge.h"
|
||||||
|
@ -2427,6 +2427,7 @@ small_size2bin_init_hard(void)
|
|||||||
* *) bin_info->run_size >= min_run_size
|
* *) bin_info->run_size >= min_run_size
|
||||||
* *) bin_info->run_size <= arena_maxclass
|
* *) bin_info->run_size <= arena_maxclass
|
||||||
* *) run header overhead <= RUN_MAX_OVRHD (or header overhead relaxed).
|
* *) run header overhead <= RUN_MAX_OVRHD (or header overhead relaxed).
|
||||||
|
* *) bin_info->nregs <= RUN_MAXREGS
|
||||||
*
|
*
|
||||||
* bin_info->nregs, bin_info->bitmap_offset, and bin_info->reg0_offset are also
|
* bin_info->nregs, bin_info->bitmap_offset, and bin_info->reg0_offset are also
|
||||||
* calculated here, since these settings are all interdependent.
|
* calculated here, since these settings are all interdependent.
|
||||||
@ -2459,6 +2460,10 @@ bin_info_run_size_calc(arena_bin_info_t *bin_info, size_t min_run_size)
|
|||||||
try_run_size = min_run_size;
|
try_run_size = min_run_size;
|
||||||
try_nregs = ((try_run_size - sizeof(arena_run_t)) / bin_info->reg_size)
|
try_nregs = ((try_run_size - sizeof(arena_run_t)) / bin_info->reg_size)
|
||||||
+ 1; /* Counter-act try_nregs-- in loop. */
|
+ 1; /* Counter-act try_nregs-- in loop. */
|
||||||
|
if (try_nregs > RUN_MAXREGS) {
|
||||||
|
try_nregs = RUN_MAXREGS
|
||||||
|
+ 1; /* Counter-act try_nregs-- in loop. */
|
||||||
|
}
|
||||||
do {
|
do {
|
||||||
try_nregs--;
|
try_nregs--;
|
||||||
try_hdr_size = sizeof(arena_run_t);
|
try_hdr_size = sizeof(arena_run_t);
|
||||||
@ -2500,6 +2505,10 @@ bin_info_run_size_calc(arena_bin_info_t *bin_info, size_t min_run_size)
|
|||||||
try_nregs = ((try_run_size - sizeof(arena_run_t)) /
|
try_nregs = ((try_run_size - sizeof(arena_run_t)) /
|
||||||
bin_info->reg_size)
|
bin_info->reg_size)
|
||||||
+ 1; /* Counter-act try_nregs-- in loop. */
|
+ 1; /* Counter-act try_nregs-- in loop. */
|
||||||
|
if (try_nregs > RUN_MAXREGS) {
|
||||||
|
try_nregs = RUN_MAXREGS
|
||||||
|
+ 1; /* Counter-act try_nregs-- in loop. */
|
||||||
|
}
|
||||||
do {
|
do {
|
||||||
try_nregs--;
|
try_nregs--;
|
||||||
try_hdr_size = sizeof(arena_run_t);
|
try_hdr_size = sizeof(arena_run_t);
|
||||||
@ -2526,7 +2535,8 @@ bin_info_run_size_calc(arena_bin_info_t *bin_info, size_t min_run_size)
|
|||||||
} while (try_run_size <= arena_maxclass
|
} while (try_run_size <= arena_maxclass
|
||||||
&& try_run_size <= arena_maxclass
|
&& try_run_size <= arena_maxclass
|
||||||
&& RUN_MAX_OVRHD * (bin_info->reg_size << 3) > RUN_MAX_OVRHD_RELAX
|
&& RUN_MAX_OVRHD * (bin_info->reg_size << 3) > RUN_MAX_OVRHD_RELAX
|
||||||
&& (try_reg0_offset << RUN_BFP) > RUN_MAX_OVRHD * try_run_size);
|
&& (try_reg0_offset << RUN_BFP) > RUN_MAX_OVRHD * try_run_size
|
||||||
|
&& try_nregs < RUN_MAXREGS);
|
||||||
|
|
||||||
assert(good_hdr_size <= good_reg0_offset);
|
assert(good_hdr_size <= good_reg0_offset);
|
||||||
|
|
||||||
|
@ -13,7 +13,11 @@
|
|||||||
*/
|
*/
|
||||||
#include "../src/bitmap.c"
|
#include "../src/bitmap.c"
|
||||||
|
|
||||||
#define MAXBITS 4500
|
#if (LG_BITMAP_MAXBITS > 12)
|
||||||
|
# define MAXBITS 4500
|
||||||
|
#else
|
||||||
|
# define MAXBITS (1U << LG_BITMAP_MAXBITS)
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_bitmap_size(void)
|
test_bitmap_size(void)
|
||||||
|
Loading…
Reference in New Issue
Block a user