Change structs use when freeing to avoid using index2size for large sizes.

1. Change the definition of emap_alloc_ctx_t
2. Change the read of both from edata_t.
3. Change the assignment and usage of emap_alloc_ctx_t.
4. Change other callsites of index2size.

Note for the changes in the data structure, i.e., emap_alloc_ctx_t,
will be used when the build-time config (--enable-limit-usize-gap) is
enabled but they will store the same value as index2size(szind) if the
runtime option (opt_limit_usize_gap) is not enabled.
This commit is contained in:
guangli-dai 2024-04-01 16:49:34 -07:00 committed by Guangli Dai
parent 96b15d5d43
commit d01d5b8f4a
9 changed files with 167 additions and 42 deletions

View file

@ -822,7 +822,7 @@ arena_reset(tsd_t *tsd, arena_t *arena) {
assert(alloc_ctx.szind != SC_NSIZES);
if (config_stats || (config_prof && opt_prof)) {
usize = sz_index2size(alloc_ctx.szind);
usize = emap_alloc_ctx_usize_get(&alloc_ctx);
assert(usize == isalloc(tsd_tsdn(tsd), ptr));
}
/* Remove large allocation from prof sample set. */
@ -1366,7 +1366,9 @@ arena_malloc_hard(tsdn_t *tsdn, arena_t *arena, size_t size, szind_t ind,
assert(sz_can_use_slab(size));
return arena_malloc_small(tsdn, arena, ind, zero);
} else {
return large_malloc(tsdn, arena, sz_index2size(ind), zero);
size_t usize = sz_limit_usize_gap_enabled()? sz_s2u(size):
sz_index2size(ind);
return large_malloc(tsdn, arena, usize, zero);
}
}

View file

