fix compilation warnings for new uint16_t size for used field
This commit is contained in:
parent
9085596eab
commit
60c4a0fe56
53
src/free.c
53
src/free.c
@ -6,6 +6,11 @@ terms of the MIT license. A copy of the license can be found in the file
|
|||||||
-----------------------------------------------------------------------------*/
|
-----------------------------------------------------------------------------*/
|
||||||
#if !defined(MI_IN_ALLOC_C)
|
#if !defined(MI_IN_ALLOC_C)
|
||||||
#error "this file should be included from 'alloc.c' (so aliases can work from alloc-override)"
|
#error "this file should be included from 'alloc.c' (so aliases can work from alloc-override)"
|
||||||
|
// add includes help an IDE
|
||||||
|
#include "mimalloc.h"
|
||||||
|
#include "mimalloc/internal.h"
|
||||||
|
#include "mimalloc/atomic.h"
|
||||||
|
#include "mimalloc/prim.h" // _mi_prim_thread_id()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// forward declarations
|
// forward declarations
|
||||||
@ -26,7 +31,7 @@ static mi_decl_noinline void mi_free_block_mt(mi_segment_t* segment, mi_page_t*
|
|||||||
// fast path written carefully to prevent spilling on the stack
|
// fast path written carefully to prevent spilling on the stack
|
||||||
static inline void mi_free_block_local(mi_page_t* page, mi_block_t* block, bool check_full)
|
static inline void mi_free_block_local(mi_page_t* page, mi_block_t* block, bool check_full)
|
||||||
{
|
{
|
||||||
// owning thread can free a block directly
|
// checks
|
||||||
if mi_unlikely(mi_check_is_double_free(page, block)) return;
|
if mi_unlikely(mi_check_is_double_free(page, block)) return;
|
||||||
mi_check_padding(page, block);
|
mi_check_padding(page, block);
|
||||||
mi_stat_free(page, block);
|
mi_stat_free(page, block);
|
||||||
@ -34,11 +39,11 @@ static inline void mi_free_block_local(mi_page_t* page, mi_block_t* block, bool
|
|||||||
memset(block, MI_DEBUG_FREED, mi_page_block_size(page));
|
memset(block, MI_DEBUG_FREED, mi_page_block_size(page));
|
||||||
#endif
|
#endif
|
||||||
mi_track_free_size(p, mi_page_usable_size_of(page,block)); // faster then mi_usable_size as we already know the page and that p is unaligned
|
mi_track_free_size(p, mi_page_usable_size_of(page,block)); // faster then mi_usable_size as we already know the page and that p is unaligned
|
||||||
|
|
||||||
|
// actual free: push on the local free list
|
||||||
mi_block_set_next(page, block, page->local_free);
|
mi_block_set_next(page, block, page->local_free);
|
||||||
page->local_free = block;
|
page->local_free = block;
|
||||||
const uint32_t used = page->used - 1;
|
if mi_unlikely(--page->used == 0) {
|
||||||
page->used = used;
|
|
||||||
if mi_unlikely(used == 0) { // generates better code than: --page->used == 0
|
|
||||||
_mi_page_retire(page);
|
_mi_page_retire(page);
|
||||||
}
|
}
|
||||||
else if mi_unlikely(check_full && mi_page_is_in_full(page)) {
|
else if mi_unlikely(check_full && mi_page_is_in_full(page)) {
|
||||||
@ -49,32 +54,42 @@ static inline void mi_free_block_local(mi_page_t* page, mi_block_t* block, bool
|
|||||||
// Adjust a block that was allocated aligned, to the actual start of the block in the page.
|
// Adjust a block that was allocated aligned, to the actual start of the block in the page.
|
||||||
mi_block_t* _mi_page_ptr_unalign(const mi_segment_t* segment, const mi_page_t* page, const void* p) {
|
mi_block_t* _mi_page_ptr_unalign(const mi_segment_t* segment, const mi_page_t* page, const void* p) {
|
||||||
mi_assert_internal(page!=NULL && p!=NULL);
|
mi_assert_internal(page!=NULL && p!=NULL);
|
||||||
const size_t diff = (mi_likely(page->block_offset_adj != 0)
|
|
||||||
? (uint8_t*)p - (uint8_t*)page - 8*(page->block_offset_adj-1)
|
|
||||||
: (uint8_t*)p - _mi_page_start(segment, page, NULL));
|
|
||||||
|
|
||||||
const size_t adjust = (mi_likely(page->block_size_shift != 0)
|
size_t diff;
|
||||||
? diff & (((size_t)1 << page->block_size_shift) - 1)
|
if mi_likely(page->block_offset_adj != 0) {
|
||||||
: diff % mi_page_block_size(page));
|
diff = (uint8_t*)p - (uint8_t*)page - 8 * (page->block_offset_adj - 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
diff = (uint8_t*)p - _mi_page_start(segment, page, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t adjust;
|
||||||
|
if mi_likely(page->block_size_shift != 0) {
|
||||||
|
adjust = diff & (((size_t)1 << page->block_size_shift) - 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
adjust = diff % mi_page_block_size(page);
|
||||||
|
}
|
||||||
|
|
||||||
return (mi_block_t*)((uintptr_t)p - adjust);
|
return (mi_block_t*)((uintptr_t)p - adjust);
|
||||||
}
|
}
|
||||||
|
|
||||||
// free a local pointer
|
// free a local pointer (page parameter comes first for better codegen)
|
||||||
static void mi_decl_noinline mi_free_generic_local(mi_segment_t* segment, mi_page_t* page, void* p) mi_attr_noexcept {
|
static void mi_decl_noinline mi_free_generic_local(mi_page_t* page, mi_segment_t* segment, void* p) mi_attr_noexcept {
|
||||||
mi_block_t* const block = (mi_page_has_aligned(page) ? _mi_page_ptr_unalign(segment, page, p) : (mi_block_t*)p);
|
mi_block_t* const block = (mi_page_has_aligned(page) ? _mi_page_ptr_unalign(segment, page, p) : (mi_block_t*)p);
|
||||||
mi_free_block_local(page, block, true);
|
mi_free_block_local(page, block, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// free a pointer owned by another thread
|
// free a pointer owned by another thread (page parameter comes first for better codegen)
|
||||||
static void mi_decl_noinline mi_free_generic_mt(mi_segment_t* segment, mi_page_t* page, void* p) mi_attr_noexcept {
|
static void mi_decl_noinline mi_free_generic_mt(mi_page_t* page, mi_segment_t* segment, void* p) mi_attr_noexcept {
|
||||||
mi_block_t* const block = _mi_page_ptr_unalign(segment, page, p); // don't check `has_aligned` flag to avoid a race (issue #865)
|
mi_block_t* const block = _mi_page_ptr_unalign(segment, page, p); // don't check `has_aligned` flag to avoid a race (issue #865)
|
||||||
mi_free_block_mt(segment, page, block);
|
mi_free_block_mt(segment, page, block);
|
||||||
}
|
}
|
||||||
|
|
||||||
// generic free (for runtime integration)
|
// generic free (for runtime integration)
|
||||||
void mi_decl_noinline _mi_free_generic(mi_segment_t* segment, mi_page_t* page, bool is_local, void* p) mi_attr_noexcept {
|
void mi_decl_noinline _mi_free_generic(mi_segment_t* segment, mi_page_t* page, bool is_local, void* p) mi_attr_noexcept {
|
||||||
if (is_local) mi_free_generic_local(segment,page,p);
|
if (is_local) mi_free_generic_local(page,segment,p);
|
||||||
else mi_free_generic_mt(segment,page,p);
|
else mi_free_generic_mt(page,segment,p);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the segment data belonging to a pointer
|
// Get the segment data belonging to a pointer
|
||||||
@ -127,16 +142,16 @@ void mi_free(void* p) mi_attr_noexcept
|
|||||||
if mi_likely(page->flags.full_aligned == 0) { // and it is not a full page (full pages need to move from the full bin), nor has aligned blocks (aligned blocks need to be unaligned)
|
if mi_likely(page->flags.full_aligned == 0) { // and it is not a full page (full pages need to move from the full bin), nor has aligned blocks (aligned blocks need to be unaligned)
|
||||||
// thread-local, aligned, and not a full page
|
// thread-local, aligned, and not a full page
|
||||||
mi_block_t* const block = (mi_block_t*)p;
|
mi_block_t* const block = (mi_block_t*)p;
|
||||||
mi_free_block_local(page,block,false /* no need to check if the page is full */);
|
mi_free_block_local(page, block, false /* no need to check if the page is full */);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// page is full or contains (inner) aligned blocks; use generic path
|
// page is full or contains (inner) aligned blocks; use generic path
|
||||||
mi_free_generic_local(segment, page, p);
|
mi_free_generic_local(page, segment, p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// not thread-local; use generic path
|
// not thread-local; use generic path
|
||||||
mi_free_generic_mt(segment, page, p);
|
mi_free_generic_mt(page, segment, p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,8 +192,8 @@ static void _mi_page_thread_free_collect(mi_page_t* page)
|
|||||||
if (head == NULL) return;
|
if (head == NULL) return;
|
||||||
|
|
||||||
// find the tail -- also to get a proper count (without data races)
|
// find the tail -- also to get a proper count (without data races)
|
||||||
uint32_t max_count = page->capacity; // cannot collect more than capacity
|
size_t max_count = page->capacity; // cannot collect more than capacity
|
||||||
uint32_t count = 1;
|
size_t count = 1;
|
||||||
mi_block_t* tail = head;
|
mi_block_t* tail = head;
|
||||||
mi_block_t* next;
|
mi_block_t* next;
|
||||||
while ((next = mi_block_next(page,tail)) != NULL && count <= max_count) {
|
while ((next = mi_block_next(page,tail)) != NULL && count <= max_count) {
|
||||||
@ -211,7 +211,7 @@ static void _mi_page_thread_free_collect(mi_page_t* page)
|
|||||||
page->local_free = head;
|
page->local_free = head;
|
||||||
|
|
||||||
// update counts now
|
// update counts now
|
||||||
page->used -= count;
|
page->used -= (uint16_t)count;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _mi_page_free_collect(mi_page_t* page, bool force) {
|
void _mi_page_free_collect(mi_page_t* page, bool force) {
|
||||||
@ -677,7 +677,7 @@ static void mi_page_init(mi_heap_t* heap, mi_page_t* page, size_t block_size, mi
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (_mi_is_power_of_two(block_size) && block_size > 0) {
|
if (_mi_is_power_of_two(block_size) && block_size > 0) {
|
||||||
page->block_size_shift = (uint32_t)(mi_ctz((uintptr_t)block_size));
|
page->block_size_shift = (uint8_t)(mi_ctz((uintptr_t)block_size));
|
||||||
}
|
}
|
||||||
const ptrdiff_t start_offset = (uint8_t*)page_start - (uint8_t*)page;
|
const ptrdiff_t start_offset = (uint8_t*)page_start - (uint8_t*)page;
|
||||||
const ptrdiff_t start_adjust = start_offset % block_size;
|
const ptrdiff_t start_adjust = start_offset % block_size;
|
||||||
|
Loading…
Reference in New Issue
Block a user