mirror of
https://github.com/jemalloc/jemalloc.git
synced 2026-08-26 00:53:34 +03:00
test: handle profiled xallocx no-grow in extent test
With profiling active, xallocx may decline to grow an allocation that is not page-aligned. The profiling path can require sampled xallocx growth to use page-aligned pointers; otherwise it can return the old usable size without committing the purged tail. Observed on Darwin, where decommit/commit are real VM state changes. The shrink/purge half succeeds and records a decommit, then the profiling-limited grow skips the matching commit. This is not Darwin-specific. Linux no-overcommit should expose the same mismatch. Usual Linux overcommit behavior papers it over by making commit/decommit hooks report unsupported, so both sides of the old equality check stay false. Relax the default-path assertion only while profiling is active, and add a page-aligned case that still requires xallocx shrink and grow to succeed, preserving commit/merge coverage. Assisted-by: Codex gpt-5.5 xhigh
This commit is contained in:
parent
fb5499aa9c
commit
7029edec97
1 changed files with 66 additions and 27 deletions
|
|
@ -4,6 +4,57 @@
|
||||||
|
|
||||||
#include "jemalloc/internal/arena.h"
|
#include "jemalloc/internal/arena.h"
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_decommit_commit(unsigned arena_ind, int flags, size_t large0,
|
||||||
|
size_t *purge_mib, size_t purge_miblen, bool expect_xallocx_success) {
|
||||||
|
void *p;
|
||||||
|
bool xallocx_success_b, xallocx_success_c;
|
||||||
|
|
||||||
|
try_dalloc = false;
|
||||||
|
try_decommit = true;
|
||||||
|
p = mallocx(large0 * 2, flags);
|
||||||
|
expect_ptr_not_null(p, "Unexpected mallocx() error");
|
||||||
|
did_decommit = false;
|
||||||
|
did_commit = false;
|
||||||
|
called_split = false;
|
||||||
|
did_split = false;
|
||||||
|
did_merge = false;
|
||||||
|
xallocx_success_b = (xallocx(p, large0, 0, flags) == large0);
|
||||||
|
expect_d_eq(mallctlbymib(purge_mib, purge_miblen, NULL, NULL, NULL, 0),
|
||||||
|
0, "Unexpected arena.%u.purge error", arena_ind);
|
||||||
|
if (xallocx_success_b) {
|
||||||
|
expect_true(did_split, "Expected split");
|
||||||
|
}
|
||||||
|
xallocx_success_c = (xallocx(p, large0 * 2, 0, flags) == large0 * 2);
|
||||||
|
if (expect_xallocx_success) {
|
||||||
|
expect_true(xallocx_success_b, "Expected xallocx shrink");
|
||||||
|
expect_true(xallocx_success_c, "Expected xallocx grow");
|
||||||
|
}
|
||||||
|
if (did_split && xallocx_success_c) {
|
||||||
|
expect_b_eq(
|
||||||
|
did_decommit, did_commit, "Expected decommit/commit match");
|
||||||
|
}
|
||||||
|
if (xallocx_success_b && xallocx_success_c) {
|
||||||
|
expect_true(did_merge, "Expected merge");
|
||||||
|
}
|
||||||
|
dallocx(p, flags);
|
||||||
|
try_dalloc = true;
|
||||||
|
try_decommit = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
prof_active_enabled(void) {
|
||||||
|
bool active = false;
|
||||||
|
size_t sz = sizeof(active);
|
||||||
|
|
||||||
|
if (!config_prof) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
expect_d_eq(mallctl("prof.active", &active, &sz, NULL, 0), 0,
|
||||||
|
"Unexpected prof.active failure");
|
||||||
|
return active;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_extent_body(unsigned arena_ind) {
|
test_extent_body(unsigned arena_ind) {
|
||||||
void *p;
|
void *p;
|
||||||
|
|
@ -11,9 +62,13 @@ test_extent_body(unsigned arena_ind) {
|
||||||
size_t purge_mib[3];
|
size_t purge_mib[3];
|
||||||
size_t purge_miblen;
|
size_t purge_miblen;
|
||||||
int flags;
|
int flags;
|
||||||
bool xallocx_success_a, xallocx_success_b, xallocx_success_c;
|
bool xallocx_success_a;
|
||||||
|
bool expect_xallocx_success;
|
||||||
|
bool prof_active;
|
||||||
|
|
||||||
flags = MALLOCX_ARENA(arena_ind) | MALLOCX_TCACHE_NONE;
|
flags = MALLOCX_ARENA(arena_ind) | MALLOCX_TCACHE_NONE;
|
||||||
|
expect_xallocx_success = maps_coalesce && try_split && try_merge;
|
||||||
|
prof_active = prof_active_enabled();
|
||||||
|
|
||||||
/* Get large size classes. */
|
/* Get large size classes. */
|
||||||
sz = sizeof(size_t);
|
sz = sizeof(size_t);
|
||||||
|
|
@ -58,32 +113,16 @@ test_extent_body(unsigned arena_ind) {
|
||||||
try_dalloc = true;
|
try_dalloc = true;
|
||||||
|
|
||||||
/* Test decommit/commit and observe split/merge. */
|
/* Test decommit/commit and observe split/merge. */
|
||||||
try_dalloc = false;
|
test_decommit_commit(arena_ind, flags, large0, purge_mib, purge_miblen,
|
||||||
try_decommit = true;
|
expect_xallocx_success && !prof_active);
|
||||||
p = mallocx(large0 * 2, flags);
|
|
||||||
expect_ptr_not_null(p, "Unexpected mallocx() error");
|
/*
|
||||||
did_decommit = false;
|
* Active profiling may decline to grow a non-sampled allocation if it
|
||||||
did_commit = false;
|
* is not page-aligned. Force page alignment to keep deterministic
|
||||||
called_split = false;
|
* coverage for the successful grow/commit/merge path.
|
||||||
did_split = false;
|
*/
|
||||||
did_merge = false;
|
test_decommit_commit(arena_ind, flags | MALLOCX_ALIGN(PAGE), large0,
|
||||||
xallocx_success_b = (xallocx(p, large0, 0, flags) == large0);
|
purge_mib, purge_miblen, expect_xallocx_success);
|
||||||
expect_d_eq(mallctlbymib(purge_mib, purge_miblen, NULL, NULL, NULL, 0),
|
|
||||||
0, "Unexpected arena.%u.purge error", arena_ind);
|
|
||||||
if (xallocx_success_b) {
|
|
||||||
expect_true(did_split, "Expected split");
|
|
||||||
}
|
|
||||||
xallocx_success_c = (xallocx(p, large0 * 2, 0, flags) == large0 * 2);
|
|
||||||
if (did_split) {
|
|
||||||
expect_b_eq(
|
|
||||||
did_decommit, did_commit, "Expected decommit/commit match");
|
|
||||||
}
|
|
||||||
if (xallocx_success_b && xallocx_success_c) {
|
|
||||||
expect_true(did_merge, "Expected merge");
|
|
||||||
}
|
|
||||||
dallocx(p, flags);
|
|
||||||
try_dalloc = true;
|
|
||||||
try_decommit = false;
|
|
||||||
|
|
||||||
/* Make sure non-large allocation succeeds. */
|
/* Make sure non-large allocation succeeds. */
|
||||||
p = mallocx(42, flags);
|
p = mallocx(42, flags);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue