Changeset 14d8a9b


Ignore:
Timestamp:
Sep 8, 2020, 1:33:50 PM (4 years ago)
Author:
Thierry Delisle <tdelisle@…>
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.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Files:
3 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/heap.cfa

    rce55a81 r14d8a9b  
    1010// Created On       : Tue Dec 19 21:58:35 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Sep  3 16:22:54 2020
    13 // Update Count     : 943
     12// Last Modified On : Mon Sep  7 22:17:46 2020
     13// Update Count     : 957
    1414//
    1515
     
    889889                size_t bsize, oalign;
    890890                headers( "resize", oaddr, header, freeElem, bsize, oalign );
    891 
    892891                size_t odsize = dataStorage( bsize, oaddr, header ); // data storage available in bucket
     892
    893893                // same size, DO NOT preserve STICKY PROPERTIES.
    894                 if ( oalign <= libAlign() && size <= odsize && odsize <= size * 2 ) { // allow 50% wasted storage for smaller size
     894                if ( oalign == libAlign() && size <= odsize && odsize <= size * 2 ) { // allow 50% wasted storage for smaller size
    895895                        header->kind.real.blockSize &= -2;                      // no alignment and turn off 0 fill
    896896                        header->kind.real.size = size;                          // reset allocation size
     
    931931                size_t odsize = dataStorage( bsize, oaddr, header ); // data storage available in bucket
    932932                size_t osize = header->kind.real.size;                  // old allocation size
    933                 bool ozfill = (header->kind.real.blockSize & 2) != 0; // old allocation zero filled
    934           if ( unlikely( size <= odsize ) && size > odsize / 2 ) { // allow up to 50% wasted storage
     933                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
    935935                        header->kind.real.size = size;                          // reset allocation size
    936936                        if ( unlikely( ozfill ) && size > osize ) {     // previous request zero fill and larger ?
     
    947947
    948948                void * naddr;
    949                 if ( likely( oalign <= libAlign() ) ) {                 // previous request not aligned ?
     949                if ( likely( oalign == libAlign() ) ) {                 // previous request not aligned ?
    950950                        naddr = mallocNoStats( size );                          // create new area
    951951                } else {
     
    12311231        } // if
    12321232
    1233         // Attempt to reuse existing storage.
     1233        // Attempt to reuse existing alignment.
    12341234        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                        ) {
    12481243                        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
    12541260        } // if
    12551261
     
    12811287        } // if
    12821288
    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
    13021305
    13031306        #ifdef __STATISTICS__
     
    13061309        #endif // __STATISTICS__
    13071310
     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
    13081317        size_t osize = header->kind.real.size;                          // old allocation size
    1309         bool ozfill = (header->kind.real.blockSize & 2) != 0; // old allocation zero filled
     1318        bool ozfill = (header->kind.real.blockSize & 2);        // old allocation zero filled
    13101319
    13111320        void * naddr = memalignNoStats( nalign, size );         // create new aligned area
  • tests/alloc2.cfa

    rce55a81 r14d8a9b  
    1313void test_base( void * ip, size_t size, size_t align) {
    1414        tests_total += 1;
     15//      printf("DEBUG: starting test %d\n", tests_total);
    1516        bool passed = (malloc_size(ip) == size) && (malloc_usable_size(ip) >= size) && (malloc_alignment(ip) == align) && ((uintptr_t)ip % align  == 0);
    1617        if (!passed) {
     
    1819                tests_failed += 1;
    1920        }
     21//      printf("DEBUG: done test %d\n", tests_total);
    2022}
    2123
    2224void test_fill( void * ip_, size_t start, size_t end, char fill) {
    2325        tests_total += 1;
     26//      printf("DEBUG: starting test %d\n", tests_total);
    2427        bool passed = true;
    2528        char * ip = (char *) ip_;
     
    2932                tests_failed += 1;
    3033        }
     34//      printf("DEBUG: done test %d\n", tests_total);
    3135}
    3236
    3337void test_fill( void * ip_, size_t start, size_t end, int fill) {
    3438        tests_total += 1;
     39//      printf("DEBUG: starting test %d\n", tests_total);
    3540        bool passed = true;
    3641        int * ip = (int *) ip_;
     
    4045                tests_failed += 1;
    4146        }
     47//      printf("DEBUG: done test %d\n", tests_total);
    4248}
    4349
    4450void test_fill( void * ip_, size_t start, size_t end, int * fill) {
    4551        tests_total += 1;
     52//      printf("DEBUG: starting test %d\n", tests_total);
    4653        bool passed = (memcmp((void*)((uintptr_t)ip_ + start), (void*)fill, end) == 0);
    4754        if (!passed) {
     
    4956                tests_failed += 1;
    5057        }
     58//      printf("DEBUG: done test %d\n", tests_total);
    5159}
    5260
    5361void test_fill( void * ip_, size_t start, size_t end, T1 fill) {
    5462        tests_total += 1;
     63//      printf("DEBUG: starting test %d\n", tests_total);
    5564        bool passed = true;
    5665        T1 * ip = (T1 *) ip_;
     
    6069                tests_failed += 1;
    6170        }
     71//      printf("DEBUG: done test %d\n", tests_total);
    6272}
    6373
    6474void test_fill( void * ip_, size_t start, size_t end, T1 * fill) {
    6575        tests_total += 1;
     76//      printf("DEBUG: starting test %d\n", tests_total);
    6677        bool passed = (memcmp((void*)((uintptr_t)ip_ + start), (void*)fill, end) == 0);
    6778        if (!passed) {
     
    6980                tests_failed += 1;
    7081        }
     82//      printf("DEBUG: done test %d\n", tests_total);
    7183}
    7284
    7385void test_use( int * ip, size_t dim) {
    7486        tests_total += 1;
     87//      printf("DEBUG: starting test %d\n", tests_total);
    7588        bool passed = true;
    7689        for (i; 0 ~ dim) ip[i] = 0xdeadbeef;
     
    8093                tests_failed += 1;
    8194        }
     95//      printf("DEBUG: done test %d\n", tests_total);
    8296}
    8397
    8498void test_use( T1 * ip, size_t dim) {
    8599        tests_total += 1;
     100//      printf("DEBUG: starting test %d\n", tests_total);
    86101        bool passed = true;
    87102        for (i; 0 ~ dim) ip[i].data = 0xdeadbeef;
     
    91106                tests_failed += 1;
    92107        }
     108//      printf("DEBUG: done test %d\n", tests_total);
    93109}
    94110
  • tests/heap.cfa

    rce55a81 r14d8a9b  
    1010// Created On       : Tue Nov  6 17:54:56 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Aug  9 08:05:16 2020
    13 // Update Count     : 57
     12// Last Modified On : Mon Sep  7 18:37:41 2020
     13// Update Count     : 72
    1414//
    1515
     
    205205                        free( area );
    206206                } // 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 );
    207281        } // for
    208282
     
    320394        } // for
    321395
     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
    322420        // check memalign/realloc with align/free
    323421
Note: See TracChangeset for help on using the changeset viewer.