diff --git a/src/memory.c b/src/memory.c index f9c53782..cad2d774 100644 --- a/src/memory.c +++ b/src/memory.c @@ -247,24 +247,11 @@ static inline size_t mi_bsf(uintptr_t x) { #endif return idx; } -static inline size_t mi_bsr(uintptr_t x) { - if (x==0) return 8*MI_INTPTR_SIZE; - DWORD idx; - #if (MI_INTPTR_SIZE==8) - _BitScanReverse64(&idx, x); - #else - _BitScanReverse(&idx, x); - #endif - return idx; -} #elif defined(__GNUC__) || defined(__clang__) #define MI_HAVE_BITSCAN static inline size_t mi_bsf(uintptr_t x) { return (x==0 ? 8*MI_INTPTR_SIZE : __builtin_ctzl(x)); } -static inline size_t mi_bsr(uintptr_t x) { - return (x==0 ? 8*MI_INTPTR_SIZE : (8*MI_INTPTR_SIZE - 1) - __builtin_clzl(x)); -} #endif // Allocate `blocks` in a `region` at `idx` of a given `size`. @@ -310,7 +297,7 @@ static bool mi_region_alloc_blocks(mem_region_t* region, size_t idx, size_t bloc else { // on to the next bit range #ifdef MI_HAVE_BITSCAN - size_t shift = (blocks == 1 ? 1 : mi_bsr(map & m) - bitidx + 1); + size_t shift = (blocks == 1 ? 1 : _mi_bsr(map & m) - bitidx + 1); mi_assert_internal(shift > 0 && shift <= blocks); #else size_t shift = 1; diff --git a/src/page-queue.c b/src/page-queue.c index 4af70b50..4e554047 100644 --- a/src/page-queue.c +++ b/src/page-queue.c @@ -59,10 +59,20 @@ static inline uint8_t mi_bsr32(uint32_t x) { _BitScanReverse((DWORD*)&idx, x); return (uint8_t)idx; } +#define HAVE_MI_BSR64 +static inline size_t mi_bsr64(uint64_t x) { + uint64_t idx; + _BitScanReverse64((DWORD*)&idx, x); + return (uint8_t)idx; +} #elif defined(__GNUC__) || defined(__clang__) static inline uint8_t mi_bsr32(uint32_t x) { return (31 - __builtin_clz(x)); } +#define HAVE_MI_BSR64 +static inline size_t mi_bsr64(uint64_t x) { + return (63 - __builtin_clzl(x)); +} #else static inline uint8_t mi_bsr32(uint32_t x) { // de Bruijn multiplication, see @@ -84,8 +94,12 @@ static inline uint8_t mi_bsr32(uint32_t x) { uint8_t _mi_bsr(uintptr_t x) { if (x == 0) return 0; #if MI_INTPTR_SIZE==8 + #ifdef HAVE_MI_BSR64 + return mi_bsr64(x); + #else uint32_t hi = (x >> 32); return (hi == 0 ? mi_bsr32((uint32_t)x) : 32 + mi_bsr32(hi)); + #endif #elif MI_INTPTR_SIZE==4 return mi_bsr32(x); #else