1*1208bc7eSAndroid Build Coastguard Worker #include "test/jemalloc_test.h"
2*1208bc7eSAndroid Build Coastguard Worker
3*1208bc7eSAndroid Build Coastguard Worker /*
4*1208bc7eSAndroid Build Coastguard Worker * Use a separate arena for xallocx() extension/contraction tests so that
5*1208bc7eSAndroid Build Coastguard Worker * internal allocation e.g. by heap profiling can't interpose allocations where
6*1208bc7eSAndroid Build Coastguard Worker * xallocx() would ordinarily be able to extend.
7*1208bc7eSAndroid Build Coastguard Worker */
8*1208bc7eSAndroid Build Coastguard Worker static unsigned
arena_ind(void)9*1208bc7eSAndroid Build Coastguard Worker arena_ind(void) {
10*1208bc7eSAndroid Build Coastguard Worker static unsigned ind = 0;
11*1208bc7eSAndroid Build Coastguard Worker
12*1208bc7eSAndroid Build Coastguard Worker if (ind == 0) {
13*1208bc7eSAndroid Build Coastguard Worker size_t sz = sizeof(ind);
14*1208bc7eSAndroid Build Coastguard Worker assert_d_eq(mallctl("arenas.create", (void *)&ind, &sz, NULL,
15*1208bc7eSAndroid Build Coastguard Worker 0), 0, "Unexpected mallctl failure creating arena");
16*1208bc7eSAndroid Build Coastguard Worker }
17*1208bc7eSAndroid Build Coastguard Worker
18*1208bc7eSAndroid Build Coastguard Worker return ind;
19*1208bc7eSAndroid Build Coastguard Worker }
20*1208bc7eSAndroid Build Coastguard Worker
TEST_BEGIN(test_same_size)21*1208bc7eSAndroid Build Coastguard Worker TEST_BEGIN(test_same_size) {
22*1208bc7eSAndroid Build Coastguard Worker void *p;
23*1208bc7eSAndroid Build Coastguard Worker size_t sz, tsz;
24*1208bc7eSAndroid Build Coastguard Worker
25*1208bc7eSAndroid Build Coastguard Worker p = mallocx(42, 0);
26*1208bc7eSAndroid Build Coastguard Worker assert_ptr_not_null(p, "Unexpected mallocx() error");
27*1208bc7eSAndroid Build Coastguard Worker sz = sallocx(p, 0);
28*1208bc7eSAndroid Build Coastguard Worker
29*1208bc7eSAndroid Build Coastguard Worker tsz = xallocx(p, sz, 0, 0);
30*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(tsz, sz, "Unexpected size change: %zu --> %zu", sz, tsz);
31*1208bc7eSAndroid Build Coastguard Worker
32*1208bc7eSAndroid Build Coastguard Worker dallocx(p, 0);
33*1208bc7eSAndroid Build Coastguard Worker }
34*1208bc7eSAndroid Build Coastguard Worker TEST_END
35*1208bc7eSAndroid Build Coastguard Worker
TEST_BEGIN(test_extra_no_move)36*1208bc7eSAndroid Build Coastguard Worker TEST_BEGIN(test_extra_no_move) {
37*1208bc7eSAndroid Build Coastguard Worker void *p;
38*1208bc7eSAndroid Build Coastguard Worker size_t sz, tsz;
39*1208bc7eSAndroid Build Coastguard Worker
40*1208bc7eSAndroid Build Coastguard Worker p = mallocx(42, 0);
41*1208bc7eSAndroid Build Coastguard Worker assert_ptr_not_null(p, "Unexpected mallocx() error");
42*1208bc7eSAndroid Build Coastguard Worker sz = sallocx(p, 0);
43*1208bc7eSAndroid Build Coastguard Worker
44*1208bc7eSAndroid Build Coastguard Worker tsz = xallocx(p, sz, sz-42, 0);
45*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(tsz, sz, "Unexpected size change: %zu --> %zu", sz, tsz);
46*1208bc7eSAndroid Build Coastguard Worker
47*1208bc7eSAndroid Build Coastguard Worker dallocx(p, 0);
48*1208bc7eSAndroid Build Coastguard Worker }
49*1208bc7eSAndroid Build Coastguard Worker TEST_END
50*1208bc7eSAndroid Build Coastguard Worker
TEST_BEGIN(test_no_move_fail)51*1208bc7eSAndroid Build Coastguard Worker TEST_BEGIN(test_no_move_fail) {
52*1208bc7eSAndroid Build Coastguard Worker void *p;
53*1208bc7eSAndroid Build Coastguard Worker size_t sz, tsz;
54*1208bc7eSAndroid Build Coastguard Worker
55*1208bc7eSAndroid Build Coastguard Worker p = mallocx(42, 0);
56*1208bc7eSAndroid Build Coastguard Worker assert_ptr_not_null(p, "Unexpected mallocx() error");
57*1208bc7eSAndroid Build Coastguard Worker sz = sallocx(p, 0);
58*1208bc7eSAndroid Build Coastguard Worker
59*1208bc7eSAndroid Build Coastguard Worker tsz = xallocx(p, sz + 5, 0, 0);
60*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(tsz, sz, "Unexpected size change: %zu --> %zu", sz, tsz);
61*1208bc7eSAndroid Build Coastguard Worker
62*1208bc7eSAndroid Build Coastguard Worker dallocx(p, 0);
63*1208bc7eSAndroid Build Coastguard Worker }
64*1208bc7eSAndroid Build Coastguard Worker TEST_END
65*1208bc7eSAndroid Build Coastguard Worker
66*1208bc7eSAndroid Build Coastguard Worker static unsigned
get_nsizes_impl(const char * cmd)67*1208bc7eSAndroid Build Coastguard Worker get_nsizes_impl(const char *cmd) {
68*1208bc7eSAndroid Build Coastguard Worker unsigned ret;
69*1208bc7eSAndroid Build Coastguard Worker size_t z;
70*1208bc7eSAndroid Build Coastguard Worker
71*1208bc7eSAndroid Build Coastguard Worker z = sizeof(unsigned);
72*1208bc7eSAndroid Build Coastguard Worker assert_d_eq(mallctl(cmd, (void *)&ret, &z, NULL, 0), 0,
73*1208bc7eSAndroid Build Coastguard Worker "Unexpected mallctl(\"%s\", ...) failure", cmd);
74*1208bc7eSAndroid Build Coastguard Worker
75*1208bc7eSAndroid Build Coastguard Worker return ret;
76*1208bc7eSAndroid Build Coastguard Worker }
77*1208bc7eSAndroid Build Coastguard Worker
78*1208bc7eSAndroid Build Coastguard Worker static unsigned
get_nsmall(void)79*1208bc7eSAndroid Build Coastguard Worker get_nsmall(void) {
80*1208bc7eSAndroid Build Coastguard Worker return get_nsizes_impl("arenas.nbins");
81*1208bc7eSAndroid Build Coastguard Worker }
82*1208bc7eSAndroid Build Coastguard Worker
83*1208bc7eSAndroid Build Coastguard Worker static unsigned
get_nlarge(void)84*1208bc7eSAndroid Build Coastguard Worker get_nlarge(void) {
85*1208bc7eSAndroid Build Coastguard Worker return get_nsizes_impl("arenas.nlextents");
86*1208bc7eSAndroid Build Coastguard Worker }
87*1208bc7eSAndroid Build Coastguard Worker
88*1208bc7eSAndroid Build Coastguard Worker static size_t
get_size_impl(const char * cmd,size_t ind)89*1208bc7eSAndroid Build Coastguard Worker get_size_impl(const char *cmd, size_t ind) {
90*1208bc7eSAndroid Build Coastguard Worker size_t ret;
91*1208bc7eSAndroid Build Coastguard Worker size_t z;
92*1208bc7eSAndroid Build Coastguard Worker size_t mib[4];
93*1208bc7eSAndroid Build Coastguard Worker size_t miblen = 4;
94*1208bc7eSAndroid Build Coastguard Worker
95*1208bc7eSAndroid Build Coastguard Worker z = sizeof(size_t);
96*1208bc7eSAndroid Build Coastguard Worker assert_d_eq(mallctlnametomib(cmd, mib, &miblen),
97*1208bc7eSAndroid Build Coastguard Worker 0, "Unexpected mallctlnametomib(\"%s\", ...) failure", cmd);
98*1208bc7eSAndroid Build Coastguard Worker mib[2] = ind;
99*1208bc7eSAndroid Build Coastguard Worker z = sizeof(size_t);
100*1208bc7eSAndroid Build Coastguard Worker assert_d_eq(mallctlbymib(mib, miblen, (void *)&ret, &z, NULL, 0),
101*1208bc7eSAndroid Build Coastguard Worker 0, "Unexpected mallctlbymib([\"%s\", %zu], ...) failure", cmd, ind);
102*1208bc7eSAndroid Build Coastguard Worker
103*1208bc7eSAndroid Build Coastguard Worker return ret;
104*1208bc7eSAndroid Build Coastguard Worker }
105*1208bc7eSAndroid Build Coastguard Worker
106*1208bc7eSAndroid Build Coastguard Worker static size_t
get_small_size(size_t ind)107*1208bc7eSAndroid Build Coastguard Worker get_small_size(size_t ind) {
108*1208bc7eSAndroid Build Coastguard Worker return get_size_impl("arenas.bin.0.size", ind);
109*1208bc7eSAndroid Build Coastguard Worker }
110*1208bc7eSAndroid Build Coastguard Worker
111*1208bc7eSAndroid Build Coastguard Worker static size_t
get_large_size(size_t ind)112*1208bc7eSAndroid Build Coastguard Worker get_large_size(size_t ind) {
113*1208bc7eSAndroid Build Coastguard Worker return get_size_impl("arenas.lextent.0.size", ind);
114*1208bc7eSAndroid Build Coastguard Worker }
115*1208bc7eSAndroid Build Coastguard Worker
TEST_BEGIN(test_size)116*1208bc7eSAndroid Build Coastguard Worker TEST_BEGIN(test_size) {
117*1208bc7eSAndroid Build Coastguard Worker size_t small0, largemax;
118*1208bc7eSAndroid Build Coastguard Worker void *p;
119*1208bc7eSAndroid Build Coastguard Worker
120*1208bc7eSAndroid Build Coastguard Worker /* Get size classes. */
121*1208bc7eSAndroid Build Coastguard Worker small0 = get_small_size(0);
122*1208bc7eSAndroid Build Coastguard Worker largemax = get_large_size(get_nlarge()-1);
123*1208bc7eSAndroid Build Coastguard Worker
124*1208bc7eSAndroid Build Coastguard Worker p = mallocx(small0, 0);
125*1208bc7eSAndroid Build Coastguard Worker assert_ptr_not_null(p, "Unexpected mallocx() error");
126*1208bc7eSAndroid Build Coastguard Worker
127*1208bc7eSAndroid Build Coastguard Worker /* Test smallest supported size. */
128*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(xallocx(p, 1, 0, 0), small0,
129*1208bc7eSAndroid Build Coastguard Worker "Unexpected xallocx() behavior");
130*1208bc7eSAndroid Build Coastguard Worker
131*1208bc7eSAndroid Build Coastguard Worker /* Test largest supported size. */
132*1208bc7eSAndroid Build Coastguard Worker assert_zu_le(xallocx(p, largemax, 0, 0), largemax,
133*1208bc7eSAndroid Build Coastguard Worker "Unexpected xallocx() behavior");
134*1208bc7eSAndroid Build Coastguard Worker
135*1208bc7eSAndroid Build Coastguard Worker /* Test size overflow. */
136*1208bc7eSAndroid Build Coastguard Worker assert_zu_le(xallocx(p, largemax+1, 0, 0), largemax,
137*1208bc7eSAndroid Build Coastguard Worker "Unexpected xallocx() behavior");
138*1208bc7eSAndroid Build Coastguard Worker assert_zu_le(xallocx(p, SIZE_T_MAX, 0, 0), largemax,
139*1208bc7eSAndroid Build Coastguard Worker "Unexpected xallocx() behavior");
140*1208bc7eSAndroid Build Coastguard Worker
141*1208bc7eSAndroid Build Coastguard Worker dallocx(p, 0);
142*1208bc7eSAndroid Build Coastguard Worker }
143*1208bc7eSAndroid Build Coastguard Worker TEST_END
144*1208bc7eSAndroid Build Coastguard Worker
TEST_BEGIN(test_size_extra_overflow)145*1208bc7eSAndroid Build Coastguard Worker TEST_BEGIN(test_size_extra_overflow) {
146*1208bc7eSAndroid Build Coastguard Worker size_t small0, largemax;
147*1208bc7eSAndroid Build Coastguard Worker void *p;
148*1208bc7eSAndroid Build Coastguard Worker
149*1208bc7eSAndroid Build Coastguard Worker /* Get size classes. */
150*1208bc7eSAndroid Build Coastguard Worker small0 = get_small_size(0);
151*1208bc7eSAndroid Build Coastguard Worker largemax = get_large_size(get_nlarge()-1);
152*1208bc7eSAndroid Build Coastguard Worker
153*1208bc7eSAndroid Build Coastguard Worker p = mallocx(small0, 0);
154*1208bc7eSAndroid Build Coastguard Worker assert_ptr_not_null(p, "Unexpected mallocx() error");
155*1208bc7eSAndroid Build Coastguard Worker
156*1208bc7eSAndroid Build Coastguard Worker /* Test overflows that can be resolved by clamping extra. */
157*1208bc7eSAndroid Build Coastguard Worker assert_zu_le(xallocx(p, largemax-1, 2, 0), largemax,
158*1208bc7eSAndroid Build Coastguard Worker "Unexpected xallocx() behavior");
159*1208bc7eSAndroid Build Coastguard Worker assert_zu_le(xallocx(p, largemax, 1, 0), largemax,
160*1208bc7eSAndroid Build Coastguard Worker "Unexpected xallocx() behavior");
161*1208bc7eSAndroid Build Coastguard Worker
162*1208bc7eSAndroid Build Coastguard Worker /* Test overflow such that largemax-size underflows. */
163*1208bc7eSAndroid Build Coastguard Worker assert_zu_le(xallocx(p, largemax+1, 2, 0), largemax,
164*1208bc7eSAndroid Build Coastguard Worker "Unexpected xallocx() behavior");
165*1208bc7eSAndroid Build Coastguard Worker assert_zu_le(xallocx(p, largemax+2, 3, 0), largemax,
166*1208bc7eSAndroid Build Coastguard Worker "Unexpected xallocx() behavior");
167*1208bc7eSAndroid Build Coastguard Worker assert_zu_le(xallocx(p, SIZE_T_MAX-2, 2, 0), largemax,
168*1208bc7eSAndroid Build Coastguard Worker "Unexpected xallocx() behavior");
169*1208bc7eSAndroid Build Coastguard Worker assert_zu_le(xallocx(p, SIZE_T_MAX-1, 1, 0), largemax,
170*1208bc7eSAndroid Build Coastguard Worker "Unexpected xallocx() behavior");
171*1208bc7eSAndroid Build Coastguard Worker
172*1208bc7eSAndroid Build Coastguard Worker dallocx(p, 0);
173*1208bc7eSAndroid Build Coastguard Worker }
174*1208bc7eSAndroid Build Coastguard Worker TEST_END
175*1208bc7eSAndroid Build Coastguard Worker
TEST_BEGIN(test_extra_small)176*1208bc7eSAndroid Build Coastguard Worker TEST_BEGIN(test_extra_small) {
177*1208bc7eSAndroid Build Coastguard Worker size_t small0, small1, largemax;
178*1208bc7eSAndroid Build Coastguard Worker void *p;
179*1208bc7eSAndroid Build Coastguard Worker
180*1208bc7eSAndroid Build Coastguard Worker /* Get size classes. */
181*1208bc7eSAndroid Build Coastguard Worker small0 = get_small_size(0);
182*1208bc7eSAndroid Build Coastguard Worker small1 = get_small_size(1);
183*1208bc7eSAndroid Build Coastguard Worker largemax = get_large_size(get_nlarge()-1);
184*1208bc7eSAndroid Build Coastguard Worker
185*1208bc7eSAndroid Build Coastguard Worker p = mallocx(small0, 0);
186*1208bc7eSAndroid Build Coastguard Worker assert_ptr_not_null(p, "Unexpected mallocx() error");
187*1208bc7eSAndroid Build Coastguard Worker
188*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(xallocx(p, small1, 0, 0), small0,
189*1208bc7eSAndroid Build Coastguard Worker "Unexpected xallocx() behavior");
190*1208bc7eSAndroid Build Coastguard Worker
191*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(xallocx(p, small1, 0, 0), small0,
192*1208bc7eSAndroid Build Coastguard Worker "Unexpected xallocx() behavior");
193*1208bc7eSAndroid Build Coastguard Worker
194*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(xallocx(p, small0, small1 - small0, 0), small0,
195*1208bc7eSAndroid Build Coastguard Worker "Unexpected xallocx() behavior");
196*1208bc7eSAndroid Build Coastguard Worker
197*1208bc7eSAndroid Build Coastguard Worker /* Test size+extra overflow. */
198*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(xallocx(p, small0, largemax - small0 + 1, 0), small0,
199*1208bc7eSAndroid Build Coastguard Worker "Unexpected xallocx() behavior");
200*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(xallocx(p, small0, SIZE_T_MAX - small0, 0), small0,
201*1208bc7eSAndroid Build Coastguard Worker "Unexpected xallocx() behavior");
202*1208bc7eSAndroid Build Coastguard Worker
203*1208bc7eSAndroid Build Coastguard Worker dallocx(p, 0);
204*1208bc7eSAndroid Build Coastguard Worker }
205*1208bc7eSAndroid Build Coastguard Worker TEST_END
206*1208bc7eSAndroid Build Coastguard Worker
TEST_BEGIN(test_extra_large)207*1208bc7eSAndroid Build Coastguard Worker TEST_BEGIN(test_extra_large) {
208*1208bc7eSAndroid Build Coastguard Worker int flags = MALLOCX_ARENA(arena_ind());
209*1208bc7eSAndroid Build Coastguard Worker size_t smallmax, large1, large2, large3, largemax;
210*1208bc7eSAndroid Build Coastguard Worker void *p;
211*1208bc7eSAndroid Build Coastguard Worker
212*1208bc7eSAndroid Build Coastguard Worker /* Get size classes. */
213*1208bc7eSAndroid Build Coastguard Worker smallmax = get_small_size(get_nsmall()-1);
214*1208bc7eSAndroid Build Coastguard Worker large1 = get_large_size(1);
215*1208bc7eSAndroid Build Coastguard Worker large2 = get_large_size(2);
216*1208bc7eSAndroid Build Coastguard Worker large3 = get_large_size(3);
217*1208bc7eSAndroid Build Coastguard Worker largemax = get_large_size(get_nlarge()-1);
218*1208bc7eSAndroid Build Coastguard Worker
219*1208bc7eSAndroid Build Coastguard Worker p = mallocx(large3, flags);
220*1208bc7eSAndroid Build Coastguard Worker assert_ptr_not_null(p, "Unexpected mallocx() error");
221*1208bc7eSAndroid Build Coastguard Worker
222*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(xallocx(p, large3, 0, flags), large3,
223*1208bc7eSAndroid Build Coastguard Worker "Unexpected xallocx() behavior");
224*1208bc7eSAndroid Build Coastguard Worker /* Test size decrease with zero extra. */
225*1208bc7eSAndroid Build Coastguard Worker assert_zu_ge(xallocx(p, large1, 0, flags), large1,
226*1208bc7eSAndroid Build Coastguard Worker "Unexpected xallocx() behavior");
227*1208bc7eSAndroid Build Coastguard Worker assert_zu_ge(xallocx(p, smallmax, 0, flags), large1,
228*1208bc7eSAndroid Build Coastguard Worker "Unexpected xallocx() behavior");
229*1208bc7eSAndroid Build Coastguard Worker
230*1208bc7eSAndroid Build Coastguard Worker if (xallocx(p, large3, 0, flags) != large3) {
231*1208bc7eSAndroid Build Coastguard Worker p = rallocx(p, large3, flags);
232*1208bc7eSAndroid Build Coastguard Worker assert_ptr_not_null(p, "Unexpected rallocx() failure");
233*1208bc7eSAndroid Build Coastguard Worker }
234*1208bc7eSAndroid Build Coastguard Worker /* Test size decrease with non-zero extra. */
235*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(xallocx(p, large1, large3 - large1, flags), large3,
236*1208bc7eSAndroid Build Coastguard Worker "Unexpected xallocx() behavior");
237*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(xallocx(p, large2, large3 - large2, flags), large3,
238*1208bc7eSAndroid Build Coastguard Worker "Unexpected xallocx() behavior");
239*1208bc7eSAndroid Build Coastguard Worker assert_zu_ge(xallocx(p, large1, large2 - large1, flags), large2,
240*1208bc7eSAndroid Build Coastguard Worker "Unexpected xallocx() behavior");
241*1208bc7eSAndroid Build Coastguard Worker assert_zu_ge(xallocx(p, smallmax, large1 - smallmax, flags), large1,
242*1208bc7eSAndroid Build Coastguard Worker "Unexpected xallocx() behavior");
243*1208bc7eSAndroid Build Coastguard Worker
244*1208bc7eSAndroid Build Coastguard Worker assert_zu_ge(xallocx(p, large1, 0, flags), large1,
245*1208bc7eSAndroid Build Coastguard Worker "Unexpected xallocx() behavior");
246*1208bc7eSAndroid Build Coastguard Worker /* Test size increase with zero extra. */
247*1208bc7eSAndroid Build Coastguard Worker assert_zu_le(xallocx(p, large3, 0, flags), large3,
248*1208bc7eSAndroid Build Coastguard Worker "Unexpected xallocx() behavior");
249*1208bc7eSAndroid Build Coastguard Worker assert_zu_le(xallocx(p, largemax+1, 0, flags), large3,
250*1208bc7eSAndroid Build Coastguard Worker "Unexpected xallocx() behavior");
251*1208bc7eSAndroid Build Coastguard Worker
252*1208bc7eSAndroid Build Coastguard Worker assert_zu_ge(xallocx(p, large1, 0, flags), large1,
253*1208bc7eSAndroid Build Coastguard Worker "Unexpected xallocx() behavior");
254*1208bc7eSAndroid Build Coastguard Worker /* Test size increase with non-zero extra. */
255*1208bc7eSAndroid Build Coastguard Worker assert_zu_le(xallocx(p, large1, SIZE_T_MAX - large1, flags), largemax,
256*1208bc7eSAndroid Build Coastguard Worker "Unexpected xallocx() behavior");
257*1208bc7eSAndroid Build Coastguard Worker
258*1208bc7eSAndroid Build Coastguard Worker assert_zu_ge(xallocx(p, large1, 0, flags), large1,
259*1208bc7eSAndroid Build Coastguard Worker "Unexpected xallocx() behavior");
260*1208bc7eSAndroid Build Coastguard Worker /* Test size increase with non-zero extra. */
261*1208bc7eSAndroid Build Coastguard Worker assert_zu_le(xallocx(p, large1, large3 - large1, flags), large3,
262*1208bc7eSAndroid Build Coastguard Worker "Unexpected xallocx() behavior");
263*1208bc7eSAndroid Build Coastguard Worker
264*1208bc7eSAndroid Build Coastguard Worker if (xallocx(p, large3, 0, flags) != large3) {
265*1208bc7eSAndroid Build Coastguard Worker p = rallocx(p, large3, flags);
266*1208bc7eSAndroid Build Coastguard Worker assert_ptr_not_null(p, "Unexpected rallocx() failure");
267*1208bc7eSAndroid Build Coastguard Worker }
268*1208bc7eSAndroid Build Coastguard Worker /* Test size+extra overflow. */
269*1208bc7eSAndroid Build Coastguard Worker assert_zu_le(xallocx(p, large3, largemax - large3 + 1, flags), largemax,
270*1208bc7eSAndroid Build Coastguard Worker "Unexpected xallocx() behavior");
271*1208bc7eSAndroid Build Coastguard Worker
272*1208bc7eSAndroid Build Coastguard Worker dallocx(p, flags);
273*1208bc7eSAndroid Build Coastguard Worker }
274*1208bc7eSAndroid Build Coastguard Worker TEST_END
275*1208bc7eSAndroid Build Coastguard Worker
276*1208bc7eSAndroid Build Coastguard Worker static void
print_filled_extents(const void * p,uint8_t c,size_t len)277*1208bc7eSAndroid Build Coastguard Worker print_filled_extents(const void *p, uint8_t c, size_t len) {
278*1208bc7eSAndroid Build Coastguard Worker const uint8_t *pc = (const uint8_t *)p;
279*1208bc7eSAndroid Build Coastguard Worker size_t i, range0;
280*1208bc7eSAndroid Build Coastguard Worker uint8_t c0;
281*1208bc7eSAndroid Build Coastguard Worker
282*1208bc7eSAndroid Build Coastguard Worker malloc_printf(" p=%p, c=%#x, len=%zu:", p, c, len);
283*1208bc7eSAndroid Build Coastguard Worker range0 = 0;
284*1208bc7eSAndroid Build Coastguard Worker c0 = pc[0];
285*1208bc7eSAndroid Build Coastguard Worker for (i = 0; i < len; i++) {
286*1208bc7eSAndroid Build Coastguard Worker if (pc[i] != c0) {
287*1208bc7eSAndroid Build Coastguard Worker malloc_printf(" %#x[%zu..%zu)", c0, range0, i);
288*1208bc7eSAndroid Build Coastguard Worker range0 = i;
289*1208bc7eSAndroid Build Coastguard Worker c0 = pc[i];
290*1208bc7eSAndroid Build Coastguard Worker }
291*1208bc7eSAndroid Build Coastguard Worker }
292*1208bc7eSAndroid Build Coastguard Worker malloc_printf(" %#x[%zu..%zu)\n", c0, range0, i);
293*1208bc7eSAndroid Build Coastguard Worker }
294*1208bc7eSAndroid Build Coastguard Worker
295*1208bc7eSAndroid Build Coastguard Worker static bool
validate_fill(const void * p,uint8_t c,size_t offset,size_t len)296*1208bc7eSAndroid Build Coastguard Worker validate_fill(const void *p, uint8_t c, size_t offset, size_t len) {
297*1208bc7eSAndroid Build Coastguard Worker const uint8_t *pc = (const uint8_t *)p;
298*1208bc7eSAndroid Build Coastguard Worker bool err;
299*1208bc7eSAndroid Build Coastguard Worker size_t i;
300*1208bc7eSAndroid Build Coastguard Worker
301*1208bc7eSAndroid Build Coastguard Worker for (i = offset, err = false; i < offset+len; i++) {
302*1208bc7eSAndroid Build Coastguard Worker if (pc[i] != c) {
303*1208bc7eSAndroid Build Coastguard Worker err = true;
304*1208bc7eSAndroid Build Coastguard Worker }
305*1208bc7eSAndroid Build Coastguard Worker }
306*1208bc7eSAndroid Build Coastguard Worker
307*1208bc7eSAndroid Build Coastguard Worker if (err) {
308*1208bc7eSAndroid Build Coastguard Worker print_filled_extents(p, c, offset + len);
309*1208bc7eSAndroid Build Coastguard Worker }
310*1208bc7eSAndroid Build Coastguard Worker
311*1208bc7eSAndroid Build Coastguard Worker return err;
312*1208bc7eSAndroid Build Coastguard Worker }
313*1208bc7eSAndroid Build Coastguard Worker
314*1208bc7eSAndroid Build Coastguard Worker static void
test_zero(size_t szmin,size_t szmax)315*1208bc7eSAndroid Build Coastguard Worker test_zero(size_t szmin, size_t szmax) {
316*1208bc7eSAndroid Build Coastguard Worker int flags = MALLOCX_ARENA(arena_ind()) | MALLOCX_ZERO;
317*1208bc7eSAndroid Build Coastguard Worker size_t sz, nsz;
318*1208bc7eSAndroid Build Coastguard Worker void *p;
319*1208bc7eSAndroid Build Coastguard Worker #define FILL_BYTE 0x7aU
320*1208bc7eSAndroid Build Coastguard Worker
321*1208bc7eSAndroid Build Coastguard Worker sz = szmax;
322*1208bc7eSAndroid Build Coastguard Worker p = mallocx(sz, flags);
323*1208bc7eSAndroid Build Coastguard Worker assert_ptr_not_null(p, "Unexpected mallocx() error");
324*1208bc7eSAndroid Build Coastguard Worker assert_false(validate_fill(p, 0x00, 0, sz), "Memory not filled: sz=%zu",
325*1208bc7eSAndroid Build Coastguard Worker sz);
326*1208bc7eSAndroid Build Coastguard Worker
327*1208bc7eSAndroid Build Coastguard Worker /*
328*1208bc7eSAndroid Build Coastguard Worker * Fill with non-zero so that non-debug builds are more likely to detect
329*1208bc7eSAndroid Build Coastguard Worker * errors.
330*1208bc7eSAndroid Build Coastguard Worker */
331*1208bc7eSAndroid Build Coastguard Worker memset(p, FILL_BYTE, sz);
332*1208bc7eSAndroid Build Coastguard Worker assert_false(validate_fill(p, FILL_BYTE, 0, sz),
333*1208bc7eSAndroid Build Coastguard Worker "Memory not filled: sz=%zu", sz);
334*1208bc7eSAndroid Build Coastguard Worker
335*1208bc7eSAndroid Build Coastguard Worker /* Shrink in place so that we can expect growing in place to succeed. */
336*1208bc7eSAndroid Build Coastguard Worker sz = szmin;
337*1208bc7eSAndroid Build Coastguard Worker if (xallocx(p, sz, 0, flags) != sz) {
338*1208bc7eSAndroid Build Coastguard Worker p = rallocx(p, sz, flags);
339*1208bc7eSAndroid Build Coastguard Worker assert_ptr_not_null(p, "Unexpected rallocx() failure");
340*1208bc7eSAndroid Build Coastguard Worker }
341*1208bc7eSAndroid Build Coastguard Worker assert_false(validate_fill(p, FILL_BYTE, 0, sz),
342*1208bc7eSAndroid Build Coastguard Worker "Memory not filled: sz=%zu", sz);
343*1208bc7eSAndroid Build Coastguard Worker
344*1208bc7eSAndroid Build Coastguard Worker for (sz = szmin; sz < szmax; sz = nsz) {
345*1208bc7eSAndroid Build Coastguard Worker nsz = nallocx(sz+1, flags);
346*1208bc7eSAndroid Build Coastguard Worker if (xallocx(p, sz+1, 0, flags) != nsz) {
347*1208bc7eSAndroid Build Coastguard Worker p = rallocx(p, sz+1, flags);
348*1208bc7eSAndroid Build Coastguard Worker assert_ptr_not_null(p, "Unexpected rallocx() failure");
349*1208bc7eSAndroid Build Coastguard Worker }
350*1208bc7eSAndroid Build Coastguard Worker assert_false(validate_fill(p, FILL_BYTE, 0, sz),
351*1208bc7eSAndroid Build Coastguard Worker "Memory not filled: sz=%zu", sz);
352*1208bc7eSAndroid Build Coastguard Worker assert_false(validate_fill(p, 0x00, sz, nsz-sz),
353*1208bc7eSAndroid Build Coastguard Worker "Memory not filled: sz=%zu, nsz-sz=%zu", sz, nsz-sz);
354*1208bc7eSAndroid Build Coastguard Worker memset((void *)((uintptr_t)p + sz), FILL_BYTE, nsz-sz);
355*1208bc7eSAndroid Build Coastguard Worker assert_false(validate_fill(p, FILL_BYTE, 0, nsz),
356*1208bc7eSAndroid Build Coastguard Worker "Memory not filled: nsz=%zu", nsz);
357*1208bc7eSAndroid Build Coastguard Worker }
358*1208bc7eSAndroid Build Coastguard Worker
359*1208bc7eSAndroid Build Coastguard Worker dallocx(p, flags);
360*1208bc7eSAndroid Build Coastguard Worker }
361*1208bc7eSAndroid Build Coastguard Worker
TEST_BEGIN(test_zero_large)362*1208bc7eSAndroid Build Coastguard Worker TEST_BEGIN(test_zero_large) {
363*1208bc7eSAndroid Build Coastguard Worker size_t large0, large1;
364*1208bc7eSAndroid Build Coastguard Worker
365*1208bc7eSAndroid Build Coastguard Worker /* Get size classes. */
366*1208bc7eSAndroid Build Coastguard Worker large0 = get_large_size(0);
367*1208bc7eSAndroid Build Coastguard Worker large1 = get_large_size(1);
368*1208bc7eSAndroid Build Coastguard Worker
369*1208bc7eSAndroid Build Coastguard Worker test_zero(large1, large0 * 2);
370*1208bc7eSAndroid Build Coastguard Worker }
371*1208bc7eSAndroid Build Coastguard Worker TEST_END
372*1208bc7eSAndroid Build Coastguard Worker
373*1208bc7eSAndroid Build Coastguard Worker int
main(void)374*1208bc7eSAndroid Build Coastguard Worker main(void) {
375*1208bc7eSAndroid Build Coastguard Worker return test(
376*1208bc7eSAndroid Build Coastguard Worker test_same_size,
377*1208bc7eSAndroid Build Coastguard Worker test_extra_no_move,
378*1208bc7eSAndroid Build Coastguard Worker test_no_move_fail,
379*1208bc7eSAndroid Build Coastguard Worker test_size,
380*1208bc7eSAndroid Build Coastguard Worker test_size_extra_overflow,
381*1208bc7eSAndroid Build Coastguard Worker test_extra_small,
382*1208bc7eSAndroid Build Coastguard Worker test_extra_large,
383*1208bc7eSAndroid Build Coastguard Worker test_zero_large);
384*1208bc7eSAndroid Build Coastguard Worker }
385