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