Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/heap.cfa

    ra3ade94 r7cfef0d  
    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 Aug 24 20:29:24 2020
     13// Update Count     : 926
    1414//
    1515
     
    2929#include "math.hfa"                                                                             // ceiling
    3030#include "bitmanip.hfa"                                                                 // is_pow2, ceiling2
     31
     32#define MIN(x, y) (y > x ? x : y)
    3133
    3234static bool traceHeap = false;
     
    954956
    955957                headers( "realloc", naddr, header, freeElem, bsize, oalign );
    956                 memcpy( naddr, oaddr, min( osize, size ) );             // copy bytes
     958                memcpy( naddr, oaddr, MIN( osize, size ) );             // copy bytes
    957959                free( oaddr );
    958960
     
    12161218        #endif // __STATISTICS__
    12171219
     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
    12181229        if ( unlikely( nalign < libAlign() ) ) nalign = libAlign(); // reset alignment to minimum
    12191230        #ifdef __CFA_DEBUG__
     
    12221233        #endif // __CFA_DEBUG__
    12231234
    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
     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 ?
    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
     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
    12521248                        return oaddr;
    12531249                } // if
     
    12711267        #endif // __CFA_DEBUG__
    12721268
    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 
    12831269        HeapManager.Storage.Header * header;
    12841270        HeapManager.FreeHeader * freeElem;
     
    12861272        headers( "realloc", oaddr, header, freeElem, bsize, oalign );
    12871273
    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)
     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
    12971278                return realloc( oaddr, size );
    1298 
    12991279        } // if
    13001280
     
    13061286        #endif // __STATISTICS__
    13071287
     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
    13081292        size_t osize = header->kind.real.size;                          // old allocation size
    13091293        bool ozfill = (header->kind.real.blockSize & 2) != 0; // old allocation zero filled
     
    13121296
    13131297        headers( "realloc", naddr, header, freeElem, bsize, oalign );
    1314         memcpy( naddr, oaddr, min( osize, size ) );                     // copy bytes
     1298        memcpy( naddr, oaddr, MIN( osize, size ) );                     // copy bytes
    13151299        free( oaddr );
    13161300
Note: See TracChangeset for help on using the changeset viewer.