Increase crst level for ReadyToRunInfo's map lock (#17376)
authorKoundinya Veluri <kouvel@users.noreply.github.com>
Tue, 3 Apr 2018 15:49:10 +0000 (08:49 -0700)
committerJan Vorlicek <janvorli@microsoft.com>
Tue, 3 Apr 2018 15:49:10 +0000 (17:49 +0200)
Fixes regex-redux-1 failure seen in https://github.com/dotnet/coreclr/issues/15309
- HashMap lookups and insertions occur under a level 0 lock and may enter cooperative GC mode inside the lock. A GC that is triggered may delete some dynamic code, which takes another level 0 lock. It does not look like it's possible for a deadlock as a result.
- Fixed by increasing the crst level for the lock used in ReadyToRunInfo

src/inc/CrstTypes.def
src/inc/crsttypes.h
src/vm/readytoruninfo.cpp
tests/src/CLRTest.Execute.Bash.targets
tests/src/CLRTest.Execute.Batch.targets
tests/src/readytorun/DynamicMethodGCStress/DynamicMethodGCStress.cs [new file with mode: 0644]
tests/src/readytorun/DynamicMethodGCStress/DynamicMethodGCStress.csproj [new file with mode: 0644]

index 5afc1ed..a048394 100644 (file)
@@ -783,3 +783,7 @@ End
 
 Crst NotifyGdb
 End
+
+Crst ReadyToRunEntryPointToMethodDescMap
+    AcquiredBefore ExecuteManRangeLock
+End
index 1d6b349..f299721 100644 (file)
@@ -24,121 +24,121 @@ enum CrstType
     CrstAssemblyIdentityCache = 5,
     CrstAssemblyList = 6,
     CrstAssemblyLoader = 7,
