[x86/Linux] Funclet-based synchronization (#10791)
authorJonghyun Park <parjong@gmail.com>
Wed, 12 Apr 2017 16:02:35 +0000 (01:02 +0900)
committerBruce Forstall <brucefo@microsoft.com>
Wed, 12 Apr 2017 16:02:35 +0000 (09:02 -0700)
* [x86/Linux] Funclet-based synchronization

* Fix x86/Windows build error

* Revise per feedback

* Fix format error

src/jit/codegenxarch.cpp
src/jit/compiler.h
src/jit/flowgraph.cpp
src/jit/gcencode.cpp
src/vm/stackwalk.cpp

index 5c23cb5..23c2a18 100644 (file)
@@ -5310,9 +5310,7 @@ void CodeGen::genCallInstruction(GenTreeCall* call)
         gcInfo.gcMarkRegSetNpt(RBM_INTRET);
     }
 
-    unsigned stackAdjustBias = 0;
-
-#if defined(_TARGET_X86_)
+#if !FEATURE_EH_FUNCLETS
     //-------------------------------------------------------------------------
     // Create a label for tracking of region protected by the monitor in synchronized methods.
     // This needs to be here, rather than above where fPossibleSyncHelperCall is set,
@@ -5340,7 +5338,11 @@ void CodeGen::genCallInstruction(GenTreeCall* call)
                 break;
         }
     }
+#endif // !FEATURE_EH_FUNCLETS
+
+    unsigned stackAdjustBias = 0;
 
+#if defined(_TARGET_X86_)
     // Is the caller supposed to pop the arguments?
     if (fCallerPop && (stackArgBytes != 0))
     {
index 832ed03..5b5ee70 100644 (file)
@@ -3646,7 +3646,7 @@ public:
 
     GenTreePtr fgGetCritSectOfStaticMethod();
 
-#if !defined(_TARGET_X86_)
+#if FEATURE_EH_FUNCLETS
 
     void fgAddSyncMethodEnterExit();
 
@@ -3654,7 +3654,7 @@ public:
 
     void fgConvertSyncReturnToLeave(BasicBlock* block);
 
-#endif // !_TARGET_X86_
+#endif // FEATURE_EH_FUNCLETS
 
     void fgAddReversePInvokeEnterExit();
 
index 90e37bd..3374b8c 100644 (file)
@@ -7630,7 +7630,7 @@ GenTreePtr Compiler::fgGetCritSectOfStaticMethod()
     return tree;
 }
 
-#if !defined(_TARGET_X86_)
+#if FEATURE_EH_FUNCLETS
 
 /*****************************************************************************
  *
@@ -8005,7 +8005,7 @@ void Compiler::fgConvertSyncReturnToLeave(BasicBlock* block)
 #endif
 }
 
-#endif // !_TARGET_X86_
+#endif // FEATURE_EH_FUNCLETS
 
 //------------------------------------------------------------------------
 // fgAddReversePInvokeEnterExit: Add enter/exit calls for reverse PInvoke methods
@@ -8266,7 +8266,7 @@ void Compiler::fgAddInternal()
         }
     }
 
-#if !defined(_TARGET_X86_)
+#if FEATURE_EH_FUNCLETS
     // Add the synchronized method enter/exit calls and try/finally protection. Note
     // that this must happen before the one BBJ_RETURN block is created below, so the
     // BBJ_RETURN block gets placed at the top-level, not within an EH region. (Otherwise,
@@ -8276,7 +8276,7 @@ void Compiler::fgAddInternal()
     {
         fgAddSyncMethodEnterExit();
     }
-#endif // !_TARGET_X86_
+#endif // FEATURE_EH_FUNCLETS
 
     if (oneReturn)
     {
@@ -8495,7 +8495,7 @@ void Compiler::fgAddInternal()
 #endif
     }
 
-#if defined(_TARGET_X86_)
+#if !FEATURE_EH_FUNCLETS
 
     /* Is this a 'synchronized' method? */
 
@@ -8571,7 +8571,7 @@ void Compiler::fgAddInternal()
         syncEndEmitCookie   = NULL;
     }
 
-#endif // _TARGET_X86_
+#endif // !FEATURE_EH_FUNCLETS
 
     /* Do we need to do runtime call out to check the security? */
 
index 1e9f288..4c300ac 100644 (file)
@@ -1318,6 +1318,8 @@ size_t GCInfo::gcInfoBlockHdrSave(
 
     header->syncStartOffset = INVALID_SYNC_OFFSET;
     header->syncEndOffset   = INVALID_SYNC_OFFSET;
+#ifndef UNIX_X86_ABI
+    // JIT is responsible for synchronization on funclet-based EH model that x86/Linux uses.
     if (compiler->info.compFlags & CORINFO_FLG_SYNCH)
     {
         assert(compiler->syncStartEmitCookie != NULL);
@@ -1332,6 +1334,7 @@ size_t GCInfo::gcInfoBlockHdrSave(
         // synchronized methods can't have more than 1 epilog
         assert(header->epilogCount <= 1);
     }
+#endif
 
     header->revPInvokeOffset = INVALID_REV_PINVOKE_OFFSET;
 
index dacc85f..31e233c 100644 (file)
@@ -3149,7 +3149,10 @@ void StackFrameIterator::PreProcessingForManagedFrames(void)
 
     INDEBUG(m_crawl.pThread->DebugLogStackWalkInfo(&m_crawl, "CONSIDER", m_uFramesProcessed));
 
-#if defined(_DEBUG) && defined(_TARGET_X86_) && !defined(DACCESS_COMPILE)
+#if defined(_DEBUG) && !defined(WIN64EXCEPTIONS) && !defined(DACCESS_COMPILE)
+    //
+    // VM is responsible for synchronization on non-funclet EH model.
+    //
     // m_crawl.GetThisPointer() requires full unwind
     // In GC's relocate phase, objects is not verifiable
     if ( !(m_flags & (LIGHTUNWIND | QUICKUNWIND | ALLOW_INVALID_OBJECTS)) && 
@@ -3173,7 +3176,7 @@ void StackFrameIterator::PreProcessingForManagedFrames(void)
 
         END_GCX_ASSERT_COOP;
     }
-#endif // _DEBUG && _TARGET_X86_ && !DACCESS_COMPILE
+#endif // _DEBUG && !WIN64EXCEPTIONS && !DACCESS_COMPILE
 
     m_frameState = SFITER_FRAMELESS_METHOD;
 } // StackFrameIterator::PreProcessingForManagedFrames()