mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-19 20:39:25 +02:00
Fix for Mantis #30110. Speed up finalization of array of primitive/simple records (aka records not containing managed types).
rtl/inc/dynarr.inc: + add elType field to tdynarraytypedata (this tells us whether a finalization is needed) * fpc_dynarray_clear: don't finalize the array elements if elType is Nil * fpc_dynarray_setlength: only call int_addref() and int_finalizearray() if elType is set * fpc_dynarray_copy: don't check for tkManagedTypes, but instead check whether elType is assigned git-svn-id: trunk@33719 -
This commit is contained in:
parent
7fd805c5d8
commit
e15816e35b
@ -33,6 +33,7 @@ type
|
||||
elSize : SizeUInt;
|
||||
elType2 : Pointer;
|
||||
varType : Longint;
|
||||
elType : Pointer;
|
||||
end;
|
||||
|
||||
procedure fpc_dynarray_rangecheck(p : pointer;i : tdynarrayindex);[Public,Alias:'FPC_DYNARRAY_RANGECHECK']; compilerproc;
|
||||
@ -73,7 +74,8 @@ procedure fpc_dynarray_clear(var p : pointer;ti : pointer); [Public,Alias:'FPC_D
|
||||
if declocked(realp^.refcount) then
|
||||
begin
|
||||
ti:=aligntoptr(ti+2+PByte(ti)[1]);
|
||||
int_finalizearray(p,pdynarraytypedata(ti)^.elType2,realp^.high+1);
|
||||
if assigned(pdynarraytypedata(ti)^.elType) then
|
||||
int_finalizearray(p,pdynarraytypedata(ti)^.elType,realp^.high+1);
|
||||
freemem(realp);
|
||||
end;
|
||||
p:=nil;
|
||||
@ -127,7 +129,7 @@ procedure fpc_dynarray_setlength(var p : pointer;pti : pointer;
|
||||
ti : pointer;
|
||||
updatep: boolean;
|
||||
elesize : sizeint;
|
||||
eletype : pointer;
|
||||
eletype,eletypemngd : pointer;
|
||||
movsize : sizeint;
|
||||
|
||||
begin
|
||||
@ -140,6 +142,8 @@ procedure fpc_dynarray_setlength(var p : pointer;pti : pointer;
|
||||
|
||||
elesize:=pdynarraytypedata(ti)^.elSize;
|
||||
eletype:=pdynarraytypedata(ti)^.elType2;
|
||||
{ only set if type needs finalization }
|
||||
eletypemngd:=pdynarraytypedata(ti)^.elType;
|
||||
|
||||
{ determine new memory size }
|
||||
size:=elesize*dims[0]+sizeof(tdynarray);
|
||||
@ -182,9 +186,10 @@ procedure fpc_dynarray_setlength(var p : pointer;pti : pointer;
|
||||
if size-sizeof(tdynarray)>movsize then
|
||||
fillchar((pointer(newp)+sizeof(tdynarray)+movsize)^,size-sizeof(tdynarray)-movsize,0);
|
||||
|
||||
{ increment ref. count of members }
|
||||
for i:= 0 to movelen-1 do
|
||||
int_addref(pointer(newp)+sizeof(tdynarray)+elesize*i,eletype);
|
||||
{ increment ref. count of managed members }
|
||||
if assigned(eletypemngd) then
|
||||
for i:= 0 to movelen-1 do
|
||||
int_addref(pointer(newp)+sizeof(tdynarray)+elesize*i,eletypemngd);
|
||||
|
||||
{ a declock(ref. count) isn't enough here }
|
||||
{ it could be that the in MT environments }
|
||||
@ -213,9 +218,10 @@ procedure fpc_dynarray_setlength(var p : pointer;pti : pointer;
|
||||
{ shrink the array? }
|
||||
if dims[0]<realp^.high+1 then
|
||||
begin
|
||||
int_finalizearray(pointer(realp)+sizeof(tdynarray)+
|
||||
elesize*dims[0],
|
||||
eletype,realp^.high-dims[0]+1);
|
||||
if assigned(eletypemngd) then
|
||||
int_finalizearray(pointer(realp)+sizeof(tdynarray)+
|
||||
elesize*dims[0],
|
||||
eletypemngd,realp^.high-dims[0]+1);
|
||||
reallocmem(realp,size);
|
||||
end
|
||||
else if dims[0]>realp^.high+1 then
|
||||
@ -286,7 +292,8 @@ function fpc_dynarray_copy(psrc : pointer;ti : pointer;
|
||||
ti:=aligntoptr(ti+2+PByte(ti)[1]);
|
||||
|
||||
elesize:=pdynarraytypedata(ti)^.elSize;
|
||||
eletype:=pdynarraytypedata(ti)^.elType2;
|
||||
{ only set if type needs finalization }
|
||||
eletype:=pdynarraytypedata(ti)^.elType;
|
||||
|
||||
{ create new array }
|
||||
size:=elesize*count;
|
||||
@ -298,7 +305,7 @@ function fpc_dynarray_copy(psrc : pointer;ti : pointer;
|
||||
move(pointer(psrc+elesize*lowidx)^,pointer(result)^,size);
|
||||
|
||||
{ increment ref. count of members? }
|
||||
if PByte(eletype)^ in tkManagedTypes then
|
||||
if assigned(eletype) then
|
||||
for i:=0 to count-1 do
|
||||
int_addref(pointer(pointer(result)+elesize*i),eletype);
|
||||
end;
|
||||
|
Loading…
Reference in New Issue
Block a user