@ -73,6 +73,11 @@ emap_try_acquire_edata_neighbor_impl(tsdn_t *tsdn, emap_t *emap, edata_t *edata,
return NULL;
}
/*
* Info in neighbor_contents may be inaccurate before
* extent_can_acquire_neighbor below confirms the neighbor can be
* acquired. Set dependent to false to avoid reading usize.
*/
rtree_contents_t neighbor_contents = rtree_leaf_elm_read(tsdn,
&emap->rtree, elm, /* dependent */ false);
if (!extent_can_acquire_neighbor(edata, neighbor_contents, pai,

View file

@ -2203,6 +2203,7 @@ malloc_init_hard(void) {
if (config_limit_usize_gap) {
assert(TCACHE_MAXCLASS_LIMIT <= USIZE_GROW_SLOW_THRESHOLD);
assert(SC_LOOKUP_MAXCLASS <= USIZE_GROW_SLOW_THRESHOLD);
}
#if defined(_WIN32) && _WIN32_WINNT < 0x0600
_init_init_lock();
@ -2384,7 +2385,8 @@ aligned_usize_get(size_t size, size_t alignment, size_t *usize, szind_t *ind,
if (unlikely(*ind >= SC_NSIZES)) {
return true;
}
*usize = sz_index2size(*ind);
*usize = sz_limit_usize_gap_enabled()? sz_s2u(size):
sz_index2size(*ind);
assert(*usize > 0 && *usize <= SC_LARGE_MAXCLASS);
return false;
}
@ -2932,7 +2934,7 @@ ifree(tsd_t *tsd, void *ptr, tcache_t *tcache, bool slow_path) {
&alloc_ctx);
assert(alloc_ctx.szind != SC_NSIZES);
size_t usize = sz_index2size(alloc_ctx.szind);
size_t usize = emap_alloc_ctx_usize_get(&alloc_ctx);
if (config_prof && opt_prof) {
prof_free(tsd, ptr, usize, &alloc_ctx);
}
@ -2964,35 +2966,38 @@ isfree(tsd_t *tsd, void *ptr, size_t usize, tcache_t *tcache, bool slow_path) {
assert(malloc_initialized() || IS_INITIALIZER);
emap_alloc_ctx_t alloc_ctx;
szind_t szind = sz_size2index(usize);
if (!config_prof) {
alloc_ctx.szind = sz_size2index(usize);
alloc_ctx.slab = (alloc_ctx.szind < SC_NBINS);
emap_alloc_ctx_set(&alloc_ctx, szind, (szind < SC_NBINS),
usize);
} else {
if (likely(!prof_sample_aligned(ptr))) {
/*
* When the ptr is not page aligned, it was not sampled.
* usize can be trusted to determine szind and slab.
*/
alloc_ctx.szind = sz_size2index(usize);
alloc_ctx.slab = (alloc_ctx.szind < SC_NBINS);
emap_alloc_ctx_set(&alloc_ctx, szind,
(szind < SC_NBINS), usize);
} else if (opt_prof) {
emap_alloc_ctx_lookup(tsd_tsdn(tsd), &arena_emap_global,
ptr, &alloc_ctx);
if (config_opt_safety_checks) {
/* Small alloc may have !slab (sampled). */
size_t true_size =
emap_alloc_ctx_usize_get(&alloc_ctx);
if (unlikely(alloc_ctx.szind !=
sz_size2index(usize))) {
safety_check_fail_sized_dealloc(
/* current_dealloc */ true, ptr,
/* true_size */ sz_index2size(
alloc_ctx.szind),
/* true_size */ true_size,
/* input_size */ usize);
}
}
} else {
alloc_ctx.szind = sz_size2index(usize);
alloc_ctx.slab = (alloc_ctx.szind < SC_NBINS);
szind_t szind = sz_size2index(usize);
emap_alloc_ctx_set(&alloc_ctx, szind,
(szind < SC_NBINS), usize);
}
}
bool fail = maybe_check_alloc_ctx(tsd, ptr, &alloc_ctx);
@ -3494,7 +3499,7 @@ do_rallocx(void *ptr, size_t size, int flags, bool is_realloc) {
emap_alloc_ctx_lookup(tsd_tsdn(tsd), &arena_emap_global, ptr,
&alloc_ctx);
assert(alloc_ctx.szind != SC_NSIZES);
old_usize = sz_index2size(alloc_ctx.szind);
old_usize = emap_alloc_ctx_usize_get(&alloc_ctx);
assert(old_usize == isalloc(tsd_tsdn(tsd), ptr));
if (aligned_usize_get(size, alignment, &usize, NULL, false)) {
goto label_oom;
@ -3716,7 +3721,15 @@ ixallocx_prof(tsd_t *tsd, void *ptr, size_t old_usize, size_t size,
prof_info_get(tsd, ptr, alloc_ctx, &prof_info);
prof_alloc_rollback(tsd, tctx);
} else {
prof_info_get_and_reset_recent(tsd, ptr, alloc_ctx, &prof_info);
/*
* Need to retrieve the new alloc_ctx since the modification
* to edata has already been done.
*/
emap_alloc_ctx_t new_alloc_ctx;
emap_alloc_ctx_lookup(tsd_tsdn(tsd), &arena_emap_global, ptr,
&new_alloc_ctx);
prof_info_get_and_reset_recent(tsd, ptr, &new_alloc_ctx,
&prof_info);
assert(usize <= usize_max);
sample_event = te_prof_sample_event_lookahead(tsd, usize);
prof_realloc(tsd, ptr, size, usize, tctx, prof_active, ptr,
@ -3756,7 +3769,7 @@ je_xallocx(void *ptr, size_t size, size_t extra, int flags) {
emap_alloc_ctx_lookup(tsd_tsdn(tsd), &arena_emap_global, ptr,
&alloc_ctx);
assert(alloc_ctx.szind != SC_NSIZES);
old_usize = sz_index2size(alloc_ctx.szind);
old_usize = emap_alloc_ctx_usize_get(&alloc_ctx);
assert(old_usize == isalloc(tsd_tsdn(tsd), ptr));
/*
* The API explicitly absolves itself of protecting against (size +

View file

@ -1047,7 +1047,8 @@ tcache_bin_flush_impl_large(tsd_t *tsd, tcache_t *tcache, cache_bin_t *cache_bin
ndeferred++;
continue;
}
if (large_dalloc_safety_checks(edata, ptr, binind)) {
if (large_dalloc_safety_checks(edata, ptr,
sz_index2size(binind))) {
/* See the comment in isfree. */
continue;
}