| 3687 | } |
| 3688 | |
| 3689 | JEMALLOC_ALWAYS_INLINE size_t |
| 3690 | ixallocx_prof(tsd_t *tsd, void *ptr, size_t old_usize, size_t size, |
| 3691 | size_t extra, size_t alignment, bool zero, emap_alloc_ctx_t *alloc_ctx) { |
| 3692 | /* |
| 3693 | * old_prof_info is only used for asserting that the profiling info |
| 3694 | * isn't changed by the ixalloc() call. |
| 3695 | */ |
| 3696 | prof_info_t old_prof_info; |
| 3697 | prof_info_get(tsd, ptr, alloc_ctx, &old_prof_info); |
| 3698 | |
| 3699 | /* |
| 3700 | * usize isn't knowable before ixalloc() returns when extra is non-zero. |
| 3701 | * Therefore, compute its maximum possible value and use that in |
| 3702 | * prof_alloc_prep() to decide whether to capture a backtrace. |
| 3703 | * prof_realloc() will use the actual usize to decide whether to sample. |
| 3704 | */ |
| 3705 | size_t usize_max; |
| 3706 | if (aligned_usize_get(size + extra, alignment, &usize_max, NULL, |
| 3707 | false)) { |
| 3708 | /* |
| 3709 | * usize_max is out of range, and chances are that allocation |
| 3710 | * will fail, but use the maximum possible value and carry on |
| 3711 | * with prof_alloc_prep(), just in case allocation succeeds. |
| 3712 | */ |
| 3713 | usize_max = SC_LARGE_MAXCLASS; |
| 3714 | } |
| 3715 | bool prof_active = prof_active_get_unlocked(); |
| 3716 | bool sample_event = te_prof_sample_event_lookahead(tsd, usize_max); |
| 3717 | prof_tctx_t *tctx = prof_alloc_prep(tsd, prof_active, sample_event); |
| 3718 | |
| 3719 | size_t usize; |
| 3720 | if (unlikely((uintptr_t)tctx != (uintptr_t)1U)) { |
| 3721 | usize = ixallocx_prof_sample(tsd_tsdn(tsd), ptr, old_usize, |
| 3722 | size, extra, alignment, zero, tctx); |
| 3723 | } else { |
| 3724 | usize = ixallocx_helper(tsd_tsdn(tsd), ptr, old_usize, size, |
| 3725 | extra, alignment, zero); |
| 3726 | } |
| 3727 | |
| 3728 | /* |
| 3729 | * At this point we can still safely get the original profiling |
| 3730 | * information associated with the ptr, because (a) the edata_t object |
| 3731 | * associated with the ptr still lives and (b) the profiling info |
| 3732 | * fields are not touched. "(a)" is asserted in the outer je_xallocx() |
| 3733 | * function, and "(b)" is indirectly verified below by checking that |
| 3734 | * the alloc_tctx field is unchanged. |
| 3735 | */ |
| 3736 | prof_info_t prof_info; |
| 3737 | if (usize == old_usize) { |
| 3738 | prof_info_get(tsd, ptr, alloc_ctx, &prof_info); |
| 3739 | prof_alloc_rollback(tsd, tctx); |
| 3740 | } else { |
| 3741 | prof_info_get_and_reset_recent(tsd, ptr, alloc_ctx, &prof_info); |
| 3742 | assert(usize <= usize_max); |
| 3743 | sample_event = te_prof_sample_event_lookahead(tsd, usize); |
| 3744 | prof_realloc(tsd, ptr, size, usize, tctx, prof_active, ptr, |
| 3745 | old_usize, &prof_info, sample_event); |
| 3746 | } |
no test coverage detected