Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/heap.cfa

    r7cfef0d ra3ade94  
    1010// Created On       : Tue Dec 19 21:58:35 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Aug 24 20:29:24 2020
    13 // Update Count     : 926
     12// Last Modified On : Thu Sep  3 16:22:54 2020
     13// Update Count     : 943
    1414//
    1515
     
    2929#include "math.hfa"                                                                             // ceiling
    3030#include "bitmanip.hfa"                                                                 // is_pow2, ceiling2
    31 
    32 #define MIN(x, y) (y > x ? x : y)
    3331
    3432static bool traceHeap = false;
     
    956954
    957955                headers( "realloc", naddr, header, freeElem, bsize, oalign );
    958                 memcpy( naddr, oaddr, MIN( osize, size ) );             // copy bytes
     956                memcpy( naddr, oaddr, min( osize, size ) );             // copy bytes
    959957                free( oaddr );
    960958
     
    12181216        #endif // __STATISTICS__
    12191217
    1220         // If size is equal to 0, either NULL or a pointer suitable to be passed to free() is returned.
    1221   if ( unlikely( size == 0 ) ) { free( oaddr ); return 0p; } // special cases
    1222   if ( unlikely( oaddr == 0p ) ) {
    1223                 #ifdef __STATISTICS__
    1224                 __atomic_add_fetch( &resize_storage, size, __ATOMIC_SEQ_CST );
    1225                 #endif // __STATISTICS__
    1226                 return memalignNoStats( nalign, size );
    1227         } // if
    1228 
    12291218        if ( unlikely( nalign < libAlign() ) ) nalign = libAlign(); // reset alignment to minimum
    12301219        #ifdef __CFA_DEBUG__
     
    12331222        #endif // __CFA_DEBUG__
    12341223
    1235         HeapManager.Storage.Header * header;
    1236         HeapManager.FreeHeader * freeElem;
    1237         size_t bsize, oalign;
    1238         headers( "resize", oaddr, header, freeElem, bsize, oalign );
    1239         size_t odsize = dataStorage( bsize, oaddr, header ); // data storage available in bucket
    1240 
    1241         if ( oalign <= nalign && (uintptr_t)oaddr % nalign == 0 ) { // <= alignment and new alignment happens to match
    1242                 if ( oalign > libAlign() ) {                                    // fake header ?
     1224        // If size is equal to 0, either NULL or a pointer suitable to be passed to free() is returned.
     1225  if ( unlikely( size == 0 ) ) { free( oaddr ); return 0p; } // special cases
     1226  if ( unlikely( oaddr == 0p ) ) {
     1227                #ifdef __STATISTICS__
     1228                __atomic_add_fetch( &resize_storage, size, __ATOMIC_SEQ_CST );
     1229                #endif // __STATISTICS__
     1230                return memalignNoStats( nalign, size );
     1231        } // if
     1232
     1233        // Attempt to reuse existing storage.
     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
    12431248                        headerAddr( oaddr )->kind.fake.alignment = nalign | 1; // update alignment (could be the same)
    1244                 } // if
    1245                 if ( size <= odsize && odsize <= size * 2 ) {   // allow 50% wasted storage for smaller size
    1246                         header->kind.real.blockSize &= -2;                      // turn off 0 fill
    1247                         header->kind.real.size = size;                          // reset allocation size
     1249
     1250                        header->kind.real.blockSize &= -2;              // turn off 0 fill
     1251                        header->kind.real.size = size;                  // reset allocation size
    12481252                        return oaddr;
    12491253                } // if
     
    12671271        #endif // __CFA_DEBUG__
    12681272
     1273        // If size is equal to 0, either NULL or a pointer suitable to be passed to free() is returned.
     1274  if ( unlikely( size == 0 ) ) { free( oaddr ); return 0p; } // special cases
     1275  if ( unlikely( oaddr == 0p ) ) {
     1276                #ifdef __STATISTICS__
     1277                __atomic_add_fetch( &realloc_calls, 1, __ATOMIC_SEQ_CST );
     1278                __atomic_add_fetch( &realloc_storage, size, __ATOMIC_SEQ_CST );
     1279                #endif // __STATISTICS__
     1280                return memalignNoStats( nalign, size );
     1281        } // if
     1282
    12691283        HeapManager.Storage.Header * header;
    12701284        HeapManager.FreeHeader * freeElem;
     
    12721286        headers( "realloc", oaddr, header, freeElem, bsize, oalign );
    12731287
    1274         if ( oalign <= nalign && (uintptr_t)oaddr % nalign == 0 ) { // <= alignment and new alignment happens to match
    1275                 if ( oalign > libAlign() ) {                                    // fake header ?
    1276                         headerAddr( oaddr )->kind.fake.alignment = nalign | 1; // update alignment (could be the same)
    1277                 } // if
     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)
    12781297                return realloc( oaddr, size );
     1298
    12791299        } // if
    12801300
     
    12861306        #endif // __STATISTICS__
    12871307
    1288         // If size is equal to 0, either NULL or a pointer suitable to be passed to free() is returned.
    1289   if ( unlikely( size == 0 ) ) { free( oaddr ); return 0p; } // special cases
    1290   if ( unlikely( oaddr == 0p ) ) return memalignNoStats( nalign, size );
    1291 
    12921308        size_t osize = header->kind.real.size;                          // old allocation size
    12931309        bool ozfill = (header->kind.real.blockSize & 2) != 0; // old allocation zero filled
     
    12961312
    12971313        headers( "realloc", naddr, header, freeElem, bsize, oalign );
    1298         memcpy( naddr, oaddr, MIN( osize, size ) );                     // copy bytes
     1314        memcpy( naddr, oaddr, min( osize, size ) );                     // copy bytes
    12991315        free( oaddr );
    13001316
Note: See TracChangeset for help on using the changeset viewer.