mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-18 14:29:13 +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;
|
elSize : SizeUInt;
|
||||||
elType2 : Pointer;
|
elType2 : Pointer;
|
||||||
varType : Longint;
|
varType : Longint;
|
||||||
|
elType : Pointer;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure fpc_dynarray_rangecheck(p : pointer;i : tdynarrayindex);[Public,Alias:'FPC_DYNARRAY_RANGECHECK']; compilerproc;
|
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
|
if declocked(realp^.refcount) then
|
||||||
begin
|
begin
|
||||||
ti:=aligntoptr(ti+2+PByte(ti)[1]);
|
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);
|
freemem(realp);
|
||||||
end;
|
end;
|
||||||
p:=nil;
|
p:=nil;
|
||||||
@ -127,7 +129,7 @@ procedure fpc_dynarray_setlength(var p : pointer;pti : pointer;
|
|||||||
ti : pointer;
|
ti : pointer;
|
||||||
updatep: boolean;
|
updatep: boolean;
|
||||||
elesize : sizeint;
|
elesize : sizeint;
|
||||||
eletype : pointer;
|
eletype,eletypemngd : pointer;
|
||||||
movsize : sizeint;
|
movsize : sizeint;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
@ -140,6 +142,8 @@ procedure fpc_dynarray_setlength(var p : pointer;pti : pointer;
|
|||||||
|
|
||||||
elesize:=pdynarraytypedata(ti)^.elSize;
|
elesize:=pdynarraytypedata(ti)^.elSize;
|
||||||
eletype:=pdynarraytypedata(ti)^.elType2;
|
eletype:=pdynarraytypedata(ti)^.elType2;
|
||||||
|
{ only set if type needs finalization }
|
||||||
|
eletypemngd:=pdynarraytypedata(ti)^.elType;
|
||||||
|
|
||||||
{ determine new memory size }
|
{ determine new memory size }
|
||||||
size:=elesize*dims[0]+sizeof(tdynarray);
|
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
|
if size-sizeof(tdynarray)>movsize then
|
||||||
fillchar((pointer(newp)+sizeof(tdynarray)+movsize)^,size-sizeof(tdynarray)-movsize,0);
|
fillchar((pointer(newp)+sizeof(tdynarray)+movsize)^,size-sizeof(tdynarray)-movsize,0);
|
||||||
|
|
||||||
{ increment ref. count of members }
|
{ increment ref. count of managed members }
|
||||||
for i:= 0 to movelen-1 do
|
if assigned(eletypemngd) then
|
||||||
int_addref(pointer(newp)+sizeof(tdynarray)+elesize*i,eletype);
|
for i:= 0 to movelen-1 do
|
||||||
|
int_addref(pointer(newp)+sizeof(tdynarray)+elesize*i,eletypemngd);
|
||||||
|
|
||||||
{ a declock(ref. count) isn't enough here }
|
{ a declock(ref. count) isn't enough here }
|
||||||
{ it could be that the in MT environments }
|
{ it could be that the in MT environments }
|
||||||
@ -213,9 +218,10 @@ procedure fpc_dynarray_setlength(var p : pointer;pti : pointer;
|
|||||||
{ shrink the array? }
|
{ shrink the array? }
|
||||||
if dims[0]<realp^.high+1 then
|
if dims[0]<realp^.high+1 then
|
||||||
begin
|
begin
|
||||||
int_finalizearray(pointer(realp)+sizeof(tdynarray)+
|
if assigned(eletypemngd) then
|
||||||
elesize*dims[0],
|
int_finalizearray(pointer(realp)+sizeof(tdynarray)+
|
||||||
eletype,realp^.high-dims[0]+1);
|
elesize*dims[0],
|
||||||
|
eletypemngd,realp^.high-dims[0]+1);
|
||||||
reallocmem(realp,size);
|
reallocmem(realp,size);
|
||||||
end
|
end
|
||||||
else if dims[0]>realp^.high+1 then
|
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]);
|
ti:=aligntoptr(ti+2+PByte(ti)[1]);
|
||||||
|
|
||||||
elesize:=pdynarraytypedata(ti)^.elSize;
|
elesize:=pdynarraytypedata(ti)^.elSize;
|
||||||
eletype:=pdynarraytypedata(ti)^.elType2;
|
{ only set if type needs finalization }
|
||||||
|
eletype:=pdynarraytypedata(ti)^.elType;
|
||||||
|
|
||||||
{ create new array }
|
{ create new array }
|
||||||
size:=elesize*count;
|
size:=elesize*count;
|
||||||
@ -298,7 +305,7 @@ function fpc_dynarray_copy(psrc : pointer;ti : pointer;
|
|||||||
move(pointer(psrc+elesize*lowidx)^,pointer(result)^,size);
|
move(pointer(psrc+elesize*lowidx)^,pointer(result)^,size);
|
||||||
|
|
||||||
{ increment ref. count of members? }
|
{ increment ref. count of members? }
|
||||||
if PByte(eletype)^ in tkManagedTypes then
|
if assigned(eletype) then
|
||||||
for i:=0 to count-1 do
|
for i:=0 to count-1 do
|
||||||
int_addref(pointer(pointer(result)+elesize*i),eletype);
|
int_addref(pointer(pointer(result)+elesize*i),eletype);
|
||||||
end;
|
end;
|
||||||
|
Loading…
Reference in New Issue
Block a user