| 3484 | } |
| 3485 | |
| 3486 | JEMALLOC_EXPORT void JEMALLOC_NOTHROW |
| 3487 | je_dallocx(void *ptr, int flags) { |
| 3488 | LOG("core.dallocx.entry", "ptr: %p, flags: %d", ptr, flags); |
| 3489 | |
| 3490 | assert(ptr != NULL); |
| 3491 | assert(malloc_initialized() || IS_INITIALIZER); |
| 3492 | |
| 3493 | tsd_t *tsd = tsd_fetch(); |
| 3494 | bool fast = tsd_fast(tsd); |
| 3495 | check_entry_exit_locking(tsd_tsdn(tsd)); |
| 3496 | |
| 3497 | tcache_t *tcache; |
| 3498 | if (unlikely((flags & MALLOCX_TCACHE_MASK) != 0)) { |
| 3499 | /* Not allowed to be reentrant and specify a custom tcache. */ |
| 3500 | assert(tsd_reentrancy_level_get(tsd) == 0); |
| 3501 | if ((flags & MALLOCX_TCACHE_MASK) == MALLOCX_TCACHE_NONE) { |
| 3502 | tcache = NULL; |
| 3503 | } else { |
| 3504 | tcache = tcaches_get(tsd, MALLOCX_TCACHE_GET(flags)); |
| 3505 | } |
| 3506 | } else { |
| 3507 | if (likely(fast)) { |
| 3508 | tcache = tsd_tcachep_get(tsd); |
| 3509 | assert(tcache == tcache_get(tsd)); |
| 3510 | } else { |
| 3511 | if (likely(tsd_reentrancy_level_get(tsd) == 0)) { |
| 3512 | tcache = tcache_get(tsd); |
| 3513 | } else { |
| 3514 | tcache = NULL; |
| 3515 | } |
| 3516 | } |
| 3517 | } |
| 3518 | |
| 3519 | UTRACE(ptr, 0, 0); |
| 3520 | if (likely(fast)) { |
| 3521 | tsd_assert_fast(tsd); |
| 3522 | ifree(tsd, ptr, tcache, false); |
| 3523 | } else { |
| 3524 | uintptr_t args_raw[3] = {(uintptr_t)ptr, flags}; |
| 3525 | hook_invoke_dalloc(hook_dalloc_dallocx, ptr, args_raw); |
| 3526 | ifree(tsd, ptr, tcache, true); |
| 3527 | } |
| 3528 | check_entry_exit_locking(tsd_tsdn(tsd)); |
| 3529 | |
| 3530 | LOG("core.dallocx.exit", ""); |
| 3531 | } |
| 3532 | |
| 3533 | JEMALLOC_ALWAYS_INLINE size_t |
| 3534 | inallocx(tsdn_t *tsdn, size_t size, int flags) { |
nothing calls this directly
no test coverage detected