| 3750 | } |
| 3751 | |
| 3752 | JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW |
| 3753 | je_xallocx(void *ptr, size_t size, size_t extra, int flags) { |
| 3754 | tsd_t *tsd; |
| 3755 | size_t usize, old_usize; |
| 3756 | size_t alignment = MALLOCX_ALIGN_GET(flags); |
| 3757 | bool zero = zero_get(MALLOCX_ZERO_GET(flags), /* slow */ true); |
| 3758 | |
| 3759 | LOG("core.xallocx.entry", "ptr: %p, size: %zu, extra: %zu, " |
| 3760 | "flags: %d", ptr, size, extra, flags); |
| 3761 | |
| 3762 | assert(ptr != NULL); |
| 3763 | assert(size != 0); |
| 3764 | assert(SIZE_T_MAX - size >= extra); |
| 3765 | assert(malloc_initialized() || IS_INITIALIZER); |
| 3766 | tsd = tsd_fetch(); |
| 3767 | check_entry_exit_locking(tsd_tsdn(tsd)); |
| 3768 | |
| 3769 | /* |
| 3770 | * old_edata is only for verifying that xallocx() keeps the edata_t |
| 3771 | * object associated with the ptr (though the content of the edata_t |
| 3772 | * object can be changed). |
| 3773 | */ |
| 3774 | edata_t *old_edata = emap_edata_lookup(tsd_tsdn(tsd), |
| 3775 | &arena_emap_global, ptr); |
| 3776 | |
| 3777 | emap_alloc_ctx_t alloc_ctx; |
| 3778 | emap_alloc_ctx_lookup(tsd_tsdn(tsd), &arena_emap_global, ptr, |
| 3779 | &alloc_ctx); |
| 3780 | assert(alloc_ctx.szind != SC_NSIZES); |
| 3781 | old_usize = sz_index2size(alloc_ctx.szind); |
| 3782 | assert(old_usize == isalloc(tsd_tsdn(tsd), ptr)); |
| 3783 | /* |
| 3784 | * The API explicitly absolves itself of protecting against (size + |
| 3785 | * extra) numerical overflow, but we may need to clamp extra to avoid |
| 3786 | * exceeding SC_LARGE_MAXCLASS. |
| 3787 | * |
| 3788 | * Ordinarily, size limit checking is handled deeper down, but here we |
| 3789 | * have to check as part of (size + extra) clamping, since we need the |
| 3790 | * clamped value in the above helper functions. |
| 3791 | */ |
| 3792 | if (unlikely(size > SC_LARGE_MAXCLASS)) { |
| 3793 | usize = old_usize; |
| 3794 | goto label_not_resized; |
| 3795 | } |
| 3796 | if (unlikely(SC_LARGE_MAXCLASS - size < extra)) { |
| 3797 | extra = SC_LARGE_MAXCLASS - size; |
| 3798 | } |
| 3799 | |
| 3800 | if (config_prof && opt_prof) { |
| 3801 | usize = ixallocx_prof(tsd, ptr, old_usize, size, extra, |
| 3802 | alignment, zero, &alloc_ctx); |
| 3803 | } else { |
| 3804 | usize = ixallocx_helper(tsd_tsdn(tsd), ptr, old_usize, size, |
| 3805 | extra, alignment, zero); |
| 3806 | } |
| 3807 | |
| 3808 | /* |
| 3809 | * xallocx() should keep using the same edata_t object (though its |
nothing calls this directly
no test coverage detected