Shortcut declocked on refcount = 1.

This commit is contained in:
Rika Ichinose 2025-01-30 05:11:44 +03:00 committed by FPK
parent d06dd9532c
commit 6ccad3dc4e
4 changed files with 19 additions and 32 deletions

View File

@ -2906,8 +2906,9 @@ asm
testl %edx,%edx
jz .Lquit
movl $0,(%eax) // s:=nil
cmpl $0,-8(%edx) // exit if refcount<0
cmpl $1,-8(%edx) // exit if refcount<1
jl .Lquit
je .Lfree // skip the decrement if refcount=1.
{$ifdef FPC_PIC}
call fpc_geteipasecx
addl $_GLOBAL_OFFSET_TABLE_,%ecx
@ -2925,15 +2926,7 @@ asm
ret
.Lfree:
leal -12(%edx),%eax // points to start of allocation
{ freemem is not an assembler leaf function like fpc_geteipasecx, so it
needs to be called with proper stack alignment }
{$ifdef FPC_SYSTEM_STACKALIGNMENT16}
leal -12(%esp),%esp
call FPC_FREEMEM
leal 12(%esp),%esp
{$else FPC_SYSTEM_STACKALIGNMENT16}
jmp FPC_FREEMEM // can perform a tail call
{$endif FPC_SYSTEM_STACKALIGNMENT16}
jmp FPC_FREEMEM // nostackframe + jmp allows to ignore stack alignment.
end;
function fpc_truely_ansistr_unique(Var S : Pointer): Pointer; forward;

View File

@ -139,18 +139,16 @@ Procedure fpc_ansistr_decr_ref (Var S : Pointer); [Public,Alias:'FPC_ANSISTR_DEC
If the reference count is zero, deallocate the string;
}
Var
p: PAnsiRec;
p: pointer;
Begin
{ Zero string }
If S=Nil then
p:=S;
If p=Nil then
exit;
{ check for constant strings ...}
p:=PAnsiRec(S-AnsiFirstOff);
s:=nil;
If p^.ref<0 then exit;
{ declocked does a MT safe dec and returns true, if the counter is 0 }
If declocked(p^.ref) then
FreeMem(p);
If (PAnsiRec(p-AnsiFirstOff)^.ref>0) and { ref = -1 is constant string. }
((PAnsiRec(p-AnsiFirstOff)^.ref=1) { Shortcut declocked on ref = 1. }
or declocked(PAnsiRec(p-AnsiFirstOff)^.ref)) then
FreeMem(p-AnsiFirstOff);
end;
{$endif FPC_SYSTEM_HAS_ANSISTR_DECR_REF}

View File

@ -86,7 +86,7 @@ procedure fpc_dynarray_clear(var p : pointer;ti : pointer); [Public,Alias:'FPC_D
if not assigned(pv) then
exit;
p:=nil;
if (pv[-1].refcount>0) and declocked(pv[-1].refcount) then
if (pv[-1].refcount>0) and ((pv[-1].refcount=1) or declocked(pv[-1].refcount)) then
begin
ti:=pdynarraytypedata(aligntoqword(ti+2+PByte(ti)[1]))^.elType;
if assigned(ti) then

View File

@ -216,20 +216,16 @@ Procedure fpc_UnicodeStr_Decr_Ref (Var S : Pointer);[Public,Alias:'FPC_UNICODEST
If the reference count is zero, deallocate the string;
}
Var
p: PUnicodeRec;
p: pointer;
Begin
{ Zero string }
if S=Nil then
p:=S;
If p=Nil then
exit;
{ check for constant strings ...}
p:=PUnicodeRec(S-UnicodeFirstOff);
S:=nil;
if p^.Ref<0 then
exit;
{ declocked does a MT safe dec and returns true, if the counter is 0 }
if declocked(p^.Ref) then
FreeMem(p);
s:=nil;
If (PUnicodeRec(p-UnicodeFirstOff)^.ref>0) and { ref = -1 is constant string. }
((PUnicodeRec(p-UnicodeFirstOff)^.ref=1) { Shortcut declocked on ref = 1. }
or declocked(PUnicodeRec(p-UnicodeFirstOff)^.ref)) then
FreeMem(p-UnicodeFirstOff);
end;
{ alias for internal use }