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_overflow) 50 { 51 size_t hugemax; 52 53 hugemax = get_huge_size(get_nhuge()-1); 54 55 assert_ptr_null(mallocx(hugemax+1, 0), 56 "Expected OOM for mallocx(size=%#zx, 0)", hugemax+1); 57 58 assert_ptr_null(mallocx(ZU(PTRDIFF_MAX)+1, 0), 59 "Expected OOM for mallocx(size=%#zx, 0)", ZU(PTRDIFF_MAX)+1); 60 61 assert_ptr_null(mallocx(SIZE_T_MAX, 0), 62 "Expected OOM for mallocx(size=%#zx, 0)", SIZE_T_MAX); 63 64 assert_ptr_null(mallocx(1, MALLOCX_ALIGN(ZU(PTRDIFF_MAX)+1)), 65 "Expected OOM for mallocx(size=1, MALLOCX_ALIGN(%#zx))", 66 ZU(PTRDIFF_MAX)+1); 67 } 68 TEST_END 69 70 TEST_BEGIN(test_oom) 71 { 72 size_t hugemax, size, alignment; 73 74 hugemax = get_huge_size(get_nhuge()-1); 75 76 /* 77 * It should be impossible to allocate two objects that each consume 78 * more than half the virtual address space. 79 */ 80 { 81 void *p; 82 83 p = mallocx(hugemax, 0); 84 if (p != NULL) { 85 assert_ptr_null(mallocx(hugemax, 0), 86 "Expected OOM for mallocx(size=%#zx, 0)", hugemax); 87 dallocx(p, 0); 88 } 89 } 90 91 #if LG_SIZEOF_PTR == 3 92 size = ZU(0x8000000000000000); 93 alignment = ZU(0x8000000000000000); 94 #else 95 size = ZU(0x80000000); 96 alignment = ZU(0x80000000); 97 #endif 98 assert_ptr_null(mallocx(size, MALLOCX_ALIGN(alignment)), 99 "Expected OOM for mallocx(size=%#zx, MALLOCX_ALIGN(%#zx)", size, 100 alignment); 101 } 102 TEST_END 103 104 TEST_BEGIN(test_basic) 105 { 106 #define MAXSZ (((size_t)1) << 26) 107 size_t sz; 108 109 for (sz = 1; sz < MAXSZ; sz = nallocx(sz, 0) + 1) { 110 size_t nsz, rsz; 111 void *p; 112 nsz = nallocx(sz, 0); 113 assert_zu_ne(nsz, 0, "Unexpected nallocx() error"); 114 p = mallocx(sz, 0); 115 assert_ptr_not_null(p, "Unexpected mallocx() error"); 116 rsz = sallocx(p, 0); 117 assert_zu_ge(rsz, sz, "Real size smaller than expected"); 118 assert_zu_eq(nsz, rsz, "nallocx()/sallocx() size mismatch"); 119 dallocx(p, 0); 120 121 p = mallocx(sz, 0); 122 assert_ptr_not_null(p, "Unexpected mallocx() error"); 123 dallocx(p, 0); 124 125 nsz = nallocx(sz, MALLOCX_ZERO); 126 assert_zu_ne(nsz, 0, "Unexpected nallocx() error"); 127 p = mallocx(sz, MALLOCX_ZERO); 128 assert_ptr_not_null(p, "Unexpected mallocx() error"); 129 rsz = sallocx(p, 0); 130 assert_zu_eq(nsz, rsz, "nallocx()/sallocx() rsize mismatch"); 131 dallocx(p, 0); 132 } 133 #undef MAXSZ 134 } 135 TEST_END 136 137 TEST_BEGIN(test_alignment_and_size) 138 { 139 #define MAXALIGN (((size_t)1) << 25) 140 #define NITER 4 141 size_t nsz, rsz, sz, alignment, total; 142 unsigned i; 143 void *ps[NITER]; 144 145 for (i = 0; i < NITER; i++) 146 ps[i] = NULL; 147 148 for (alignment = 8; 149 alignment <= MAXALIGN; 150 alignment <<= 1) { 151 total = 0; 152 for (sz = 1; 153 sz < 3 * alignment && sz < (1U << 31); 154 sz += (alignment >> (LG_SIZEOF_PTR-1)) - 1) { 155 for (i = 0; i < NITER; i++) { 156 nsz = nallocx(sz, MALLOCX_ALIGN(alignment) | 157 MALLOCX_ZERO); 158 assert_zu_ne(nsz, 0, 159 "nallocx() error for alignment=%zu, " 160 "size=%zu (%#zx)", alignment, sz, sz); 161 ps[i] = mallocx(sz, MALLOCX_ALIGN(alignment) | 162 MALLOCX_ZERO); 163 assert_ptr_not_null(ps[i], 164 "mallocx() error for alignment=%zu, " 165 "size=%zu (%#zx)", alignment, sz, sz); 166 rsz = sallocx(ps[i], 0); 167 assert_zu_ge(rsz, sz, 168 "Real size smaller than expected for " 169 "alignment=%zu, size=%zu", alignment, sz); 170 assert_zu_eq(nsz, rsz, 171 "nallocx()/sallocx() size mismatch for " 172 "alignment=%zu, size=%zu", alignment, sz); 173 assert_ptr_null( 174 (void *)((uintptr_t)ps[i] & (alignment-1)), 175 "%p inadequately aligned for" 176 " alignment=%zu, size=%zu", ps[i], 177 alignment, sz); 178 total += rsz; 179 if (total >= (MAXALIGN << 1)) 180 break; 181 } 182 for (i = 0; i < NITER; i++) { 183 if (ps[i] != NULL) { 184 dallocx(ps[i], 0); 185 ps[i] = NULL; 186 } 187 } 188 } 189 } 190 #undef MAXALIGN 191 #undef NITER 192 } 193 TEST_END 194 195 int 196 main(void) 197 { 198 199 return (test( 200 test_overflow, 201 test_oom, 202 test_basic, 203 test_alignment_and_size)); 204 } 205