-    CrstAssemblyUsageLog = 8,
-    CrstAvailableClass = 9,
-    CrstAvailableParamTypes = 10,
-    CrstBaseDomain = 11,
-    CrstCCompRC = 12,
-    CrstCer = 13,
-    CrstClassFactInfoHash = 14,
-    CrstClassInit = 15,
-    CrstClrNotification = 16,
-    CrstCLRPrivBinderMaps = 17,
-    CrstCLRPrivBinderMapsAdd = 18,
-    CrstCodeFragmentHeap = 19,
-    CrstCOMWrapperCache = 20,
-    CrstConnectionNameTable = 21,
-    CrstContexts = 22,
-    CrstCoreCLRBinderLog = 23,
-    CrstCrstCLRPrivBinderLocalWinMDPath = 24,
-    CrstCSPCache = 25,
-    CrstDataTest1 = 26,
-    CrstDataTest2 = 27,
-    CrstDbgTransport = 28,
-    CrstDeadlockDetection = 29,
-    CrstDebuggerController = 30,
-    CrstDebuggerFavorLock = 31,
-    CrstDebuggerHeapExecMemLock = 32,
-    CrstDebuggerHeapLock = 33,
-    CrstDebuggerJitInfo = 34,
-    CrstDebuggerMutex = 35,
-    CrstDelegateToFPtrHash = 36,
-    CrstDomainLocalBlock = 37,
-    CrstDynamicIL = 38,
-    CrstDynamicMT = 39,
-    CrstDynLinkZapItems = 40,
-    CrstEtwTypeLogHash = 41,
-    CrstEventPipe = 42,
-    CrstEventStore = 43,
-    CrstException = 44,
-    CrstExecuteManLock = 45,
-    CrstExecuteManRangeLock = 46,
-    CrstFCall = 47,
-    CrstFriendAccessCache = 48,
-    CrstFuncPtrStubs = 49,
-    CrstFusionAppCtx = 50,
-    CrstFusionAssemblyDownload = 51,
-    CrstFusionBindContext = 52,
-    CrstFusionBindResult = 53,
-    CrstFusionClb = 54,
-    CrstFusionClosure = 55,
-    CrstFusionClosureGraph = 56,
-    CrstFusionConfigSettings = 57,
-    CrstFusionDownload = 58,
-    CrstFusionIsoLibInit = 59,
-    CrstFusionLoadContext = 60,
-    CrstFusionLog = 61,
-    CrstFusionNgenIndex = 62,
-    CrstFusionNgenIndexPool = 63,
-    CrstFusionPcyCache = 64,
-    CrstFusionPolicyConfigPool = 65,
-    CrstFusionSingleUse = 66,
-    CrstFusionWarningLog = 67,
-    CrstGCMemoryPressure = 68,
-    CrstGlobalStrLiteralMap = 69,
-    CrstHandleTable = 70,
-    CrstHostAssemblyMap = 71,
-    CrstHostAssemblyMapAdd = 72,
-    CrstIbcProfile = 73,
-    CrstIJWFixupData = 74,
-    CrstIJWHash = 75,
-    CrstILFingerprintCache = 76,
-    CrstILStubGen = 77,
-    CrstInlineTrackingMap = 78,
-    CrstInstMethodHashTable = 79,
-    CrstInterfaceVTableMap = 80,
-    CrstInterop = 81,
-    CrstInteropData = 82,
-    CrstIOThreadpoolWorker = 83,
-    CrstIsJMCMethod = 84,
-    CrstISymUnmanagedReader = 85,
-    CrstJit = 86,
-    CrstJitGenericHandleCache = 87,
-    CrstJitPerf = 88,
-    CrstJumpStubCache = 89,
-    CrstLeafLock = 90,
-    CrstListLock = 91,
-    CrstLoaderAllocator = 92,
-    CrstLoaderAllocatorReferences = 93,
-    CrstLoaderHeap = 94,
-    CrstMda = 95,
-    CrstMetadataTracker = 96,
-    CrstModIntPairList = 97,
-    CrstModule = 98,
-    CrstModuleFixup = 99,
-    CrstModuleLookupTable = 100,
-    CrstMulticoreJitHash = 101,
-    CrstMulticoreJitManager = 102,
-    CrstMUThunkHash = 103,
-    CrstNativeBinderInit = 104,
-    CrstNativeImageCache = 105,
-    CrstNls = 106,
-    CrstNotifyGdb = 107,
-    CrstObjectList = 108,
-    CrstOnEventManager = 109,
-    CrstPatchEntryPoint = 110,
-    CrstPEFileSecurityManager = 111,
-    CrstPEImage = 112,
-    CrstPEImagePDBStream = 113,
-    CrstPendingTypeLoadEntry = 114,
-    CrstPinHandle = 115,
-    CrstPinnedByrefValidation = 116,
-    CrstProfilerGCRefDataFreeList = 117,
-    CrstProfilingAPIStatus = 118,
-    CrstPublisherCertificate = 119,
-    CrstRCWCache = 120,
-    CrstRCWCleanupList = 121,
-    CrstRCWRefCache = 122,
+    CrstAvailableClass = 8,
+    CrstAvailableParamTypes = 9,
+    CrstBaseDomain = 10,
+    CrstCCompRC = 11,
+    CrstCer = 12,
+    CrstClassFactInfoHash = 13,
+    CrstClassInit = 14,
+    CrstClrNotification = 15,
+    CrstCLRPrivBinderMaps = 16,
+    CrstCLRPrivBinderMapsAdd = 17,
+    CrstCodeFragmentHeap = 18,
+    CrstCOMWrapperCache = 19,
+    CrstConnectionNameTable = 20,
+    CrstContexts = 21,
+    CrstCoreCLRBinderLog = 22,
+    CrstCrstCLRPrivBinderLocalWinMDPath = 23,
+    CrstCSPCache = 24,
+    CrstDataTest1 = 25,
+    CrstDataTest2 = 26,
+    CrstDbgTransport = 27,
+    CrstDeadlockDetection = 28,
+    CrstDebuggerController = 29,
+    CrstDebuggerFavorLock = 30,
+    CrstDebuggerHeapExecMemLock = 31,
+    CrstDebuggerHeapLock = 32,
+    CrstDebuggerJitInfo = 33,
+    CrstDebuggerMutex = 34,
+    CrstDelegateToFPtrHash = 35,
+    CrstDomainLocalBlock = 36,
+    CrstDynamicIL = 37,
+    CrstDynamicMT = 38,
+    CrstDynLinkZapItems = 39,
+    CrstEtwTypeLogHash = 40,
+    CrstEventPipe = 41,
+    CrstEventStore = 42,
+    CrstException = 43,
+    CrstExecuteManLock = 44,
+    CrstExecuteManRangeLock = 45,
+    CrstFCall = 46,
+    CrstFriendAccessCache = 47,
+    CrstFuncPtrStubs = 48,
+    CrstFusionAppCtx = 49,
+    CrstFusionAssemblyDownload = 50,
+    CrstFusionBindContext = 51,
+    CrstFusionBindResult = 52,
+    CrstFusionClb = 53,
+    CrstFusionClosure = 54,
+    CrstFusionClosureGraph = 55,
+    CrstFusionConfigSettings = 56,
+    CrstFusionDownload = 57,
+    CrstFusionIsoLibInit = 58,
+    CrstFusionLoadContext = 59,
+    CrstFusionLog = 60,
+    CrstFusionNgenIndex = 61,
+    CrstFusionNgenIndexPool = 62,
+    CrstFusionPcyCache = 63,
+    CrstFusionPolicyConfigPool = 64,
+    CrstFusionSingleUse = 65,
+    CrstFusionWarningLog = 66,
+    CrstGCMemoryPressure = 67,
+    CrstGlobalStrLiteralMap = 68,
+    CrstHandleTable = 69,
+    CrstHostAssemblyMap = 70,
+    CrstHostAssemblyMapAdd = 71,
+    CrstIbcProfile = 72,
+    CrstIJWFixupData = 73,
+    CrstIJWHash = 74,
+    CrstILFingerprintCache = 75,
+    CrstILStubGen = 76,
+    CrstInlineTrackingMap = 77,
+    CrstInstMethodHashTable = 78,
+    CrstInterfaceVTableMap = 79,
+    CrstInterop = 80,
+    CrstInteropData = 81,
+    CrstIOThreadpoolWorker = 82,
+    CrstIsJMCMethod = 83,
+    CrstISymUnmanagedReader = 84,
+    CrstJit = 85,
+    CrstJitGenericHandleCache = 86,
+    CrstJitPerf = 87,
+    CrstJumpStubCache = 88,
+    CrstLeafLock = 89,
+    CrstListLock = 90,
+    CrstLoaderAllocator = 91,
+    CrstLoaderAllocatorReferences = 92,
+    CrstLoaderHeap = 93,
+    CrstMda = 94,
+    CrstMetadataTracker = 95,
+    CrstModIntPairList = 96,
+    CrstModule = 97,
+    CrstModuleFixup = 98,
+    CrstModuleLookupTable = 99,
+    CrstMulticoreJitHash = 100,
+    CrstMulticoreJitManager = 101,
+    CrstMUThunkHash = 102,
+    CrstNativeBinderInit = 103,
+    CrstNativeImageCache = 104,
+    CrstNls = 105,
+    CrstNotifyGdb = 106,
+    CrstObjectList = 107,
+    CrstOnEventManager = 108,
+    CrstPatchEntryPoint = 109,
+    CrstPEFileSecurityManager = 110,
+    CrstPEImage = 111,
+    CrstPEImagePDBStream = 112,
+    CrstPendingTypeLoadEntry = 113,
+    CrstPinHandle = 114,
+    CrstPinnedByrefValidation = 115,
+    CrstProfilerGCRefDataFreeList = 116,
+    CrstProfilingAPIStatus = 117,
+    CrstPublisherCertificate = 118,
+    CrstRCWCache = 119,
+    CrstRCWCleanupList = 120,
+    CrstRCWRefCache = 121,
+    CrstReadyToRunEntryPointToMethodDescMap = 122,
     CrstReDacl = 123,
     CrstReflection = 124,
     CrstReJITDomainTable = 125,
