Explorar o código

Add a bit to indicate we are within tryfinally, so that we dont insert BailOutOnEarlyExit for an orpahned leave inside trycatch

Meghana Gupta %!s(int64=8) %!d(string=hai) anos
pai
achega
b204ce9bbc

+ 5 - 5
lib/Backend/FlowGraph.cpp

@@ -172,7 +172,7 @@ FlowGraph::Build(void)
 
     bool assignRegionsBeforeGlobopt = this->func->HasTry() && (this->func->DoOptimizeTry() ||
         (this->func->IsSimpleJit() && this->func->hasBailout) ||
-        (this->func->HasFinally() && this->func->IsLoopBodyInTry()));
+        this->func->IsLoopBodyInTryFinally());
 
     // We don't optimize fully with SimpleJit. But, when JIT loop body is enabled, we do support
     // bailing out from a simple jitted function to do a full jit of a loop body in the function
@@ -536,7 +536,7 @@ FlowGraph::Build(void)
         } NEXT_BLOCK_ALL;
     }
 
-    if (this->func->HasFinally() && this->func->IsLoopBodyInTry())
+    if (this->func->IsLoopBodyInTryFinally())
     {
         FOREACH_BLOCK_IN_FUNC(block, this->func)
         {
@@ -1089,7 +1089,7 @@ FlowGraph::MoveBlocksBefore(BasicBlock *blockStart, BasicBlock *blockEnd, BasicB
 
     bool assignRegionsBeforeGlobopt = this->func->HasTry() && (this->func->DoOptimizeTry() ||
         (this->func->IsSimpleJit() && this->func->hasBailout) ||
-        (this->func->HasFinally() && this->func->IsLoopBodyInTry()));
+        this->func->IsLoopBodyInTryFinally());
 
     if (dstLastInstr->IsBranchInstr() && dstLastInstr->AsBranchInstr()->HasFallThrough())
     {
@@ -1878,7 +1878,7 @@ FlowGraph::UpdateRegionForBlock(BasicBlock * block)
 #if DBG
         bool assignRegionsBeforeGlobopt = this->func->HasTry() && (this->func->DoOptimizeTry() ||
         (this->func->IsSimpleJit() && this->func->hasBailout) ||
-        (this->func->HasFinally() && this->func->IsLoopBodyInTry()));
+        this->func->IsLoopBodyInTryFinally());
         Assert(assignRegionsBeforeGlobopt);
 #endif
         return;
@@ -2420,7 +2420,7 @@ FlowGraph::InsertCompensationCodeForBlockMove(FlowEdge * edge,  bool insertToLoo
 
     bool assignRegionsBeforeGlobopt = this->func->HasTry() && (this->func->DoOptimizeTry() ||
         (this->func->IsSimpleJit() && this->func->hasBailout) ||
-        (this->func->HasFinally() && this->func->IsLoopBodyInTry()));
+        this->func->IsLoopBodyInTryFinally());
 
     if (assignRegionsBeforeGlobopt)
     {

+ 6 - 0
lib/Backend/Func.cpp

@@ -278,6 +278,12 @@ Func::IsLoopBodyInTry() const
     return IsLoopBody() && m_workItem->GetLoopHeader()->isInTry;
 }
 
+bool
+Func::IsLoopBodyInTryFinally() const
+{
+    return IsLoopBody() && m_workItem->GetLoopHeader()->isInTryFinally;
+}
+
 /* static */
 void
 Func::Codegen(JitArenaAllocator *alloc, JITTimeWorkItem * workItem,

+ 1 - 0
lib/Backend/Func.h

@@ -187,6 +187,7 @@ public:
     bool HasArgumentSlot() const { return this->GetInParamsCount() != 0 && !this->IsLoopBody(); }
     bool IsLoopBody() const { return m_workItem->IsLoopBody(); }
     bool IsLoopBodyInTry() const;
+    bool IsLoopBodyInTryFinally() const;
     bool CanAllocInPreReservedHeapPageSegment();
     void SetDoFastPaths();
     bool DoFastPaths() const { Assert(this->hasCalledSetDoFastPaths); return this->m_doFastPaths; }

+ 1 - 0
lib/Backend/JITTimeFunctionBody.cpp

@@ -157,6 +157,7 @@ JITTimeFunctionBody::InitializeJITFunctionData(
             jitBody->loopHeaders[i].endOffset = loopHeaders[i].endOffset;
             jitBody->loopHeaders[i].isNested = loopHeaders[i].isNested;
             jitBody->loopHeaders[i].isInTry = loopHeaders[i].isInTry;
+            jitBody->loopHeaders[i].isInTryFinally = loopHeaders[i].isInTryFinally;
             jitBody->loopHeaders[i].interpretCount = functionBody->GetLoopInterpretCount(&loopHeaders[i]);
         }
     }

+ 2 - 1
lib/JITIDL/JITTypes.h

@@ -393,7 +393,8 @@ typedef struct JITLoopHeaderIDL
 {
     boolean isNested;
     boolean isInTry;
-    IDL_PAD2(0)
+    boolean isInTryFinally;
+    IDL_PAD1(0)
     unsigned int interpretCount;
     unsigned int startOffset;
     unsigned int endOffset;

+ 1 - 0
lib/Runtime/Base/FunctionBody.h

@@ -1021,6 +1021,7 @@ namespace Js
 #endif
         Field(bool) isNested;
         Field(bool) isInTry;
+        Field(bool) isInTryFinally;
         Field(FunctionBody *) functionBody;
 
 #if DBG_DUMP

+ 9 - 3
lib/Runtime/Language/InterpreterStackFrame.cpp

@@ -5754,6 +5754,7 @@ const byte * InterpreterStackFrame::OP_ProfiledLoopBodyStart(uint loopId)
 
         Js::LoopHeader *loopHeader = fn->GetLoopHeader(loopNumber);
         loopHeader->isInTry = this->TestFlags(Js::InterpreterStackFrameFlags_WithinTryBlock);
+        loopHeader->isInTryFinally = this->TestFlags(Js::InterpreterStackFrameFlags_WithinTryFinallyBlock);
 
         Js::LoopEntryPointInfo * entryPointInfo = loopHeader->GetCurrentEntryPointInfo();
 
@@ -6538,6 +6539,11 @@ const byte * InterpreterStackFrame::OP_ProfiledLoopBodyStart(uint loopId)
                 // mark the stackFrame as 'in try block'
                 this->OrFlags(InterpreterStackFrameFlags_WithinTryBlock);
 
+                if (finallyOffset != 0)
+                {
+                    this->OrFlags(InterpreterStackFrameFlags_WithinTryFinallyBlock);
+                }
+
                 if (tryNestingDepth != 0)
                 {
                     this->ProcessTryHandlerBailout(ehBailoutData->child, --tryNestingDepth);
@@ -6638,7 +6644,7 @@ const byte * InterpreterStackFrame::OP_ProfiledLoopBodyStart(uint loopId)
         if (--this->nestedTryDepth == -1)
         {
             // unmark the stackFrame as 'in try block'
-            this->ClearFlags(InterpreterStackFrameFlags_WithinTryBlock);
+            this->ClearFlags(InterpreterStackFrameFlags_WithinTryBlock | InterpreterStackFrameFlags_WithinTryFinallyBlock);
         }
 
         // Now that the stack is unwound, let's run the catch block.
@@ -6844,7 +6850,7 @@ const byte * InterpreterStackFrame::OP_ProfiledLoopBodyStart(uint loopId)
 
             this->nestedTryDepth++;
             // mark the stackFrame as 'in try block'
-            this->OrFlags(InterpreterStackFrameFlags_WithinTryBlock);
+            this->OrFlags(InterpreterStackFrameFlags_WithinTryBlock | InterpreterStackFrameFlags_WithinTryFinallyBlock);
 
             if (shouldCacheSP)
             {
@@ -6887,7 +6893,7 @@ const byte * InterpreterStackFrame::OP_ProfiledLoopBodyStart(uint loopId)
         if (--this->nestedTryDepth == -1)
         {
             // unmark the stackFrame as 'in try block'
-            this->ClearFlags(InterpreterStackFrameFlags_WithinTryBlock);
+            this->ClearFlags(InterpreterStackFrameFlags_WithinTryBlock | InterpreterStackFrameFlags_WithinTryFinallyBlock);
         }
 
         shouldCacheSP = !skipFinallyBlock;

+ 1 - 0
lib/Runtime/Language/InterpreterStackFrame.h

@@ -29,6 +29,7 @@ namespace Js
         InterpreterStackFrameFlags_ProcessingBailOutFromEHCode = 0x20,
         InterpreterStackFrameFlags_FromBailOutInInlinee = 0x40,
         InterpreterStackFrameFlags_ProcessingBailOutOnArraySpecialization = 0x80,
+        InterpreterStackFrameFlags_WithinTryFinallyBlock = 0x100,
         InterpreterStackFrameFlags_All = 0xFFFF,
     };