mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-10-26 22:51:40 +01:00
* Win64 SEH: Track control flow out of unwind-protected regions in a more precise way and don't generate expensive calls to __fpc_local_unwind when not necessary.
git-svn-id: trunk@31582 -
This commit is contained in:
parent
5f3c45d370
commit
e542800ea9
@ -100,7 +100,7 @@ procedure ti386onnode.pass_generate_code;
|
|||||||
location_reset(location,LOC_VOID,OS_NO);
|
location_reset(location,LOC_VOID,OS_NO);
|
||||||
|
|
||||||
oldflowcontrol:=flowcontrol;
|
oldflowcontrol:=flowcontrol;
|
||||||
flowcontrol:=flowcontrol*[fc_unwind]+[fc_inflowcontrol];
|
flowcontrol:=[fc_inflowcontrol];
|
||||||
|
|
||||||
{ RTL will put exceptobject into EAX when jumping here }
|
{ RTL will put exceptobject into EAX when jumping here }
|
||||||
cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_FUNCTION_RESULT_REG);
|
cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_FUNCTION_RESULT_REG);
|
||||||
|
|||||||
@ -148,6 +148,7 @@ implementation
|
|||||||
oldclabel:=current_procinfo.CurrContinueLabel;
|
oldclabel:=current_procinfo.CurrContinueLabel;
|
||||||
oldblabel:=current_procinfo.CurrBreakLabel;
|
oldblabel:=current_procinfo.CurrBreakLabel;
|
||||||
include(flowcontrol,fc_inflowcontrol);
|
include(flowcontrol,fc_inflowcontrol);
|
||||||
|
exclude(flowcontrol,fc_unwind_loop);
|
||||||
|
|
||||||
sync_regvars(true);
|
sync_regvars(true);
|
||||||
{$ifdef OLDREGVARS}
|
{$ifdef OLDREGVARS}
|
||||||
@ -470,6 +471,7 @@ implementation
|
|||||||
hlcg.maybe_change_load_node_reg(current_asmdata.CurrAsmList,left,false);
|
hlcg.maybe_change_load_node_reg(current_asmdata.CurrAsmList,left,false);
|
||||||
oldflowcontrol:=flowcontrol;
|
oldflowcontrol:=flowcontrol;
|
||||||
include(flowcontrol,fc_inflowcontrol);
|
include(flowcontrol,fc_inflowcontrol);
|
||||||
|
exclude(flowcontrol,fc_unwind_loop);
|
||||||
{ produce start assignment }
|
{ produce start assignment }
|
||||||
case left.location.loc of
|
case left.location.loc of
|
||||||
LOC_REFERENCE,
|
LOC_REFERENCE,
|
||||||
@ -816,7 +818,7 @@ implementation
|
|||||||
if assigned(left) then
|
if assigned(left) then
|
||||||
secondpass(left);
|
secondpass(left);
|
||||||
|
|
||||||
if (fc_unwind in flowcontrol) then
|
if (fc_unwind_exit in flowcontrol) then
|
||||||
hlcg.g_local_unwind(current_asmdata.CurrAsmList,current_procinfo.CurrExitLabel)
|
hlcg.g_local_unwind(current_asmdata.CurrAsmList,current_procinfo.CurrExitLabel)
|
||||||
else
|
else
|
||||||
hlcg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrExitLabel);
|
hlcg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrExitLabel);
|
||||||
@ -837,7 +839,7 @@ implementation
|
|||||||
{$ifdef OLDREGVARS}
|
{$ifdef OLDREGVARS}
|
||||||
load_all_regvars(current_asmdata.CurrAsmList);
|
load_all_regvars(current_asmdata.CurrAsmList);
|
||||||
{$endif OLDREGVARS}
|
{$endif OLDREGVARS}
|
||||||
if (fc_unwind in flowcontrol) then
|
if (fc_unwind_loop in flowcontrol) then
|
||||||
hlcg.g_local_unwind(current_asmdata.CurrAsmList,current_procinfo.CurrBreakLabel)
|
hlcg.g_local_unwind(current_asmdata.CurrAsmList,current_procinfo.CurrBreakLabel)
|
||||||
else
|
else
|
||||||
hlcg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrBreakLabel)
|
hlcg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrBreakLabel)
|
||||||
@ -861,7 +863,7 @@ implementation
|
|||||||
{$ifdef OLDREGVARS}
|
{$ifdef OLDREGVARS}
|
||||||
load_all_regvars(current_asmdata.CurrAsmList);
|
load_all_regvars(current_asmdata.CurrAsmList);
|
||||||
{$endif OLDREGVARS}
|
{$endif OLDREGVARS}
|
||||||
if (fc_unwind in flowcontrol) then
|
if (fc_unwind_loop in flowcontrol) then
|
||||||
hlcg.g_local_unwind(current_asmdata.CurrAsmList,current_procinfo.CurrContinueLabel)
|
hlcg.g_local_unwind(current_asmdata.CurrAsmList,current_procinfo.CurrContinueLabel)
|
||||||
else
|
else
|
||||||
hlcg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrContinueLabel)
|
hlcg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrContinueLabel)
|
||||||
|
|||||||
@ -36,7 +36,8 @@ uses
|
|||||||
fc_inflowcontrol,
|
fc_inflowcontrol,
|
||||||
fc_gotolabel,
|
fc_gotolabel,
|
||||||
{ in try block of try..finally }
|
{ in try block of try..finally }
|
||||||
fc_unwind,
|
fc_unwind_exit,
|
||||||
|
fc_unwind_loop,
|
||||||
{ the left side of an expression is already handled, so we are
|
{ the left side of an expression is already handled, so we are
|
||||||
not allowed to do ssl }
|
not allowed to do ssl }
|
||||||
fc_lefthandled);
|
fc_lefthandled);
|
||||||
|
|||||||
@ -87,7 +87,6 @@ end;
|
|||||||
|
|
||||||
procedure tx64onnode.pass_generate_code;
|
procedure tx64onnode.pass_generate_code;
|
||||||
var
|
var
|
||||||
oldflowcontrol : tflowcontrol;
|
|
||||||
exceptvarsym : tlocalvarsym;
|
exceptvarsym : tlocalvarsym;
|
||||||
begin
|
begin
|
||||||
if (target_info.system<>system_x86_64_win64) then
|
if (target_info.system<>system_x86_64_win64) then
|
||||||
@ -98,9 +97,6 @@ procedure tx64onnode.pass_generate_code;
|
|||||||
|
|
||||||
location_reset(location,LOC_VOID,OS_NO);
|
location_reset(location,LOC_VOID,OS_NO);
|
||||||
|
|
||||||
oldflowcontrol:=flowcontrol;
|
|
||||||
flowcontrol:=flowcontrol*[fc_unwind]+[fc_inflowcontrol];
|
|
||||||
|
|
||||||
{ RTL will put exceptobject into RAX when jumping here }
|
{ RTL will put exceptobject into RAX when jumping here }
|
||||||
cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_FUNCTION_RESULT_REG);
|
cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_FUNCTION_RESULT_REG);
|
||||||
|
|
||||||
@ -130,8 +126,6 @@ procedure tx64onnode.pass_generate_code;
|
|||||||
end;
|
end;
|
||||||
cg.g_call(current_asmdata.CurrAsmList,'FPC_DONEEXCEPTION');
|
cg.g_call(current_asmdata.CurrAsmList,'FPC_DONEEXCEPTION');
|
||||||
cg.a_jmp_always(current_asmdata.CurrAsmList,endexceptlabel);
|
cg.a_jmp_always(current_asmdata.CurrAsmList,endexceptlabel);
|
||||||
|
|
||||||
flowcontrol:=oldflowcontrol+(flowcontrol-[fc_inflowcontrol]);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ tx64tryfinallynode }
|
{ tx64tryfinallynode }
|
||||||
@ -299,12 +293,12 @@ procedure tx64tryfinallynode.pass_generate_code;
|
|||||||
{ try code }
|
{ try code }
|
||||||
if assigned(left) then
|
if assigned(left) then
|
||||||
begin
|
begin
|
||||||
{ fc_unwind tells exit/continue/break statements to emit special
|
{ fc_unwind_xx tells exit/continue/break statements to emit special
|
||||||
unwind code instead of just JMP }
|
unwind code instead of just JMP }
|
||||||
if not implicitframe then
|
if not implicitframe then
|
||||||
include(flowcontrol,fc_unwind);
|
flowcontrol:=flowcontrol+[fc_unwind_exit,fc_unwind_loop];
|
||||||
secondpass(left);
|
secondpass(left);
|
||||||
exclude(flowcontrol,fc_unwind);
|
flowcontrol:=flowcontrol-[fc_unwind_exit,fc_unwind_loop];
|
||||||
if codegenerror then
|
if codegenerror then
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
@ -393,7 +387,7 @@ procedure tx64tryexceptnode.pass_generate_code;
|
|||||||
continueexceptlabel:=nil;
|
continueexceptlabel:=nil;
|
||||||
breakexceptlabel:=nil;
|
breakexceptlabel:=nil;
|
||||||
|
|
||||||
flowcontrol:=flowcontrol*[fc_unwind]+[fc_inflowcontrol];
|
include(flowcontrol,fc_inflowcontrol);
|
||||||
{ this can be called recursivly }
|
{ this can be called recursivly }
|
||||||
oldBreakLabel:=nil;
|
oldBreakLabel:=nil;
|
||||||
oldContinueLabel:=nil;
|
oldContinueLabel:=nil;
|
||||||
@ -442,7 +436,7 @@ procedure tx64tryexceptnode.pass_generate_code;
|
|||||||
current_procinfo.CurrBreakLabel:=breakexceptlabel;
|
current_procinfo.CurrBreakLabel:=breakexceptlabel;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
flowcontrol:=flowcontrol*[fc_unwind]+[fc_inflowcontrol];
|
flowcontrol:=[fc_inflowcontrol];
|
||||||
{ on statements }
|
{ on statements }
|
||||||
if assigned(right) then
|
if assigned(right) then
|
||||||
begin
|
begin
|
||||||
@ -496,7 +490,7 @@ procedure tx64tryexceptnode.pass_generate_code;
|
|||||||
{ do some magic for exit in the try block }
|
{ do some magic for exit in the try block }
|
||||||
cg.a_label(current_asmdata.CurrAsmList,exitexceptlabel);
|
cg.a_label(current_asmdata.CurrAsmList,exitexceptlabel);
|
||||||
cg.g_call(current_asmdata.CurrAsmList,'FPC_DONEEXCEPTION');
|
cg.g_call(current_asmdata.CurrAsmList,'FPC_DONEEXCEPTION');
|
||||||
if (fc_unwind in flowcontrol) then
|
if (fc_unwind_exit in oldflowcontrol) then
|
||||||
cg.g_local_unwind(current_asmdata.CurrAsmList,oldCurrExitLabel)
|
cg.g_local_unwind(current_asmdata.CurrAsmList,oldCurrExitLabel)
|
||||||
else
|
else
|
||||||
cg.a_jmp_always(current_asmdata.CurrAsmList,oldCurrExitLabel);
|
cg.a_jmp_always(current_asmdata.CurrAsmList,oldCurrExitLabel);
|
||||||
@ -506,7 +500,7 @@ procedure tx64tryexceptnode.pass_generate_code;
|
|||||||
begin
|
begin
|
||||||
cg.a_label(current_asmdata.CurrAsmList,breakexceptlabel);
|
cg.a_label(current_asmdata.CurrAsmList,breakexceptlabel);
|
||||||
cg.g_call(current_asmdata.CurrAsmList,'FPC_DONEEXCEPTION');
|
cg.g_call(current_asmdata.CurrAsmList,'FPC_DONEEXCEPTION');
|
||||||
if (fc_unwind in flowcontrol) then
|
if (fc_unwind_loop in oldflowcontrol) then
|
||||||
cg.g_local_unwind(current_asmdata.CurrAsmList,oldBreakLabel)
|
cg.g_local_unwind(current_asmdata.CurrAsmList,oldBreakLabel)
|
||||||
else
|
else
|
||||||
cg.a_jmp_always(current_asmdata.CurrAsmList,oldBreakLabel);
|
cg.a_jmp_always(current_asmdata.CurrAsmList,oldBreakLabel);
|
||||||
@ -516,7 +510,7 @@ procedure tx64tryexceptnode.pass_generate_code;
|
|||||||
begin
|
begin
|
||||||
cg.a_label(current_asmdata.CurrAsmList,continueexceptlabel);
|
cg.a_label(current_asmdata.CurrAsmList,continueexceptlabel);
|
||||||
cg.g_call(current_asmdata.CurrAsmList,'FPC_DONEEXCEPTION');
|
cg.g_call(current_asmdata.CurrAsmList,'FPC_DONEEXCEPTION');
|
||||||
if (fc_unwind in flowcontrol) then
|
if (fc_unwind_loop in oldflowcontrol) then
|
||||||
cg.g_local_unwind(current_asmdata.CurrAsmList,oldContinueLabel)
|
cg.g_local_unwind(current_asmdata.CurrAsmList,oldContinueLabel)
|
||||||
else
|
else
|
||||||
cg.a_jmp_always(current_asmdata.CurrAsmList,oldContinueLabel);
|
cg.a_jmp_always(current_asmdata.CurrAsmList,oldContinueLabel);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user