Ignore:
Timestamp:
Sep 3, 2020, 4:28:10 PM (14 months ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
arm-eh, jacob/cs343-translation, master, new-ast-unique-expr
Children:
9617533
Parents:
41096dc
Message:

use math.hfa 'min' routine, work on code to reuse existing storage in aligned resize

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/heap.cfa

    r41096dc r47dd0d2  
    1010// Created On       : Tue Dec 19 21:58:35 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Sep  1 21:58:36 2020
    13 // Update Count     : 927
     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
     
    12331231        } // if
    12341232
    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 && size <= odsize && odsize <= size * 2 ) { // <= alignment and new alignment are same, allow 50% wasted storage for smaller size
    1242                 header->kind.real.blockSize &= -2;                      // turn off 0 fill
    1243                 header->kind.real.size = size;                          // reset allocation size
    1244                 return oaddr;
    1245         } // if
    1246         if ( oalign < nalign && (uintptr_t)oaddr % nalign == 0 && oalign > libAlign() ) { // <= alignment and new alignment happens to match, and oaddr has a fake header
    1247                 headerAddr( oaddr )->kind.fake.alignment = nalign | 1; // update alignment (could be the same)
    1248                 if ( size <= odsize && odsize <= size * 2 ) {   // allow 50% wasted storage for smaller size
    1249                         header->kind.real.blockSize &= -2;                      // turn off 0 fill
    1250                         header->kind.real.size = size;                          // reset allocation size
    1251                         return oaddr;
     1233        // Attempt to reuse existing storage.
     1234        HeapManager.Storage.Header * header = headerAddr( oaddr );
     1235        if ( header->kind.fake.alignment & 1 == 1 ) {           // old fake header ?
     1236                if ( unlikely( (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
     1240                        HeapManager.FreeHeader * freeElem;
     1241                        size_t bsize, oalign;
     1242                        headers( "resize", oaddr, header, freeElem, bsize, oalign );
     1243                        size_t odsize = dataStorage( bsize, oaddr, header ); // data storage available in bucket
     1244
     1245                        if ( size <= odsize && odsize <= size * 2 ) { // allow 50% wasted data storage
     1246                                headerAddr( oaddr )->kind.fake.alignment = nalign | 1; // update alignment (could be the same)
     1247
     1248                                header->kind.real.blockSize &= -2;              // turn off 0 fill
     1249                                header->kind.real.size = size;                  // reset allocation size
     1250                                return oaddr;
     1251                        } // if
     1252                } // if
     1253        } else {                                                                                        // no old fake header
     1254                if ( nalign == libAlign() ) {                                   // no new fake header needed => try to reuse storage
     1255                        HeapManager.FreeHeader * freeElem;
     1256                        size_t bsize, oalign;
     1257                        headers( "resize", oaddr, header, freeElem, bsize, oalign );
     1258                        size_t odsize = dataStorage( bsize, oaddr, header ); // data storage available in bucket
     1259
     1260                        if ( size <= odsize && odsize <= size * 2 ) { // allow 50% wasted data storage
     1261                                header->kind.real.blockSize &= -2;              // turn off 0 fill
     1262                                header->kind.real.size = size;                  // reset allocation size
     1263                                return oaddr;
     1264                        } // if
    12521265                } // if
    12531266        } // if
     
    13061319
    13071320        headers( "realloc", naddr, header, freeElem, bsize, oalign );
    1308         memcpy( naddr, oaddr, MIN( osize, size ) );                     // copy bytes
     1321        memcpy( naddr, oaddr, min( osize, size ) );                     // copy bytes
    13091322        free( oaddr );
    13101323
Note: See TracChangeset for help on using the changeset viewer.