]>
git.proxmox.com Git - rustc.git/blob - src/jemalloc/test/integration/xallocx.c
1 #include "test/jemalloc_test.h"
4 * Use a separate arena for xallocx() extension/contraction tests so that
5 * internal allocation e.g. by heap profiling can't interpose allocations where
6 * xallocx() would ordinarily be able to extend.
11 static unsigned ind
= 0;
14 size_t sz
= sizeof(ind
);
15 assert_d_eq(mallctl("arenas.extend", &ind
, &sz
, NULL
, 0), 0,
16 "Unexpected mallctl failure creating arena");
22 TEST_BEGIN(test_same_size
)
28 assert_ptr_not_null(p
, "Unexpected mallocx() error");
31 tsz
= xallocx(p
, sz
, 0, 0);
32 assert_zu_eq(tsz
, sz
, "Unexpected size change: %zu --> %zu", sz
, tsz
);
38 TEST_BEGIN(test_extra_no_move
)
44 assert_ptr_not_null(p
, "Unexpected mallocx() error");
47 tsz
= xallocx(p
, sz
, sz
-42, 0);
48 assert_zu_eq(tsz
, sz
, "Unexpected size change: %zu --> %zu", sz
, tsz
);
54 TEST_BEGIN(test_no_move_fail
)
60 assert_ptr_not_null(p
, "Unexpected mallocx() error");
63 tsz
= xallocx(p
, sz
+ 5, 0, 0);
64 assert_zu_eq(tsz
, sz
, "Unexpected size change: %zu --> %zu", sz
, tsz
);
71 get_nsizes_impl(const char *cmd
)
77 assert_d_eq(mallctl(cmd
, &ret
, &z
, NULL
, 0), 0,
78 "Unexpected mallctl(\"%s\", ...) failure", cmd
);
87 return (get_nsizes_impl("arenas.nbins"));
94 return (get_nsizes_impl("arenas.nlruns"));
101 return (get_nsizes_impl("arenas.nhchunks"));
105 get_size_impl(const char *cmd
, size_t ind
)
113 assert_d_eq(mallctlnametomib(cmd
, mib
, &miblen
),
114 0, "Unexpected mallctlnametomib(\"%s\", ...) failure", cmd
);
117 assert_d_eq(mallctlbymib(mib
, miblen
, &ret
, &z
, NULL
, 0),
118 0, "Unexpected mallctlbymib([\"%s\", %zu], ...) failure", cmd
, ind
);
124 get_small_size(size_t ind
)
127 return (get_size_impl("arenas.bin.0.size", ind
));
131 get_large_size(size_t ind
)
134 return (get_size_impl("arenas.lrun.0.size", ind
));
138 get_huge_size(size_t ind
)
141 return (get_size_impl("arenas.hchunk.0.size", ind
));
144 TEST_BEGIN(test_size
)
146 size_t small0
, hugemax
;
149 /* Get size classes. */
150 small0
= get_small_size(0);
151 hugemax
= get_huge_size(get_nhuge()-1);
153 p
= mallocx(small0
, 0);
154 assert_ptr_not_null(p
, "Unexpected mallocx() error");
156 /* Test smallest supported size. */
157 assert_zu_eq(xallocx(p
, 1, 0, 0), small0
,
158 "Unexpected xallocx() behavior");
160 /* Test largest supported size. */
161 assert_zu_le(xallocx(p
, hugemax
, 0, 0), hugemax
,
162 "Unexpected xallocx() behavior");
164 /* Test size overflow. */
165 assert_zu_le(xallocx(p
, hugemax
+1, 0, 0), hugemax
,
166 "Unexpected xallocx() behavior");
167 assert_zu_le(xallocx(p
, SIZE_T_MAX
, 0, 0), hugemax
,
168 "Unexpected xallocx() behavior");
174 TEST_BEGIN(test_size_extra_overflow
)
176 size_t small0
, hugemax
;
179 /* Get size classes. */
180 small0
= get_small_size(0);
181 hugemax
= get_huge_size(get_nhuge()-1);
183 p
= mallocx(small0
, 0);
184 assert_ptr_not_null(p
, "Unexpected mallocx() error");
186 /* Test overflows that can be resolved by clamping extra. */
187 assert_zu_le(xallocx(p
, hugemax
-1, 2, 0), hugemax
,
188 "Unexpected xallocx() behavior");
189 assert_zu_le(xallocx(p
, hugemax
, 1, 0), hugemax
,
190 "Unexpected xallocx() behavior");
192 /* Test overflow such that hugemax-size underflows. */
193 assert_zu_le(xallocx(p
, hugemax
+1, 2, 0), hugemax
,
194 "Unexpected xallocx() behavior");
195 assert_zu_le(xallocx(p
, hugemax
+2, 3, 0), hugemax
,
196 "Unexpected xallocx() behavior");
197 assert_zu_le(xallocx(p
, SIZE_T_MAX
-2, 2, 0), hugemax
,
198 "Unexpected xallocx() behavior");
199 assert_zu_le(xallocx(p
, SIZE_T_MAX
-1, 1, 0), hugemax
,
200 "Unexpected xallocx() behavior");
206 TEST_BEGIN(test_extra_small
)
208 size_t small0
, small1
, hugemax
;
211 /* Get size classes. */
212 small0
= get_small_size(0);
213 small1
= get_small_size(1);
214 hugemax
= get_huge_size(get_nhuge()-1);
216 p
= mallocx(small0
, 0);
217 assert_ptr_not_null(p
, "Unexpected mallocx() error");
219 assert_zu_eq(xallocx(p
, small1
, 0, 0), small0
,
220 "Unexpected xallocx() behavior");
222 assert_zu_eq(xallocx(p
, small1
, 0, 0), small0
,
223 "Unexpected xallocx() behavior");
225 assert_zu_eq(xallocx(p
, small0
, small1
- small0
, 0), small0
,
226 "Unexpected xallocx() behavior");
228 /* Test size+extra overflow. */
229 assert_zu_eq(xallocx(p
, small0
, hugemax
- small0
+ 1, 0), small0
,
230 "Unexpected xallocx() behavior");
231 assert_zu_eq(xallocx(p
, small0
, SIZE_T_MAX
- small0
, 0), small0
,
232 "Unexpected xallocx() behavior");
238 TEST_BEGIN(test_extra_large
)
240 int flags
= MALLOCX_ARENA(arena_ind());
241 size_t smallmax
, large0
, large1
, large2
, huge0
, hugemax
;
244 /* Get size classes. */
245 smallmax
= get_small_size(get_nsmall()-1);
246 large0
= get_large_size(0);
247 large1
= get_large_size(1);
248 large2
= get_large_size(2);
249 huge0
= get_huge_size(0);
250 hugemax
= get_huge_size(get_nhuge()-1);
252 p
= mallocx(large2
, flags
);
253 assert_ptr_not_null(p
, "Unexpected mallocx() error");
255 assert_zu_eq(xallocx(p
, large2
, 0, flags
), large2
,
256 "Unexpected xallocx() behavior");
257 /* Test size decrease with zero extra. */
258 assert_zu_eq(xallocx(p
, large0
, 0, flags
), large0
,
259 "Unexpected xallocx() behavior");
260 assert_zu_eq(xallocx(p
, smallmax
, 0, flags
), large0
,
261 "Unexpected xallocx() behavior");
263 assert_zu_eq(xallocx(p
, large2
, 0, flags
), large2
,
264 "Unexpected xallocx() behavior");
265 /* Test size decrease with non-zero extra. */
266 assert_zu_eq(xallocx(p
, large0
, large2
- large0
, flags
), large2
,
267 "Unexpected xallocx() behavior");
268 assert_zu_eq(xallocx(p
, large1
, large2
- large1
, flags
), large2
,
269 "Unexpected xallocx() behavior");
270 assert_zu_eq(xallocx(p
, large0
, large1
- large0
, flags
), large1
,
271 "Unexpected xallocx() behavior");
272 assert_zu_eq(xallocx(p
, smallmax
, large0
- smallmax
, flags
), large0
,
273 "Unexpected xallocx() behavior");
275 assert_zu_eq(xallocx(p
, large0
, 0, flags
), large0
,
276 "Unexpected xallocx() behavior");
277 /* Test size increase with zero extra. */
278 assert_zu_eq(xallocx(p
, large2
, 0, flags
), large2
,
279 "Unexpected xallocx() behavior");
280 assert_zu_eq(xallocx(p
, huge0
, 0, flags
), large2
,
281 "Unexpected xallocx() behavior");
283 assert_zu_eq(xallocx(p
, large0
, 0, flags
), large0
,
284 "Unexpected xallocx() behavior");
285 /* Test size increase with non-zero extra. */
286 assert_zu_lt(xallocx(p
, large0
, huge0
- large0
, flags
), huge0
,
287 "Unexpected xallocx() behavior");
289 assert_zu_eq(xallocx(p
, large0
, 0, flags
), large0
,
290 "Unexpected xallocx() behavior");
291 /* Test size increase with non-zero extra. */
292 assert_zu_eq(xallocx(p
, large0
, large2
- large0
, flags
), large2
,
293 "Unexpected xallocx() behavior");
295 assert_zu_eq(xallocx(p
, large2
, 0, flags
), large2
,
296 "Unexpected xallocx() behavior");
297 /* Test size+extra overflow. */
298 assert_zu_lt(xallocx(p
, large2
, hugemax
- large2
+ 1, flags
), huge0
,
299 "Unexpected xallocx() behavior");
305 TEST_BEGIN(test_extra_huge
)
307 int flags
= MALLOCX_ARENA(arena_ind());
308 size_t largemax
, huge1
, huge2
, huge3
, hugemax
;
311 /* Get size classes. */
312 largemax
= get_large_size(get_nlarge()-1);
313 huge1
= get_huge_size(1);
314 huge2
= get_huge_size(2);
315 huge3
= get_huge_size(3);
316 hugemax
= get_huge_size(get_nhuge()-1);
318 p
= mallocx(huge3
, flags
);
319 assert_ptr_not_null(p
, "Unexpected mallocx() error");
321 assert_zu_eq(xallocx(p
, huge3
, 0, flags
), huge3
,
322 "Unexpected xallocx() behavior");
323 /* Test size decrease with zero extra. */
324 assert_zu_ge(xallocx(p
, huge1
, 0, flags
), huge1
,
325 "Unexpected xallocx() behavior");
326 assert_zu_ge(xallocx(p
, largemax
, 0, flags
), huge1
,
327 "Unexpected xallocx() behavior");
329 assert_zu_eq(xallocx(p
, huge3
, 0, flags
), huge3
,
330 "Unexpected xallocx() behavior");
331 /* Test size decrease with non-zero extra. */
332 assert_zu_eq(xallocx(p
, huge1
, huge3
- huge1
, flags
), huge3
,
333 "Unexpected xallocx() behavior");
334 assert_zu_eq(xallocx(p
, huge2
, huge3
- huge2
, flags
), huge3
,
335 "Unexpected xallocx() behavior");
336 assert_zu_eq(xallocx(p
, huge1
, huge2
- huge1
, flags
), huge2
,
337 "Unexpected xallocx() behavior");
338 assert_zu_ge(xallocx(p
, largemax
, huge1
- largemax
, flags
), huge1
,
339 "Unexpected xallocx() behavior");
341 assert_zu_ge(xallocx(p
, huge1
, 0, flags
), huge1
,
342 "Unexpected xallocx() behavior");
343 /* Test size increase with zero extra. */
344 assert_zu_le(xallocx(p
, huge3
, 0, flags
), huge3
,
345 "Unexpected xallocx() behavior");
346 assert_zu_le(xallocx(p
, hugemax
+1, 0, flags
), huge3
,
347 "Unexpected xallocx() behavior");
349 assert_zu_ge(xallocx(p
, huge1
, 0, flags
), huge1
,
350 "Unexpected xallocx() behavior");
351 /* Test size increase with non-zero extra. */
352 assert_zu_le(xallocx(p
, huge1
, SIZE_T_MAX
- huge1
, flags
), hugemax
,
353 "Unexpected xallocx() behavior");
355 assert_zu_ge(xallocx(p
, huge1
, 0, flags
), huge1
,
356 "Unexpected xallocx() behavior");
357 /* Test size increase with non-zero extra. */
358 assert_zu_le(xallocx(p
, huge1
, huge3
- huge1
, flags
), huge3
,
359 "Unexpected xallocx() behavior");
361 assert_zu_eq(xallocx(p
, huge3
, 0, flags
), huge3
,
362 "Unexpected xallocx() behavior");
363 /* Test size+extra overflow. */
364 assert_zu_le(xallocx(p
, huge3
, hugemax
- huge3
+ 1, flags
), hugemax
,
365 "Unexpected xallocx() behavior");
372 print_filled_extents(const void *p
, uint8_t c
, size_t len
)
374 const uint8_t *pc
= (const uint8_t *)p
;
378 malloc_printf(" p=%p, c=%#x, len=%zu:", p
, c
, len
);
381 for (i
= 0; i
< len
; i
++) {
383 malloc_printf(" %#x[%zu..%zu)", c0
, range0
, i
);
388 malloc_printf(" %#x[%zu..%zu)\n", c0
, range0
, i
);
392 validate_fill(const void *p
, uint8_t c
, size_t offset
, size_t len
)
394 const uint8_t *pc
= (const uint8_t *)p
;
398 for (i
= offset
, err
= false; i
< offset
+len
; i
++) {
404 print_filled_extents(p
, c
, offset
+ len
);
410 test_zero(size_t szmin
, size_t szmax
)
412 int flags
= MALLOCX_ARENA(arena_ind()) | MALLOCX_ZERO
;
415 #define FILL_BYTE 0x7aU
418 p
= mallocx(sz
, flags
);
419 assert_ptr_not_null(p
, "Unexpected mallocx() error");
420 assert_false(validate_fill(p
, 0x00, 0, sz
), "Memory not filled: sz=%zu",
424 * Fill with non-zero so that non-debug builds are more likely to detect
427 memset(p
, FILL_BYTE
, sz
);
428 assert_false(validate_fill(p
, FILL_BYTE
, 0, sz
),
429 "Memory not filled: sz=%zu", sz
);
431 /* Shrink in place so that we can expect growing in place to succeed. */
433 assert_zu_eq(xallocx(p
, sz
, 0, flags
), sz
,
434 "Unexpected xallocx() error");
435 assert_false(validate_fill(p
, FILL_BYTE
, 0, sz
),
436 "Memory not filled: sz=%zu", sz
);
438 for (sz
= szmin
; sz
< szmax
; sz
= nsz
) {
439 nsz
= nallocx(sz
+1, flags
);
440 assert_zu_eq(xallocx(p
, sz
+1, 0, flags
), nsz
,
441 "Unexpected xallocx() failure");
442 assert_false(validate_fill(p
, FILL_BYTE
, 0, sz
),
443 "Memory not filled: sz=%zu", sz
);
444 assert_false(validate_fill(p
, 0x00, sz
, nsz
-sz
),
445 "Memory not filled: sz=%zu, nsz-sz=%zu", sz
, nsz
-sz
);
446 memset((void *)((uintptr_t)p
+ sz
), FILL_BYTE
, nsz
-sz
);
447 assert_false(validate_fill(p
, FILL_BYTE
, 0, nsz
),
448 "Memory not filled: nsz=%zu", nsz
);
454 TEST_BEGIN(test_zero_large
)
456 size_t large0
, largemax
;
458 /* Get size classes. */
459 large0
= get_large_size(0);
460 largemax
= get_large_size(get_nlarge()-1);
462 test_zero(large0
, largemax
);
466 TEST_BEGIN(test_zero_huge
)
470 /* Get size classes. */
471 huge0
= get_huge_size(0);
472 huge1
= get_huge_size(1);
474 test_zero(huge1
, huge0
* 2);
487 test_size_extra_overflow
,