mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-15 14:19:28 +02:00
+ optimizations in SysTinyReAllocMem for the case when growing the heap block
and there is enough free space after the block git-svn-id: trunk@28723 -
This commit is contained in:
parent
b70c5efa65
commit
1e0a69fa7f
@ -260,6 +260,9 @@
|
||||
function SysTinyReAllocMem(var p: pointer; size: ptruint):pointer;
|
||||
var
|
||||
oldsize, OldAllocSize, NewAllocSize: ptruint;
|
||||
after_block, before_block: PTinyHeapBlock;
|
||||
after_block_size: PtrUInt;
|
||||
new_after_block: PTinyHeapBlock;
|
||||
begin
|
||||
{$ifdef DEBUG_TINY_HEAP}
|
||||
Write('SysTinyReAllocMem(', HexStr(p), ',', size, ')=');
|
||||
@ -299,15 +302,75 @@
|
||||
end
|
||||
else
|
||||
begin
|
||||
result := AllocMem(size);
|
||||
if result <> nil then
|
||||
{ we're increasing the memory block size. First, find if there are free memory blocks immediately
|
||||
before and after our memory block. }
|
||||
after_block := FreeList;
|
||||
before_block := nil;
|
||||
while (after_block<>HeapPtr) and (TTinyHeapPointerArithmeticType(after_block) < TTinyHeapPointerArithmeticType(p)) do
|
||||
begin
|
||||
if oldsize > size then
|
||||
oldsize := size;
|
||||
move(pbyte(p)^, pbyte(result)^, oldsize);
|
||||
before_block := after_block;
|
||||
after_block := after_block^.Next;
|
||||
end;
|
||||
{ is after_block immediately after our block? }
|
||||
if after_block=Pointer(TTinyHeapPointerArithmeticType(p)+(OldAllocSize-PtrUInt(SizeOf(TTinyHeapMemBlockSize)))) then
|
||||
begin
|
||||
if after_block = HeapPtr then
|
||||
after_block_size := PtrUInt(TTinyHeapPointerArithmeticType(HeapEnd)-TTinyHeapPointerArithmeticType(HeapPtr))
|
||||
else
|
||||
after_block_size := DecodeTinyHeapFreeBlockSize(after_block^.size);
|
||||
end
|
||||
else
|
||||
after_block_size := 0;
|
||||
{ is there enough room after the block? }
|
||||
if (OldAllocSize+after_block_size)>=NewAllocSize then
|
||||
begin
|
||||
if after_block = HeapPtr then
|
||||
begin
|
||||
HeapPtr:=Pointer(TTinyHeapPointerArithmeticType(HeapPtr)+(NewAllocSize-OldAllocSize));
|
||||
if assigned(before_block) then
|
||||
before_block^.Next := HeapPtr
|
||||
else
|
||||
FreeList := HeapPtr;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (NewAllocSize-OldAllocSize)=after_block_size then
|
||||
begin
|
||||
if assigned(before_block) then
|
||||
before_block^.Next := after_block^.Next
|
||||
else
|
||||
FreeList := after_block^.Next;
|
||||
end
|
||||
else
|
||||
begin
|
||||
new_after_block := PTinyHeapBlock(TTinyHeapPointerArithmeticType(after_block)+(NewAllocSize-OldAllocSize));
|
||||
new_after_block^.Next:=after_block^.Next;
|
||||
new_after_block^.Size:=EncodeTinyHeapFreeBlockSize(after_block_size-(NewAllocSize-OldAllocSize));
|
||||
if assigned(before_block) then
|
||||
before_block^.Next := new_after_block
|
||||
else
|
||||
FreeList := new_after_block;
|
||||
end;
|
||||
end;
|
||||
PTinyHeapMemBlockSize(p)[-1] := size;
|
||||
FillChar((TTinyHeapPointerArithmeticType(p)+oldsize)^, size-oldsize, 0);
|
||||
end
|
||||
else
|
||||
begin
|
||||
{ is before_block immediately before our block? }
|
||||
//if assigned(before_block) and (Pointer(TTinyHeapPointerArithmeticType(before_block)+DecodeTinyHeapFreeBlockSize(before_block^.Size))=Pointer(TTinyHeapPointerArithmeticType(p)-SizeOf(TTinyHeapMemBlockSize))) then
|
||||
// ;
|
||||
|
||||
result := AllocMem(size);
|
||||
if result <> nil then
|
||||
begin
|
||||
if oldsize > size then
|
||||
oldsize := size;
|
||||
move(pbyte(p)^, pbyte(result)^, oldsize);
|
||||
end;
|
||||
SysTinyFreeMem(p);
|
||||
p := result;
|
||||
end;
|
||||
SysTinyFreeMem(p);
|
||||
p := result;
|
||||
end;
|
||||
end;
|
||||
{$ifdef DEBUG_TINY_HEAP}
|
||||
|
Loading…
Reference in New Issue
Block a user