From b27bb5275d58b0abeadc4664ed27febe625f8ff0 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Thu, 29 Nov 2012 19:25:07 +0100 Subject: erts: Fix bug when allocating size near sbc_threshold A block larger than sbc_threshold can be allocated in MBC if the subsequent "residue block" is smaller than min_block_size. Solved by lowering sbc_threshold to ("hard limit" - min_block_size). --- erts/emulator/beam/erl_alloc_util.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/erts/emulator/beam/erl_alloc_util.c b/erts/emulator/beam/erl_alloc_util.c index e6aa93b9d8..f4e6f0bba0 100644 --- a/erts/emulator/beam/erl_alloc_util.c +++ b/erts/emulator/beam/erl_alloc_util.c @@ -1404,6 +1404,7 @@ mbc_alloc_finalize(Allctr_t *allctr, ASSERT(FBLK_TO_MBC(nxt_blk) == crr); } else { + ASSERT(org_blk_sz <= MBC_ABLK_SZ_MASK); blk_sz = org_blk_sz; if (flags & LAST_BLK_HDR_FLG) { if (valid_blk_info) @@ -4163,12 +4164,6 @@ erts_alcu_start(Allctr_t *allctr, AllctrInit_t *init) allctr->ramv = init->ramv; allctr->main_carrier_size = init->mmbcs; - allctr->sbc_threshold = init->sbct; -#ifndef ARCH_64 - if (allctr->sbc_threshold > MBC_ABLK_SZ_MASK - ABLK_HDR_SZ) { - allctr->sbc_threshold = MBC_ABLK_SZ_MASK - ABLK_HDR_SZ + 1; - } -#endif #if HAVE_ERTS_MSEG allctr->mseg_opt.abs_shrink_th = init->asbcst; @@ -4210,6 +4205,23 @@ erts_alcu_start(Allctr_t *allctr, AllctrInit_t *init) } #endif + allctr->sbc_threshold = init->sbct; +#ifndef ARCH_64 + if (allctr->sbc_threshold > 0) { + Uint max_mbc_block_sz = UNIT_CEILING(allctr->sbc_threshold - 1 + ABLK_HDR_SZ); + if (max_mbc_block_sz + UNIT_FLOOR(allctr->min_block_size - 1) > MBC_ABLK_SZ_MASK + || max_mbc_block_sz < allctr->sbc_threshold) { /* wrap around */ + /* + * By limiting sbc_threshold to (hard limit - min_block_size) + * we avoid having to split off free "residue blocks" + * smaller than min_block_size. + */ + max_mbc_block_sz = MBC_ABLK_SZ_MASK - UNIT_FLOOR(allctr->min_block_size - 1); + allctr->sbc_threshold = max_mbc_block_sz - ABLK_HDR_SZ + 1; + } + } +#endif + allctr->sbmbc_threshold = init->sbmbct; -- cgit v1.2.3