@@ -206,7 +206,6 @@ int g_rgCrstLevelMap[] =
     0,                 // CrstAssemblyIdentityCache
     0,                 // CrstAssemblyList
     7,                 // CrstAssemblyLoader
-    0,                 // CrstAssemblyUsageLog
     3,                 // CrstAvailableClass
     6,                 // CrstAvailableParamTypes
     7,                 // CrstBaseDomain
@@ -321,6 +320,7 @@ int g_rgCrstLevelMap[] =
     3,                 // CrstRCWCache
     0,                 // CrstRCWCleanupList
     3,                 // CrstRCWRefCache
+    3,                 // CrstReadyToRunEntryPointToMethodDescMap
     0,                 // CrstReDacl
     9,                 // CrstReflection
     7,                 // CrstReJITDomainTable
@@ -382,7 +382,6 @@ LPCSTR g_rgCrstNameMap[] =
     "CrstAssemblyIdentityCache",
     "CrstAssemblyList",
     "CrstAssemblyLoader",
-    "CrstAssemblyUsageLog",
     "CrstAvailableClass",
     "CrstAvailableParamTypes",
     "CrstBaseDomain",
@@ -497,6 +496,7 @@ LPCSTR g_rgCrstNameMap[] =
     "CrstRCWCache",
     "CrstRCWCleanupList",
     "CrstRCWRefCache",
