Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 728b0aa

Browse files
committed
Improve realloc() per idea from Karel Zak --- if chunk to be enlarged is
at end of its block, maybe we can enlarge it in-place.
1 parent c0bb21b commit 728b0aa

File tree

1 file changed

+52
-2
lines changed

1 file changed

+52
-2
lines changed

src/backend/utils/mmgr/aset.c

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* Portions Copyright (c) 1994, Regents of the University of California
1212
*
1313
* IDENTIFICATION
14-
* $Header: /cvsroot/pgsql/src/backend/utils/mmgr/aset.c,v 1.37 2001/01/12 21:54:01 tgl Exp $
14+
* $Header: /cvsroot/pgsql/src/backend/utils/mmgr/aset.c,v 1.38 2001/01/23 01:01:36 tgl Exp $
1515
*
1616
* NOTE:
1717
* This is a new (Feb. 05, 1999) implementation of the allocation set
@@ -879,10 +879,60 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size)
879879
}
880880
else
881881
{
882+
/*
883+
* Small-chunk case. If the chunk is the last one in its block,
884+
* there might be enough free space after it that we can just
885+
* enlarge the chunk in-place. It's relatively painful to find
886+
* the containing block in the general case, but we can detect
887+
* last-ness quite cheaply for the typical case where the chunk
888+
* is in the active (topmost) allocation block. (At least with
889+
* the regression tests and code as of 1/2001, realloc'ing the last
890+
* chunk of a non-topmost block hardly ever happens, so it's not
891+
* worth scanning the block list to catch that case.)
892+
*
893+
* NOTE: must be careful not to create a chunk of a size that
894+
* AllocSetAlloc would not create, else we'll get confused later.
895+
*/
896+
AllocPointer newPointer;
897+
898+
if (size <= ALLOC_CHUNK_LIMIT)
899+
{
900+
AllocBlock block = set->blocks;
901+
char *chunk_end;
902+
903+
chunk_end = (char *) chunk + (oldsize + ALLOC_CHUNKHDRSZ);
904+
if (chunk_end == block->freeptr)
905+
{
906+
/* OK, it's last in block ... is there room? */
907+
Size freespace = block->endptr - block->freeptr;
908+
int fidx;
909+
Size newsize;
910+
Size delta;
911+
912+
fidx = AllocSetFreeIndex(size);
913+
newsize = 1 << (fidx + ALLOC_MINBITS);
914+
Assert(newsize >= oldsize);
915+
delta = newsize - oldsize;
916+
if (freespace >= delta)
917+
{
918+
/* Yes, so just enlarge the chunk. */
919+
block->freeptr += delta;
920+
chunk->size += delta;
921+
#ifdef MEMORY_CONTEXT_CHECKING
922+
chunk->requested_size = size;
923+
/* set mark to catch clobber of "unused" space */
924+
if (size < chunk->size)
925+
((char *) pointer)[size] = 0x7E;
926+
#endif
927+
return pointer;
928+
}
929+
}
930+
}
931+
882932
/* Normal small-chunk case: just do it by brute force. */
883933

884934
/* allocate new chunk */
885-
AllocPointer newPointer = AllocSetAlloc((MemoryContext) set, size);
935+
newPointer = AllocSetAlloc((MemoryContext) set, size);
886936

887937
/* transfer existing data (certain to fit) */
888938
memcpy(newPointer, pointer, oldsize);

0 commit comments

Comments
 (0)