Jason Evans | d82a5e6 | 2013-12-12 22:35:52 -0800 | [diff] [blame] | 1 | #include "test/jemalloc_test.h" |
| 2 | |
Jason Evans | fed1f9f | 2015-10-01 13:48:09 -0700 | [diff] [blame] | 3 | /* |
| 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. |
| 7 | */ |
| 8 | static unsigned |
| 9 | arena_ind(void) |
| 10 | { |
| 11 | static unsigned ind = 0; |
| 12 | |
| 13 | if (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"); |
| 17 | } |
| 18 | |
| 19 | return (ind); |
| 20 | } |
| 21 | |
Jason Evans | d82a5e6 | 2013-12-12 22:35:52 -0800 | [diff] [blame] | 22 | TEST_BEGIN(test_same_size) |
| 23 | { |
| 24 | void *p; |
| 25 | size_t sz, tsz; |
| 26 | |
| 27 | p = mallocx(42, 0); |
| 28 | assert_ptr_not_null(p, "Unexpected mallocx() error"); |
| 29 | sz = sallocx(p, 0); |
| 30 | |
| 31 | tsz = xallocx(p, sz, 0, 0); |
| 32 | assert_zu_eq(tsz, sz, "Unexpected size change: %zu --> %zu", sz, tsz); |
| 33 | |
| 34 | dallocx(p, 0); |
| 35 | } |
| 36 | TEST_END |
| 37 | |
| 38 | TEST_BEGIN(test_extra_no_move) |
| 39 | { |
| 40 | void *p; |
| 41 | size_t sz, tsz; |
| 42 | |
| 43 | p = mallocx(42, 0); |
| 44 | assert_ptr_not_null(p, "Unexpected mallocx() error"); |
| 45 | sz = sallocx(p, 0); |
| 46 | |
| 47 | tsz = xallocx(p, sz, sz-42, 0); |
| 48 | assert_zu_eq(tsz, sz, "Unexpected size change: %zu --> %zu", sz, tsz); |
| 49 | |
| 50 | dallocx(p, 0); |
| 51 | } |
| 52 | TEST_END |
| 53 | |
| 54 | TEST_BEGIN(test_no_move_fail) |
| 55 | { |
| 56 | void *p; |
| 57 | size_t sz, tsz; |
| 58 | |
| 59 | p = mallocx(42, 0); |
| 60 | assert_ptr_not_null(p, "Unexpected mallocx() error"); |
| 61 | sz = sallocx(p, 0); |
| 62 | |
| 63 | tsz = xallocx(p, sz + 5, 0, 0); |
| 64 | assert_zu_eq(tsz, sz, "Unexpected size change: %zu --> %zu", sz, tsz); |
| 65 | |
| 66 | dallocx(p, 0); |
| 67 | } |
| 68 | TEST_END |
| 69 | |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 70 | static unsigned |
| 71 | get_nsizes_impl(const char *cmd) |
| 72 | { |
| 73 | unsigned ret; |
| 74 | size_t z; |
| 75 | |
| 76 | z = sizeof(unsigned); |
| 77 | assert_d_eq(mallctl(cmd, &ret, &z, NULL, 0), 0, |
| 78 | "Unexpected mallctl(\"%s\", ...) failure", cmd); |
| 79 | |
| 80 | return (ret); |
| 81 | } |
| 82 | |
| 83 | static unsigned |
| 84 | get_nsmall(void) |
| 85 | { |
| 86 | |
| 87 | return (get_nsizes_impl("arenas.nbins")); |
| 88 | } |
| 89 | |
| 90 | static unsigned |
| 91 | get_nlarge(void) |
| 92 | { |
| 93 | |
| 94 | return (get_nsizes_impl("arenas.nlruns")); |
| 95 | } |
| 96 | |
| 97 | static unsigned |
| 98 | get_nhuge(void) |
| 99 | { |
| 100 | |
| 101 | return (get_nsizes_impl("arenas.nhchunks")); |
| 102 | } |
| 103 | |
| 104 | static size_t |
| 105 | get_size_impl(const char *cmd, size_t ind) |
| 106 | { |
| 107 | size_t ret; |
| 108 | size_t z; |
| 109 | size_t mib[4]; |
| 110 | size_t miblen = 4; |
| 111 | |
| 112 | z = sizeof(size_t); |
| 113 | assert_d_eq(mallctlnametomib(cmd, mib, &miblen), |
| 114 | 0, "Unexpected mallctlnametomib(\"%s\", ...) failure", cmd); |
| 115 | mib[2] = ind; |
| 116 | z = sizeof(size_t); |
| 117 | assert_d_eq(mallctlbymib(mib, miblen, &ret, &z, NULL, 0), |
| 118 | 0, "Unexpected mallctlbymib([\"%s\", %zu], ...) failure", cmd, ind); |
| 119 | |
| 120 | return (ret); |
| 121 | } |
| 122 | |
| 123 | static size_t |
| 124 | get_small_size(size_t ind) |
| 125 | { |
| 126 | |
| 127 | return (get_size_impl("arenas.bin.0.size", ind)); |
| 128 | } |
| 129 | |
| 130 | static size_t |
| 131 | get_large_size(size_t ind) |
| 132 | { |
| 133 | |
| 134 | return (get_size_impl("arenas.lrun.0.size", ind)); |
| 135 | } |
| 136 | |
| 137 | static size_t |
| 138 | get_huge_size(size_t ind) |
| 139 | { |
| 140 | |
| 141 | return (get_size_impl("arenas.hchunk.0.size", ind)); |
| 142 | } |
| 143 | |
Jason Evans | aca490f | 2015-09-15 14:39:29 -0700 | [diff] [blame] | 144 | TEST_BEGIN(test_size) |
| 145 | { |
| 146 | size_t small0, hugemax; |
| 147 | void *p; |
| 148 | |
| 149 | /* Get size classes. */ |
| 150 | small0 = get_small_size(0); |
| 151 | hugemax = get_huge_size(get_nhuge()-1); |
| 152 | |
| 153 | p = mallocx(small0, 0); |
| 154 | assert_ptr_not_null(p, "Unexpected mallocx() error"); |
| 155 | |
| 156 | /* Test smallest supported size. */ |
| 157 | assert_zu_eq(xallocx(p, 1, 0, 0), small0, |
| 158 | "Unexpected xallocx() behavior"); |
| 159 | |
| 160 | /* Test largest supported size. */ |
| 161 | assert_zu_le(xallocx(p, hugemax, 0, 0), hugemax, |
| 162 | "Unexpected xallocx() behavior"); |
| 163 | |
| 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"); |
| 169 | |
| 170 | dallocx(p, 0); |
| 171 | } |
| 172 | TEST_END |
| 173 | |
| 174 | TEST_BEGIN(test_size_extra_overflow) |
| 175 | { |
| 176 | size_t small0, hugemax; |
| 177 | void *p; |
| 178 | |
| 179 | /* Get size classes. */ |
| 180 | small0 = get_small_size(0); |
| 181 | hugemax = get_huge_size(get_nhuge()-1); |
| 182 | |
| 183 | p = mallocx(small0, 0); |
| 184 | assert_ptr_not_null(p, "Unexpected mallocx() error"); |
| 185 | |
| 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"); |
| 191 | |
| 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"); |
| 201 | |
| 202 | dallocx(p, 0); |
| 203 | } |
| 204 | TEST_END |
| 205 | |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 206 | TEST_BEGIN(test_extra_small) |
| 207 | { |
| 208 | size_t small0, small1, hugemax; |
| 209 | void *p; |
| 210 | |
| 211 | /* Get size classes. */ |
| 212 | small0 = get_small_size(0); |
| 213 | small1 = get_small_size(1); |
| 214 | hugemax = get_huge_size(get_nhuge()-1); |
| 215 | |
| 216 | p = mallocx(small0, 0); |
| 217 | assert_ptr_not_null(p, "Unexpected mallocx() error"); |
| 218 | |
| 219 | assert_zu_eq(xallocx(p, small1, 0, 0), small0, |
| 220 | "Unexpected xallocx() behavior"); |
| 221 | |
| 222 | assert_zu_eq(xallocx(p, small1, 0, 0), small0, |
| 223 | "Unexpected xallocx() behavior"); |
| 224 | |
| 225 | assert_zu_eq(xallocx(p, small0, small1 - small0, 0), small0, |
| 226 | "Unexpected xallocx() behavior"); |
| 227 | |
| 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"); |
| 233 | |
| 234 | dallocx(p, 0); |
| 235 | } |
| 236 | TEST_END |
| 237 | |
| 238 | TEST_BEGIN(test_extra_large) |
| 239 | { |
Jason Evans | fed1f9f | 2015-10-01 13:48:09 -0700 | [diff] [blame] | 240 | int flags = MALLOCX_ARENA(arena_ind()); |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 241 | size_t smallmax, large0, large1, large2, huge0, hugemax; |
| 242 | void *p; |
| 243 | |
| 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); |
| 251 | |
Jason Evans | fed1f9f | 2015-10-01 13:48:09 -0700 | [diff] [blame] | 252 | p = mallocx(large2, flags); |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 253 | assert_ptr_not_null(p, "Unexpected mallocx() error"); |
| 254 | |
Jason Evans | fed1f9f | 2015-10-01 13:48:09 -0700 | [diff] [blame] | 255 | assert_zu_eq(xallocx(p, large2, 0, flags), large2, |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 256 | "Unexpected xallocx() behavior"); |
| 257 | /* Test size decrease with zero extra. */ |
Jason Evans | fed1f9f | 2015-10-01 13:48:09 -0700 | [diff] [blame] | 258 | assert_zu_eq(xallocx(p, large0, 0, flags), large0, |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 259 | "Unexpected xallocx() behavior"); |
Jason Evans | fed1f9f | 2015-10-01 13:48:09 -0700 | [diff] [blame] | 260 | assert_zu_eq(xallocx(p, smallmax, 0, flags), large0, |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 261 | "Unexpected xallocx() behavior"); |
| 262 | |
Jason Evans | fed1f9f | 2015-10-01 13:48:09 -0700 | [diff] [blame] | 263 | assert_zu_eq(xallocx(p, large2, 0, flags), large2, |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 264 | "Unexpected xallocx() behavior"); |
| 265 | /* Test size decrease with non-zero extra. */ |
Jason Evans | fed1f9f | 2015-10-01 13:48:09 -0700 | [diff] [blame] | 266 | assert_zu_eq(xallocx(p, large0, large2 - large0, flags), large2, |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 267 | "Unexpected xallocx() behavior"); |
Jason Evans | fed1f9f | 2015-10-01 13:48:09 -0700 | [diff] [blame] | 268 | assert_zu_eq(xallocx(p, large1, large2 - large1, flags), large2, |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 269 | "Unexpected xallocx() behavior"); |
Jason Evans | fed1f9f | 2015-10-01 13:48:09 -0700 | [diff] [blame] | 270 | assert_zu_eq(xallocx(p, large0, large1 - large0, flags), large1, |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 271 | "Unexpected xallocx() behavior"); |
Jason Evans | fed1f9f | 2015-10-01 13:48:09 -0700 | [diff] [blame] | 272 | assert_zu_eq(xallocx(p, smallmax, large0 - smallmax, flags), large0, |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 273 | "Unexpected xallocx() behavior"); |
| 274 | |
Jason Evans | fed1f9f | 2015-10-01 13:48:09 -0700 | [diff] [blame] | 275 | assert_zu_eq(xallocx(p, large0, 0, flags), large0, |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 276 | "Unexpected xallocx() behavior"); |
| 277 | /* Test size increase with zero extra. */ |
Jason Evans | fed1f9f | 2015-10-01 13:48:09 -0700 | [diff] [blame] | 278 | assert_zu_eq(xallocx(p, large2, 0, flags), large2, |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 279 | "Unexpected xallocx() behavior"); |
Jason Evans | fed1f9f | 2015-10-01 13:48:09 -0700 | [diff] [blame] | 280 | assert_zu_eq(xallocx(p, huge0, 0, flags), large2, |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 281 | "Unexpected xallocx() behavior"); |
| 282 | |
Jason Evans | fed1f9f | 2015-10-01 13:48:09 -0700 | [diff] [blame] | 283 | assert_zu_eq(xallocx(p, large0, 0, flags), large0, |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 284 | "Unexpected xallocx() behavior"); |
| 285 | /* Test size increase with non-zero extra. */ |
Jason Evans | fed1f9f | 2015-10-01 13:48:09 -0700 | [diff] [blame] | 286 | assert_zu_lt(xallocx(p, large0, huge0 - large0, flags), huge0, |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 287 | "Unexpected xallocx() behavior"); |
| 288 | |
Jason Evans | fed1f9f | 2015-10-01 13:48:09 -0700 | [diff] [blame] | 289 | assert_zu_eq(xallocx(p, large0, 0, flags), large0, |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 290 | "Unexpected xallocx() behavior"); |
| 291 | /* Test size increase with non-zero extra. */ |
Jason Evans | fed1f9f | 2015-10-01 13:48:09 -0700 | [diff] [blame] | 292 | assert_zu_eq(xallocx(p, large0, large2 - large0, flags), large2, |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 293 | "Unexpected xallocx() behavior"); |
| 294 | |
Jason Evans | fed1f9f | 2015-10-01 13:48:09 -0700 | [diff] [blame] | 295 | assert_zu_eq(xallocx(p, large2, 0, flags), large2, |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 296 | "Unexpected xallocx() behavior"); |
| 297 | /* Test size+extra overflow. */ |
Jason Evans | fed1f9f | 2015-10-01 13:48:09 -0700 | [diff] [blame] | 298 | assert_zu_lt(xallocx(p, large2, hugemax - large2 + 1, flags), huge0, |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 299 | "Unexpected xallocx() behavior"); |
| 300 | |
Jason Evans | fed1f9f | 2015-10-01 13:48:09 -0700 | [diff] [blame] | 301 | dallocx(p, flags); |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 302 | } |
| 303 | TEST_END |
| 304 | |
| 305 | TEST_BEGIN(test_extra_huge) |
| 306 | { |
Jason Evans | fed1f9f | 2015-10-01 13:48:09 -0700 | [diff] [blame] | 307 | int flags = MALLOCX_ARENA(arena_ind()); |
Christopher Ferris | e429403 | 2016-03-02 14:33:02 -0800 | [diff] [blame] | 308 | size_t largemax, huge1, huge2, huge3, hugemax; |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 309 | void *p; |
| 310 | |
| 311 | /* Get size classes. */ |
| 312 | largemax = get_large_size(get_nlarge()-1); |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 313 | huge1 = get_huge_size(1); |
| 314 | huge2 = get_huge_size(2); |
Christopher Ferris | e429403 | 2016-03-02 14:33:02 -0800 | [diff] [blame] | 315 | huge3 = get_huge_size(3); |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 316 | hugemax = get_huge_size(get_nhuge()-1); |
| 317 | |
Christopher Ferris | e429403 | 2016-03-02 14:33:02 -0800 | [diff] [blame] | 318 | p = mallocx(huge3, flags); |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 319 | assert_ptr_not_null(p, "Unexpected mallocx() error"); |
| 320 | |
Christopher Ferris | e429403 | 2016-03-02 14:33:02 -0800 | [diff] [blame] | 321 | assert_zu_eq(xallocx(p, huge3, 0, flags), huge3, |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 322 | "Unexpected xallocx() behavior"); |
| 323 | /* Test size decrease with zero extra. */ |
Christopher Ferris | e429403 | 2016-03-02 14:33:02 -0800 | [diff] [blame] | 324 | assert_zu_ge(xallocx(p, huge1, 0, flags), huge1, |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 325 | "Unexpected xallocx() behavior"); |
Christopher Ferris | e429403 | 2016-03-02 14:33:02 -0800 | [diff] [blame] | 326 | assert_zu_ge(xallocx(p, largemax, 0, flags), huge1, |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 327 | "Unexpected xallocx() behavior"); |
| 328 | |
Christopher Ferris | e429403 | 2016-03-02 14:33:02 -0800 | [diff] [blame] | 329 | assert_zu_eq(xallocx(p, huge3, 0, flags), huge3, |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 330 | "Unexpected xallocx() behavior"); |
| 331 | /* Test size decrease with non-zero extra. */ |
Christopher Ferris | e429403 | 2016-03-02 14:33:02 -0800 | [diff] [blame] | 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, |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 335 | "Unexpected xallocx() behavior"); |
Jason Evans | fed1f9f | 2015-10-01 13:48:09 -0700 | [diff] [blame] | 336 | assert_zu_eq(xallocx(p, huge1, huge2 - huge1, flags), huge2, |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 337 | "Unexpected xallocx() behavior"); |
Christopher Ferris | e429403 | 2016-03-02 14:33:02 -0800 | [diff] [blame] | 338 | assert_zu_ge(xallocx(p, largemax, huge1 - largemax, flags), huge1, |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 339 | "Unexpected xallocx() behavior"); |
| 340 | |
Christopher Ferris | e429403 | 2016-03-02 14:33:02 -0800 | [diff] [blame] | 341 | assert_zu_ge(xallocx(p, huge1, 0, flags), huge1, |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 342 | "Unexpected xallocx() behavior"); |
| 343 | /* Test size increase with zero extra. */ |
Christopher Ferris | e429403 | 2016-03-02 14:33:02 -0800 | [diff] [blame] | 344 | assert_zu_le(xallocx(p, huge3, 0, flags), huge3, |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 345 | "Unexpected xallocx() behavior"); |
Christopher Ferris | e429403 | 2016-03-02 14:33:02 -0800 | [diff] [blame] | 346 | assert_zu_le(xallocx(p, hugemax+1, 0, flags), huge3, |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 347 | "Unexpected xallocx() behavior"); |
| 348 | |
Christopher Ferris | e429403 | 2016-03-02 14:33:02 -0800 | [diff] [blame] | 349 | assert_zu_ge(xallocx(p, huge1, 0, flags), huge1, |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 350 | "Unexpected xallocx() behavior"); |
| 351 | /* Test size increase with non-zero extra. */ |
Christopher Ferris | e429403 | 2016-03-02 14:33:02 -0800 | [diff] [blame] | 352 | assert_zu_le(xallocx(p, huge1, SIZE_T_MAX - huge1, flags), hugemax, |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 353 | "Unexpected xallocx() behavior"); |
| 354 | |
Christopher Ferris | e429403 | 2016-03-02 14:33:02 -0800 | [diff] [blame] | 355 | assert_zu_ge(xallocx(p, huge1, 0, flags), huge1, |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 356 | "Unexpected xallocx() behavior"); |
| 357 | /* Test size increase with non-zero extra. */ |
Christopher Ferris | e429403 | 2016-03-02 14:33:02 -0800 | [diff] [blame] | 358 | assert_zu_le(xallocx(p, huge1, huge3 - huge1, flags), huge3, |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 359 | "Unexpected xallocx() behavior"); |
| 360 | |
Christopher Ferris | e429403 | 2016-03-02 14:33:02 -0800 | [diff] [blame] | 361 | assert_zu_eq(xallocx(p, huge3, 0, flags), huge3, |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 362 | "Unexpected xallocx() behavior"); |
| 363 | /* Test size+extra overflow. */ |
Christopher Ferris | e429403 | 2016-03-02 14:33:02 -0800 | [diff] [blame] | 364 | assert_zu_le(xallocx(p, huge3, hugemax - huge3 + 1, flags), hugemax, |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 365 | "Unexpected xallocx() behavior"); |
| 366 | |
Jason Evans | fed1f9f | 2015-10-01 13:48:09 -0700 | [diff] [blame] | 367 | dallocx(p, flags); |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 368 | } |
| 369 | TEST_END |
| 370 | |
Jason Evans | d260f44 | 2015-09-24 16:38:45 -0700 | [diff] [blame] | 371 | static void |
| 372 | print_filled_extents(const void *p, uint8_t c, size_t len) |
| 373 | { |
| 374 | const uint8_t *pc = (const uint8_t *)p; |
| 375 | size_t i, range0; |
| 376 | uint8_t c0; |
| 377 | |
| 378 | malloc_printf(" p=%p, c=%#x, len=%zu:", p, c, len); |
| 379 | range0 = 0; |
| 380 | c0 = pc[0]; |
| 381 | for (i = 0; i < len; i++) { |
| 382 | if (pc[i] != c0) { |
| 383 | malloc_printf(" %#x[%zu..%zu)", c0, range0, i); |
| 384 | range0 = i; |
| 385 | c0 = pc[i]; |
| 386 | } |
| 387 | } |
| 388 | malloc_printf(" %#x[%zu..%zu)\n", c0, range0, i); |
| 389 | } |
| 390 | |
| 391 | static bool |
| 392 | validate_fill(const void *p, uint8_t c, size_t offset, size_t len) |
| 393 | { |
| 394 | const uint8_t *pc = (const uint8_t *)p; |
| 395 | bool err; |
| 396 | size_t i; |
| 397 | |
| 398 | for (i = offset, err = false; i < offset+len; i++) { |
| 399 | if (pc[i] != c) |
| 400 | err = true; |
| 401 | } |
| 402 | |
| 403 | if (err) |
| 404 | print_filled_extents(p, c, offset + len); |
| 405 | |
| 406 | return (err); |
| 407 | } |
| 408 | |
| 409 | static void |
| 410 | test_zero(size_t szmin, size_t szmax) |
| 411 | { |
Jason Evans | fed1f9f | 2015-10-01 13:48:09 -0700 | [diff] [blame] | 412 | int flags = MALLOCX_ARENA(arena_ind()) | MALLOCX_ZERO; |
Jason Evans | d260f44 | 2015-09-24 16:38:45 -0700 | [diff] [blame] | 413 | size_t sz, nsz; |
| 414 | void *p; |
| 415 | #define FILL_BYTE 0x7aU |
| 416 | |
| 417 | sz = szmax; |
Jason Evans | fed1f9f | 2015-10-01 13:48:09 -0700 | [diff] [blame] | 418 | p = mallocx(sz, flags); |
Jason Evans | d260f44 | 2015-09-24 16:38:45 -0700 | [diff] [blame] | 419 | assert_ptr_not_null(p, "Unexpected mallocx() error"); |
| 420 | assert_false(validate_fill(p, 0x00, 0, sz), "Memory not filled: sz=%zu", |
| 421 | sz); |
| 422 | |
| 423 | /* |
| 424 | * Fill with non-zero so that non-debug builds are more likely to detect |
| 425 | * errors. |
| 426 | */ |
| 427 | memset(p, FILL_BYTE, sz); |
| 428 | assert_false(validate_fill(p, FILL_BYTE, 0, sz), |
| 429 | "Memory not filled: sz=%zu", sz); |
| 430 | |
| 431 | /* Shrink in place so that we can expect growing in place to succeed. */ |
| 432 | sz = szmin; |
Jason Evans | fed1f9f | 2015-10-01 13:48:09 -0700 | [diff] [blame] | 433 | assert_zu_eq(xallocx(p, sz, 0, flags), sz, |
Jason Evans | d260f44 | 2015-09-24 16:38:45 -0700 | [diff] [blame] | 434 | "Unexpected xallocx() error"); |
| 435 | assert_false(validate_fill(p, FILL_BYTE, 0, sz), |
| 436 | "Memory not filled: sz=%zu", sz); |
| 437 | |
| 438 | for (sz = szmin; sz < szmax; sz = nsz) { |
Jason Evans | fed1f9f | 2015-10-01 13:48:09 -0700 | [diff] [blame] | 439 | nsz = nallocx(sz+1, flags); |
| 440 | assert_zu_eq(xallocx(p, sz+1, 0, flags), nsz, |
Jason Evans | d260f44 | 2015-09-24 16:38:45 -0700 | [diff] [blame] | 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); |
| 449 | } |
| 450 | |
Jason Evans | fed1f9f | 2015-10-01 13:48:09 -0700 | [diff] [blame] | 451 | dallocx(p, flags); |
Jason Evans | d260f44 | 2015-09-24 16:38:45 -0700 | [diff] [blame] | 452 | } |
| 453 | |
| 454 | TEST_BEGIN(test_zero_large) |
| 455 | { |
| 456 | size_t large0, largemax; |
| 457 | |
| 458 | /* Get size classes. */ |
| 459 | large0 = get_large_size(0); |
| 460 | largemax = get_large_size(get_nlarge()-1); |
| 461 | |
| 462 | test_zero(large0, largemax); |
| 463 | } |
| 464 | TEST_END |
| 465 | |
| 466 | TEST_BEGIN(test_zero_huge) |
| 467 | { |
| 468 | size_t huge0, huge1; |
Jason Evans | d260f44 | 2015-09-24 16:38:45 -0700 | [diff] [blame] | 469 | |
| 470 | /* Get size classes. */ |
| 471 | huge0 = get_huge_size(0); |
| 472 | huge1 = get_huge_size(1); |
| 473 | |
Jason Evans | d260f44 | 2015-09-24 16:38:45 -0700 | [diff] [blame] | 474 | test_zero(huge1, huge0 * 2); |
| 475 | } |
| 476 | TEST_END |
| 477 | |
Jason Evans | d82a5e6 | 2013-12-12 22:35:52 -0800 | [diff] [blame] | 478 | int |
| 479 | main(void) |
| 480 | { |
| 481 | |
| 482 | return (test( |
| 483 | test_same_size, |
| 484 | test_extra_no_move, |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 485 | test_no_move_fail, |
Jason Evans | aca490f | 2015-09-15 14:39:29 -0700 | [diff] [blame] | 486 | test_size, |
| 487 | test_size_extra_overflow, |
Jason Evans | 560a4e1 | 2015-09-11 16:18:53 -0700 | [diff] [blame] | 488 | test_extra_small, |
| 489 | test_extra_large, |
Jason Evans | d260f44 | 2015-09-24 16:38:45 -0700 | [diff] [blame] | 490 | test_extra_huge, |
| 491 | test_zero_large, |
| 492 | test_zero_huge)); |
Jason Evans | d82a5e6 | 2013-12-12 22:35:52 -0800 | [diff] [blame] | 493 | } |