* An open array/array of const parameter passed by value and requiring a local copy on heap (currently all targets except non-Darwin i386 ones) should not be placed into register and should force procedure to have an implicit finally block.

* At the same time, allow non-value parameters to be placed into registers even if they have managed type (it is ok because they don't participate in implicit exception handing; explicit exception handling still forces them to memory due to logic in tabstractvarsym.is_regvar).
+ Added tparavarsym.needs_finalization method to handle this logic in a single place.
+ Added tparamanager.use_stackalloc method to determine if local copies should be allocated on heap.

git-svn-id: trunk@19762 -
This commit is contained in:
sergei 2011-12-06 19:44:24 +00:00
parent 8d8a1a23e9
commit 270fc39432
4 changed files with 23 additions and 3 deletions

View File

@ -134,6 +134,8 @@ unit paramgr;
{ allocate room for parameters on the stack in the entry code? }
function use_fixed_stack: boolean;
{ whether stack pointer can be changed in the middle of procedure }
function use_stackalloc: boolean;
end;
@ -467,6 +469,13 @@ implementation
{$endif i386}
end;
{ This is a separate function because at least win64 allows stack allocations
despite of fixed stack semantics (actually supporting it requires generating
a compliant stack frame, not yet possible) }
function tparamanager.use_stackalloc: boolean;
begin
result:=not use_fixed_stack;
end;
initialization
;

View File

@ -488,7 +488,7 @@ implementation
exit;
with tparavarsym(p) do
begin
if not is_managed_type(vardef) and
if (not needs_finalization) and
paramanager.push_addr_param(varspez,vardef,tprocdef(arg).proccalloption) then
varregable:=vr_intreg;
end;

View File

@ -144,8 +144,7 @@ implementation
procedure check_finalize_paras(p:TObject;arg:pointer);
begin
if (tsym(p).typ=paravarsym) and
(tparavarsym(p).varspez=vs_value) and
is_managed_type(tparavarsym(p).vardef) then
tparavarsym(p).needs_finalization then
include(current_procinfo.flags,pi_needs_implicit_finally);
end;

View File

@ -206,6 +206,7 @@ interface
constructor ppuload(ppufile:tcompilerppufile);
destructor destroy;override;
procedure ppuwrite(ppufile:tcompilerppufile);override;
function needs_finalization: boolean;
end;
tstaticvarsym = class(tabstractnormalvarsym)
@ -1592,6 +1593,17 @@ implementation
ppufile.writeentry(ibparavarsym);
end;
function tparavarsym.needs_finalization:boolean;
begin
result:=(varspez=vs_value) and
(is_managed_type(vardef) or
(
(not (tabstractprocdef(owner.defowner).proccalloption in cdecl_pocalls)) and
(not paramanager.use_stackalloc) and
(is_open_array(vardef) or is_array_of_const(vardef))
)
);
end;
{****************************************************************************
TABSOLUTEVARSYM