|
11 | 11 | * Portions Copyright (c) 1994, Regents of the University of California
|
12 | 12 | *
|
13 | 13 | * 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 $ |
15 | 15 | *
|
16 | 16 | * NOTE:
|
17 | 17 | *This is a new (Feb. 05, 1999) implementation of the allocation set
|
@@ -879,10 +879,60 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size)
|
879 | 879 | }
|
880 | 880 | else
|
881 | 881 | {
|
| 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 | +AllocPointernewPointer; |
| 897 | + |
| 898 | +if (size <=ALLOC_CHUNK_LIMIT) |
| 899 | +{ |
| 900 | +AllocBlockblock=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 | +Sizefreespace=block->endptr-block->freeptr; |
| 908 | +intfidx; |
| 909 | +Sizenewsize; |
| 910 | +Sizedelta; |
| 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 | +#ifdefMEMORY_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 | +returnpointer; |
| 928 | +} |
| 929 | +} |
| 930 | +} |
| 931 | + |
882 | 932 | /* Normal small-chunk case: just do it by brute force. */
|
883 | 933 |
|
884 | 934 | /* allocate new chunk */
|
885 |
| -AllocPointernewPointer=AllocSetAlloc((MemoryContext)set,size); |
| 935 | +newPointer=AllocSetAlloc((MemoryContext)set,size); |
886 | 936 |
|
887 | 937 | /* transfer existing data (certain to fit) */
|
888 | 938 | memcpy(newPointer,pointer,oldsize);
|
|