Hooks: hook the realloc pathways that move/expand.
This commit is contained in:
committed by
David Goldblatt
parent
67270040a5
commit
cb0707c0fc
18
src/arena.c
18
src/arena.c
@@ -1630,7 +1630,8 @@ arena_ralloc_move_helper(tsdn_t *tsdn, arena_t *arena, size_t usize,
|
||||
|
||||
void *
|
||||
arena_ralloc(tsdn_t *tsdn, arena_t *arena, void *ptr, size_t oldsize,
|
||||
size_t size, size_t alignment, bool zero, tcache_t *tcache) {
|
||||
size_t size, size_t alignment, bool zero, tcache_t *tcache,
|
||||
hook_ralloc_args_t *hook_args) {
|
||||
size_t usize = sz_s2u(size);
|
||||
if (unlikely(usize == 0 || size > LARGE_MAXCLASS)) {
|
||||
return NULL;
|
||||
@@ -1639,13 +1640,17 @@ arena_ralloc(tsdn_t *tsdn, arena_t *arena, void *ptr, size_t oldsize,
|
||||
if (likely(usize <= SMALL_MAXCLASS)) {
|
||||
/* Try to avoid moving the allocation. */
|
||||
if (!arena_ralloc_no_move(tsdn, ptr, oldsize, usize, 0, zero)) {
|
||||
hook_invoke_expand(hook_args->is_realloc
|
||||
? hook_expand_realloc : hook_expand_rallocx,
|
||||
ptr, oldsize, usize, (uintptr_t)ptr,
|
||||
hook_args->args);
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (oldsize >= LARGE_MINCLASS && usize >= LARGE_MINCLASS) {
|
||||
return large_ralloc(tsdn, arena, iealloc(tsdn, ptr), usize,
|
||||
alignment, zero, tcache);
|
||||
return large_ralloc(tsdn, arena, ptr, usize,
|
||||
alignment, zero, tcache, hook_args);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1658,11 +1663,16 @@ arena_ralloc(tsdn_t *tsdn, arena_t *arena, void *ptr, size_t oldsize,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hook_invoke_alloc(hook_args->is_realloc
|
||||
? hook_alloc_realloc : hook_alloc_rallocx, ret, (uintptr_t)ret,
|
||||
hook_args->args);
|
||||
hook_invoke_dalloc(hook_args->is_realloc
|
||||
? hook_dalloc_realloc : hook_dalloc_rallocx, ptr, hook_args->args);
|
||||
|
||||
/*
|
||||
* Junk/zero-filling were already done by
|
||||
* ipalloc()/arena_malloc().
|
||||
*/
|
||||
|
||||
size_t copysize = (usize < oldsize) ? usize : oldsize;
|
||||
memcpy(ret, ptr, copysize);
|
||||
isdalloct(tsdn, ptr, oldsize, tcache, NULL, true);
|
||||
|
@@ -2169,20 +2169,22 @@ je_calloc(size_t num, size_t size) {
|
||||
|
||||
static void *
|
||||
irealloc_prof_sample(tsd_t *tsd, void *old_ptr, size_t old_usize, size_t usize,
|
||||
prof_tctx_t *tctx) {
|
||||
prof_tctx_t *tctx, hook_ralloc_args_t *hook_args) {
|
||||
void *p;
|
||||
|
||||
if (tctx == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (usize <= SMALL_MAXCLASS) {
|
||||
p = iralloc(tsd, old_ptr, old_usize, LARGE_MINCLASS, 0, false);
|
||||
p = iralloc(tsd, old_ptr, old_usize, LARGE_MINCLASS, 0, false,
|
||||
hook_args);
|
||||
if (p == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
arena_prof_promote(tsd_tsdn(tsd), p, usize);
|
||||
} else {
|
||||
p = iralloc(tsd, old_ptr, old_usize, usize, 0, false);
|
||||
p = iralloc(tsd, old_ptr, old_usize, usize, 0, false,
|
||||
hook_args);
|
||||
}
|
||||
|
||||
return p;
|
||||
@@ -2190,7 +2192,7 @@ irealloc_prof_sample(tsd_t *tsd, void *old_ptr, size_t old_usize, size_t usize,
|
||||
|
||||
JEMALLOC_ALWAYS_INLINE void *
|
||||
irealloc_prof(tsd_t *tsd, void *old_ptr, size_t old_usize, size_t usize,
|
||||
alloc_ctx_t *alloc_ctx) {
|
||||
alloc_ctx_t *alloc_ctx, hook_ralloc_args_t *hook_args) {
|
||||
void *p;
|
||||
bool prof_active;
|
||||
prof_tctx_t *old_tctx, *tctx;
|
||||
@@ -2199,9 +2201,11 @@ irealloc_prof(tsd_t *tsd, void *old_ptr, size_t old_usize, size_t usize,
|
||||
old_tctx = prof_tctx_get(tsd_tsdn(tsd), old_ptr, alloc_ctx);
|
||||
tctx = prof_alloc_prep(tsd, usize, prof_active, true);
|
||||
if (unlikely((uintptr_t)tctx != (uintptr_t)1U)) {
|
||||
p = irealloc_prof_sample(tsd, old_ptr, old_usize, usize, tctx);
|
||||
p = irealloc_prof_sample(tsd, old_ptr, old_usize, usize, tctx,
|
||||
hook_args);
|
||||
} else {
|
||||
p = iralloc(tsd, old_ptr, old_usize, usize, 0, false);
|
||||
p = iralloc(tsd, old_ptr, old_usize, usize, 0, false,
|
||||
hook_args);
|
||||
}
|
||||
if (unlikely(p == NULL)) {
|
||||
prof_alloc_rollback(tsd, tctx, true);
|
||||
@@ -2349,6 +2353,10 @@ je_realloc(void *ptr, size_t arg_size) {
|
||||
|
||||
check_entry_exit_locking(tsd_tsdn(tsd));
|
||||
|
||||
|
||||
hook_ralloc_args_t hook_args = {true, {(uintptr_t)ptr,
|
||||
(uintptr_t)arg_size, 0, 0}};
|
||||
|
||||
alloc_ctx_t alloc_ctx;
|
||||
rtree_ctx_t *rtree_ctx = tsd_rtree_ctx(tsd);
|
||||
rtree_szind_slab_read(tsd_tsdn(tsd), &extents_rtree, rtree_ctx,
|
||||
@@ -2362,13 +2370,14 @@ je_realloc(void *ptr, size_t arg_size) {
|
||||
ret = NULL;
|
||||
} else {
|
||||
ret = irealloc_prof(tsd, ptr, old_usize, usize,
|
||||
&alloc_ctx);
|
||||
&alloc_ctx, &hook_args);
|
||||
}
|
||||
} else {
|
||||
if (config_stats) {
|
||||
usize = sz_s2u(size);
|
||||
}
|
||||
ret = iralloc(tsd, ptr, old_usize, size, 0, false);
|
||||
ret = iralloc(tsd, ptr, old_usize, size, 0, false,
|
||||
&hook_args);
|
||||
}
|
||||
tsdn = tsd_tsdn(tsd);
|
||||
} else {
|
||||
@@ -2664,7 +2673,7 @@ je_mallocx(size_t size, int flags) {
|
||||
static void *
|
||||
irallocx_prof_sample(tsdn_t *tsdn, void *old_ptr, size_t old_usize,
|
||||
size_t usize, size_t alignment, bool zero, tcache_t *tcache, arena_t *arena,
|
||||
prof_tctx_t *tctx) {
|
||||
prof_tctx_t *tctx, hook_ralloc_args_t *hook_args) {
|
||||
void *p;
|
||||
|
||||
if (tctx == NULL) {
|
||||
@@ -2672,14 +2681,14 @@ irallocx_prof_sample(tsdn_t *tsdn, void *old_ptr, size_t old_usize,
|
||||
}
|
||||
if (usize <= SMALL_MAXCLASS) {
|
||||
p = iralloct(tsdn, old_ptr, old_usize, LARGE_MINCLASS,
|
||||
alignment, zero, tcache, arena);
|
||||
alignment, zero, tcache, arena, hook_args);
|
||||
if (p == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
arena_prof_promote(tsdn, p, usize);
|
||||
} else {
|
||||
p = iralloct(tsdn, old_ptr, old_usize, usize, alignment, zero,
|
||||
tcache, arena);
|
||||
tcache, arena, hook_args);
|
||||
}
|
||||
|
||||
return p;
|
||||
@@ -2688,7 +2697,7 @@ irallocx_prof_sample(tsdn_t *tsdn, void *old_ptr, size_t old_usize,
|
||||
JEMALLOC_ALWAYS_INLINE void *
|
||||
irallocx_prof(tsd_t *tsd, void *old_ptr, size_t old_usize, size_t size,
|
||||
size_t alignment, size_t *usize, bool zero, tcache_t *tcache,
|
||||
arena_t *arena, alloc_ctx_t *alloc_ctx) {
|
||||
arena_t *arena, alloc_ctx_t *alloc_ctx, hook_ralloc_args_t *hook_args) {
|
||||
void *p;
|
||||
bool prof_active;
|
||||
prof_tctx_t *old_tctx, *tctx;
|
||||
@@ -2698,10 +2707,10 @@ irallocx_prof(tsd_t *tsd, void *old_ptr, size_t old_usize, size_t size,
|
||||
tctx = prof_alloc_prep(tsd, *usize, prof_active, false);
|
||||
if (unlikely((uintptr_t)tctx != (uintptr_t)1U)) {
|
||||
p = irallocx_prof_sample(tsd_tsdn(tsd), old_ptr, old_usize,
|
||||
*usize, alignment, zero, tcache, arena, tctx);
|
||||
*usize, alignment, zero, tcache, arena, tctx, hook_args);
|
||||
} else {
|
||||
p = iralloct(tsd_tsdn(tsd), old_ptr, old_usize, size, alignment,
|
||||
zero, tcache, arena);
|
||||
zero, tcache, arena, hook_args);
|
||||
}
|
||||
if (unlikely(p == NULL)) {
|
||||
prof_alloc_rollback(tsd, tctx, false);
|
||||
@@ -2775,6 +2784,9 @@ je_rallocx(void *ptr, size_t size, int flags) {
|
||||
assert(alloc_ctx.szind != NSIZES);
|
||||
old_usize = sz_index2size(alloc_ctx.szind);
|
||||
assert(old_usize == isalloc(tsd_tsdn(tsd), ptr));
|
||||
|
||||
hook_ralloc_args_t hook_args = {false, {(uintptr_t)ptr, size, flags,
|
||||
0}};
|
||||
if (config_prof && opt_prof) {
|
||||
usize = (alignment == 0) ?
|
||||
sz_s2u(size) : sz_sa2u(size, alignment);
|
||||
@@ -2782,13 +2794,13 @@ je_rallocx(void *ptr, size_t size, int flags) {
|
||||
goto label_oom;
|
||||
}
|
||||
p = irallocx_prof(tsd, ptr, old_usize, size, alignment, &usize,
|
||||
zero, tcache, arena, &alloc_ctx);
|
||||
zero, tcache, arena, &alloc_ctx, &hook_args);
|
||||
if (unlikely(p == NULL)) {
|
||||
goto label_oom;
|
||||
}
|
||||
} else {
|
||||
p = iralloct(tsd_tsdn(tsd), ptr, old_usize, size, alignment,
|
||||
zero, tcache, arena);
|
||||
zero, tcache, arena, &hook_args);
|
||||
if (unlikely(p == NULL)) {
|
||||
goto label_oom;
|
||||
}
|
||||
|
17
src/large.c
17
src/large.c
@@ -270,10 +270,12 @@ large_ralloc_move_helper(tsdn_t *tsdn, arena_t *arena, size_t usize,
|
||||
}
|
||||
|
||||
void *
|
||||
large_ralloc(tsdn_t *tsdn, arena_t *arena, extent_t *extent, size_t usize,
|
||||
size_t alignment, bool zero, tcache_t *tcache) {
|
||||
size_t oldusize = extent_usize_get(extent);
|
||||
large_ralloc(tsdn_t *tsdn, arena_t *arena, void *ptr, size_t usize,
|
||||
size_t alignment, bool zero, tcache_t *tcache,
|
||||
hook_ralloc_args_t *hook_args) {
|
||||
extent_t *extent = iealloc(tsdn, ptr);
|
||||
|
||||
size_t oldusize = extent_usize_get(extent);
|
||||
/* The following should have been caught by callers. */
|
||||
assert(usize > 0 && usize <= LARGE_MAXCLASS);
|
||||
/* Both allocation sizes must be large to avoid a move. */
|
||||
@@ -281,6 +283,9 @@ large_ralloc(tsdn_t *tsdn, arena_t *arena, extent_t *extent, size_t usize,
|
||||
|
||||
/* Try to avoid moving the allocation. */
|
||||
if (!large_ralloc_no_move(tsdn, extent, usize, usize, zero)) {
|
||||
hook_invoke_expand(hook_args->is_realloc
|
||||
? hook_expand_realloc : hook_expand_rallocx, ptr, oldusize,
|
||||
usize, (uintptr_t)ptr, hook_args->args);
|
||||
return extent_addr_get(extent);
|
||||
}
|
||||
|
||||
@@ -295,6 +300,12 @@ large_ralloc(tsdn_t *tsdn, arena_t *arena, extent_t *extent, size_t usize,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hook_invoke_alloc(hook_args->is_realloc
|
||||
? hook_alloc_realloc : hook_alloc_rallocx, ret, (uintptr_t)ret,
|
||||
hook_args->args);
|
||||
hook_invoke_dalloc(hook_args->is_realloc
|
||||
? hook_dalloc_realloc : hook_dalloc_rallocx, ptr, hook_args->args);
|
||||
|
||||
size_t copysize = (usize < oldusize) ? usize : oldusize;
|
||||
memcpy(ret, extent_addr_get(extent), copysize);
|
||||
isdalloct(tsdn, extent_addr_get(extent), oldusize, tcache, NULL, true);
|
||||
|
Reference in New Issue
Block a user