1*1208bc7eSAndroid Build Coastguard Worker #include "test/jemalloc_test.h"
2*1208bc7eSAndroid Build Coastguard Worker
3*1208bc7eSAndroid Build Coastguard Worker static unsigned
get_nsizes_impl(const char * cmd)4*1208bc7eSAndroid Build Coastguard Worker get_nsizes_impl(const char *cmd) {
5*1208bc7eSAndroid Build Coastguard Worker unsigned ret;
6*1208bc7eSAndroid Build Coastguard Worker size_t z;
7*1208bc7eSAndroid Build Coastguard Worker
8*1208bc7eSAndroid Build Coastguard Worker z = sizeof(unsigned);
9*1208bc7eSAndroid Build Coastguard Worker assert_d_eq(mallctl(cmd, (void *)&ret, &z, NULL, 0), 0,
10*1208bc7eSAndroid Build Coastguard Worker "Unexpected mallctl(\"%s\", ...) failure", cmd);
11*1208bc7eSAndroid Build Coastguard Worker
12*1208bc7eSAndroid Build Coastguard Worker return ret;
13*1208bc7eSAndroid Build Coastguard Worker }
14*1208bc7eSAndroid Build Coastguard Worker
15*1208bc7eSAndroid Build Coastguard Worker static unsigned
get_nlarge(void)16*1208bc7eSAndroid Build Coastguard Worker get_nlarge(void) {
17*1208bc7eSAndroid Build Coastguard Worker return get_nsizes_impl("arenas.nlextents");
18*1208bc7eSAndroid Build Coastguard Worker }
19*1208bc7eSAndroid Build Coastguard Worker
20*1208bc7eSAndroid Build Coastguard Worker static size_t
get_size_impl(const char * cmd,size_t ind)21*1208bc7eSAndroid Build Coastguard Worker get_size_impl(const char *cmd, size_t ind) {
22*1208bc7eSAndroid Build Coastguard Worker size_t ret;
23*1208bc7eSAndroid Build Coastguard Worker size_t z;
24*1208bc7eSAndroid Build Coastguard Worker size_t mib[4];
25*1208bc7eSAndroid Build Coastguard Worker size_t miblen = 4;
26*1208bc7eSAndroid Build Coastguard Worker
27*1208bc7eSAndroid Build Coastguard Worker z = sizeof(size_t);
28*1208bc7eSAndroid Build Coastguard Worker assert_d_eq(mallctlnametomib(cmd, mib, &miblen),
29*1208bc7eSAndroid Build Coastguard Worker 0, "Unexpected mallctlnametomib(\"%s\", ...) failure", cmd);
30*1208bc7eSAndroid Build Coastguard Worker mib[2] = ind;
31*1208bc7eSAndroid Build Coastguard Worker z = sizeof(size_t);
32*1208bc7eSAndroid Build Coastguard Worker assert_d_eq(mallctlbymib(mib, miblen, (void *)&ret, &z, NULL, 0),
33*1208bc7eSAndroid Build Coastguard Worker 0, "Unexpected mallctlbymib([\"%s\", %zu], ...) failure", cmd, ind);
34*1208bc7eSAndroid Build Coastguard Worker
35*1208bc7eSAndroid Build Coastguard Worker return ret;
36*1208bc7eSAndroid Build Coastguard Worker }
37*1208bc7eSAndroid Build Coastguard Worker
38*1208bc7eSAndroid Build Coastguard Worker static size_t
get_large_size(size_t ind)39*1208bc7eSAndroid Build Coastguard Worker get_large_size(size_t ind) {
40*1208bc7eSAndroid Build Coastguard Worker return get_size_impl("arenas.lextent.0.size", ind);
41*1208bc7eSAndroid Build Coastguard Worker }
42*1208bc7eSAndroid Build Coastguard Worker
TEST_BEGIN(test_grow_and_shrink)43*1208bc7eSAndroid Build Coastguard Worker TEST_BEGIN(test_grow_and_shrink) {
44*1208bc7eSAndroid Build Coastguard Worker void *p, *q;
45*1208bc7eSAndroid Build Coastguard Worker size_t tsz;
46*1208bc7eSAndroid Build Coastguard Worker #define NCYCLES 3
47*1208bc7eSAndroid Build Coastguard Worker unsigned i, j;
48*1208bc7eSAndroid Build Coastguard Worker #define NSZS 1024
49*1208bc7eSAndroid Build Coastguard Worker size_t szs[NSZS];
50*1208bc7eSAndroid Build Coastguard Worker #define MAXSZ ZU(12 * 1024 * 1024)
51*1208bc7eSAndroid Build Coastguard Worker
52*1208bc7eSAndroid Build Coastguard Worker p = mallocx(1, 0);
53*1208bc7eSAndroid Build Coastguard Worker assert_ptr_not_null(p, "Unexpected mallocx() error");
54*1208bc7eSAndroid Build Coastguard Worker szs[0] = sallocx(p, 0);
55*1208bc7eSAndroid Build Coastguard Worker
56*1208bc7eSAndroid Build Coastguard Worker for (i = 0; i < NCYCLES; i++) {
57*1208bc7eSAndroid Build Coastguard Worker for (j = 1; j < NSZS && szs[j-1] < MAXSZ; j++) {
58*1208bc7eSAndroid Build Coastguard Worker q = rallocx(p, szs[j-1]+1, 0);
59*1208bc7eSAndroid Build Coastguard Worker assert_ptr_not_null(q,
60*1208bc7eSAndroid Build Coastguard Worker "Unexpected rallocx() error for size=%zu-->%zu",
61*1208bc7eSAndroid Build Coastguard Worker szs[j-1], szs[j-1]+1);
62*1208bc7eSAndroid Build Coastguard Worker szs[j] = sallocx(q, 0);
63*1208bc7eSAndroid Build Coastguard Worker assert_zu_ne(szs[j], szs[j-1]+1,
64*1208bc7eSAndroid Build Coastguard Worker "Expected size to be at least: %zu", szs[j-1]+1);
65*1208bc7eSAndroid Build Coastguard Worker p = q;
66*1208bc7eSAndroid Build Coastguard Worker }
67*1208bc7eSAndroid Build Coastguard Worker
68*1208bc7eSAndroid Build Coastguard Worker for (j--; j > 0; j--) {
69*1208bc7eSAndroid Build Coastguard Worker q = rallocx(p, szs[j-1], 0);
70*1208bc7eSAndroid Build Coastguard Worker assert_ptr_not_null(q,
71*1208bc7eSAndroid Build Coastguard Worker "Unexpected rallocx() error for size=%zu-->%zu",
72*1208bc7eSAndroid Build Coastguard Worker szs[j], szs[j-1]);
73*1208bc7eSAndroid Build Coastguard Worker tsz = sallocx(q, 0);
74*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(tsz, szs[j-1],
75*1208bc7eSAndroid Build Coastguard Worker "Expected size=%zu, got size=%zu", szs[j-1], tsz);
76*1208bc7eSAndroid Build Coastguard Worker p = q;
77*1208bc7eSAndroid Build Coastguard Worker }
78*1208bc7eSAndroid Build Coastguard Worker }
79*1208bc7eSAndroid Build Coastguard Worker
80*1208bc7eSAndroid Build Coastguard Worker dallocx(p, 0);
81*1208bc7eSAndroid Build Coastguard Worker #undef MAXSZ
82*1208bc7eSAndroid Build Coastguard Worker #undef NSZS
83*1208bc7eSAndroid Build Coastguard Worker #undef NCYCLES
84*1208bc7eSAndroid Build Coastguard Worker }
85*1208bc7eSAndroid Build Coastguard Worker TEST_END
86*1208bc7eSAndroid Build Coastguard Worker
87*1208bc7eSAndroid Build Coastguard Worker static bool
validate_fill(const void * p,uint8_t c,size_t offset,size_t len)88*1208bc7eSAndroid Build Coastguard Worker validate_fill(const void *p, uint8_t c, size_t offset, size_t len) {
89*1208bc7eSAndroid Build Coastguard Worker bool ret = false;
90*1208bc7eSAndroid Build Coastguard Worker const uint8_t *buf = (const uint8_t *)p;
91*1208bc7eSAndroid Build Coastguard Worker size_t i;
92*1208bc7eSAndroid Build Coastguard Worker
93*1208bc7eSAndroid Build Coastguard Worker for (i = 0; i < len; i++) {
94*1208bc7eSAndroid Build Coastguard Worker uint8_t b = buf[offset+i];
95*1208bc7eSAndroid Build Coastguard Worker if (b != c) {
96*1208bc7eSAndroid Build Coastguard Worker test_fail("Allocation at %p (len=%zu) contains %#x "
97*1208bc7eSAndroid Build Coastguard Worker "rather than %#x at offset %zu", p, len, b, c,
98*1208bc7eSAndroid Build Coastguard Worker offset+i);
99*1208bc7eSAndroid Build Coastguard Worker ret = true;
100*1208bc7eSAndroid Build Coastguard Worker }
101*1208bc7eSAndroid Build Coastguard Worker }
102*1208bc7eSAndroid Build Coastguard Worker
103*1208bc7eSAndroid Build Coastguard Worker return ret;
104*1208bc7eSAndroid Build Coastguard Worker }
105*1208bc7eSAndroid Build Coastguard Worker
TEST_BEGIN(test_zero)106*1208bc7eSAndroid Build Coastguard Worker TEST_BEGIN(test_zero) {
107*1208bc7eSAndroid Build Coastguard Worker void *p, *q;
108*1208bc7eSAndroid Build Coastguard Worker size_t psz, qsz, i, j;
109*1208bc7eSAndroid Build Coastguard Worker size_t start_sizes[] = {1, 3*1024, 63*1024, 4095*1024};
110*1208bc7eSAndroid Build Coastguard Worker #define FILL_BYTE 0xaaU
111*1208bc7eSAndroid Build Coastguard Worker #define RANGE 2048
112*1208bc7eSAndroid Build Coastguard Worker
113*1208bc7eSAndroid Build Coastguard Worker for (i = 0; i < sizeof(start_sizes)/sizeof(size_t); i++) {
114*1208bc7eSAndroid Build Coastguard Worker size_t start_size = start_sizes[i];
115*1208bc7eSAndroid Build Coastguard Worker p = mallocx(start_size, MALLOCX_ZERO);
116*1208bc7eSAndroid Build Coastguard Worker assert_ptr_not_null(p, "Unexpected mallocx() error");
117*1208bc7eSAndroid Build Coastguard Worker psz = sallocx(p, 0);
118*1208bc7eSAndroid Build Coastguard Worker
119*1208bc7eSAndroid Build Coastguard Worker assert_false(validate_fill(p, 0, 0, psz),
120*1208bc7eSAndroid Build Coastguard Worker "Expected zeroed memory");
121*1208bc7eSAndroid Build Coastguard Worker memset(p, FILL_BYTE, psz);
122*1208bc7eSAndroid Build Coastguard Worker assert_false(validate_fill(p, FILL_BYTE, 0, psz),
123*1208bc7eSAndroid Build Coastguard Worker "Expected filled memory");
124*1208bc7eSAndroid Build Coastguard Worker
125*1208bc7eSAndroid Build Coastguard Worker for (j = 1; j < RANGE; j++) {
126*1208bc7eSAndroid Build Coastguard Worker q = rallocx(p, start_size+j, MALLOCX_ZERO);
127*1208bc7eSAndroid Build Coastguard Worker assert_ptr_not_null(q, "Unexpected rallocx() error");
128*1208bc7eSAndroid Build Coastguard Worker qsz = sallocx(q, 0);
129*1208bc7eSAndroid Build Coastguard Worker if (q != p || qsz != psz) {
130*1208bc7eSAndroid Build Coastguard Worker assert_false(validate_fill(q, FILL_BYTE, 0,
131*1208bc7eSAndroid Build Coastguard Worker psz), "Expected filled memory");
132*1208bc7eSAndroid Build Coastguard Worker assert_false(validate_fill(q, 0, psz, qsz-psz),
133*1208bc7eSAndroid Build Coastguard Worker "Expected zeroed memory");
134*1208bc7eSAndroid Build Coastguard Worker }
135*1208bc7eSAndroid Build Coastguard Worker if (psz != qsz) {
136*1208bc7eSAndroid Build Coastguard Worker memset((void *)((uintptr_t)q+psz), FILL_BYTE,
137*1208bc7eSAndroid Build Coastguard Worker qsz-psz);
138*1208bc7eSAndroid Build Coastguard Worker psz = qsz;
139*1208bc7eSAndroid Build Coastguard Worker }
140*1208bc7eSAndroid Build Coastguard Worker p = q;
141*1208bc7eSAndroid Build Coastguard Worker }
142*1208bc7eSAndroid Build Coastguard Worker assert_false(validate_fill(p, FILL_BYTE, 0, psz),
143*1208bc7eSAndroid Build Coastguard Worker "Expected filled memory");
144*1208bc7eSAndroid Build Coastguard Worker dallocx(p, 0);
145*1208bc7eSAndroid Build Coastguard Worker }
146*1208bc7eSAndroid Build Coastguard Worker #undef FILL_BYTE
147*1208bc7eSAndroid Build Coastguard Worker }
148*1208bc7eSAndroid Build Coastguard Worker TEST_END
149*1208bc7eSAndroid Build Coastguard Worker
TEST_BEGIN(test_align)150*1208bc7eSAndroid Build Coastguard Worker TEST_BEGIN(test_align) {
151*1208bc7eSAndroid Build Coastguard Worker void *p, *q;
152*1208bc7eSAndroid Build Coastguard Worker size_t align;
153*1208bc7eSAndroid Build Coastguard Worker #define MAX_ALIGN (ZU(1) << 25)
154*1208bc7eSAndroid Build Coastguard Worker
155*1208bc7eSAndroid Build Coastguard Worker align = ZU(1);
156*1208bc7eSAndroid Build Coastguard Worker p = mallocx(1, MALLOCX_ALIGN(align));
157*1208bc7eSAndroid Build Coastguard Worker assert_ptr_not_null(p, "Unexpected mallocx() error");
158*1208bc7eSAndroid Build Coastguard Worker
159*1208bc7eSAndroid Build Coastguard Worker for (align <<= 1; align <= MAX_ALIGN; align <<= 1) {
160*1208bc7eSAndroid Build Coastguard Worker q = rallocx(p, 1, MALLOCX_ALIGN(align));
161*1208bc7eSAndroid Build Coastguard Worker assert_ptr_not_null(q,
162*1208bc7eSAndroid Build Coastguard Worker "Unexpected rallocx() error for align=%zu", align);
163*1208bc7eSAndroid Build Coastguard Worker assert_ptr_null(
164*1208bc7eSAndroid Build Coastguard Worker (void *)((uintptr_t)q & (align-1)),
165*1208bc7eSAndroid Build Coastguard Worker "%p inadequately aligned for align=%zu",
166*1208bc7eSAndroid Build Coastguard Worker q, align);
167*1208bc7eSAndroid Build Coastguard Worker p = q;
168*1208bc7eSAndroid Build Coastguard Worker }
169*1208bc7eSAndroid Build Coastguard Worker dallocx(p, 0);
170*1208bc7eSAndroid Build Coastguard Worker #undef MAX_ALIGN
171*1208bc7eSAndroid Build Coastguard Worker }
172*1208bc7eSAndroid Build Coastguard Worker TEST_END
173*1208bc7eSAndroid Build Coastguard Worker
TEST_BEGIN(test_lg_align_and_zero)174*1208bc7eSAndroid Build Coastguard Worker TEST_BEGIN(test_lg_align_and_zero) {
175*1208bc7eSAndroid Build Coastguard Worker void *p, *q;
176*1208bc7eSAndroid Build Coastguard Worker unsigned lg_align;
177*1208bc7eSAndroid Build Coastguard Worker size_t sz;
178*1208bc7eSAndroid Build Coastguard Worker #define MAX_LG_ALIGN 25
179*1208bc7eSAndroid Build Coastguard Worker #define MAX_VALIDATE (ZU(1) << 22)
180*1208bc7eSAndroid Build Coastguard Worker
181*1208bc7eSAndroid Build Coastguard Worker lg_align = 0;
182*1208bc7eSAndroid Build Coastguard Worker p = mallocx(1, MALLOCX_LG_ALIGN(lg_align)|MALLOCX_ZERO);
183*1208bc7eSAndroid Build Coastguard Worker assert_ptr_not_null(p, "Unexpected mallocx() error");
184*1208bc7eSAndroid Build Coastguard Worker
185*1208bc7eSAndroid Build Coastguard Worker for (lg_align++; lg_align <= MAX_LG_ALIGN; lg_align++) {
186*1208bc7eSAndroid Build Coastguard Worker q = rallocx(p, 1, MALLOCX_LG_ALIGN(lg_align)|MALLOCX_ZERO);
187*1208bc7eSAndroid Build Coastguard Worker assert_ptr_not_null(q,
188*1208bc7eSAndroid Build Coastguard Worker "Unexpected rallocx() error for lg_align=%u", lg_align);
189*1208bc7eSAndroid Build Coastguard Worker assert_ptr_null(
190*1208bc7eSAndroid Build Coastguard Worker (void *)((uintptr_t)q & ((ZU(1) << lg_align)-1)),
191*1208bc7eSAndroid Build Coastguard Worker "%p inadequately aligned for lg_align=%u", q, lg_align);
192*1208bc7eSAndroid Build Coastguard Worker sz = sallocx(q, 0);
193*1208bc7eSAndroid Build Coastguard Worker if ((sz << 1) <= MAX_VALIDATE) {
194*1208bc7eSAndroid Build Coastguard Worker assert_false(validate_fill(q, 0, 0, sz),
195*1208bc7eSAndroid Build Coastguard Worker "Expected zeroed memory");
196*1208bc7eSAndroid Build Coastguard Worker } else {
197*1208bc7eSAndroid Build Coastguard Worker assert_false(validate_fill(q, 0, 0, MAX_VALIDATE),
198*1208bc7eSAndroid Build Coastguard Worker "Expected zeroed memory");
199*1208bc7eSAndroid Build Coastguard Worker assert_false(validate_fill(
200*1208bc7eSAndroid Build Coastguard Worker (void *)((uintptr_t)q+sz-MAX_VALIDATE),
201*1208bc7eSAndroid Build Coastguard Worker 0, 0, MAX_VALIDATE), "Expected zeroed memory");
202*1208bc7eSAndroid Build Coastguard Worker }
203*1208bc7eSAndroid Build Coastguard Worker p = q;
204*1208bc7eSAndroid Build Coastguard Worker }
205*1208bc7eSAndroid Build Coastguard Worker dallocx(p, 0);
206*1208bc7eSAndroid Build Coastguard Worker #undef MAX_VALIDATE
207*1208bc7eSAndroid Build Coastguard Worker #undef MAX_LG_ALIGN
208*1208bc7eSAndroid Build Coastguard Worker }
209*1208bc7eSAndroid Build Coastguard Worker TEST_END
210*1208bc7eSAndroid Build Coastguard Worker
TEST_BEGIN(test_overflow)211*1208bc7eSAndroid Build Coastguard Worker TEST_BEGIN(test_overflow) {
212*1208bc7eSAndroid Build Coastguard Worker size_t largemax;
213*1208bc7eSAndroid Build Coastguard Worker void *p;
214*1208bc7eSAndroid Build Coastguard Worker
215*1208bc7eSAndroid Build Coastguard Worker largemax = get_large_size(get_nlarge()-1);
216*1208bc7eSAndroid Build Coastguard Worker
217*1208bc7eSAndroid Build Coastguard Worker p = mallocx(1, 0);
218*1208bc7eSAndroid Build Coastguard Worker assert_ptr_not_null(p, "Unexpected mallocx() failure");
219*1208bc7eSAndroid Build Coastguard Worker
220*1208bc7eSAndroid Build Coastguard Worker assert_ptr_null(rallocx(p, largemax+1, 0),
221*1208bc7eSAndroid Build Coastguard Worker "Expected OOM for rallocx(p, size=%#zx, 0)", largemax+1);
222*1208bc7eSAndroid Build Coastguard Worker
223*1208bc7eSAndroid Build Coastguard Worker assert_ptr_null(rallocx(p, ZU(PTRDIFF_MAX)+1, 0),
224*1208bc7eSAndroid Build Coastguard Worker "Expected OOM for rallocx(p, size=%#zx, 0)", ZU(PTRDIFF_MAX)+1);
225*1208bc7eSAndroid Build Coastguard Worker
226*1208bc7eSAndroid Build Coastguard Worker assert_ptr_null(rallocx(p, SIZE_T_MAX, 0),
227*1208bc7eSAndroid Build Coastguard Worker "Expected OOM for rallocx(p, size=%#zx, 0)", SIZE_T_MAX);
228*1208bc7eSAndroid Build Coastguard Worker
229*1208bc7eSAndroid Build Coastguard Worker assert_ptr_null(rallocx(p, 1, MALLOCX_ALIGN(ZU(PTRDIFF_MAX)+1)),
230*1208bc7eSAndroid Build Coastguard Worker "Expected OOM for rallocx(p, size=1, MALLOCX_ALIGN(%#zx))",
231*1208bc7eSAndroid Build Coastguard Worker ZU(PTRDIFF_MAX)+1);
232*1208bc7eSAndroid Build Coastguard Worker
233*1208bc7eSAndroid Build Coastguard Worker dallocx(p, 0);
234*1208bc7eSAndroid Build Coastguard Worker }
235*1208bc7eSAndroid Build Coastguard Worker TEST_END
236*1208bc7eSAndroid Build Coastguard Worker
237*1208bc7eSAndroid Build Coastguard Worker int
main(void)238*1208bc7eSAndroid Build Coastguard Worker main(void) {
239*1208bc7eSAndroid Build Coastguard Worker return test(
240*1208bc7eSAndroid Build Coastguard Worker test_grow_and_shrink,
241*1208bc7eSAndroid Build Coastguard Worker test_zero,
242*1208bc7eSAndroid Build Coastguard Worker test_align,
243*1208bc7eSAndroid Build Coastguard Worker test_lg_align_and_zero,
244*1208bc7eSAndroid Build Coastguard Worker test_overflow);
245*1208bc7eSAndroid Build Coastguard Worker }
246