@@ -932,61 +932,12 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size)
932932set -> header .name ,chunk );
933933#endif
934934
935- /*
936- * Chunk sizes are aligned to power of 2 in AllocSetAlloc(). Maybe the
937- * allocated area already is >= the new size. (In particular, we always
938- * fall out here if the requested size is a decrease.)
939- */
940- if (oldsize >=size )
941- {
942- #ifdef MEMORY_CONTEXT_CHECKING
943- Size oldrequest = chunk -> requested_size ;
944-
945- #ifdef RANDOMIZE_ALLOCATED_MEMORY
946- /* We can only fill the extra space if we know the prior request */
947- if (size > oldrequest )
948- randomize_mem ((char * )pointer + oldrequest ,
949- size - oldrequest );
950- #endif
951-
952- chunk -> requested_size = size ;
953- VALGRIND_MAKE_MEM_NOACCESS (& chunk -> requested_size ,
954- sizeof (chunk -> requested_size ));
955-
956- /*
957- * If this is an increase, mark any newly-available part UNDEFINED.
958- * Otherwise, mark the obsolete part NOACCESS.
959- */
960- if (size > oldrequest )
961- VALGRIND_MAKE_MEM_UNDEFINED ((char * )pointer + oldrequest ,
962- size - oldrequest );
963- else
964- VALGRIND_MAKE_MEM_NOACCESS ((char * )pointer + size ,
965- oldsize - size );
966-
967- /* set mark to catch clobber of "unused" space */
968- if (size < oldsize )
969- set_sentinel (pointer ,size );
970- #else /* !MEMORY_CONTEXT_CHECKING */
971-
972- /*
973- * We don't have the information to determine whether we're growing
974- * the old request or shrinking it, so we conservatively mark the
975- * entire new allocation DEFINED.
976- */
977- VALGRIND_MAKE_MEM_NOACCESS (pointer ,oldsize );
978- VALGRIND_MAKE_MEM_DEFINED (pointer ,size );
979- #endif
980-
981- return pointer ;
982- }
983-
984935if (oldsize > set -> allocChunkLimit )
985936{
986937/*
987938 * The chunk must have been allocated as a single-chunk block. Use
988- * realloc() to make the containing block bigger with minimum space
989- * wastage.
939+ * realloc() to make the containing block bigger, or smaller, with
940+ *minimum space wastage.
990941 */
991942AllocBlock block = (AllocBlock ) (((char * )chunk )- ALLOC_BLOCKHDRSZ );
992943Size chksize ;
@@ -1000,11 +951,19 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size)
1000951if (block -> aset != set ||
1001952block -> freeptr != block -> endptr ||
1002953block -> freeptr != ((char * )block )+
1003- (chunk -> size + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ ))
954+ (oldsize + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ ))
1004955elog (ERROR ,"could not find block containing chunk %p" ,chunk );
1005956
957+ /*
958+ * Even if the new request is less than set->allocChunkLimit, we stick
959+ * with the single-chunk block approach. Therefore we need
960+ * chunk->size to be bigger than set->allocChunkLimit, so we don't get
961+ * confused about the chunk's status in future calls.
962+ */
963+ chksize = Max (size ,set -> allocChunkLimit + 1 );
964+ chksize = MAXALIGN (chksize );
965+
1006966/* Do the realloc */
1007- chksize = MAXALIGN (size );
1008967blksize = chksize + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ ;
1009968block = (AllocBlock )realloc (block ,blksize );
1010969if (block == NULL )
@@ -1025,17 +984,21 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size)
1025984#ifdef MEMORY_CONTEXT_CHECKING
1026985#ifdef RANDOMIZE_ALLOCATED_MEMORY
1027986/* We can only fill the extra space if we know the prior request */
1028- randomize_mem ((char * )pointer + chunk -> requested_size ,
1029- size - chunk -> requested_size );
987+ if (size > chunk -> requested_size )
988+ randomize_mem ((char * )pointer + chunk -> requested_size ,
989+ size - chunk -> requested_size );
1030990#endif
1031991
1032992/*
1033- * realloc() (or randomize_mem()) will have leftthe newly-allocated
993+ * realloc() (or randomize_mem()) will have leftany newly-allocated
1034994 * part UNDEFINED, but we may need to adjust trailing bytes from the
1035995 * old allocation.
1036996 */
1037- VALGRIND_MAKE_MEM_UNDEFINED ((char * )pointer + chunk -> requested_size ,
1038- oldsize - chunk -> requested_size );
997+ #ifdef USE_VALGRIND
998+ if (oldsize > chunk -> requested_size )
999+ VALGRIND_MAKE_MEM_UNDEFINED ((char * )pointer + chunk -> requested_size ,
1000+ oldsize - chunk -> requested_size );
1001+ #endif
10391002
10401003chunk -> requested_size = size ;
10411004VALGRIND_MAKE_MEM_NOACCESS (& chunk -> requested_size ,
@@ -1059,15 +1022,64 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size)
10591022
10601023return pointer ;
10611024}
1025+
1026+ /*
1027+ * Chunk sizes are aligned to power of 2 in AllocSetAlloc(). Maybe the
1028+ * allocated area already is >= the new size. (In particular, we will
1029+ * fall out here if the requested size is a decrease.)
1030+ */
1031+ else if (oldsize >=size )
1032+ {
1033+ #ifdef MEMORY_CONTEXT_CHECKING
1034+ Size oldrequest = chunk -> requested_size ;
1035+
1036+ #ifdef RANDOMIZE_ALLOCATED_MEMORY
1037+ /* We can only fill the extra space if we know the prior request */
1038+ if (size > oldrequest )
1039+ randomize_mem ((char * )pointer + oldrequest ,
1040+ size - oldrequest );
1041+ #endif
1042+
1043+ chunk -> requested_size = size ;
1044+ VALGRIND_MAKE_MEM_NOACCESS (& chunk -> requested_size ,
1045+ sizeof (chunk -> requested_size ));
1046+
1047+ /*
1048+ * If this is an increase, mark any newly-available part UNDEFINED.
1049+ * Otherwise, mark the obsolete part NOACCESS.
1050+ */
1051+ if (size > oldrequest )
1052+ VALGRIND_MAKE_MEM_UNDEFINED ((char * )pointer + oldrequest ,
1053+ size - oldrequest );
1054+ else
1055+ VALGRIND_MAKE_MEM_NOACCESS ((char * )pointer + size ,
1056+ oldsize - size );
1057+
1058+ /* set mark to catch clobber of "unused" space */
1059+ if (size < oldsize )
1060+ set_sentinel (pointer ,size );
1061+ #else /* !MEMORY_CONTEXT_CHECKING */
1062+
1063+ /*
1064+ * We don't have the information to determine whether we're growing
1065+ * the old request or shrinking it, so we conservatively mark the
1066+ * entire new allocation DEFINED.
1067+ */
1068+ VALGRIND_MAKE_MEM_NOACCESS (pointer ,oldsize );
1069+ VALGRIND_MAKE_MEM_DEFINED (pointer ,size );
1070+ #endif
1071+
1072+ return pointer ;
1073+ }
10621074else
10631075{
10641076/*
1065- *Small- chunk case. We just do this by brute force, ie, allocate a
1066- * new chunk and copy the data. Since we know the existing data isn't
1067- * huge, this won't involve any great memcpy expense, so it's not
1068- * worth being smarter. (At one time we tried to avoid memcpy when it
1069- * was possible to enlarge the chunk in-place, but that turns out to
1070- * misbehave unpleasantly for repeated cycles of
1077+ *Enlarge-a-small- chunk case. We just do this by brute force, ie,
1078+ *allocate a new chunk and copy the data. Since we know the existing
1079+ *data isn't huge, this won't involve any great memcpy expense, so
1080+ *it's not worth being smarter. (At one time we tried to avoid
1081+ *memcpy when it was possible to enlarge the chunk in-place, but that
1082+ *turns out to misbehave unpleasantly for repeated cycles of
10711083 * palloc/repalloc/pfree: the eventually freed chunks go into the
10721084 * wrong freelist for the next initial palloc request, and so we leak
10731085 * memory indefinitely. See pgsql-hackers archives for 2007-08-11.)