Optimize arena_prof_tctx_set().
Optimize arena_prof_tctx_set() to avoid reading run metadata when deciding whether it's actually necessary to write.
This commit is contained in:
parent
c0f43b6550
commit
594c759f37
@ -555,7 +555,7 @@ szind_t arena_bin_index(arena_t *arena, arena_bin_t *bin);
|
|||||||
unsigned arena_run_regind(arena_run_t *run, arena_bin_info_t *bin_info,
|
unsigned arena_run_regind(arena_run_t *run, arena_bin_info_t *bin_info,
|
||||||
const void *ptr);
|
const void *ptr);
|
||||||
prof_tctx_t *arena_prof_tctx_get(const void *ptr);
|
prof_tctx_t *arena_prof_tctx_get(const void *ptr);
|
||||||
void arena_prof_tctx_set(const void *ptr, prof_tctx_t *tctx);
|
void arena_prof_tctx_set(const void *ptr, size_t usize, prof_tctx_t *tctx);
|
||||||
void *arena_malloc(tsd_t *tsd, arena_t *arena, size_t size, bool zero,
|
void *arena_malloc(tsd_t *tsd, arena_t *arena, size_t size, bool zero,
|
||||||
tcache_t *tcache);
|
tcache_t *tcache);
|
||||||
arena_t *arena_aalloc(const void *ptr);
|
arena_t *arena_aalloc(const void *ptr);
|
||||||
@ -1092,7 +1092,7 @@ arena_prof_tctx_get(const void *ptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
JEMALLOC_INLINE void
|
JEMALLOC_INLINE void
|
||||||
arena_prof_tctx_set(const void *ptr, prof_tctx_t *tctx)
|
arena_prof_tctx_set(const void *ptr, size_t usize, prof_tctx_t *tctx)
|
||||||
{
|
{
|
||||||
arena_chunk_t *chunk;
|
arena_chunk_t *chunk;
|
||||||
|
|
||||||
@ -1102,12 +1102,25 @@ arena_prof_tctx_set(const void *ptr, prof_tctx_t *tctx)
|
|||||||
chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
|
chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
|
||||||
if (likely(chunk != ptr)) {
|
if (likely(chunk != ptr)) {
|
||||||
size_t pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE;
|
size_t pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE;
|
||||||
|
|
||||||
assert(arena_mapbits_allocated_get(chunk, pageind) != 0);
|
assert(arena_mapbits_allocated_get(chunk, pageind) != 0);
|
||||||
|
|
||||||
if (unlikely(arena_mapbits_large_get(chunk, pageind) != 0)) {
|
if (unlikely(usize > SMALL_MAXCLASS || tctx >
|
||||||
arena_chunk_map_misc_t *elm = arena_miscelm_get(chunk,
|
(prof_tctx_t *)(uintptr_t)1U)) {
|
||||||
pageind);
|
arena_chunk_map_misc_t *elm;
|
||||||
|
|
||||||
|
assert(arena_mapbits_large_get(chunk, pageind) != 0);
|
||||||
|
|
||||||
|
elm = arena_miscelm_get(chunk, pageind);
|
||||||
atomic_write_p(&elm->prof_tctx_pun, tctx);
|
atomic_write_p(&elm->prof_tctx_pun, tctx);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* tctx must always be initialized for large runs.
|
||||||
|
* Assert that the surrounding conditional logic is
|
||||||
|
* equivalent to checking whether ptr refers to a large
|
||||||
|
* run.
|
||||||
|
*/
|
||||||
|
assert(arena_mapbits_large_get(chunk, pageind) == 0);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
huge_prof_tctx_set(ptr, tctx);
|
huge_prof_tctx_set(ptr, tctx);
|
||||||
|
@ -332,7 +332,7 @@ bool prof_sample_accum_update(tsd_t *tsd, size_t usize, bool commit,
|
|||||||
prof_tdata_t **tdata_out);
|
prof_tdata_t **tdata_out);
|
||||||
prof_tctx_t *prof_alloc_prep(tsd_t *tsd, size_t usize, bool update);
|
prof_tctx_t *prof_alloc_prep(tsd_t *tsd, size_t usize, bool update);
|
||||||
prof_tctx_t *prof_tctx_get(const void *ptr);
|
prof_tctx_t *prof_tctx_get(const void *ptr);
|
||||||
void prof_tctx_set(const void *ptr, prof_tctx_t *tctx);
|
void prof_tctx_set(const void *ptr, size_t usize, prof_tctx_t *tctx);
|
||||||
void prof_malloc_sample_object(const void *ptr, size_t usize,
|
void prof_malloc_sample_object(const void *ptr, size_t usize,
|
||||||
prof_tctx_t *tctx);
|
prof_tctx_t *tctx);
|
||||||
void prof_malloc(const void *ptr, size_t usize, prof_tctx_t *tctx);
|
void prof_malloc(const void *ptr, size_t usize, prof_tctx_t *tctx);
|
||||||
@ -402,13 +402,13 @@ prof_tctx_get(const void *ptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
JEMALLOC_ALWAYS_INLINE void
|
JEMALLOC_ALWAYS_INLINE void
|
||||||
prof_tctx_set(const void *ptr, prof_tctx_t *tctx)
|
prof_tctx_set(const void *ptr, size_t usize, prof_tctx_t *tctx)
|
||||||
{
|
{
|
||||||
|
|
||||||
cassert(config_prof);
|
cassert(config_prof);
|
||||||
assert(ptr != NULL);
|
assert(ptr != NULL);
|
||||||
|
|
||||||
arena_prof_tctx_set(ptr, tctx);
|
arena_prof_tctx_set(ptr, usize, tctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
JEMALLOC_ALWAYS_INLINE bool
|
JEMALLOC_ALWAYS_INLINE bool
|
||||||
@ -473,7 +473,7 @@ prof_malloc(const void *ptr, size_t usize, prof_tctx_t *tctx)
|
|||||||
if (unlikely((uintptr_t)tctx > (uintptr_t)1U))
|
if (unlikely((uintptr_t)tctx > (uintptr_t)1U))
|
||||||
prof_malloc_sample_object(ptr, usize, tctx);
|
prof_malloc_sample_object(ptr, usize, tctx);
|
||||||
else
|
else
|
||||||
prof_tctx_set(ptr, (prof_tctx_t *)(uintptr_t)1U);
|
prof_tctx_set(ptr, usize, (prof_tctx_t *)(uintptr_t)1U);
|
||||||
}
|
}
|
||||||
|
|
||||||
JEMALLOC_ALWAYS_INLINE void
|
JEMALLOC_ALWAYS_INLINE void
|
||||||
@ -503,7 +503,7 @@ prof_realloc(tsd_t *tsd, const void *ptr, size_t usize, prof_tctx_t *tctx,
|
|||||||
if (unlikely((uintptr_t)tctx > (uintptr_t)1U))
|
if (unlikely((uintptr_t)tctx > (uintptr_t)1U))
|
||||||
prof_malloc_sample_object(ptr, usize, tctx);
|
prof_malloc_sample_object(ptr, usize, tctx);
|
||||||
else
|
else
|
||||||
prof_tctx_set(ptr, (prof_tctx_t *)(uintptr_t)1U);
|
prof_tctx_set(ptr, usize, (prof_tctx_t *)(uintptr_t)1U);
|
||||||
}
|
}
|
||||||
|
|
||||||
JEMALLOC_ALWAYS_INLINE void
|
JEMALLOC_ALWAYS_INLINE void
|
||||||
|
@ -219,7 +219,7 @@ void
|
|||||||
prof_malloc_sample_object(const void *ptr, size_t usize, prof_tctx_t *tctx)
|
prof_malloc_sample_object(const void *ptr, size_t usize, prof_tctx_t *tctx)
|
||||||
{
|
{
|
||||||
|
|
||||||
prof_tctx_set(ptr, tctx);
|
prof_tctx_set(ptr, usize, tctx);
|
||||||
|
|
||||||
malloc_mutex_lock(tctx->tdata->lock);
|
malloc_mutex_lock(tctx->tdata->lock);
|
||||||
tctx->cnts.curobjs++;
|
tctx->cnts.curobjs++;
|
||||||
|
@ -16,6 +16,27 @@ prof_dump_open_intercept(bool propagate_err, const char *filename)
|
|||||||
return (fd);
|
return (fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static size_t
|
||||||
|
get_lg_prof_sample(void)
|
||||||
|
{
|
||||||
|
size_t lg_prof_sample;
|
||||||
|
size_t sz = sizeof(size_t);
|
||||||
|
|
||||||
|
assert_d_eq(mallctl("prof.lg_sample", &lg_prof_sample, &sz, NULL, 0), 0,
|
||||||
|
"Unexpected mallctl failure while reading profiling sample rate");
|
||||||
|
return (lg_prof_sample);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
do_prof_reset(size_t lg_prof_sample)
|
||||||
|
{
|
||||||
|
assert_d_eq(mallctl("prof.reset", NULL, NULL,
|
||||||
|
&lg_prof_sample, sizeof(size_t)), 0,
|
||||||
|
"Unexpected mallctl failure while resetting profile data");
|
||||||
|
assert_zu_eq(lg_prof_sample, get_lg_prof_sample(),
|
||||||
|
"Expected profile sample rate change");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_BEGIN(test_prof_reset_basic)
|
TEST_BEGIN(test_prof_reset_basic)
|
||||||
{
|
{
|
||||||
size_t lg_prof_sample_orig, lg_prof_sample, lg_prof_sample_next;
|
size_t lg_prof_sample_orig, lg_prof_sample, lg_prof_sample_next;
|
||||||
@ -30,9 +51,7 @@ TEST_BEGIN(test_prof_reset_basic)
|
|||||||
"Unexpected mallctl failure while reading profiling sample rate");
|
"Unexpected mallctl failure while reading profiling sample rate");
|
||||||
assert_zu_eq(lg_prof_sample_orig, 0,
|
assert_zu_eq(lg_prof_sample_orig, 0,
|
||||||
"Unexpected profiling sample rate");
|
"Unexpected profiling sample rate");
|
||||||
sz = sizeof(size_t);
|
lg_prof_sample = get_lg_prof_sample();
|
||||||
assert_d_eq(mallctl("prof.lg_sample", &lg_prof_sample, &sz, NULL, 0), 0,
|
|
||||||
"Unexpected mallctl failure while reading profiling sample rate");
|
|
||||||
assert_zu_eq(lg_prof_sample_orig, lg_prof_sample,
|
assert_zu_eq(lg_prof_sample_orig, lg_prof_sample,
|
||||||
"Unexpected disagreement between \"opt.lg_prof_sample\" and "
|
"Unexpected disagreement between \"opt.lg_prof_sample\" and "
|
||||||
"\"prof.lg_sample\"");
|
"\"prof.lg_sample\"");
|
||||||
@ -41,10 +60,7 @@ TEST_BEGIN(test_prof_reset_basic)
|
|||||||
for (i = 0; i < 2; i++) {
|
for (i = 0; i < 2; i++) {
|
||||||
assert_d_eq(mallctl("prof.reset", NULL, NULL, NULL, 0), 0,
|
assert_d_eq(mallctl("prof.reset", NULL, NULL, NULL, 0), 0,
|
||||||
"Unexpected mallctl failure while resetting profile data");
|
"Unexpected mallctl failure while resetting profile data");
|
||||||
sz = sizeof(size_t);
|
lg_prof_sample = get_lg_prof_sample();
|
||||||
assert_d_eq(mallctl("prof.lg_sample", &lg_prof_sample, &sz,
|
|
||||||
NULL, 0), 0, "Unexpected mallctl failure while reading "
|
|
||||||
"profiling sample rate");
|
|
||||||
assert_zu_eq(lg_prof_sample_orig, lg_prof_sample,
|
assert_zu_eq(lg_prof_sample_orig, lg_prof_sample,
|
||||||
"Unexpected profile sample rate change");
|
"Unexpected profile sample rate change");
|
||||||
}
|
}
|
||||||
@ -52,22 +68,15 @@ TEST_BEGIN(test_prof_reset_basic)
|
|||||||
/* Test resets with prof.lg_sample changes. */
|
/* Test resets with prof.lg_sample changes. */
|
||||||
lg_prof_sample_next = 1;
|
lg_prof_sample_next = 1;
|
||||||
for (i = 0; i < 2; i++) {
|
for (i = 0; i < 2; i++) {
|
||||||
assert_d_eq(mallctl("prof.reset", NULL, NULL,
|
do_prof_reset(lg_prof_sample_next);
|
||||||
&lg_prof_sample_next, sizeof(size_t)), 0,
|
lg_prof_sample = get_lg_prof_sample();
|
||||||
"Unexpected mallctl failure while resetting profile data");
|
|
||||||
sz = sizeof(size_t);
|
|
||||||
assert_d_eq(mallctl("prof.lg_sample", &lg_prof_sample, &sz,
|
|
||||||
NULL, 0), 0, "Unexpected mallctl failure while reading "
|
|
||||||
"profiling sample rate");
|
|
||||||
assert_zu_eq(lg_prof_sample, lg_prof_sample_next,
|
assert_zu_eq(lg_prof_sample, lg_prof_sample_next,
|
||||||
"Expected profile sample rate change");
|
"Expected profile sample rate change");
|
||||||
lg_prof_sample_next = lg_prof_sample_orig;
|
lg_prof_sample_next = lg_prof_sample_orig;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure the test code restored prof.lg_sample. */
|
/* Make sure the test code restored prof.lg_sample. */
|
||||||
sz = sizeof(size_t);
|
lg_prof_sample = get_lg_prof_sample();
|
||||||
assert_d_eq(mallctl("prof.lg_sample", &lg_prof_sample, &sz, NULL, 0), 0,
|
|
||||||
"Unexpected mallctl failure while reading profiling sample rate");
|
|
||||||
assert_zu_eq(lg_prof_sample_orig, lg_prof_sample,
|
assert_zu_eq(lg_prof_sample_orig, lg_prof_sample,
|
||||||
"Unexpected disagreement between \"opt.lg_prof_sample\" and "
|
"Unexpected disagreement between \"opt.lg_prof_sample\" and "
|
||||||
"\"prof.lg_sample\"");
|
"\"prof.lg_sample\"");
|
||||||
@ -182,6 +191,7 @@ thd_start(void *varg)
|
|||||||
|
|
||||||
TEST_BEGIN(test_prof_reset)
|
TEST_BEGIN(test_prof_reset)
|
||||||
{
|
{
|
||||||
|
size_t lg_prof_sample_orig;
|
||||||
bool active;
|
bool active;
|
||||||
thd_t thds[NTHREADS];
|
thd_t thds[NTHREADS];
|
||||||
unsigned thd_args[NTHREADS];
|
unsigned thd_args[NTHREADS];
|
||||||
@ -195,6 +205,9 @@ TEST_BEGIN(test_prof_reset)
|
|||||||
"Unexpected pre-existing tdata structures");
|
"Unexpected pre-existing tdata structures");
|
||||||
tdata_count = prof_tdata_count();
|
tdata_count = prof_tdata_count();
|
||||||
|
|
||||||
|
lg_prof_sample_orig = get_lg_prof_sample();
|
||||||
|
do_prof_reset(5);
|
||||||
|
|
||||||
active = true;
|
active = true;
|
||||||
assert_d_eq(mallctl("prof.active", NULL, NULL, &active, sizeof(active)),
|
assert_d_eq(mallctl("prof.active", NULL, NULL, &active, sizeof(active)),
|
||||||
0, "Unexpected mallctl failure while activating profiling");
|
0, "Unexpected mallctl failure while activating profiling");
|
||||||
@ -214,6 +227,8 @@ TEST_BEGIN(test_prof_reset)
|
|||||||
active = false;
|
active = false;
|
||||||
assert_d_eq(mallctl("prof.active", NULL, NULL, &active, sizeof(active)),
|
assert_d_eq(mallctl("prof.active", NULL, NULL, &active, sizeof(active)),
|
||||||
0, "Unexpected mallctl failure while deactivating profiling");
|
0, "Unexpected mallctl failure while deactivating profiling");
|
||||||
|
|
||||||
|
do_prof_reset(lg_prof_sample_orig);
|
||||||
}
|
}
|
||||||
TEST_END
|
TEST_END
|
||||||
#undef NTHREADS
|
#undef NTHREADS
|
||||||
|
Loading…
Reference in New Issue
Block a user