MCPcopy Create free account
hub / github.com/CppCXY/EmmyLuaCodeStyle / mi_checked_ptr_segment

Function mi_checked_ptr_segment

3rd/mimalloc-2.0.9/src/alloc.c:492–567  ·  view source on GitHub ↗

Get the segment data belonging to a pointer This is just a single `and` in assembly but does further checks in debug mode (and secure mode) if this was a valid pointer.

Source from the content-addressed store, hash-verified

490// This is just a single `and` in assembly but does further checks in debug mode
491// (and secure mode) if this was a valid pointer.
492static inline mi_segment_t* mi_checked_ptr_segment(const void* p, const char* msg)
493{
494 MI_UNUSED(msg);
495 mi_assert(p != NULL);
496
497#if (MI_DEBUG>0)
498 if mi_unlikely(((uintptr_t)p & (MI_INTPTR_SIZE - 1)) != 0) {
499 _mi_error_message(EINVAL, "%s: invalid (unaligned) pointer: %p\n", msg, p);
500 return NULL;
501 }
502#endif
503
504 mi_segment_t* const segment = _mi_ptr_segment(p);
505 mi_assert_internal(segment != NULL);
506
507#if (MI_DEBUG>0)
508 if mi_unlikely(!mi_is_in_heap_region(p)) {
509 #if (MI_INTPTR_SIZE == 8 && defined(__linux__))
510 if (((uintptr_t)p >> 40) != 0x7F) { // linux tends to align large blocks above 0x7F000000000 (issue #640)
511 #else
512 {
513 #endif
514 _mi_warning_message("%s: pointer might not point to a valid heap region: %p\n"
515 "(this may still be a valid very large allocation (over 64MiB))\n", msg, p);
516 if mi_likely(_mi_ptr_cookie(segment) == segment->cookie) {
517 _mi_warning_message("(yes, the previous pointer %p was valid after all)\n", p);
518 }
519 }
520 }
521#endif
522#if (MI_DEBUG>0 || MI_SECURE>=4)
523 if mi_unlikely(_mi_ptr_cookie(segment) != segment->cookie) {
524 _mi_error_message(EINVAL, "%s: pointer does not point to a valid heap space: %p\n", msg, p);
525 return NULL;
526 }
527#endif
528
529 return segment;
530}
531
532// Free a block
533// fast path written carefully to prevent spilling on the stack
534void mi_free(void* p) mi_attr_noexcept
535{
536 if mi_unlikely(p == NULL) return;
537 mi_segment_t* const segment = mi_checked_ptr_segment(p,"mi_free");
538 const bool is_local= (_mi_thread_id() == mi_atomic_load_relaxed(&segment->thread_id));
539 mi_page_t* const page = _mi_segment_page_of(segment, p);
540
541 if mi_likely(is_local) { // thread-local free?
542 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)
543 {
544 mi_block_t* const block = (mi_block_t*)p;
545 if mi_unlikely(mi_check_is_double_free(page, block)) return;
546 mi_check_padding(page, block);
547 mi_stat_free(page, block);
548 #if (MI_DEBUG!=0) && !MI_TRACK_ENABLED
549 memset(block, MI_DEBUG_FREED, mi_page_block_size(page));

Callers 2

mi_freeFunction · 0.85
_mi_usable_sizeFunction · 0.85

Calls 7

mi_unlikelyFunction · 0.85
_mi_error_messageFunction · 0.85
_mi_ptr_segmentFunction · 0.85
_mi_warning_messageFunction · 0.85
_mi_ptr_cookieFunction · 0.85
_mi_free_genericFunction · 0.85
mi_is_in_heap_regionFunction · 0.70

Tested by

no test coverage detected