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