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