+    "CrstReadyToRunEntryPointToMethodDescMap",
     "CrstReDacl",
     "CrstReflection",
     "CrstReJITDomainTable",
index e8446d4..699e159 100644 (file)
@@ -544,7 +544,8 @@ PTR_ReadyToRunInfo ReadyToRunInfo::Initialize(Module * pModule, AllocMemTracker
 }
 
 ReadyToRunInfo::ReadyToRunInfo(Module * pModule, PEImageLayout * pLayout, READYTORUN_HEADER * pHeader, AllocMemTracker *pamTracker)
-    : m_pModule(pModule), m_pLayout(pLayout), m_pHeader(pHeader), m_Crst(CrstLeafLock), m_pPersistentInlineTrackingMap(NULL)
+    : m_pModule(pModule), m_pLayout(pLayout), m_pHeader(pHeader), m_Crst(CrstReadyToRunEntryPointToMethodDescMap),
+    m_pPersistentInlineTrackingMap(NULL)
 {
     STANDARD_VM_CONTRACT;
 
index 53b632b..a3fecb2 100644 (file)
@@ -252,7 +252,6 @@ fi
 
       <BashCLRTestLaunchCmds Condition="'$(CLRTestKind)' == 'BuildAndRun'">
     <![CDATA[
-ExePath=$(InputAssemblyName)
 $(BashLinkerTestLaunchCmds)
 $(BashCLRTestLaunchCmds)
 if [ ! -z ${RunCrossGen+x} ]%3B then
@@ -373,6 +372,8 @@ $(BashCLRTestArgPrep)
 $(BashCLRTestExitCodePrep)
 $(JitDisasmBashScript)
 $(IlasmRoundTripBashScript)
+# Allow precommands to override the ExePath
+ExePath=$(InputAssemblyName)
 # PreCommands
 $(BashCLRTestPreCommands)
 # Launch
index b02c396..0a6fd43 100644 (file)
@@ -257,7 +257,6 @@ $(BatchIlrtTestLaunchCmds)
       ]]></BatchCLRTestLaunchCmds>
       <BatchCLRTestLaunchCmds Condition="'$(CLRTestKind)' == 'BuildAndRun'">
     <![CDATA[
-set ExePath=$(InputAssemblyName)
 $(BatchLinkerTestLaunchCmds)
 $(BatchCLRTestLaunchCmds)
 
@@ -375,6 +374,9 @@ $(JitDisasmBatchScript)
 
 $(IlasmRoundTripBatchScript)
 
+REM Allow precommands to override the ExePath
+set ExePath=$(InputAssemblyName)
+
 REM Precommands
 $(CLRTestBatchPreCommands)
 REM Launch
diff --git a/tests/src/readytorun/DynamicMethodGCStress/DynamicMethodGCStress.cs b/tests/src/readytorun/DynamicMethodGCStress/DynamicMethodGCStress.cs
new file mode 100644 (file)
index 0000000..85fbf02
--- /dev/null
@@ -0,0 +1,151 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Threading;
+
+internal static class Program
+{
+    private static int Main()
+    {
+        // Verify crst levels with GCs triggered during R2R code lookup in the Prestub on the main thread, during which dynamic
+        // code from a background thread is deleted at the start of the GC in the main thread
+
+        var t = new Thread(() =>
+        {
+            for (uint i = 0; ; ++i)
+            {
+                DynamicMethod dynamicMethod = CreateDynamicMethod($"DynMethod{i}");
+                var dynamicMethodDelegate = (Action)dynamicMethod.CreateDelegate(typeof(Action));
+                dynamicMethodDelegate();
+            }
+        });
+        t.IsBackground = true;
+        t.Start();
+
+        for (int i = 0; i < 100; ++i)
+        {
+            typeof(Program).InvokeMember(
+                $"Func{i}",
+                BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Static,
+                null,
+                null,
+                Array.Empty<object>());
+        }
+
+        return 100;
+    }
+
+    private static DynamicMethod CreateDynamicMethod(string name)
+    {
+        var dynamicMethod = new DynamicMethod(name, null, null);
+        ILGenerator ilGenerator = dynamicMethod.GetILGenerator();
+        ilGenerator.Emit(OpCodes.Ret);
+        return dynamicMethod;
+    }
+
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func0() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func1() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func2() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func3() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func4() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func5() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func6() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func7() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func8() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func9() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func10() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func11() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func12() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func13() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func14() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func15() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func16() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func17() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func18() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func19() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func20() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func21() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func22() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func23() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func24() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func25() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func26() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func27() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func28() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func29() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func30() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func31() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func32() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func33() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func34() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func35() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func36() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func37() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func38() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func39() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func40() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func41() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func42() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func43() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func44() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func45() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func46() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func47() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func48() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func49() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func50() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func51() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func52() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func53() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func54() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func55() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func56() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func57() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func58() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func59() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func60() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func61() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func62() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func63() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func64() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func65() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func66() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func67() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func68() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func69() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func70() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func71() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func72() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func73() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func74() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func75() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func76() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func77() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func78() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func79() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func80() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func81() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func82() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func83() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func84() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func85() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func86() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func87() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func88() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func89() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func90() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func91() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func92() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func93() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func94() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func95() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func96() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func97() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func98() {}
+    [MethodImpl(MethodImplOptions.NoInlining)] private static void Func99() {}
+}
diff --git a/tests/src/readytorun/DynamicMethodGCStress/DynamicMethodGCStress.csproj b/tests/src/readytorun/DynamicMethodGCStress/DynamicMethodGCStress.csproj
new file mode 100644 (file)
index 0000000..cce52cc
--- /dev/null
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{8884AF49-72DA-44EC-B3E0-9FC8F9BCC1F9}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <LangVersion>latest</LangVersion>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+    <Optimize>true</Optimize>
+  </PropertyGroup>
+  <!-- Default configurations to help VS understand the configurations -->
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="DynamicMethodGCStress.cs" />
+  </ItemGroup>
+  <PropertyGroup>
+    <CLRTestBatchPreCommands><![CDATA[
+$(CLRTestBatchPreCommands)
+%CORE_ROOT%\crossgen.exe /readytorun /platform_assemblies_paths %CORE_ROOT%%3B%25CD% /out DynamicMethodGCStress.ni.exe DynamicMethodGCStress.exe
+set ExePath=DynamicMethodGCStress.ni.exe
+set COMPlus_GCStress=3
+]]></CLRTestBatchPreCommands>
+  <BashCLRTestPreCommands><![CDATA[
+$(BashCLRTestPreCommands)
+$CORE_ROOT/crossgen -readytorun -platform_assemblies_paths $CORE_ROOT:`pwd` -out DynamicMethodGCStress.ni.exe DynamicMethodGCStress.exe
+ExePath=DynamicMethodGCStress.ni.exe
+export COMPlus_GCStress=3
+]]></BashCLRTestPreCommands>
+  </PropertyGroup>  
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>