1fb7fe50a88ca9bde74e9a401ae17ad3b15bbae28aravind#include "test/jemalloc_test.h"
2fb7fe50a88ca9bde74e9a401ae17ad3b15bbae28aravind
34a2a3c9a6e5f8fda3536f48095d68ddaa13cd977Mike Hommey#ifdef JEMALLOC_FILL
44a2a3c9a6e5f8fda3536f48095d68ddaa13cd977Mike Hommeyconst char *malloc_conf = "junk:false";
54a2a3c9a6e5f8fda3536f48095d68ddaa13cd977Mike Hommey#endif
64a2a3c9a6e5f8fda3536f48095d68ddaa13cd977Mike Hommey
7b49a334a645b854dbb1649f15c38d646fee66738Jason Evansstatic chunk_hooks_t orig_hooks;
8b49a334a645b854dbb1649f15c38d646fee66738Jason Evansstatic chunk_hooks_t old_hooks;
9b49a334a645b854dbb1649f15c38d646fee66738Jason Evans
10b49a334a645b854dbb1649f15c38d646fee66738Jason Evansstatic bool do_dalloc = true;
11b49a334a645b854dbb1649f15c38d646fee66738Jason Evansstatic bool do_decommit;
12b49a334a645b854dbb1649f15c38d646fee66738Jason Evans
13b49a334a645b854dbb1649f15c38d646fee66738Jason Evansstatic bool did_alloc;
14b49a334a645b854dbb1649f15c38d646fee66738Jason Evansstatic bool did_dalloc;
15b49a334a645b854dbb1649f15c38d646fee66738Jason Evansstatic bool did_commit;
16b49a334a645b854dbb1649f15c38d646fee66738Jason Evansstatic bool did_decommit;
17b49a334a645b854dbb1649f15c38d646fee66738Jason Evansstatic bool did_purge;
18b49a334a645b854dbb1649f15c38d646fee66738Jason Evansstatic bool did_split;
19b49a334a645b854dbb1649f15c38d646fee66738Jason Evansstatic bool did_merge;
20b49a334a645b854dbb1649f15c38d646fee66738Jason Evans
21b49a334a645b854dbb1649f15c38d646fee66738Jason Evans#if 0
22b49a334a645b854dbb1649f15c38d646fee66738Jason Evans#  define TRACE_HOOK(fmt, ...) malloc_printf(fmt, __VA_ARGS__)
23b49a334a645b854dbb1649f15c38d646fee66738Jason Evans#else
24b49a334a645b854dbb1649f15c38d646fee66738Jason Evans#  define TRACE_HOOK(fmt, ...)
25b49a334a645b854dbb1649f15c38d646fee66738Jason Evans#endif
268d6a3e8321a7767cb2ca0930b85d5d488a8cc659Jason Evans
278d6a3e8321a7767cb2ca0930b85d5d488a8cc659Jason Evansvoid *
288d6a3e8321a7767cb2ca0930b85d5d488a8cc659Jason Evanschunk_alloc(void *new_addr, size_t size, size_t alignment, bool *zero,
298fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans    bool *commit, unsigned arena_ind)
308d6a3e8321a7767cb2ca0930b85d5d488a8cc659Jason Evans{
318d6a3e8321a7767cb2ca0930b85d5d488a8cc659Jason Evans
32b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	TRACE_HOOK("%s(new_addr=%p, size=%zu, alignment=%zu, *zero=%s, "
338fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans	    "*commit=%s, arena_ind=%u)\n", __func__, new_addr, size, alignment,
348fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans	    *zero ?  "true" : "false", *commit ? "true" : "false", arena_ind);
35b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	did_alloc = true;
368fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans	return (old_hooks.alloc(new_addr, size, alignment, zero, commit,
378fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans	    arena_ind));
388d6a3e8321a7767cb2ca0930b85d5d488a8cc659Jason Evans}
39fb7fe50a88ca9bde74e9a401ae17ad3b15bbae28aravind
40fb7fe50a88ca9bde74e9a401ae17ad3b15bbae28aravindbool
418fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evanschunk_dalloc(void *chunk, size_t size, bool committed, unsigned arena_ind)
42fb7fe50a88ca9bde74e9a401ae17ad3b15bbae28aravind{
43fb7fe50a88ca9bde74e9a401ae17ad3b15bbae28aravind
448fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans	TRACE_HOOK("%s(chunk=%p, size=%zu, committed=%s, arena_ind=%u)\n",
458fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans	    __func__, chunk, size, committed ? "true" : "false", arena_ind);
46b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	did_dalloc = true;
47b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	if (!do_dalloc)
48b49a334a645b854dbb1649f15c38d646fee66738Jason Evans		return (true);
498fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans	return (old_hooks.dalloc(chunk, size, committed, arena_ind));
50fb7fe50a88ca9bde74e9a401ae17ad3b15bbae28aravind}
51fb7fe50a88ca9bde74e9a401ae17ad3b15bbae28aravind
528d6a3e8321a7767cb2ca0930b85d5d488a8cc659Jason Evansbool
538fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evanschunk_commit(void *chunk, size_t size, size_t offset, size_t length,
548fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans    unsigned arena_ind)
55fb7fe50a88ca9bde74e9a401ae17ad3b15bbae28aravind{
5603bf5b67be92db3a49f81816dccb5c18c0f2a0c0Jason Evans	bool err;
57fb7fe50a88ca9bde74e9a401ae17ad3b15bbae28aravind
588fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans	TRACE_HOOK("%s(chunk=%p, size=%zu, offset=%zu, length=%zu, "
598fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans	    "arena_ind=%u)\n", __func__, chunk, size, offset, length,
608fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans	    arena_ind);
6103bf5b67be92db3a49f81816dccb5c18c0f2a0c0Jason Evans	err = old_hooks.commit(chunk, size, offset, length, arena_ind);
6203bf5b67be92db3a49f81816dccb5c18c0f2a0c0Jason Evans	did_commit = !err;
6303bf5b67be92db3a49f81816dccb5c18c0f2a0c0Jason Evans	return (err);
64fb7fe50a88ca9bde74e9a401ae17ad3b15bbae28aravind}
65fb7fe50a88ca9bde74e9a401ae17ad3b15bbae28aravind
66b49a334a645b854dbb1649f15c38d646fee66738Jason Evansbool
678fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evanschunk_decommit(void *chunk, size_t size, size_t offset, size_t length,
688fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans    unsigned arena_ind)
69fb7fe50a88ca9bde74e9a401ae17ad3b15bbae28aravind{
7003bf5b67be92db3a49f81816dccb5c18c0f2a0c0Jason Evans	bool err;
71fb7fe50a88ca9bde74e9a401ae17ad3b15bbae28aravind
728fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans	TRACE_HOOK("%s(chunk=%p, size=%zu, offset=%zu, length=%zu, "
738fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans	    "arena_ind=%u)\n", __func__, chunk, size, offset, length,
748fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans	    arena_ind);
7503bf5b67be92db3a49f81816dccb5c18c0f2a0c0Jason Evans	if (!do_decommit)
7603bf5b67be92db3a49f81816dccb5c18c0f2a0c0Jason Evans		return (true);
7703bf5b67be92db3a49f81816dccb5c18c0f2a0c0Jason Evans	err = old_hooks.decommit(chunk, size, offset, length, arena_ind);
7803bf5b67be92db3a49f81816dccb5c18c0f2a0c0Jason Evans	did_decommit = !err;
7903bf5b67be92db3a49f81816dccb5c18c0f2a0c0Jason Evans	return (err);
80b49a334a645b854dbb1649f15c38d646fee66738Jason Evans}
81fb7fe50a88ca9bde74e9a401ae17ad3b15bbae28aravind
82b49a334a645b854dbb1649f15c38d646fee66738Jason Evansbool
83b49a334a645b854dbb1649f15c38d646fee66738Jason Evanschunk_purge(void *chunk, size_t size, size_t offset, size_t length,
84b49a334a645b854dbb1649f15c38d646fee66738Jason Evans    unsigned arena_ind)
85b49a334a645b854dbb1649f15c38d646fee66738Jason Evans{
86b49a334a645b854dbb1649f15c38d646fee66738Jason Evans
87b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	TRACE_HOOK("%s(chunk=%p, size=%zu, offset=%zu, length=%zu "
88b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	    "arena_ind=%u)\n", __func__, chunk, size, offset, length,
89b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	    arena_ind);
90b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	did_purge = true;
91b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	return (old_hooks.purge(chunk, size, offset, length, arena_ind));
92b49a334a645b854dbb1649f15c38d646fee66738Jason Evans}
938d6a3e8321a7767cb2ca0930b85d5d488a8cc659Jason Evans
94b49a334a645b854dbb1649f15c38d646fee66738Jason Evansbool
95b49a334a645b854dbb1649f15c38d646fee66738Jason Evanschunk_split(void *chunk, size_t size, size_t size_a, size_t size_b,
96b49a334a645b854dbb1649f15c38d646fee66738Jason Evans    bool committed, unsigned arena_ind)
97b49a334a645b854dbb1649f15c38d646fee66738Jason Evans{
98fb7fe50a88ca9bde74e9a401ae17ad3b15bbae28aravind
99b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	TRACE_HOOK("%s(chunk=%p, size=%zu, size_a=%zu, size_b=%zu, "
100b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	    "committed=%s, arena_ind=%u)\n", __func__, chunk, size, size_a,
101b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	    size_b, committed ? "true" : "false", arena_ind);
102b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	did_split = true;
103b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	return (old_hooks.split(chunk, size, size_a, size_b, committed,
104b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	    arena_ind));
105b49a334a645b854dbb1649f15c38d646fee66738Jason Evans}
1068d6a3e8321a7767cb2ca0930b85d5d488a8cc659Jason Evans
107b49a334a645b854dbb1649f15c38d646fee66738Jason Evansbool
108b49a334a645b854dbb1649f15c38d646fee66738Jason Evanschunk_merge(void *chunk_a, size_t size_a, void *chunk_b, size_t size_b,
109b49a334a645b854dbb1649f15c38d646fee66738Jason Evans    bool committed, unsigned arena_ind)
110b49a334a645b854dbb1649f15c38d646fee66738Jason Evans{
111b49a334a645b854dbb1649f15c38d646fee66738Jason Evans
112b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	TRACE_HOOK("%s(chunk_a=%p, size_a=%zu, chunk_b=%p size_b=%zu, "
113b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	    "committed=%s, arena_ind=%u)\n", __func__, chunk_a, size_a, chunk_b,
114b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	    size_b, committed ? "true" : "false", arena_ind);
115b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	did_merge = true;
116b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	return (old_hooks.merge(chunk_a, size_a, chunk_b, size_b,
117b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	    committed, arena_ind));
118b49a334a645b854dbb1649f15c38d646fee66738Jason Evans}
119b49a334a645b854dbb1649f15c38d646fee66738Jason Evans
120b49a334a645b854dbb1649f15c38d646fee66738Jason EvansTEST_BEGIN(test_chunk)
121b49a334a645b854dbb1649f15c38d646fee66738Jason Evans{
122b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	void *p;
1238fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans	size_t old_size, new_size, large0, large1, huge0, huge1, huge2, sz;
124b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	chunk_hooks_t new_hooks = {
125b49a334a645b854dbb1649f15c38d646fee66738Jason Evans		chunk_alloc,
126b49a334a645b854dbb1649f15c38d646fee66738Jason Evans		chunk_dalloc,
127b49a334a645b854dbb1649f15c38d646fee66738Jason Evans		chunk_commit,
128b49a334a645b854dbb1649f15c38d646fee66738Jason Evans		chunk_decommit,
129b49a334a645b854dbb1649f15c38d646fee66738Jason Evans		chunk_purge,
130b49a334a645b854dbb1649f15c38d646fee66738Jason Evans		chunk_split,
131b49a334a645b854dbb1649f15c38d646fee66738Jason Evans		chunk_merge
132b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	};
133828d919b5ec9d8f4438f80d160a6c8c9a871d1e1Jason Evans	bool xallocx_success_a, xallocx_success_b, xallocx_success_c;
134b49a334a645b854dbb1649f15c38d646fee66738Jason Evans
135b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	/* Install custom chunk hooks. */
136b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	old_size = sizeof(chunk_hooks_t);
137b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	new_size = sizeof(chunk_hooks_t);
138b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	assert_d_eq(mallctl("arena.0.chunk_hooks", &old_hooks, &old_size,
139b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	    &new_hooks, new_size), 0, "Unexpected chunk_hooks error");
140b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	orig_hooks = old_hooks;
141b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	assert_ptr_ne(old_hooks.alloc, chunk_alloc, "Unexpected alloc error");
142b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	assert_ptr_ne(old_hooks.dalloc, chunk_dalloc,
143b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	    "Unexpected dalloc error");
144b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	assert_ptr_ne(old_hooks.commit, chunk_commit,
145b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	    "Unexpected commit error");
146b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	assert_ptr_ne(old_hooks.decommit, chunk_decommit,
147b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	    "Unexpected decommit error");
148b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	assert_ptr_ne(old_hooks.purge, chunk_purge, "Unexpected purge error");
149b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	assert_ptr_ne(old_hooks.split, chunk_split, "Unexpected split error");
150b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	assert_ptr_ne(old_hooks.merge, chunk_merge, "Unexpected merge error");
151b49a334a645b854dbb1649f15c38d646fee66738Jason Evans
1528fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans	/* Get large size classes. */
1538d6a3e8321a7767cb2ca0930b85d5d488a8cc659Jason Evans	sz = sizeof(size_t);
1548fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans	assert_d_eq(mallctl("arenas.lrun.0.size", &large0, &sz, NULL, 0), 0,
1558fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans	    "Unexpected arenas.lrun.0.size failure");
1568fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans	assert_d_eq(mallctl("arenas.lrun.1.size", &large1, &sz, NULL, 0), 0,
1578fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans	    "Unexpected arenas.lrun.1.size failure");
1588fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans
1598fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans	/* Get huge size classes. */
1608d6a3e8321a7767cb2ca0930b85d5d488a8cc659Jason Evans	assert_d_eq(mallctl("arenas.hchunk.0.size", &huge0, &sz, NULL, 0), 0,
1618d6a3e8321a7767cb2ca0930b85d5d488a8cc659Jason Evans	    "Unexpected arenas.hchunk.0.size failure");
1628d6a3e8321a7767cb2ca0930b85d5d488a8cc659Jason Evans	assert_d_eq(mallctl("arenas.hchunk.1.size", &huge1, &sz, NULL, 0), 0,
1638d6a3e8321a7767cb2ca0930b85d5d488a8cc659Jason Evans	    "Unexpected arenas.hchunk.1.size failure");
1648d6a3e8321a7767cb2ca0930b85d5d488a8cc659Jason Evans	assert_d_eq(mallctl("arenas.hchunk.2.size", &huge2, &sz, NULL, 0), 0,
1658d6a3e8321a7767cb2ca0930b85d5d488a8cc659Jason Evans	    "Unexpected arenas.hchunk.2.size failure");
166b49a334a645b854dbb1649f15c38d646fee66738Jason Evans
167b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	/* Test dalloc/decommit/purge cascade. */
168b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	do_dalloc = false;
169b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	do_decommit = false;
170b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	p = mallocx(huge0 * 2, 0);
171b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	assert_ptr_not_null(p, "Unexpected mallocx() error");
172b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	did_dalloc = false;
173b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	did_decommit = false;
174b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	did_purge = false;
175828d919b5ec9d8f4438f80d160a6c8c9a871d1e1Jason Evans	did_split = false;
176828d919b5ec9d8f4438f80d160a6c8c9a871d1e1Jason Evans	xallocx_success_a = (xallocx(p, huge0, 0, 0) == huge0);
177b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	assert_d_eq(mallctl("arena.0.purge", NULL, NULL, NULL, 0), 0,
178b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	    "Unexpected arena.0.purge error");
179828d919b5ec9d8f4438f80d160a6c8c9a871d1e1Jason Evans	if (xallocx_success_a) {
180828d919b5ec9d8f4438f80d160a6c8c9a871d1e1Jason Evans		assert_true(did_dalloc, "Expected dalloc");
181828d919b5ec9d8f4438f80d160a6c8c9a871d1e1Jason Evans		assert_false(did_decommit, "Unexpected decommit");
182828d919b5ec9d8f4438f80d160a6c8c9a871d1e1Jason Evans		assert_true(did_purge, "Expected purge");
183828d919b5ec9d8f4438f80d160a6c8c9a871d1e1Jason Evans	}
184828d919b5ec9d8f4438f80d160a6c8c9a871d1e1Jason Evans	assert_true(did_split, "Expected split");
185b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	dallocx(p, 0);
186b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	do_dalloc = true;
187b49a334a645b854dbb1649f15c38d646fee66738Jason Evans
188b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	/* Test decommit/commit and observe split/merge. */
189b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	do_dalloc = false;
190b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	do_decommit = true;
191b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	p = mallocx(huge0 * 2, 0);
192b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	assert_ptr_not_null(p, "Unexpected mallocx() error");
193b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	did_decommit = false;
194b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	did_commit = false;
195b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	did_split = false;
196b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	did_merge = false;
197828d919b5ec9d8f4438f80d160a6c8c9a871d1e1Jason Evans	xallocx_success_b = (xallocx(p, huge0, 0, 0) == huge0);
198b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	assert_d_eq(mallctl("arena.0.purge", NULL, NULL, NULL, 0), 0,
199b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	    "Unexpected arena.0.purge error");
200828d919b5ec9d8f4438f80d160a6c8c9a871d1e1Jason Evans	if (xallocx_success_b)
201828d919b5ec9d8f4438f80d160a6c8c9a871d1e1Jason Evans		assert_true(did_split, "Expected split");
202828d919b5ec9d8f4438f80d160a6c8c9a871d1e1Jason Evans	xallocx_success_c = (xallocx(p, huge0 * 2, 0, 0) == huge0 * 2);
20303bf5b67be92db3a49f81816dccb5c18c0f2a0c0Jason Evans	assert_b_eq(did_decommit, did_commit, "Expected decommit/commit match");
204828d919b5ec9d8f4438f80d160a6c8c9a871d1e1Jason Evans	if (xallocx_success_b && xallocx_success_c)
205828d919b5ec9d8f4438f80d160a6c8c9a871d1e1Jason Evans		assert_true(did_merge, "Expected merge");
206b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	dallocx(p, 0);
207b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	do_dalloc = true;
208b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	do_decommit = false;
209b49a334a645b854dbb1649f15c38d646fee66738Jason Evans
210b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	/* Test purge for partial-chunk huge allocations. */
2118d6a3e8321a7767cb2ca0930b85d5d488a8cc659Jason Evans	if (huge0 * 2 > huge2) {
2128d6a3e8321a7767cb2ca0930b85d5d488a8cc659Jason Evans		/*
213d059b9d6a1ac3e7f834260ba001bf0d1599fb0bfJason Evans		 * There are at least four size classes per doubling, so a
214d059b9d6a1ac3e7f834260ba001bf0d1599fb0bfJason Evans		 * successful xallocx() from size=huge2 to size=huge1 is
215d059b9d6a1ac3e7f834260ba001bf0d1599fb0bfJason Evans		 * guaranteed to leave trailing purgeable memory.
2168d6a3e8321a7767cb2ca0930b85d5d488a8cc659Jason Evans		 */
2178d6a3e8321a7767cb2ca0930b85d5d488a8cc659Jason Evans		p = mallocx(huge2, 0);
2188d6a3e8321a7767cb2ca0930b85d5d488a8cc659Jason Evans		assert_ptr_not_null(p, "Unexpected mallocx() error");
219b49a334a645b854dbb1649f15c38d646fee66738Jason Evans		did_purge = false;
2208d6a3e8321a7767cb2ca0930b85d5d488a8cc659Jason Evans		assert_zu_eq(xallocx(p, huge1, 0, 0), huge1,
2218d6a3e8321a7767cb2ca0930b85d5d488a8cc659Jason Evans		    "Unexpected xallocx() failure");
2228fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans		assert_true(did_purge, "Expected purge");
2238d6a3e8321a7767cb2ca0930b85d5d488a8cc659Jason Evans		dallocx(p, 0);
2248d6a3e8321a7767cb2ca0930b85d5d488a8cc659Jason Evans	}
2258d6a3e8321a7767cb2ca0930b85d5d488a8cc659Jason Evans
2268fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans	/* Test decommit for large allocations. */
2278fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans	do_decommit = true;
2288fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans	p = mallocx(large1, 0);
2298fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans	assert_ptr_not_null(p, "Unexpected mallocx() error");
2308fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans	assert_d_eq(mallctl("arena.0.purge", NULL, NULL, NULL, 0), 0,
2318fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans	    "Unexpected arena.0.purge error");
2328fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans	did_decommit = false;
2338fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans	assert_zu_eq(xallocx(p, large0, 0, 0), large0,
2348fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans	    "Unexpected xallocx() failure");
2358fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans	assert_d_eq(mallctl("arena.0.purge", NULL, NULL, NULL, 0), 0,
2368fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans	    "Unexpected arena.0.purge error");
2378fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans	did_commit = false;
2388fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans	assert_zu_eq(xallocx(p, large1, 0, 0), large1,
2398fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans	    "Unexpected xallocx() failure");
24003bf5b67be92db3a49f81816dccb5c18c0f2a0c0Jason Evans	assert_b_eq(did_decommit, did_commit, "Expected decommit/commit match");
2418fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans	dallocx(p, 0);
2428fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans	do_decommit = false;
2438fadb1a8c2d0219aded566bc5fac7d29cff9bb67Jason Evans
244b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	/* Make sure non-huge allocation succeeds. */
245fb7fe50a88ca9bde74e9a401ae17ad3b15bbae28aravind	p = mallocx(42, 0);
2468d6a3e8321a7767cb2ca0930b85d5d488a8cc659Jason Evans	assert_ptr_not_null(p, "Unexpected mallocx() error");
247b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	dallocx(p, 0);
248b49a334a645b854dbb1649f15c38d646fee66738Jason Evans
249b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	/* Restore chunk hooks. */
250b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	assert_d_eq(mallctl("arena.0.chunk_hooks", NULL, NULL, &old_hooks,
251b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	    new_size), 0, "Unexpected chunk_hooks error");
252b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	assert_d_eq(mallctl("arena.0.chunk_hooks", &old_hooks, &old_size,
253b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	    NULL, 0), 0, "Unexpected chunk_hooks error");
254b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	assert_ptr_eq(old_hooks.alloc, orig_hooks.alloc,
255b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	    "Unexpected alloc error");
256b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	assert_ptr_eq(old_hooks.dalloc, orig_hooks.dalloc,
257b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	    "Unexpected dalloc error");
258b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	assert_ptr_eq(old_hooks.commit, orig_hooks.commit,
259b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	    "Unexpected commit error");
260b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	assert_ptr_eq(old_hooks.decommit, orig_hooks.decommit,
261b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	    "Unexpected decommit error");
262b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	assert_ptr_eq(old_hooks.purge, orig_hooks.purge,
263b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	    "Unexpected purge error");
264b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	assert_ptr_eq(old_hooks.split, orig_hooks.split,
265b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	    "Unexpected split error");
266b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	assert_ptr_eq(old_hooks.merge, orig_hooks.merge,
267b49a334a645b854dbb1649f15c38d646fee66738Jason Evans	    "Unexpected merge error");
268fb7fe50a88ca9bde74e9a401ae17ad3b15bbae28aravind}
269fb7fe50a88ca9bde74e9a401ae17ad3b15bbae28aravindTEST_END
270fb7fe50a88ca9bde74e9a401ae17ad3b15bbae28aravind
271fb7fe50a88ca9bde74e9a401ae17ad3b15bbae28aravindint
272fb7fe50a88ca9bde74e9a401ae17ad3b15bbae28aravindmain(void)
273fb7fe50a88ca9bde74e9a401ae17ad3b15bbae28aravind{
274fb7fe50a88ca9bde74e9a401ae17ad3b15bbae28aravind
275fb7fe50a88ca9bde74e9a401ae17ad3b15bbae28aravind	return (test(test_chunk));
276fb7fe50a88ca9bde74e9a401ae17ad3b15bbae28aravind}
277