Avoid corner cases where aset.c would unnecessarily make malloc()
authorTom Lane
Sat, 13 Sep 2003 22:25:38 +0000 (22:25 +0000)
committerTom Lane
Sat, 13 Sep 2003 22:25:38 +0000 (22:25 +0000)
requests of sizes that aren't powers of 2.  Per observation from
David Schultz, 28-Aug.

src/backend/utils/mmgr/aset.c

index fddcad7a29bdeae8a96891a343fb39da9152593a..b36596734d746d30b7afcc6040a3d49ec252cd80 100644 (file)
@@ -11,7 +11,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/utils/mmgr/aset.c,v 1.52 2003/08/04 02:40:08 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/utils/mmgr/aset.c,v 1.53 2003/09/13 22:25:38 tgl Exp $
  *
  * NOTE:
  * This is a new (Feb. 05, 1999) implementation of the allocation set
@@ -650,32 +650,29 @@ AllocSetAlloc(MemoryContext context, Size size)
        }
        else
        {
-           /* Get size of prior block */
-           blksize = set->blocks->endptr - ((char *) set->blocks);
-
            /*
-            * Special case: if very first allocation was for a large
-            * chunk (or we have a small "keeper" block), could have an
-            * undersized top block.  Do something reasonable.
+            * Use first power of 2 that is larger than previous block,
+            * but not more than the allowed limit.  (We don't simply double
+            * the prior block size, because in some cases this could be a
+            * funny size, eg if very first allocation was for an odd-sized
+            * large chunk.)
             */
-           if (blksize < set->initBlockSize)
-               blksize = set->initBlockSize;
-           else
-           {
-               /* Crank it up, but not past max */
+           Size    pblksize = set->blocks->endptr - ((char *) set->blocks);
+
+           blksize = set->initBlockSize;
+           while (blksize <= pblksize)
                blksize <<= 1;
-               if (blksize > set->maxBlockSize)
-                   blksize = set->maxBlockSize;
-           }
+           if (blksize > set->maxBlockSize)
+               blksize = set->maxBlockSize;
        }
 
        /*
         * If initBlockSize is less than ALLOC_CHUNK_LIMIT, we could need
-        * more space...
+        * more space... but try to keep it a power of 2.
         */
        required_size = chunk_size + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ;
-       if (blksize < required_size)
-           blksize = required_size;
+       while (blksize < required_size)
+           blksize <<= 1;
 
        /* Try to allocate it */
        block = (AllocBlock) malloc(blksize);