mirror of
https://github.com/microsoft/mimalloc.git
synced 2025-05-08 00:09:31 +03:00
optimize mi_bin
This commit is contained in:
parent
d3897635ad
commit
c62d276835
2 changed files with 43 additions and 42 deletions
|
@ -59,25 +59,21 @@ static inline bool mi_page_queue_is_special(const mi_page_queue_t* pq) {
|
||||||
// i.e. byte size == `wsize*sizeof(void*)`.
|
// i.e. byte size == `wsize*sizeof(void*)`.
|
||||||
static inline uint8_t mi_bin(size_t size) {
|
static inline uint8_t mi_bin(size_t size) {
|
||||||
size_t wsize = _mi_wsize_from_size(size);
|
size_t wsize = _mi_wsize_from_size(size);
|
||||||
uint8_t bin;
|
|
||||||
if (wsize <= 1) {
|
|
||||||
bin = 1;
|
|
||||||
}
|
|
||||||
#if defined(MI_ALIGN4W)
|
#if defined(MI_ALIGN4W)
|
||||||
else if (wsize <= 4) {
|
if mi_likely(wsize <= 4) {
|
||||||
bin = (uint8_t)((wsize+1)&~1); // round to double word sizes
|
return (wsize <= 1 ? 1 : (wsize+1)&~1); // round to double word sizes
|
||||||
}
|
}
|
||||||
#elif defined(MI_ALIGN2W)
|
#elif defined(MI_ALIGN2W)
|
||||||
else if (wsize <= 8) {
|
if mi_likely(wsize <= 8) {
|
||||||
bin = (uint8_t)((wsize+1)&~1); // round to double word sizes
|
return (wsize <= 1 ? 1 : (wsize+1)&~1); // round to double word sizes
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
else if (wsize <= 8) {
|
if mi_likely(wsize <= 8) {
|
||||||
bin = (uint8_t)wsize;
|
return (wsize == 0 ? 1 : wsize);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else if (wsize > MI_LARGE_OBJ_WSIZE_MAX) {
|
else if mi_unlikely(wsize > MI_LARGE_OBJ_WSIZE_MAX) {
|
||||||
bin = MI_BIN_HUGE;
|
return MI_BIN_HUGE;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
#if defined(MI_ALIGN4W)
|
#if defined(MI_ALIGN4W)
|
||||||
|
@ -85,16 +81,15 @@ static inline uint8_t mi_bin(size_t size) {
|
||||||
#endif
|
#endif
|
||||||
wsize--;
|
wsize--;
|
||||||
// find the highest bit
|
// find the highest bit
|
||||||
uint8_t b = (uint8_t)mi_bsr(wsize); // note: wsize != 0
|
const size_t b = mi_bsr(wsize); // note: wsize != 0
|
||||||
// and use the top 3 bits to determine the bin (~12.5% worst internal fragmentation).
|
// and use the top 3 bits to determine the bin (~12.5% worst internal fragmentation).
|
||||||
// - adjust with 3 because we use do not round the first 8 sizes
|
// - adjust with 3 because we use do not round the first 8 sizes
|
||||||
// which each get an exact bin
|
// which each get an exact bin
|
||||||
bin = ((b << 2) + (uint8_t)((wsize >> (b - 2)) & 0x03)) - 3;
|
const size_t bin = ((b << 2) + ((wsize >> (b - 2)) & 0x03)) - 3;
|
||||||
mi_assert_internal(bin < MI_BIN_HUGE);
|
mi_assert_internal(bin > 0 && bin < MI_BIN_HUGE);
|
||||||
}
|
|
||||||
mi_assert_internal(bin > 0 && bin <= MI_BIN_HUGE);
|
|
||||||
return bin;
|
return bin;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,10 @@ static void test_manage_os_memory(void);
|
||||||
int main() {
|
int main() {
|
||||||
mi_version();
|
mi_version();
|
||||||
mi_stats_reset();
|
mi_stats_reset();
|
||||||
test_manage_os_memory();
|
|
||||||
|
mi_bins();
|
||||||
|
|
||||||
|
// test_manage_os_memory();
|
||||||
// test_large_pages();
|
// test_large_pages();
|
||||||
// detect double frees and heap corruption
|
// detect double frees and heap corruption
|
||||||
// double_free1();
|
// double_free1();
|
||||||
|
@ -40,7 +43,7 @@ int main() {
|
||||||
// corrupt_free();
|
// corrupt_free();
|
||||||
// block_overflow1();
|
// block_overflow1();
|
||||||
// block_overflow2();
|
// block_overflow2();
|
||||||
test_canary_leak();
|
// test_canary_leak();
|
||||||
// test_aslr();
|
// test_aslr();
|
||||||
// invalid_free();
|
// invalid_free();
|
||||||
// test_reserved();
|
// test_reserved();
|
||||||
|
@ -48,8 +51,6 @@ int main() {
|
||||||
// test_heap_walk();
|
// test_heap_walk();
|
||||||
// alloc_huge();
|
// alloc_huge();
|
||||||
|
|
||||||
// mi_bins();
|
|
||||||
|
|
||||||
|
|
||||||
void* p1 = malloc(78);
|
void* p1 = malloc(78);
|
||||||
void* p2 = malloc(24);
|
void* p2 = malloc(24);
|
||||||
|
@ -314,7 +315,7 @@ static void test_large_pages(void) {
|
||||||
// bin size experiments
|
// bin size experiments
|
||||||
// ------------------------------
|
// ------------------------------
|
||||||
|
|
||||||
#if 0
|
#if 1
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
@ -376,31 +377,34 @@ static inline size_t _mi_wsize_from_size(size_t size) {
|
||||||
return (size + sizeof(uintptr_t) - 1) / sizeof(uintptr_t);
|
return (size + sizeof(uintptr_t) - 1) / sizeof(uintptr_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #define MI_ALIGN2W
|
||||||
|
|
||||||
// Return the bin for a given field size.
|
// Return the bin for a given field size.
|
||||||
// Returns MI_BIN_HUGE if the size is too large.
|
// Returns MI_BIN_HUGE if the size is too large.
|
||||||
// We use `wsize` for the size in "machine word sizes",
|
// We use `wsize` for the size in "machine word sizes",
|
||||||
// i.e. byte size == `wsize*sizeof(void*)`.
|
// i.e. byte size == `wsize*sizeof(void*)`.
|
||||||
extern inline uint8_t _mi_bin8(size_t size) {
|
static inline size_t mi_bin(size_t wsize) {
|
||||||
size_t wsize = _mi_wsize_from_size(size);
|
// size_t wsize = _mi_wsize_from_size(size);
|
||||||
uint8_t bin;
|
// size_t bin;
|
||||||
if (wsize <= 1) {
|
/*if (wsize <= 1) {
|
||||||
bin = 1;
|
bin = 1;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
#if defined(MI_ALIGN4W)
|
#if defined(MI_ALIGN4W)
|
||||||
else if (wsize <= 4) {
|
if (wsize <= 4) {
|
||||||
bin = (uint8_t)((wsize+1)&~1); // round to double word sizes
|
return (wsize <= 1 ? 1 : (wsize+1)&~1); // round to double word sizes
|
||||||
}
|
}
|
||||||
#elif defined(MI_ALIGN2W)
|
#elif defined(MI_ALIGN2W)
|
||||||
else if (wsize <= 8) {
|
if (wsize <= 8) {
|
||||||
bin = (uint8_t)((wsize+1)&~1); // round to double word sizes
|
return (wsize <= 1 ? 1 : (wsize+1)&~1); // round to double word sizes
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
else if (wsize <= 8) {
|
if (wsize <= 8) {
|
||||||
bin = (uint8_t)wsize;
|
return (wsize == 0 ? 1 : wsize);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else if (wsize > MI_LARGE_WSIZE_MAX) {
|
else if (wsize > MI_LARGE_WSIZE_MAX) {
|
||||||
bin = MI_BIN_HUGE;
|
return MI_BIN_HUGE;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
#if defined(MI_ALIGN4W)
|
#if defined(MI_ALIGN4W)
|
||||||
|
@ -408,14 +412,16 @@ extern inline uint8_t _mi_bin8(size_t size) {
|
||||||
#endif
|
#endif
|
||||||
wsize--;
|
wsize--;
|
||||||
// find the highest bit
|
// find the highest bit
|
||||||
uint8_t b = mi_bsr32((uint32_t)wsize);
|
const size_t b = _mi_bsr(wsize); // note: wsize != 0
|
||||||
// and use the top 3 bits to determine the bin (~12.5% worst internal fragmentation).
|
// and use the top 3 bits to determine the bin (~12.5% worst internal fragmentation).
|
||||||
// - adjust with 3 because we use do not round the first 8 sizes
|
// - adjust with 3 because we use do not round the first 8 sizes
|
||||||
// which each get an exact bin
|
// which each get an exact bin
|
||||||
bin = ((b << 2) + (uint8_t)((wsize >> (b - 2)) & 0x03)) - 3;
|
const size_t bin = ((b << 2) + ((wsize >> (b - 2)) & 0x03)) - 3;
|
||||||
}
|
assert(bin > 0 && bin < MI_BIN_HUGE);
|
||||||
return bin;
|
return bin;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline uint8_t _mi_bin4(size_t size) {
|
static inline uint8_t _mi_bin4(size_t size) {
|
||||||
size_t wsize = _mi_wsize_from_size(size);
|
size_t wsize = _mi_wsize_from_size(size);
|
||||||
|
@ -472,7 +478,7 @@ static size_t _mi_binx8(size_t bsize) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline size_t mi_bin(size_t wsize) {
|
static inline size_t mi_binx(size_t wsize) {
|
||||||
uint8_t bin;
|
uint8_t bin;
|
||||||
if (wsize <= 1) {
|
if (wsize <= 1) {
|
||||||
bin = 1;
|
bin = 1;
|
||||||
|
|
Loading…
Add table
Reference in a new issue