| 3387 | } |
| 3388 | |
| 3389 | JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW |
| 3390 | je_xallocx(void *ptr, size_t size, size_t extra, int flags) { |
| 3391 | tsd_t *tsd; |
| 3392 | size_t usize, old_usize; |
| 3393 | size_t alignment = MALLOCX_ALIGN_GET(flags); |
| 3394 | bool zero = flags & MALLOCX_ZERO; |
| 3395 | |
| 3396 | LOG("core.xallocx.entry", "ptr: %p, size: %zu, extra: %zu, " |
| 3397 | "flags: %d", ptr, size, extra, flags); |
| 3398 | |
| 3399 | assert(ptr != NULL); |
| 3400 | assert(size != 0); |
| 3401 | assert(SIZE_T_MAX - size >= extra); |
| 3402 | assert(malloc_initialized() || IS_INITIALIZER); |
| 3403 | tsd = tsd_fetch(); |
| 3404 | check_entry_exit_locking(tsd_tsdn(tsd)); |
| 3405 | |
| 3406 | alloc_ctx_t alloc_ctx; |
| 3407 | rtree_ctx_t *rtree_ctx = tsd_rtree_ctx(tsd); |
| 3408 | rtree_szind_slab_read(tsd_tsdn(tsd), &extents_rtree, rtree_ctx, |
| 3409 | (uintptr_t)ptr, true, &alloc_ctx.szind, &alloc_ctx.slab); |
| 3410 | assert(alloc_ctx.szind != SC_NSIZES); |
| 3411 | old_usize = sz_index2size(alloc_ctx.szind); |
| 3412 | assert(old_usize == isalloc(tsd_tsdn(tsd), ptr)); |
| 3413 | /* |
| 3414 | * The API explicitly absolves itself of protecting against (size + |
| 3415 | * extra) numerical overflow, but we may need to clamp extra to avoid |
| 3416 | * exceeding SC_LARGE_MAXCLASS. |
| 3417 | * |
| 3418 | * Ordinarily, size limit checking is handled deeper down, but here we |
| 3419 | * have to check as part of (size + extra) clamping, since we need the |
| 3420 | * clamped value in the above helper functions. |
| 3421 | */ |
| 3422 | if (unlikely(size > SC_LARGE_MAXCLASS)) { |
| 3423 | usize = old_usize; |
| 3424 | goto label_not_resized; |
| 3425 | } |
| 3426 | if (unlikely(SC_LARGE_MAXCLASS - size < extra)) { |
| 3427 | extra = SC_LARGE_MAXCLASS - size; |
| 3428 | } |
| 3429 | |
| 3430 | if (config_prof && opt_prof) { |
| 3431 | usize = ixallocx_prof(tsd, ptr, old_usize, size, extra, |
| 3432 | alignment, zero, &alloc_ctx); |
| 3433 | } else { |
| 3434 | usize = ixallocx_helper(tsd_tsdn(tsd), ptr, old_usize, size, |
| 3435 | extra, alignment, zero); |
| 3436 | } |
| 3437 | if (unlikely(usize == old_usize)) { |
| 3438 | goto label_not_resized; |
| 3439 | } |
| 3440 | |
| 3441 | if (config_stats) { |
| 3442 | *tsd_thread_allocatedp_get(tsd) += usize; |
| 3443 | *tsd_thread_deallocatedp_get(tsd) += old_usize; |
| 3444 | } |
| 3445 | label_not_resized: |
| 3446 | if (unlikely(!tsd_fast(tsd))) { |
nothing calls this directly
no test coverage detected