Forráskód Böngészése

* 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 -
sergei 10 éve
szülő
commit
e542800ea9
4 módosított fájl, 16 hozzáadás és 19 törlés
  1. 1 1
      compiler/i386/n386flw.pas
  2. 5 3
      compiler/ncgflw.pas
  3. 2 1
      compiler/pass_2.pas
  4. 8 14
      compiler/x86_64/nx64flw.pas

+ 1 - 1
compiler/i386/n386flw.pas

@@ -100,7 +100,7 @@ procedure ti386onnode.pass_generate_code;
     location_reset(location,LOC_VOID,OS_NO);
 
     oldflowcontrol:=flowcontrol;
-    flowcontrol:=flowcontrol*[fc_unwind]+[fc_inflowcontrol];
+    flowcontrol:=[fc_inflowcontrol];
 
     { RTL will put exceptobject into EAX when jumping here }
     cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_FUNCTION_RESULT_REG);

+ 5 - 3
compiler/ncgflw.pas

@@ -148,6 +148,7 @@ implementation
          oldclabel:=current_procinfo.CurrContinueLabel;
          oldblabel:=current_procinfo.CurrBreakLabel;
          include(flowcontrol,fc_inflowcontrol);
+         exclude(flowcontrol,fc_unwind_loop);
 
          sync_regvars(true);
 {$ifdef OLDREGVARS}
@@ -470,6 +471,7 @@ implementation
          hlcg.maybe_change_load_node_reg(current_asmdata.CurrAsmList,left,false);
          oldflowcontrol:=flowcontrol;
          include(flowcontrol,fc_inflowcontrol);
+         exclude(flowcontrol,fc_unwind_loop);
          { produce start assignment }
          case left.location.loc of
            LOC_REFERENCE,
@@ -816,7 +818,7 @@ implementation
          if assigned(left) then
            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)
          else
            hlcg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrExitLabel);
@@ -837,7 +839,7 @@ implementation
 {$ifdef OLDREGVARS}
              load_all_regvars(current_asmdata.CurrAsmList);
 {$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)
              else
                hlcg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrBreakLabel)
@@ -861,7 +863,7 @@ implementation
 {$ifdef OLDREGVARS}
              load_all_regvars(current_asmdata.CurrAsmList);
 {$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)
              else
                hlcg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrContinueLabel)

+ 2 - 1
compiler/pass_2.pas

@@ -36,7 +36,8 @@ uses
          fc_inflowcontrol,
          fc_gotolabel,
          { 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
            not allowed to do ssl }
          fc_lefthandled);

+ 8 - 14
compiler/x86_64/nx64flw.pas

@@ -87,7 +87,6 @@ end;
 
 procedure tx64onnode.pass_generate_code;
   var
-    oldflowcontrol : tflowcontrol;
     exceptvarsym : tlocalvarsym;
   begin
     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);
 
-    oldflowcontrol:=flowcontrol;
-    flowcontrol:=flowcontrol*[fc_unwind]+[fc_inflowcontrol];
-
     { RTL will put exceptobject into RAX when jumping here }
     cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_FUNCTION_RESULT_REG);
 
@@ -130,8 +126,6 @@ procedure tx64onnode.pass_generate_code;
       end;
     cg.g_call(current_asmdata.CurrAsmList,'FPC_DONEEXCEPTION');
     cg.a_jmp_always(current_asmdata.CurrAsmList,endexceptlabel);
-
-    flowcontrol:=oldflowcontrol+(flowcontrol-[fc_inflowcontrol]);
   end;
 
 { tx64tryfinallynode }
@@ -299,12 +293,12 @@ procedure tx64tryfinallynode.pass_generate_code;
     { try code }
     if assigned(left) then
       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 }
         if not implicitframe then
-          include(flowcontrol,fc_unwind);
+          flowcontrol:=flowcontrol+[fc_unwind_exit,fc_unwind_loop];
         secondpass(left);
-        exclude(flowcontrol,fc_unwind);
+        flowcontrol:=flowcontrol-[fc_unwind_exit,fc_unwind_loop];
         if codegenerror then
           exit;
       end;
@@ -393,7 +387,7 @@ procedure tx64tryexceptnode.pass_generate_code;
     continueexceptlabel:=nil;
     breakexceptlabel:=nil;
 
-    flowcontrol:=flowcontrol*[fc_unwind]+[fc_inflowcontrol];
+    include(flowcontrol,fc_inflowcontrol);
     { this can be called recursivly }
     oldBreakLabel:=nil;
     oldContinueLabel:=nil;
@@ -442,7 +436,7 @@ procedure tx64tryexceptnode.pass_generate_code;
         current_procinfo.CurrBreakLabel:=breakexceptlabel;
       end;
 
-    flowcontrol:=flowcontrol*[fc_unwind]+[fc_inflowcontrol];
+    flowcontrol:=[fc_inflowcontrol];
     { on statements }
     if assigned(right) then
       begin
@@ -496,7 +490,7 @@ procedure tx64tryexceptnode.pass_generate_code;
         { do some magic for exit in the try block }
         cg.a_label(current_asmdata.CurrAsmList,exitexceptlabel);
         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)
         else
           cg.a_jmp_always(current_asmdata.CurrAsmList,oldCurrExitLabel);
@@ -506,7 +500,7 @@ procedure tx64tryexceptnode.pass_generate_code;
       begin
         cg.a_label(current_asmdata.CurrAsmList,breakexceptlabel);
         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)
         else
           cg.a_jmp_always(current_asmdata.CurrAsmList,oldBreakLabel);
@@ -516,7 +510,7 @@ procedure tx64tryexceptnode.pass_generate_code;
       begin
         cg.a_label(current_asmdata.CurrAsmList,continueexceptlabel);
         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)
         else
           cg.a_jmp_always(current_asmdata.CurrAsmList,oldContinueLabel);