Index: libcfa/src/heap.cfa
===================================================================
--- libcfa/src/heap.cfa	(revision f76ff0bec23814dcce2b5631e99a1cbe08fd2c74)
+++ libcfa/src/heap.cfa	(revision 47dd0d2c75578359efd1ebb654a94a61e5cc8a3d)
@@ -10,6 +10,6 @@
 // Created On       : Tue Dec 19 21:58:35 2017
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Sep  1 21:58:36 2020
-// Update Count     : 927
+// Last Modified On : Thu Sep  3 16:22:54 2020
+// Update Count     : 943
 //
 
@@ -29,6 +29,4 @@
 #include "math.hfa"										// ceiling
 #include "bitmanip.hfa"									// is_pow2, ceiling2
-
-#define MIN(x, y) (y > x ? x : y)
 
 static bool traceHeap = false;
@@ -956,5 +954,5 @@
 
 		headers( "realloc", naddr, header, freeElem, bsize, oalign );
-		memcpy( naddr, oaddr, MIN( osize, size ) );		// copy bytes
+		memcpy( naddr, oaddr, min( osize, size ) );		// copy bytes
 		free( oaddr );
 
@@ -1233,21 +1231,36 @@
 	} // if
 
-	HeapManager.Storage.Header * header;
-	HeapManager.FreeHeader * freeElem;
-	size_t bsize, oalign;
-	headers( "resize", oaddr, header, freeElem, bsize, oalign );
-	size_t odsize = dataStorage( bsize, oaddr, header ); // data storage available in bucket
-
-	if ( oalign == nalign && size <= odsize && odsize <= size * 2 ) { // <= alignment and new alignment are same, allow 50% wasted storage for smaller size
-		header->kind.real.blockSize &= -2;			// turn off 0 fill
-		header->kind.real.size = size;				// reset allocation size
-		return oaddr;
-	} // if
-	if ( oalign < nalign && (uintptr_t)oaddr % nalign == 0 && oalign > libAlign() ) { // <= alignment and new alignment happens to match, and oaddr has a fake header
-		headerAddr( oaddr )->kind.fake.alignment = nalign | 1; // update alignment (could be the same)
-		if ( size <= odsize && odsize <= size * 2 ) {	// allow 50% wasted storage for smaller size
-			header->kind.real.blockSize &= -2;			// turn off 0 fill
-			header->kind.real.size = size;				// reset allocation size
-			return oaddr;
+	// Attempt to reuse existing storage.
+	HeapManager.Storage.Header * header = headerAddr( oaddr );
+	if ( header->kind.fake.alignment & 1 == 1 ) {		// old fake header ?
+		if ( unlikely( (uintptr_t)oaddr % nalign == 0) && // lucky match ?
+			 header->kind.fake.alignment <= nalign &&	// ok to leave LSB at 1
+			 nalign <= 128 ) {							// not too much alignment storage wasted ?
+
+			HeapManager.FreeHeader * freeElem;
+			size_t bsize, oalign;
+			headers( "resize", oaddr, header, freeElem, bsize, oalign );
+			size_t odsize = dataStorage( bsize, oaddr, header ); // data storage available in bucket
+
+			if ( size <= odsize && odsize <= size * 2 ) { // allow 50% wasted data storage
+				headerAddr( oaddr )->kind.fake.alignment = nalign | 1; // update alignment (could be the same)
+
+				header->kind.real.blockSize &= -2;		// turn off 0 fill
+				header->kind.real.size = size;			// reset allocation size
+				return oaddr;
+			} // if
+		} // if
+	} else {											// no old fake header
+		if ( nalign == libAlign() ) {					// no new fake header needed => try to reuse storage
+			HeapManager.FreeHeader * freeElem;
+			size_t bsize, oalign;
+			headers( "resize", oaddr, header, freeElem, bsize, oalign );
+			size_t odsize = dataStorage( bsize, oaddr, header ); // data storage available in bucket
+
+			if ( size <= odsize && odsize <= size * 2 ) { // allow 50% wasted data storage
+				header->kind.real.blockSize &= -2;		// turn off 0 fill
+				header->kind.real.size = size;			// reset allocation size
+				return oaddr;
+			} // if
 		} // if
 	} // if
@@ -1306,5 +1319,5 @@
 
 	headers( "realloc", naddr, header, freeElem, bsize, oalign );
-	memcpy( naddr, oaddr, MIN( osize, size ) );			// copy bytes
+	memcpy( naddr, oaddr, min( osize, size ) );			// copy bytes
 	free( oaddr );
 
