Changeset 14d8a9b
- Timestamp:
- Sep 8, 2020, 1:33:50 PM (4 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 2b7f6f0
- Parents:
- ce55a81 (diff), dfc13bb (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/heap.cfa
rce55a81 r14d8a9b 10 10 // Created On : Tue Dec 19 21:58:35 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Sep 3 16:22:54202013 // Update Count : 9 4312 // Last Modified On : Mon Sep 7 22:17:46 2020 13 // Update Count : 957 14 14 // 15 15 … … 889 889 size_t bsize, oalign; 890 890 headers( "resize", oaddr, header, freeElem, bsize, oalign ); 891 892 891 size_t odsize = dataStorage( bsize, oaddr, header ); // data storage available in bucket 892 893 893 // same size, DO NOT preserve STICKY PROPERTIES. 894 if ( oalign <= libAlign() && size <= odsize && odsize <= size * 2 ) { // allow 50% wasted storage for smaller size894 if ( oalign == libAlign() && size <= odsize && odsize <= size * 2 ) { // allow 50% wasted storage for smaller size 895 895 header->kind.real.blockSize &= -2; // no alignment and turn off 0 fill 896 896 header->kind.real.size = size; // reset allocation size … … 931 931 size_t odsize = dataStorage( bsize, oaddr, header ); // data storage available in bucket 932 932 size_t osize = header->kind.real.size; // old allocation size 933 bool ozfill = (header->kind.real.blockSize & 2) != 0; // old allocation zero filled934 if ( unlikely( size <= odsize ) && size > odsize /2 ) { // allow up to 50% wasted storage933 bool ozfill = (header->kind.real.blockSize & 2); // old allocation zero filled 934 if ( unlikely( size <= odsize ) && odsize <= size * 2 ) { // allow up to 50% wasted storage 935 935 header->kind.real.size = size; // reset allocation size 936 936 if ( unlikely( ozfill ) && size > osize ) { // previous request zero fill and larger ? … … 947 947 948 948 void * naddr; 949 if ( likely( oalign <= libAlign() ) ) { // previous request not aligned ?949 if ( likely( oalign == libAlign() ) ) { // previous request not aligned ? 950 950 naddr = mallocNoStats( size ); // create new area 951 951 } else { … … 1231 1231 } // if 1232 1232 1233 // Attempt to reuse existing storage.1233 // Attempt to reuse existing alignment. 1234 1234 HeapManager.Storage.Header * header = headerAddr( oaddr ); 1235 if ( unlikely ( ( header->kind.fake.alignment & 1 == 1 && // old fake header ? 1236 (uintptr_t)oaddr % nalign == 0 && // lucky match ? 1237 header->kind.fake.alignment <= nalign && // ok to leave LSB at 1 1238 nalign <= 128 ) // not too much alignment storage wasted ? 1239 || ( header->kind.fake.alignment & 1 != 1 && // old real header ( aligned on libAlign ) ? 1240 nalign == libAlign() ) ) ) { // new alignment also on libAlign 1241 1242 HeapManager.FreeHeader * freeElem; 1243 size_t bsize, oalign; 1244 headers( "resize", oaddr, header, freeElem, bsize, oalign ); 1245 size_t odsize = dataStorage( bsize, oaddr, header ); // data storage available in bucket 1246 1247 if ( size <= odsize && odsize <= size * 2 ) { // allow 50% wasted data storage 1235 bool isFakeHeader = header->kind.fake.alignment & 1; // old fake header ? 1236 size_t oalign; 1237 if ( isFakeHeader ) { 1238 oalign = header->kind.fake.alignment & -2; // old alignment 1239 if ( (uintptr_t)oaddr % nalign == 0 // lucky match ? 1240 && ( oalign <= nalign // going down 1241 || (oalign >= nalign && oalign <= 256) ) // little alignment storage wasted ? 1242 ) { 1248 1243 headerAddr( oaddr )->kind.fake.alignment = nalign | 1; // update alignment (could be the same) 1249 1250 header->kind.real.blockSize &= -2; // turn off 0 fill 1251 header->kind.real.size = size; // reset allocation size 1252 return oaddr; 1253 } // if 1244 HeapManager.FreeHeader * freeElem; 1245 size_t bsize, oalign; 1246 headers( "resize", oaddr, header, freeElem, bsize, oalign ); 1247 size_t odsize = dataStorage( bsize, oaddr, header ); // data storage available in bucket 1248 1249 if ( size <= odsize && odsize <= size * 2 ) { // allow 50% wasted data storage 1250 headerAddr( oaddr )->kind.fake.alignment = nalign | 1; // update alignment (could be the same) 1251 1252 header->kind.real.blockSize &= -2; // turn off 0 fill 1253 header->kind.real.size = size; // reset allocation size 1254 return oaddr; 1255 } // if 1256 } // if 1257 } else if ( ! isFakeHeader // old real header (aligned on libAlign) ? 1258 && nalign == libAlign() ) { // new alignment also on libAlign => no fake header needed 1259 return resize( oaddr, size ); // duplicate special case checks 1254 1260 } // if 1255 1261 … … 1281 1287 } // if 1282 1288 1283 HeapManager.Storage.Header * header; 1284 HeapManager.FreeHeader * freeElem; 1285 size_t bsize, oalign; 1286 headers( "realloc", oaddr, header, freeElem, bsize, oalign ); 1287 1288 // Attempt to reuse existing storage. 1289 if ( unlikely ( ( header->kind.fake.alignment & 1 == 1 && // old fake header ? 1290 (uintptr_t)oaddr % nalign == 0 && // lucky match ? 1291 header->kind.fake.alignment <= nalign && // ok to leave LSB at 1 1292 nalign <= 128 ) // not too much alignment storage wasted ? 1293 || ( header->kind.fake.alignment & 1 != 1 && // old real header ( aligned on libAlign ) ? 1294 nalign == libAlign() ) ) ) { // new alignment also on libAlign 1295 1296 headerAddr( oaddr )->kind.fake.alignment = nalign | 1; // update alignment (could be the same) 1297 return realloc( oaddr, size ); 1298 1299 } // if 1300 1301 // change size and copy old content to new storage 1289 // Attempt to reuse existing alignment. 1290 HeapManager.Storage.Header * header = headerAddr( oaddr ); 1291 bool isFakeHeader = header->kind.fake.alignment & 1; // old fake header ? 1292 size_t oalign; 1293 if ( isFakeHeader ) { 1294 oalign = header->kind.fake.alignment & -2; // old alignment 1295 if ( (uintptr_t)oaddr % nalign == 0 // lucky match ? 1296 && ( oalign <= nalign // going down 1297 || (oalign >= nalign && oalign <= 256) ) // little alignment storage wasted ? 1298 ) { 1299 headerAddr( oaddr )->kind.fake.alignment = nalign | 1; // update alignment (could be the same) 1300 return realloc( oaddr, size ); // duplicate alignment and special case checks 1301 } // if 1302 } else if ( ! isFakeHeader // old real header (aligned on libAlign) ? 1303 && nalign == libAlign() ) // new alignment also on libAlign => no fake header needed 1304 return realloc( oaddr, size ); // duplicate alignment and special case checks 1302 1305 1303 1306 #ifdef __STATISTICS__ … … 1306 1309 #endif // __STATISTICS__ 1307 1310 1311 HeapManager.FreeHeader * freeElem; 1312 size_t bsize; 1313 headers( "realloc", oaddr, header, freeElem, bsize, oalign ); 1314 1315 // change size and copy old content to new storage 1316 1308 1317 size_t osize = header->kind.real.size; // old allocation size 1309 bool ozfill = (header->kind.real.blockSize & 2) != 0;// old allocation zero filled1318 bool ozfill = (header->kind.real.blockSize & 2); // old allocation zero filled 1310 1319 1311 1320 void * naddr = memalignNoStats( nalign, size ); // create new aligned area -
tests/alloc2.cfa
rce55a81 r14d8a9b 13 13 void test_base( void * ip, size_t size, size_t align) { 14 14 tests_total += 1; 15 // printf("DEBUG: starting test %d\n", tests_total); 15 16 bool passed = (malloc_size(ip) == size) && (malloc_usable_size(ip) >= size) && (malloc_alignment(ip) == align) && ((uintptr_t)ip % align == 0); 16 17 if (!passed) { … … 18 19 tests_failed += 1; 19 20 } 21 // printf("DEBUG: done test %d\n", tests_total); 20 22 } 21 23 22 24 void test_fill( void * ip_, size_t start, size_t end, char fill) { 23 25 tests_total += 1; 26 // printf("DEBUG: starting test %d\n", tests_total); 24 27 bool passed = true; 25 28 char * ip = (char *) ip_; … … 29 32 tests_failed += 1; 30 33 } 34 // printf("DEBUG: done test %d\n", tests_total); 31 35 } 32 36 33 37 void test_fill( void * ip_, size_t start, size_t end, int fill) { 34 38 tests_total += 1; 39 // printf("DEBUG: starting test %d\n", tests_total); 35 40 bool passed = true; 36 41 int * ip = (int *) ip_; … … 40 45 tests_failed += 1; 41 46 } 47 // printf("DEBUG: done test %d\n", tests_total); 42 48 } 43 49 44 50 void test_fill( void * ip_, size_t start, size_t end, int * fill) { 45 51 tests_total += 1; 52 // printf("DEBUG: starting test %d\n", tests_total); 46 53 bool passed = (memcmp((void*)((uintptr_t)ip_ + start), (void*)fill, end) == 0); 47 54 if (!passed) { … … 49 56 tests_failed += 1; 50 57 } 58 // printf("DEBUG: done test %d\n", tests_total); 51 59 } 52 60 53 61 void test_fill( void * ip_, size_t start, size_t end, T1 fill) { 54 62 tests_total += 1; 63 // printf("DEBUG: starting test %d\n", tests_total); 55 64 bool passed = true; 56 65 T1 * ip = (T1 *) ip_; … … 60 69 tests_failed += 1; 61 70 } 71 // printf("DEBUG: done test %d\n", tests_total); 62 72 } 63 73 64 74 void test_fill( void * ip_, size_t start, size_t end, T1 * fill) { 65 75 tests_total += 1; 76 // printf("DEBUG: starting test %d\n", tests_total); 66 77 bool passed = (memcmp((void*)((uintptr_t)ip_ + start), (void*)fill, end) == 0); 67 78 if (!passed) { … … 69 80 tests_failed += 1; 70 81 } 82 // printf("DEBUG: done test %d\n", tests_total); 71 83 } 72 84 73 85 void test_use( int * ip, size_t dim) { 74 86 tests_total += 1; 87 // printf("DEBUG: starting test %d\n", tests_total); 75 88 bool passed = true; 76 89 for (i; 0 ~ dim) ip[i] = 0xdeadbeef; … … 80 93 tests_failed += 1; 81 94 } 95 // printf("DEBUG: done test %d\n", tests_total); 82 96 } 83 97 84 98 void test_use( T1 * ip, size_t dim) { 85 99 tests_total += 1; 100 // printf("DEBUG: starting test %d\n", tests_total); 86 101 bool passed = true; 87 102 for (i; 0 ~ dim) ip[i].data = 0xdeadbeef; … … 91 106 tests_failed += 1; 92 107 } 108 // printf("DEBUG: done test %d\n", tests_total); 93 109 } 94 110 -
tests/heap.cfa
rce55a81 r14d8a9b 10 10 // Created On : Tue Nov 6 17:54:56 2018 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Aug 9 08:05:16202013 // Update Count : 5712 // Last Modified On : Mon Sep 7 18:37:41 2020 13 // Update Count : 72 14 14 // 15 15 … … 205 205 free( area ); 206 206 } // for 207 } // for 208 209 // check malloc/resize/free (sbrk) 210 211 for ( i; 2 ~ NoOfAllocs ~ 12 ) { 212 // initial N byte allocation 213 char * area = (char *)malloc( i ); 214 area[0] = '\345'; area[i - 1] = '\345'; // fill first/penultimate byte 215 216 // Do not start this loop index at 0 because resize of 0 bytes frees the storage. 217 int prev = i; 218 for ( s; i ~ 256 * 1024 ~ 26 ) { // start at initial memory request 219 if ( area[0] != '\345' || area[prev - 1] != '\345' ) abort( "malloc/resize/free corrupt storage" ); 220 area = (char *)resize( area, s ); // attempt to reuse storage 221 area[0] = area[s - 1] = '\345'; // fill last byte 222 prev = s; 223 } // for 224 free( area ); 225 } // for 226 227 // check malloc/resize/free (mmap) 228 229 for ( i; 2 ~ NoOfAllocs ~ 12 ) { 230 // initial N byte allocation 231 size_t s = i + default_mmap_start(); // cross over point 232 char * area = (char *)malloc( s ); 233 area[0] = '\345'; area[s - 1] = '\345'; // fill first/penultimate byte 234 235 // Do not start this loop index at 0 because resize of 0 bytes frees the storage. 236 int prev = s; 237 for ( r; s ~ 256 * 1024 ~ 26 ) { // start at initial memory request 238 if ( area[0] != '\345' || area[prev - 1] != '\345' ) abort( "malloc/resize/free corrupt storage" ); 239 area = (char *)resize( area, s ); // attempt to reuse storage 240 area[0] = area[r - 1] = '\345'; // fill last byte 241 prev = r; 242 } // for 243 free( area ); 244 } // for 245 246 // check malloc/realloc/free (sbrk) 247 248 for ( i; 2 ~ NoOfAllocs ~ 12 ) { 249 // initial N byte allocation 250 char * area = (char *)malloc( i ); 251 area[0] = '\345'; area[i - 1] = '\345'; // fill first/penultimate byte 252 253 // Do not start this loop index at 0 because realloc of 0 bytes frees the storage. 254 int prev = i; 255 for ( s; i ~ 256 * 1024 ~ 26 ) { // start at initial memory request 256 if ( area[0] != '\345' || area[prev - 1] != '\345' ) abort( "malloc/realloc/free corrupt storage" ); 257 area = (char *)realloc( area, s ); // attempt to reuse storage 258 area[s - 1] = '\345'; // fill last byte 259 prev = s; 260 } // for 261 free( area ); 262 } // for 263 264 // check malloc/realloc/free (mmap) 265 266 for ( i; 2 ~ NoOfAllocs ~ 12 ) { 267 // initial N byte allocation 268 size_t s = i + default_mmap_start(); // cross over point 269 char * area = (char *)malloc( s ); 270 area[0] = '\345'; area[s - 1] = '\345'; // fill first/penultimate byte 271 272 // Do not start this loop index at 0 because realloc of 0 bytes frees the storage. 273 int prev = s; 274 for ( r; s ~ 256 * 1024 ~ 26 ) { // start at initial memory request 275 if ( area[0] != '\345' || area[prev - 1] != '\345' ) abort( "malloc/realloc/free corrupt storage" ); 276 area = (char *)realloc( area, s ); // attempt to reuse storage 277 area[r - 1] = '\345'; // fill last byte 278 prev = r; 279 } // for 280 free( area ); 207 281 } // for 208 282 … … 320 394 } // for 321 395 396 // check memalign/resize with align/free 397 398 amount = 2; 399 for ( a; libAlign() ~= limit ~ a ) { // generate powers of 2 400 // initial N byte allocation 401 char * area = (char *)memalign( a, amount ); // aligned N-byte allocation 402 //sout | alignments[a] | area | endl; 403 if ( (size_t)area % a != 0 || malloc_alignment( area ) != a ) { // check for initial alignment 404 abort( "memalign/resize with align/free bad alignment : memalign(%d,%d) = %p", (int)a, (int)amount, area ); 405 } // if 406 area[0] = '\345'; area[amount - 2] = '\345'; // fill first/penultimate byte 407 408 // Do not start this loop index at 0 because resize of 0 bytes frees the storage. 409 for ( s; amount ~ 256 * 1024 ) { // start at initial memory request 410 area = (char *)resize( area, a * 2, s ); // attempt to reuse storage 411 //sout | i | area | endl; 412 if ( (size_t)area % a * 2 != 0 ) { // check for initial alignment 413 abort( "memalign/resize with align/free bad alignment %p", area ); 414 } // if 415 area[s - 1] = '\345'; // fill last byte 416 } // for 417 free( area ); 418 } // for 419 322 420 // check memalign/realloc with align/free 323 421
Note: See TracChangeset
for help on using the changeset viewer.