* use saveregisters for incr routines, saves also problems with

the optimizer
This commit is contained in:
peter 2002-04-26 15:19:04 +00:00
parent 99ef970960
commit 268e4bb7e7
6 changed files with 88 additions and 83 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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