mirror of
https://github.com/microsoft/mimalloc.git
synced 2025-07-06 11:34:38 +03:00
first version that passes the make test
This commit is contained in:
parent
55b70f1588
commit
9ebe941ce0
10 changed files with 155 additions and 91 deletions
|
@ -440,16 +440,34 @@ static inline mi_page_t* _mi_heap_get_free_small_page(mi_heap_t* heap, size_t si
|
|||
|
||||
extern uint8_t* _mi_page_map;
|
||||
|
||||
#define MI_PAGE_PTR_INVALID ((mi_page_t*)(1))
|
||||
static inline mi_page_t* _mi_ptr_page_ex(const void* p, bool* valid) {
|
||||
#if 1
|
||||
const uintptr_t idx = ((uintptr_t)p) >> MI_ARENA_SLICE_SHIFT;
|
||||
const size_t ofs = _mi_page_map[idx];
|
||||
if (valid != NULL) *valid = (ofs != 0);
|
||||
return (mi_page_t*)((idx - ofs + 1) << MI_ARENA_SLICE_SHIFT);
|
||||
#else
|
||||
const uintptr_t idx = ((uintptr_t)p) >> MI_ARENA_SLICE_SHIFT;
|
||||
const uintptr_t up = idx << MI_ARENA_SLICE_SHIFT;
|
||||
__builtin_prefetch((void*)up);
|
||||
const size_t ofs = _mi_page_map[idx];
|
||||
if (valid != NULL) *valid = (ofs != 0);
|
||||
return (mi_page_t*)(up - ((ofs - 1) << MI_ARENA_SLICE_SHIFT));
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline mi_page_t* _mi_checked_ptr_page(const void* p) {
|
||||
bool valid;
|
||||
mi_page_t* const page = _mi_ptr_page_ex(p,&valid);
|
||||
return (valid ? page : NULL);
|
||||
}
|
||||
|
||||
static inline mi_page_t* _mi_ptr_page(const void* p) {
|
||||
const uintptr_t up = ((uintptr_t)p) >> MI_ARENA_SLICE_SHIFT;
|
||||
// __builtin_prefetch((void*)(up << MI_ARENA_SLICE_SHIFT));
|
||||
const ptrdiff_t ofs = _mi_page_map[up];
|
||||
#if MI_DEBUG
|
||||
if mi_unlikely(ofs==0) return MI_PAGE_PTR_INVALID;
|
||||
return _mi_checked_ptr_page(p);
|
||||
#else
|
||||
return _mi_ptr_page_ex(p,NULL);
|
||||
#endif
|
||||
return (mi_page_t*)((up - ofs + 1) << MI_ARENA_SLICE_SHIFT);
|
||||
}
|
||||
|
||||
|
||||
|
@ -509,12 +527,13 @@ static inline mi_threadid_t mi_page_thread_id(const mi_page_t* page) {
|
|||
|
||||
static inline void mi_page_set_heap(mi_page_t* page, mi_heap_t* heap) {
|
||||
mi_assert_internal(mi_page_thread_free_flag(page) != MI_DELAYED_FREEING);
|
||||
mi_atomic_store_release(&page->xheap,(uintptr_t)heap);
|
||||
if (heap != NULL) {
|
||||
mi_atomic_store_release(&page->xheap, (uintptr_t)heap);
|
||||
page->heap_tag = heap->tag;
|
||||
mi_atomic_store_release(&page->xthread_id, heap->thread_id);
|
||||
}
|
||||
else {
|
||||
mi_atomic_store_release(&page->xheap, (uintptr_t)mi_page_heap(page)->tld->subproc);
|
||||
mi_atomic_store_release(&page->xthread_id,0);
|
||||
}
|
||||
}
|
||||
|
@ -578,11 +597,12 @@ static inline bool mi_page_mostly_used(const mi_page_t* page) {
|
|||
}
|
||||
|
||||
static inline bool mi_page_is_abandoned(const mi_page_t* page) {
|
||||
// note: the xheap field of an abandoned heap is set to the subproc (for fast reclaim-on-free)
|
||||
return (mi_page_thread_id(page) == 0);
|
||||
}
|
||||
|
||||
static inline bool mi_page_is_huge(const mi_page_t* page) {
|
||||
return (page->block_size > MI_LARGE_MAX_OBJ_SIZE);
|
||||
return (page->block_size > MI_LARGE_MAX_OBJ_SIZE || (mi_memkind_is_os(page->memid.memkind) && page->memid.mem.os.alignment > MI_PAGE_MAX_OVERALLOC_ALIGN));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -123,15 +123,16 @@ terms of the MIT license. A copy of the license can be found in the file
|
|||
#define MI_BITMAP_CHUNK_BITS_SHIFT 8 // optimized for 256 bits per chunk (avx2)
|
||||
#endif
|
||||
|
||||
#define MI_BITMAP_CHUNK_BITS (1 << MI_BITMAP_CHUNK_BITS_SHIFT)
|
||||
#define MI_ARENA_SLICE_SIZE (MI_ZU(1) << MI_ARENA_SLICE_SHIFT)
|
||||
#define MI_ARENA_SLICE_ALIGN (MI_ARENA_SLICE_SIZE)
|
||||
#define MI_BITMAP_CHUNK_BITS (1 << MI_BITMAP_CHUNK_BITS_SHIFT)
|
||||
|
||||
#define MI_ARENA_MIN_OBJ_BLOCKS (1)
|
||||
#define MI_ARENA_MAX_OBJ_BLOCKS (MI_BITMAP_CHUNK_BITS) // for now, cannot cross chunk boundaries
|
||||
#define MI_ARENA_MIN_OBJ_SLICES (1)
|
||||
#define MI_ARENA_MAX_OBJ_SLICES (MI_SIZE_BITS) // for now, cannot cross bit field boundaries.. todo: make it at least MI_BITMAP_CHUNK_BITS ? (16 MiB)
|
||||
// #define MI_ARENA_MAX_OBJ_BLOCKS (MI_BITMAP_CHUNK_BITS) // for now, cannot cross chunk boundaries
|
||||
|
||||
#define MI_ARENA_MIN_OBJ_SIZE (MI_ARENA_MIN_OBJ_BLOCKS * MI_ARENA_SLICE_SIZE)
|
||||
#define MI_ARENA_MAX_OBJ_SIZE (MI_ARENA_MAX_OBJ_BLOCKS * MI_ARENA_SLICE_SIZE)
|
||||
#define MI_ARENA_MIN_OBJ_SIZE (MI_ARENA_MIN_OBJ_SLICES * MI_ARENA_SLICE_SIZE)
|
||||
#define MI_ARENA_MAX_OBJ_SIZE (MI_ARENA_MAX_OBJ_SLICES * MI_ARENA_SLICE_SIZE)
|
||||
|
||||
#define MI_SMALL_PAGE_SIZE MI_ARENA_MIN_OBJ_SIZE
|
||||
#define MI_MEDIUM_PAGE_SIZE (8*MI_SMALL_PAGE_SIZE) // 512 KiB (=byte in the bitmap)
|
||||
|
@ -144,9 +145,6 @@ terms of the MIT license. A copy of the license can be found in the file
|
|||
#define MI_BIN_COUNT (MI_BIN_FULL+1)
|
||||
|
||||
|
||||
// Alignments over MI_BLOCK_ALIGNMENT_MAX are allocated in singleton pages
|
||||
#define MI_BLOCK_ALIGNMENT_MAX (MI_ARENA_SLICE_ALIGN)
|
||||
|
||||
// We never allocate more than PTRDIFF_MAX (see also <https://sourceware.org/ml/libc-announce/2019/msg00001.html>)
|
||||
#define MI_MAX_ALLOC_SIZE PTRDIFF_MAX
|
||||
|
||||
|
@ -318,8 +316,10 @@ typedef struct mi_page_s {
|
|||
// Object sizes
|
||||
// ------------------------------------------------------
|
||||
|
||||
#define MI_PAGE_ALIGN (64)
|
||||
#define MI_PAGE_INFO_SIZE (2*MI_PAGE_ALIGN) // should be > sizeof(mi_page_t)
|
||||
#define MI_PAGE_ALIGN MI_ARENA_SLICE_ALIGN // pages must be aligned on this for the page map.
|
||||
#define MI_PAGE_MIN_BLOCK_ALIGN (32) // minimal block alignment in a page
|
||||
#define MI_PAGE_MAX_OVERALLOC_ALIGN MI_ARENA_SLICE_SIZE // (64 KiB) limit for which we overallocate in arena pages, beyond this use OS allocation
|
||||
#define MI_PAGE_INFO_SIZE ((MI_INTPTR_SHIFT+1)*MI_PAGE_MIN_BLOCK_ALIGN) // >= sizeof(mi_page_t)
|
||||
|
||||
// The max object size are checked to not waste more than 12.5% internally over the page sizes.
|
||||
// (Except for large pages since huge objects are allocated in 4MiB chunks)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue