mirror of
https://github.com/microsoft/mimalloc.git
synced 2025-05-05 06:59:32 +03:00
fix eager commit on large pages (issue #182)
This commit is contained in:
parent
1b5a08cd25
commit
9629a0190f
1 changed files with 7 additions and 7 deletions
14
src/alloc.c
14
src/alloc.c
|
@ -125,7 +125,7 @@ mi_decl_allocator void* mi_zalloc(size_t size) mi_attr_noexcept {
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------
|
// ------------------------------------------------------
|
||||||
// Check for double free in secure and debug mode
|
// Check for double free in secure and debug mode
|
||||||
// This is somewhat expensive so only enabled for secure mode 4
|
// This is somewhat expensive so only enabled for secure mode 4
|
||||||
// ------------------------------------------------------
|
// ------------------------------------------------------
|
||||||
|
|
||||||
|
@ -139,12 +139,12 @@ static bool mi_list_contains(const mi_page_t* page, const mi_block_t* list, cons
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static mi_decl_noinline bool mi_check_is_double_freex(const mi_page_t* page, const mi_block_t* block, const mi_block_t* n) {
|
static mi_decl_noinline bool mi_check_is_double_freex(const mi_page_t* page, const mi_block_t* block) {
|
||||||
// The decoded value is in the same page (or NULL).
|
// The decoded value is in the same page (or NULL).
|
||||||
// Walk the free lists to verify positively if it is already freed
|
// Walk the free lists to verify positively if it is already freed
|
||||||
if (mi_list_contains(page, page->free, block) ||
|
if (mi_list_contains(page, page->free, block) ||
|
||||||
mi_list_contains(page, page->local_free, block) ||
|
mi_list_contains(page, page->local_free, block) ||
|
||||||
mi_list_contains(page, (const mi_block_t*)mi_atomic_read_ptr_relaxed(mi_atomic_cast(void*,&page->thread_free)), block))
|
mi_list_contains(page, (const mi_block_t*)mi_atomic_read_ptr_relaxed(mi_atomic_cast(void*,&page->thread_free)), block))
|
||||||
{
|
{
|
||||||
_mi_fatal_error("double free detected of block %p with size %zu\n", block, page->block_size);
|
_mi_fatal_error("double free detected of block %p with size %zu\n", block, page->block_size);
|
||||||
return true;
|
return true;
|
||||||
|
@ -156,11 +156,11 @@ static inline bool mi_check_is_double_free(const mi_page_t* page, const mi_block
|
||||||
mi_block_t* n = mi_block_nextx(page, block, page->key[0], page->key[1]); // pretend it is freed, and get the decoded first field
|
mi_block_t* n = mi_block_nextx(page, block, page->key[0], page->key[1]); // pretend it is freed, and get the decoded first field
|
||||||
if (((uintptr_t)n & (MI_INTPTR_SIZE-1))==0 && // quick check: aligned pointer?
|
if (((uintptr_t)n & (MI_INTPTR_SIZE-1))==0 && // quick check: aligned pointer?
|
||||||
(n==NULL || mi_is_in_same_page(block, n))) // quick check: in same page or NULL?
|
(n==NULL || mi_is_in_same_page(block, n))) // quick check: in same page or NULL?
|
||||||
{
|
{
|
||||||
// Suspicous: decoded value a in block is in the same page (or NULL) -- maybe a double free?
|
// Suspicous: decoded value a in block is in the same page (or NULL) -- maybe a double free?
|
||||||
// (continue in separate function to improve code generation)
|
// (continue in separate function to improve code generation)
|
||||||
return mi_check_is_double_freex(page, block, n);
|
return mi_check_is_double_freex(page, block);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -337,7 +337,7 @@ void mi_free(void* p) mi_attr_noexcept
|
||||||
if (mi_likely(tid == segment->thread_id && page->flags.full_aligned == 0)) { // the thread id matches and it is not a full page, nor has aligned blocks
|
if (mi_likely(tid == segment->thread_id && page->flags.full_aligned == 0)) { // the thread id matches and it is not a full page, nor has aligned blocks
|
||||||
// local, and not full or aligned
|
// local, and not full or aligned
|
||||||
mi_block_t* block = (mi_block_t*)p;
|
mi_block_t* block = (mi_block_t*)p;
|
||||||
if (mi_unlikely(mi_check_is_double_free(page,block))) return;
|
if (mi_unlikely(mi_check_is_double_free(page,block))) return;
|
||||||
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;
|
||||||
page->used--;
|
page->used--;
|
||||||
|
|
Loading…
Add table
Reference in a new issue