Implement prof sample hooks "experimental.hooks.prof_sample(_free)".

The added hooks hooks.prof_sample and hooks.prof_sample_free are intended to
allow advanced users to track additional information, to enable new ways of
profiling on top of the jemalloc heap profile and sample features.

The sample hook is invoked after the allocation and backtracing, and forwards
the both the allocation and backtrace to the user hook; the sample_free hook
happens before the actual deallocation, and forwards only the ptr and usz to the
hook.
This commit is contained in:
Qi Wang 2022-11-02 15:17:16 -07:00 committed by Qi Wang
parent a74acb57e8
commit 8580c65f81
7 changed files with 307 additions and 19 deletions

View file

@ -78,6 +78,12 @@ atomic_p_t prof_backtrace_hook;
/* Logically a prof_dump_hook_t. */
atomic_p_t prof_dump_hook;
/* Logically a prof_sample_hook_t. */
atomic_p_t prof_sample_hook;
/* Logically a prof_sample_free_hook_t. */
atomic_p_t prof_sample_free_hook;
/******************************************************************************/
void
@ -145,10 +151,20 @@ prof_malloc_sample_object(tsd_t *tsd, const void *ptr, size_t size,
if (opt_prof_stats) {
prof_stats_inc(tsd, szind, size);
}
/* Sample hook. */
prof_sample_hook_t prof_sample_hook = prof_sample_hook_get();
if (prof_sample_hook != NULL) {
prof_bt_t *bt = &tctx->gctx->bt;
pre_reentrancy(tsd, NULL);
prof_sample_hook(ptr, size, bt->vec, bt->len);
post_reentrancy(tsd);
}
}
void
prof_free_sampled_object(tsd_t *tsd, size_t usize, prof_info_t *prof_info) {
prof_free_sampled_object(tsd_t *tsd, const void *ptr, size_t usize,
prof_info_t *prof_info) {
cassert(config_prof);
assert(prof_info != NULL);
@ -156,6 +172,16 @@ prof_free_sampled_object(tsd_t *tsd, size_t usize, prof_info_t *prof_info) {
assert((uintptr_t)tctx > (uintptr_t)1U);
szind_t szind = sz_size2index(usize);
/* Unsample hook. */
prof_sample_free_hook_t prof_sample_free_hook =
prof_sample_free_hook_get();
if (prof_sample_free_hook != NULL) {
pre_reentrancy(tsd, NULL);
prof_sample_free_hook(ptr, usize);
post_reentrancy(tsd);
}
malloc_mutex_lock(tsd_tsdn(tsd), tctx->tdata->lock);
assert(tctx->cnts.curobjs > 0);
@ -549,6 +575,28 @@ prof_dump_hook_get() {
ATOMIC_ACQUIRE);
}
void
prof_sample_hook_set(prof_sample_hook_t hook) {
atomic_store_p(&prof_sample_hook, hook, ATOMIC_RELEASE);
}
prof_sample_hook_t
prof_sample_hook_get() {
return (prof_sample_hook_t)atomic_load_p(&prof_sample_hook,
ATOMIC_ACQUIRE);
}
void
prof_sample_free_hook_set(prof_sample_free_hook_t hook) {
atomic_store_p(&prof_sample_free_hook, hook, ATOMIC_RELEASE);
}
prof_sample_free_hook_t
prof_sample_free_hook_get() {
return (prof_sample_free_hook_t)atomic_load_p(&prof_sample_free_hook,
ATOMIC_ACQUIRE);
}
void
prof_boot0(void) {
cassert(config_prof);