mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-20 21:09:24 +02:00
* use saveregisters for incr routines, saves also problems with
the optimizer
This commit is contained in:
parent
99ef970960
commit
268e4bb7e7
@ -1405,62 +1405,64 @@ unit cgobj;
|
||||
procedure tcg.g_incrrefcount(list : taasmoutput;t: tdef; const ref: treference);
|
||||
var
|
||||
href : treference;
|
||||
pushedregs : tpushedsaved;
|
||||
decrfunc : string;
|
||||
incrfunc : string;
|
||||
begin
|
||||
rg.saveusedregisters(list,pushedregs,all_registers);
|
||||
{ These functions should not change the registers (they use
|
||||
the saveregister proc directive }
|
||||
if is_interfacecom(t) then
|
||||
decrfunc:='FPC_INTF_INCR_REF'
|
||||
incrfunc:='FPC_INTF_INCR_REF'
|
||||
else if is_ansistring(t) then
|
||||
decrfunc:='FPC_ANSISTR_INCR_REF'
|
||||
incrfunc:='FPC_ANSISTR_INCR_REF'
|
||||
else if is_widestring(t) then
|
||||
decrfunc:='FPC_WIDESTR_INCR_REF'
|
||||
incrfunc:='FPC_WIDESTR_INCR_REF'
|
||||
else if is_dynamic_array(t) then
|
||||
incrfunc:='FPC_DYNARRAY_INCR_REF'
|
||||
else
|
||||
decrfunc:='';
|
||||
{ call the special decr function or the generic decref }
|
||||
if decrfunc<>'' then
|
||||
cg.a_param_ref(list,OS_ADDR,ref,1)
|
||||
incrfunc:='';
|
||||
{ call the special incr function or the generic addref }
|
||||
if incrfunc<>'' then
|
||||
begin
|
||||
a_param_ref(list,OS_ADDR,ref,1);
|
||||
a_call_name(list,incrfunc,0);
|
||||
end
|
||||
else
|
||||
begin
|
||||
reference_reset_symbol(href,tstoreddef(t).get_rtti_label(initrtti),0);
|
||||
a_paramaddr_ref(list,href,2);
|
||||
a_paramaddr_ref(list,ref,1);
|
||||
decrfunc:='FPC_ADDREF';
|
||||
a_call_name(list,'FPC_ADDREF',0);
|
||||
end;
|
||||
rg.saveregvars(exprasmlist,all_registers);
|
||||
a_call_name(list,decrfunc,0);
|
||||
rg.restoreusedregisters(list,pushedregs);
|
||||
end;
|
||||
|
||||
|
||||
procedure tcg.g_decrrefcount(list : taasmoutput;t: tdef; const ref: treference);
|
||||
var
|
||||
href : treference;
|
||||
pushedregs : tpushedsaved;
|
||||
decrfunc : string;
|
||||
begin
|
||||
rg.saveusedregisters(list,pushedregs,all_registers);
|
||||
if is_interfacecom(t) then
|
||||
decrfunc:='FPC_INTF_DECR_REF'
|
||||
else if is_ansistring(t) then
|
||||
decrfunc:='FPC_ANSISTR_DECR_REF'
|
||||
else if is_widestring(t) then
|
||||
decrfunc:='FPC_WIDESTR_DECR_REF'
|
||||
else if is_dynamic_array(t) then
|
||||
decrfunc:='FPC_DYNARRAY_INCR_REF'
|
||||
else
|
||||
decrfunc:='';
|
||||
{ call the special decr function or the generic decref }
|
||||
if decrfunc<>'' then
|
||||
cg.a_paramaddr_ref(list,ref,1)
|
||||
begin
|
||||
a_paramaddr_ref(list,ref,1);
|
||||
a_call_name(list,decrfunc,0);
|
||||
end
|
||||
else
|
||||
begin
|
||||
reference_reset_symbol(href,tstoreddef(t).get_rtti_label(initrtti),0);
|
||||
a_paramaddr_ref(list,href,2);
|
||||
a_paramaddr_ref(list,ref,1);
|
||||
decrfunc:='FPC_DECREF';
|
||||
a_call_name(list,'FPC_DECREF',0);
|
||||
end;
|
||||
rg.saveregvars(exprasmlist,all_registers);
|
||||
a_call_name(list,decrfunc,0);
|
||||
rg.restoreusedregisters(list,pushedregs);
|
||||
end;
|
||||
|
||||
|
||||
@ -1636,7 +1638,11 @@ finalization
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.18 2002-04-25 20:16:38 peter
|
||||
Revision 1.19 2002-04-26 15:19:04 peter
|
||||
* use saveregisters for incr routines, saves also problems with
|
||||
the optimizer
|
||||
|
||||
Revision 1.18 2002/04/25 20:16:38 peter
|
||||
* moved more routines from cga/n386util
|
||||
|
||||
Revision 1.17 2002/04/22 16:30:05 peter
|
||||
|
@ -418,6 +418,11 @@ implementation
|
||||
(right.registers32>=left.registers32)) then
|
||||
begin
|
||||
secondpass(right);
|
||||
{ increment source reference counter, this is
|
||||
useless for string constants}
|
||||
if (right.resulttype.def.needs_inittable) and
|
||||
(right.nodetype<>stringconstn) then
|
||||
cg.g_incrrefcount(exprasmlist,right.resulttype.def,right.location.reference);
|
||||
if codegenerror then
|
||||
exit;
|
||||
|
||||
@ -430,6 +435,9 @@ implementation
|
||||
{ can be false }
|
||||
pushed:=maybe_push(left.registers32,right,false);
|
||||
secondpass(left);
|
||||
{ decrement destination reference counter }
|
||||
if (left.resulttype.def.needs_inittable) then
|
||||
cg.g_decrrefcount(exprasmlist,left.resulttype.def,left.location.reference);
|
||||
if pushed then
|
||||
restore(right,false);
|
||||
if codegenerror then
|
||||
@ -443,43 +451,27 @@ implementation
|
||||
if not(nf_concat_string in flags) then
|
||||
begin
|
||||
secondpass(left);
|
||||
{ decrement destination reference counter }
|
||||
if (left.resulttype.def.needs_inittable) then
|
||||
cg.g_decrrefcount(exprasmlist,left.resulttype.def,left.location.reference);
|
||||
if codegenerror then
|
||||
exit;
|
||||
end;
|
||||
|
||||
{$ifdef test_dest_loc}
|
||||
{ lets try to optimize this (PM) }
|
||||
{ define a dest_loc that is the location }
|
||||
{ and a ptree to verify that it is the right }
|
||||
{ place to insert it }
|
||||
if (aktexprlevel<4) then
|
||||
begin
|
||||
dest_loc_known:=true;
|
||||
dest_loc:=left.location;
|
||||
dest_loc_tree:=right;
|
||||
end;
|
||||
{$endif test_dest_loc}
|
||||
|
||||
{ left can't be never a 64 bit LOC_REGISTER, so the 3. arg }
|
||||
{ can be false }
|
||||
pushed:=maybe_push(right.registers32,left,is_64bitint(right.resulttype.def));
|
||||
secondpass(right);
|
||||
{ increment source reference counter, this is
|
||||
useless for string constants}
|
||||
if (right.resulttype.def.needs_inittable) and
|
||||
(right.nodetype<>stringconstn) then
|
||||
cg.g_incrrefcount(exprasmlist,right.resulttype.def,right.location.reference);
|
||||
if pushed then
|
||||
restore(left,false);
|
||||
|
||||
if codegenerror then
|
||||
exit;
|
||||
|
||||
{$ifdef test_dest_loc}
|
||||
dest_loc_known:=false;
|
||||
if in_dest_loc then
|
||||
begin
|
||||
truelabel:=otlabel;
|
||||
falselabel:=oflabel;
|
||||
in_dest_loc:=false;
|
||||
exit;
|
||||
end;
|
||||
{$endif test_dest_loc}
|
||||
end;
|
||||
|
||||
if not(left.location.loc in [LOC_REFERENCE,LOC_CFPUREGISTER,
|
||||
@ -575,19 +567,6 @@ implementation
|
||||
LOC_REFERENCE,
|
||||
LOC_CREFERENCE :
|
||||
begin
|
||||
if (right.resulttype.def.needs_inittable) then
|
||||
begin
|
||||
{ this would be a problem }
|
||||
if not(left.resulttype.def.needs_inittable) then
|
||||
internalerror(3457);
|
||||
{ increment source reference counter, this is
|
||||
useless for string constants}
|
||||
if right.nodetype<>stringconstn then
|
||||
cg.g_incrrefcount(exprasmlist,right.resulttype.def,right.location.reference);
|
||||
{ decrement destination reference counter }
|
||||
cg.g_decrrefcount(exprasmlist,left.resulttype.def,left.location.reference);
|
||||
end;
|
||||
|
||||
concatcopy(right.location.reference,
|
||||
left.location.reference,left.resulttype.def.size,true,false);
|
||||
{ right.location is already released by concatcopy }
|
||||
@ -744,7 +723,11 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.39 2002-04-25 20:16:40 peter
|
||||
Revision 1.40 2002-04-26 15:19:05 peter
|
||||
* use saveregisters for incr routines, saves also problems with
|
||||
the optimizer
|
||||
|
||||
Revision 1.39 2002/04/25 20:16:40 peter
|
||||
* moved more routines from cga/n386util
|
||||
|
||||
Revision 1.38 2002/04/22 16:30:06 peter
|
||||
|
@ -106,7 +106,7 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
Procedure fpc_AnsiStr_Decr_Ref (Var S : Pointer);[Public,Alias:'FPC_ANSISTR_DECR_REF']; {$ifdef hascompilerproc} compilerproc; {$endif}
|
||||
Procedure fpc_AnsiStr_Decr_Ref (Var S : Pointer);saveregisters;[Public,Alias:'FPC_ANSISTR_DECR_REF']; {$ifdef hascompilerproc} compilerproc; {$endif}
|
||||
{
|
||||
Decreases the ReferenceCount of a non constant ansistring;
|
||||
If the reference count is zero, deallocate the string;
|
||||
@ -132,13 +132,13 @@ end;
|
||||
|
||||
{$ifdef hascompilerproc}
|
||||
{ also define alias for internal use in the system unit }
|
||||
Procedure fpc_AnsiStr_Decr_Ref (Var S : Pointer); [external name 'FPC_ANSISTR_DECR_REF'];
|
||||
Procedure fpc_AnsiStr_Decr_Ref (Var S : Pointer);saveregisters; [external name 'FPC_ANSISTR_DECR_REF'];
|
||||
{$endif hascompilerproc}
|
||||
|
||||
{$ifdef hascompilerproc}
|
||||
Procedure fpc_AnsiStr_Incr_Ref (S : Pointer);[Public,Alias:'FPC_ANSISTR_INCR_REF']; {$ifdef hascompilerproc} compilerproc; {$endif}
|
||||
Procedure fpc_AnsiStr_Incr_Ref (S : Pointer);saveregisters;[Public,Alias:'FPC_ANSISTR_INCR_REF']; {$ifdef hascompilerproc} compilerproc; {$endif}
|
||||
{$else}
|
||||
Procedure fpc_AnsiStr_Incr_Ref (Var S : Pointer);[Public,Alias:'FPC_ANSISTR_INCR_REF'];
|
||||
Procedure fpc_AnsiStr_Incr_Ref (Var S : Pointer);saveregisters;[Public,Alias:'FPC_ANSISTR_INCR_REF'];
|
||||
{$endif}
|
||||
Begin
|
||||
If S=Nil then
|
||||
@ -150,7 +150,7 @@ end;
|
||||
|
||||
{$ifdef hascompilerproc}
|
||||
{ also define alias which can be used inside the system unit }
|
||||
Procedure fpc_AnsiStr_Incr_Ref (S : Pointer); [external name 'FPC_ANSISTR_INCR_REF'];
|
||||
Procedure fpc_AnsiStr_Incr_Ref (S : Pointer);saveregisters; [external name 'FPC_ANSISTR_INCR_REF'];
|
||||
{$endif hascompilerproc}
|
||||
|
||||
Procedure fpc_AnsiStr_Assign (Var S1 : Pointer;S2 : Pointer);[Public,Alias:'FPC_ANSISTR_ASSIGN']; {$ifdef hascompilerproc} compilerproc; {$endif}
|
||||
@ -801,7 +801,11 @@ end;
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.24 2002-04-25 20:14:56 peter
|
||||
Revision 1.25 2002-04-26 15:19:05 peter
|
||||
* use saveregisters for incr routines, saves also problems with
|
||||
the optimizer
|
||||
|
||||
Revision 1.24 2002/04/25 20:14:56 peter
|
||||
* updated compilerprocs
|
||||
* incr ref count has now a value argument instead of var
|
||||
|
||||
|
@ -76,7 +76,7 @@ Procedure fpc_dynarray_clear (var p : pointer;ti : pointer);[external name 'FPC_
|
||||
{$endif hascompilerproc}
|
||||
|
||||
|
||||
procedure fpc_dynarray_decr_ref(var p : pointer;ti : pointer);[Public,Alias:'FPC_DYNARRAY_DECR_REF']; {$ifdef hascompilerproc} compilerproc; {$endif}
|
||||
procedure fpc_dynarray_decr_ref(var p : pointer;ti : pointer);saveregisters;[Public,Alias:'FPC_DYNARRAY_DECR_REF']; {$ifdef hascompilerproc} compilerproc; {$endif}
|
||||
var
|
||||
realp : pdynarray;
|
||||
begin
|
||||
@ -96,10 +96,10 @@ procedure fpc_dynarray_decr_ref(var p : pointer;ti : pointer);[Public,Alias:'FPC
|
||||
|
||||
{$ifdef hascompilerproc}
|
||||
{ provide local access to dynarr_decr_ref for dynarr_setlength }
|
||||
procedure fpc_dynarray_decr_ref(var p : pointer;ti : pointer); [external name 'FPC_DYNARRAY_DECR_REF'];
|
||||
procedure fpc_dynarray_decr_ref(var p : pointer;ti : pointer);saveregisters; [external name 'FPC_DYNARRAY_DECR_REF'];
|
||||
{$endif}
|
||||
|
||||
procedure fpc_dynarray_incr_ref(p : pointer);[Public,Alias:'FPC_DYNARRAY_INCR_REF']; {$ifdef hascompilerproc} compilerproc; {$endif}
|
||||
procedure fpc_dynarray_incr_ref(p : pointer);saveregisters;[Public,Alias:'FPC_DYNARRAY_INCR_REF']; {$ifdef hascompilerproc} compilerproc; {$endif}
|
||||
var
|
||||
realp : pdynarray;
|
||||
begin
|
||||
@ -115,7 +115,7 @@ procedure fpc_dynarray_incr_ref(p : pointer);[Public,Alias:'FPC_DYNARRAY_INCR_RE
|
||||
|
||||
{$ifdef hascompilerproc}
|
||||
{ provide local access to dynarr_decr_ref for dynarr_setlength }
|
||||
procedure fpc_dynarray_incr_ref(p : pointer); [external name 'FPC_DYNARRAY_INCR_REF'];
|
||||
procedure fpc_dynarray_incr_ref(p : pointer);saveregisters; [external name 'FPC_DYNARRAY_INCR_REF'];
|
||||
{$endif}
|
||||
|
||||
{ provide local access to dynarr_setlength }
|
||||
@ -261,7 +261,11 @@ function fpc_dynarray_copy(var p : pointer;ti : pointer;
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.16 2002-04-25 20:14:56 peter
|
||||
Revision 1.17 2002-04-26 15:19:05 peter
|
||||
* use saveregisters for incr routines, saves also problems with
|
||||
the optimizer
|
||||
|
||||
Revision 1.16 2002/04/25 20:14:56 peter
|
||||
* updated compilerprocs
|
||||
* incr ref count has now a value argument instead of var
|
||||
|
||||
|
@ -36,11 +36,11 @@
|
||||
|
||||
{$ifndef HASINTF}
|
||||
{ dummies for make cycle with 1.0.x }
|
||||
procedure intf_decr_ref(var i: pointer);[public,alias: 'FPC_INTF_DECR_REF'];
|
||||
procedure intf_decr_ref(var i: pointer);saveregisters;[public,alias: 'FPC_INTF_DECR_REF'];
|
||||
begin
|
||||
end;
|
||||
|
||||
procedure intf_incr_ref(const i: pointer);[public,alias: 'FPC_INTF_INCR_REF'];
|
||||
procedure intf_incr_ref(const i: pointer);saveregisters;[public,alias: 'FPC_INTF_INCR_REF'];
|
||||
begin
|
||||
end;
|
||||
|
||||
@ -54,7 +54,7 @@
|
||||
|
||||
{$else HASINTF}
|
||||
{ interface helpers }
|
||||
procedure fpc_intf_decr_ref(var i: pointer);[public,alias: 'FPC_INTF_DECR_REF']; {$ifdef hascompilerproc} compilerproc; {$endif}
|
||||
procedure fpc_intf_decr_ref(var i: pointer);saveregisters;[public,alias: 'FPC_INTF_DECR_REF']; {$ifdef hascompilerproc} compilerproc; {$endif}
|
||||
begin
|
||||
if assigned(i) then
|
||||
IUnknown(i)._Release;
|
||||
@ -63,11 +63,11 @@
|
||||
|
||||
{$ifdef hascompilerproc}
|
||||
{ local declaration for intf_decr_ref for local access }
|
||||
procedure intf_decr_ref(var i: pointer); [external name 'FPC_INTF_DECR_REF'];
|
||||
procedure intf_decr_ref(var i: pointer);saveregisters; [external name 'FPC_INTF_DECR_REF'];
|
||||
{$endif hascompilerproc}
|
||||
|
||||
|
||||
procedure fpc_intf_incr_ref(i: pointer);[public,alias: 'FPC_INTF_INCR_REF']; {$ifdef hascompilerproc} compilerproc; {$endif}
|
||||
procedure fpc_intf_incr_ref(i: pointer);saveregisters;[public,alias: 'FPC_INTF_INCR_REF']; {$ifdef hascompilerproc} compilerproc; {$endif}
|
||||
begin
|
||||
if assigned(i) then
|
||||
IUnknown(i)._AddRef;
|
||||
@ -75,7 +75,7 @@
|
||||
|
||||
{$ifdef hascompilerproc}
|
||||
{ local declaration of intf_incr_ref for local access }
|
||||
procedure intf_incr_ref(i: pointer); [external name 'FPC_INTF_INCR_REF'];
|
||||
procedure intf_incr_ref(i: pointer);saveregisters; [external name 'FPC_INTF_INCR_REF'];
|
||||
{$endif hascompilerproc}
|
||||
|
||||
procedure fpc_intf_assign(var D: pointer; const S: pointer);[public,alias: 'FPC_INTF_ASSIGN']; {$ifdef hascompilerproc} compilerproc; {$endif}
|
||||
@ -696,7 +696,11 @@
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.20 2002-04-25 20:14:57 peter
|
||||
Revision 1.21 2002-04-26 15:19:05 peter
|
||||
* use saveregisters for incr routines, saves also problems with
|
||||
the optimizer
|
||||
|
||||
Revision 1.20 2002/04/25 20:14:57 peter
|
||||
* updated compilerprocs
|
||||
* incr ref count has now a value argument instead of var
|
||||
|
||||
|
@ -161,7 +161,7 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
Procedure fpc_WideStr_Decr_Ref (Var S : Pointer);[Public,Alias:'FPC_WIDESTR_DECR_REF']; {$ifdef hascompilerproc} compilerproc; {$endif}
|
||||
Procedure fpc_WideStr_Decr_Ref (Var S : Pointer);saveregisters;[Public,Alias:'FPC_WIDESTR_DECR_REF']; {$ifdef hascompilerproc} compilerproc; {$endif}
|
||||
{
|
||||
Decreases the ReferenceCount of a non constant widestring;
|
||||
If the reference count is zero, deallocate the string;
|
||||
@ -187,13 +187,13 @@ end;
|
||||
|
||||
{$ifdef hascompilerproc}
|
||||
{ alias for internal use }
|
||||
Procedure fpc_WideStr_Decr_Ref (Var S : Pointer);[external name 'FPC_WIDESTR_DECR_REF'];
|
||||
Procedure fpc_WideStr_Decr_Ref (Var S : Pointer);saveregisters;[external name 'FPC_WIDESTR_DECR_REF'];
|
||||
{$endif compilerproc}
|
||||
|
||||
{$ifdef hascompilerproc}
|
||||
Procedure fpc_WideStr_Incr_Ref (S : Pointer);[Public,Alias:'FPC_WIDESTR_INCR_REF']; {$ifdef hascompilerproc} compilerproc; {$endif}
|
||||
Procedure fpc_WideStr_Incr_Ref (S : Pointer);saveregisters;[Public,Alias:'FPC_WIDESTR_INCR_REF']; {$ifdef hascompilerproc} compilerproc; {$endif}
|
||||
{$else}
|
||||
Procedure fpc_WideStr_Incr_Ref (Var S : Pointer);[Public,Alias:'FPC_WIDESTR_INCR_REF'];
|
||||
Procedure fpc_WideStr_Incr_Ref (Var S : Pointer);saveregisters;[Public,Alias:'FPC_WIDESTR_INCR_REF'];
|
||||
{$endif compilerproc}
|
||||
Begin
|
||||
If S=Nil then
|
||||
@ -849,7 +849,11 @@ end;
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.16 2002-04-25 20:14:57 peter
|
||||
Revision 1.17 2002-04-26 15:19:05 peter
|
||||
* use saveregisters for incr routines, saves also problems with
|
||||
the optimizer
|
||||
|
||||
Revision 1.16 2002/04/25 20:14:57 peter
|
||||
* updated compilerprocs
|
||||
* incr ref count has now a value argument instead of var
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user