Changes in libcfa/src/heap.cfa [7cfef0d:a3ade94]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/heap.cfa
r7cfef0d ra3ade94 10 10 // Created On : Tue Dec 19 21:58:35 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Aug 24 20:29:24 202013 // Update Count : 9 2612 // Last Modified On : Thu Sep 3 16:22:54 2020 13 // Update Count : 943 14 14 // 15 15 … … 29 29 #include "math.hfa" // ceiling 30 30 #include "bitmanip.hfa" // is_pow2, ceiling2 31 32 #define MIN(x, y) (y > x ? x : y)33 31 34 32 static bool traceHeap = false; … … 956 954 957 955 headers( "realloc", naddr, header, freeElem, bsize, oalign ); 958 memcpy( naddr, oaddr, MIN( osize, size ) ); // copy bytes956 memcpy( naddr, oaddr, min( osize, size ) ); // copy bytes 959 957 free( oaddr ); 960 958 … … 1218 1216 #endif // __STATISTICS__ 1219 1217 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 cases1222 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 } // if1228 1229 1218 if ( unlikely( nalign < libAlign() ) ) nalign = libAlign(); // reset alignment to minimum 1230 1219 #ifdef __CFA_DEBUG__ … … 1233 1222 #endif // __CFA_DEBUG__ 1234 1223 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 1243 1248 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 1248 1252 return oaddr; 1249 1253 } // if … … 1267 1271 #endif // __CFA_DEBUG__ 1268 1272 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 1269 1283 HeapManager.Storage.Header * header; 1270 1284 HeapManager.FreeHeader * freeElem; … … 1272 1286 headers( "realloc", oaddr, header, freeElem, bsize, oalign ); 1273 1287 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) 1278 1297 return realloc( oaddr, size ); 1298 1279 1299 } // if 1280 1300 … … 1286 1306 #endif // __STATISTICS__ 1287 1307 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 cases1290 if ( unlikely( oaddr == 0p ) ) return memalignNoStats( nalign, size );1291 1292 1308 size_t osize = header->kind.real.size; // old allocation size 1293 1309 bool ozfill = (header->kind.real.blockSize & 2) != 0; // old allocation zero filled … … 1296 1312 1297 1313 headers( "realloc", naddr, header, freeElem, bsize, oalign ); 1298 memcpy( naddr, oaddr, MIN( osize, size ) ); // copy bytes1314 memcpy( naddr, oaddr, min( osize, size ) ); // copy bytes 1299 1315 free( oaddr ); 1300 1316
Note: See TracChangeset
for help on using the changeset viewer.