summaryrefslogtreecommitdiff
path: root/src/vm
diff options
context:
space:
mode:
authorKoundinya Veluri <kouvel@users.noreply.github.com>2019-07-03 16:22:31 -0700
committerSergiy Kuryata <sergeyk@microsoft.com>2019-07-03 16:22:31 -0700
commit01da3bdd734c887856f89037cd4a3f2b5a072967 (patch)
tree28658a9738acc9d03828c877678a7be6fcc59aba /src/vm
parentf36453660859bb88875b655922b4c3e8d28da4c0 (diff)
downloadcoreclr-01da3bdd734c887856f89037cd4a3f2b5a072967.tar.gz
coreclr-01da3bdd734c887856f89037cd4a3f2b5a072967.tar.bz2
coreclr-01da3bdd734c887856f89037cd4a3f2b5a072967.zip
Fix GCStress modes that do code instrumentation to work with code versioning (#25261)
- SOS changes are in https://github.com/dotnet/diagnostics/pull/369 - Fixes https://github.com/dotnet/coreclr/issues/17646
Diffstat (limited to 'src/vm')
-rw-r--r--src/vm/codeman.cpp15
-rw-r--r--src/vm/codeman.h4
-rw-r--r--src/vm/codeversion.cpp73
-rw-r--r--src/vm/codeversion.h33
-rw-r--r--src/vm/gccover.cpp69
-rw-r--r--src/vm/gccover.h3
-rw-r--r--src/vm/jitinterface.cpp24
-rw-r--r--src/vm/jitinterface.h4
-rw-r--r--src/vm/prestub.cpp2
-rw-r--r--src/vm/threads.h3
10 files changed, 182 insertions, 48 deletions
diff --git a/src/vm/codeman.cpp b/src/vm/codeman.cpp
index 059690631e..a7fa9d9cad 100644
--- a/src/vm/codeman.cpp
+++ b/src/vm/codeman.cpp
@@ -4207,6 +4207,21 @@ PCODE ExecutionManager::GetCodeStartAddress(PCODE currentPC)
}
//**************************************************************************
+NativeCodeVersion ExecutionManager::GetNativeCodeVersion(PCODE currentPC)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ FORBID_FAULT;
+ }
+ CONTRACTL_END;
+
+ EECodeInfo codeInfo(currentPC);
+ return codeInfo.IsValid() ? codeInfo.GetNativeCodeVersion() : NativeCodeVersion();
+}
+
+//**************************************************************************
MethodDesc * ExecutionManager::GetCodeMethodDesc(PCODE currentPC)
{
CONTRACTL
diff --git a/src/vm/codeman.h b/src/vm/codeman.h
index 1dc8d8f1ad..a4ad3ffe8b 100644
--- a/src/vm/codeman.h
+++ b/src/vm/codeman.h
@@ -1251,6 +1251,8 @@ public:
// Returns method's start address for a given PC
static PCODE GetCodeStartAddress(PCODE currentPC);
+ static NativeCodeVersion GetNativeCodeVersion(PCODE currentPC);
+
// Returns methodDesc for given PC
static MethodDesc * GetCodeMethodDesc(PCODE currentPC);
@@ -1805,6 +1807,8 @@ public:
return PCODEToPINSTR(m_codeAddress);
}
+ NativeCodeVersion GetNativeCodeVersion();
+
MethodDesc * GetMethodDesc()
{
LIMITED_METHOD_DAC_CONTRACT;
diff --git a/src/vm/codeversion.cpp b/src/vm/codeversion.cpp
index c90189be1e..eb5f15f245 100644
--- a/src/vm/codeversion.cpp
+++ b/src/vm/codeversion.cpp
@@ -25,17 +25,29 @@
// versioning information
//
+NativeCodeVersion::NativeCodeVersion() : m_pMethodDesc(PTR_NULL) {};
NativeCodeVersion::NativeCodeVersion(const NativeCodeVersion & rhs) : m_pMethodDesc(rhs.m_pMethodDesc) {}
NativeCodeVersion::NativeCodeVersion(PTR_MethodDesc pMethod) : m_pMethodDesc(pMethod) {}
BOOL NativeCodeVersion::IsNull() const { return m_pMethodDesc == NULL; }
PTR_MethodDesc NativeCodeVersion::GetMethodDesc() const { return m_pMethodDesc; }
-PCODE NativeCodeVersion::GetNativeCode() const { return m_pMethodDesc->GetNativeCode(); }
NativeCodeVersionId NativeCodeVersion::GetVersionId() const { return 0; }
-// ReJITID NativeCodeVersion::GetILCodeVersionId() const; { return 0; }
-// ILCodeVersion NativeCodeVersion::GetILCodeVersion() const { return ILCodeVersion(m_pMethodDesc); }
+BOOL NativeCodeVersion::IsDefaultVersion() const { return TRUE; }
+PCODE NativeCodeVersion::GetNativeCode() const { return m_pMethodDesc->GetNativeCode(); }
+
#ifndef DACCESS_COMPILE
BOOL NativeCodeVersion::SetNativeCodeInterlocked(PCODE pCode, PCODE pExpected) { return m_pMethodDesc->SetNativeCodeInterlocked(pCode, pExpected); }
#endif
+
+#ifdef HAVE_GCCOVER
+PTR_GCCoverageInfo NativeCodeVersion::GetGCCoverageInfo() const { return GetMethodDesc()->m_GcCover; }
+void NativeCodeVersion::SetGCCoverageInfo(PTR_GCCoverageInfo gcCover)
+{
+ MethodDesc *pMD = GetMethodDesc();
+ _ASSERTE(gcCover == NULL || pMD->m_GcCover == NULL);
+ *EnsureWritablePages(&pMD->m_GcCover) = gcCover;
+}
+#endif
+
bool NativeCodeVersion::operator==(const NativeCodeVersion & rhs) const { return m_pMethodDesc == rhs.m_pMethodDesc; }
bool NativeCodeVersion::operator!=(const NativeCodeVersion & rhs) const { return !operator==(rhs); }
@@ -64,6 +76,9 @@ NativeCodeVersionNode::NativeCodeVersionNode(
#ifdef FEATURE_TIERED_COMPILATION
m_optTier(optimizationTier),
#endif
+#ifdef HAVE_GCCOVER
+ m_gcCover(PTR_NULL),
+#endif
m_flags(0)
{}
#endif
@@ -166,6 +181,24 @@ void NativeCodeVersionNode::SetOptimizationTier(NativeCodeVersion::OptimizationT
#endif // FEATURE_TIERED_COMPILATION
+#ifdef HAVE_GCCOVER
+
+PTR_GCCoverageInfo NativeCodeVersionNode::GetGCCoverageInfo() const
+{
+ LIMITED_METHOD_CONTRACT;
+ return m_gcCover;
+}
+
+void NativeCodeVersionNode::SetGCCoverageInfo(PTR_GCCoverageInfo gcCover)
+{
+ LIMITED_METHOD_CONTRACT;
+ _ASSERTE(gcCover == NULL || m_gcCover == NULL);
+
+ m_gcCover = gcCover;
+}
+
+#endif // HAVE_GCCOVER
+
NativeCodeVersion::NativeCodeVersion() :
m_storageKind(StorageKind::Unknown)
{}
@@ -371,6 +404,40 @@ void NativeCodeVersion::SetOptimizationTier(OptimizationTier tier)
#endif
+#ifdef HAVE_GCCOVER
+
+PTR_GCCoverageInfo NativeCodeVersion::GetGCCoverageInfo() const
+{
+ WRAPPER_NO_CONTRACT;
+
+ if (m_storageKind == StorageKind::Explicit)
+ {
+ return AsNode()->GetGCCoverageInfo();
+ }
+ else
+ {
+ return GetMethodDesc()->m_GcCover;
+ }
+}
+
+void NativeCodeVersion::SetGCCoverageInfo(PTR_GCCoverageInfo gcCover)
+{
+ WRAPPER_NO_CONTRACT;
+
+ if (m_storageKind == StorageKind::Explicit)
+ {
+ AsNode()->SetGCCoverageInfo(gcCover);
+ }
+ else
+ {
+ MethodDesc *pMD = GetMethodDesc();
+ _ASSERTE(gcCover == NULL || pMD->m_GcCover == NULL);
+ *EnsureWritablePages(&pMD->m_GcCover) = gcCover;
+ }
+}
+
+#endif // HAVE_GCCOVER
+
PTR_NativeCodeVersionNode NativeCodeVersion::AsNode() const
{
LIMITED_METHOD_DAC_CONTRACT;
diff --git a/src/vm/codeversion.h b/src/vm/codeversion.h
index 23fb908575..898796f183 100644
--- a/src/vm/codeversion.h
+++ b/src/vm/codeversion.h
@@ -37,8 +37,10 @@ typedef DPTR(class CodeVersionManager) PTR_CodeVersionManager;
#endif
-
-
+#ifdef HAVE_GCCOVER
+class GCCoverageInfo;
+typedef DPTR(class GCCoverageInfo) PTR_GCCoverageInfo;
+#endif
class NativeCodeVersion
{
@@ -54,16 +56,22 @@ public:
NativeCodeVersion(PTR_NativeCodeVersionNode pVersionNode);
#endif
explicit NativeCodeVersion(PTR_MethodDesc pMethod);
+
BOOL IsNull() const;
PTR_MethodDesc GetMethodDesc() const;
NativeCodeVersionId GetVersionId() const;
BOOL IsDefaultVersion() const;
PCODE GetNativeCode() const;
+
+#ifdef FEATURE_CODE_VERSIONING
ILCodeVersion GetILCodeVersion() const;
ReJITID GetILCodeVersionId() const;
+#endif
+
#ifndef DACCESS_COMPILE
BOOL SetNativeCodeInterlocked(PCODE pCode, PCODE pExpected = NULL);
#endif
+
enum OptimizationTier
{
OptimizationTier0,
@@ -76,8 +84,15 @@ public:
void SetOptimizationTier(OptimizationTier tier);
#endif
#endif // FEATURE_TIERED_COMPILATION
+
+#ifdef HAVE_GCCOVER
+ PTR_GCCoverageInfo GetGCCoverageInfo() const;
+ void SetGCCoverageInfo(PTR_GCCoverageInfo gcCover);
+#endif
+
bool operator==(const NativeCodeVersion & rhs) const;
bool operator!=(const NativeCodeVersion & rhs) const;
+
#if defined(DACCESS_COMPILE) && defined(FEATURE_CODE_VERSIONING)
// The DAC is privy to the backing node abstraction
PTR_NativeCodeVersionNode AsNode() const;
@@ -86,7 +101,7 @@ public:
private:
#ifndef FEATURE_CODE_VERSIONING
- MethodDesc* m_pMethodDesc;
+ PTR_MethodDesc m_pMethodDesc;
#else // FEATURE_CODE_VERSIONING
#ifndef DACCESS_COMPILE
@@ -229,13 +244,16 @@ class NativeCodeVersionNode
friend NativeCodeVersionIterator;
friend MethodDescVersioningState;
friend ILCodeVersionNode;
+
public:
#ifndef DACCESS_COMPILE
NativeCodeVersionNode(NativeCodeVersionId id, MethodDesc* pMethod, ReJITID parentId, NativeCodeVersion::OptimizationTier optimizationTier);
#endif
+
#ifdef DEBUG
BOOL LockOwnedByCurrentThread() const;
#endif
+
PTR_MethodDesc GetMethodDesc() const;
NativeCodeVersionId GetVersionId() const;
PCODE GetNativeCode() const;
@@ -246,6 +264,7 @@ public:
BOOL SetNativeCodeInterlocked(PCODE pCode, PCODE pExpected);
void SetActiveChildFlag(BOOL isActive);
#endif
+
#ifdef FEATURE_TIERED_COMPILATION
NativeCodeVersion::OptimizationTier GetOptimizationTier() const;
#ifndef DACCESS_COMPILE
@@ -253,6 +272,11 @@ public:
#endif
#endif // FEATURE_TIERED_COMPILATION
+#ifdef HAVE_GCCOVER
+ PTR_GCCoverageInfo GetGCCoverageInfo() const;
+ void SetGCCoverageInfo(PTR_GCCoverageInfo gcCover);
+#endif
+
private:
//union - could save a little memory?
//{
@@ -266,6 +290,9 @@ private:
#ifdef FEATURE_TIERED_COMPILATION
NativeCodeVersion::OptimizationTier m_optTier;
#endif
+#ifdef HAVE_GCCOVER
+ PTR_GCCoverageInfo m_gcCover;
+#endif
enum NativeCodeVersionNodeFlags
{
diff --git a/src/vm/gccover.cpp b/src/vm/gccover.cpp
index 7b8c4742f9..2ede08d823 100644
--- a/src/vm/gccover.cpp
+++ b/src/vm/gccover.cpp
@@ -125,13 +125,16 @@ bool IsOriginalInstruction(PBYTE instrPtr, GCCoverageInfo* gcCover, DWORD offset
void SetupAndSprinkleBreakpoints(
- MethodDesc * pMD,
+ NativeCodeVersion nativeCodeVersion,
EECodeInfo * pCodeInfo,
IJitManager::MethodRegionInfo methodRegionInfo,
BOOL fZapped
)
{
+ _ASSERTE(!nativeCodeVersion.IsNull());
+
// Allocate room for the GCCoverageInfo and copy of the method instructions
+ MethodDesc *pMD = nativeCodeVersion.GetMethodDesc();
size_t memSize = sizeof(GCCoverageInfo) + methodRegionInfo.hotSize + methodRegionInfo.coldSize;
GCCoverageInfo* gcCover = (GCCoverageInfo*)(void*) pMD->GetLoaderAllocator()->GetHighFrequencyHeap()->AllocAlignedMem(memSize, CODE_SIZE_ALIGN);
@@ -143,8 +146,6 @@ void SetupAndSprinkleBreakpoints(
gcCover->callerThread = 0;
gcCover->doingEpilogChecks = true;
- gcCover->lastMD = pMD; /* pass pMD to SprinkleBreakpoints */
-
gcCover->SprinkleBreakpoints(gcCover->savedCode,
gcCover->methodRegion.hotStartAddress,
gcCover->methodRegion.hotSize,
@@ -163,16 +164,15 @@ void SetupAndSprinkleBreakpoints(
}
#endif
- gcCover->lastMD = NULL; /* clear lastMD */
-
- _ASSERTE(!pMD->m_GcCover);
- *EnsureWritablePages(&pMD->m_GcCover) = gcCover;
+ nativeCodeVersion.SetGCCoverageInfo(gcCover);
}
-void SetupAndSprinkleBreakpointsForJittedMethod(MethodDesc * pMD,
+void SetupAndSprinkleBreakpointsForJittedMethod(NativeCodeVersion nativeCodeVersion,
PCODE codeStart
)
{
+ _ASSERTE(!nativeCodeVersion.IsNull());
+
EECodeInfo codeInfo(codeStart);
_ASSERTE(codeInfo.IsValid());
_ASSERTE(codeInfo.GetRelOffset() == 0);
@@ -183,9 +183,9 @@ void SetupAndSprinkleBreakpointsForJittedMethod(MethodDesc *
_ASSERTE(PCODEToPINSTR(codeStart) == methodRegionInfo.hotStartAddress);
#ifdef _DEBUG
- if (!g_pConfig->SkipGCCoverage(pMD->GetModule()->GetSimpleName()))
+ if (!g_pConfig->SkipGCCoverage(nativeCodeVersion.GetMethodDesc()->GetModule()->GetSimpleName()))
#endif
- SetupAndSprinkleBreakpoints(pMD,
+ SetupAndSprinkleBreakpoints(nativeCodeVersion,
&codeInfo,
methodRegionInfo,
FALSE
@@ -195,10 +195,12 @@ void SetupAndSprinkleBreakpointsForJittedMethod(MethodDesc *
/****************************************************************************/
/* called when a method is first jitted when GCStress level 4 or 8 is on */
-void SetupGcCoverage(MethodDesc* pMD, BYTE* methodStartPtr) {
+void SetupGcCoverage(NativeCodeVersion nativeCodeVersion, BYTE* methodStartPtr)
+{
+ _ASSERTE(!nativeCodeVersion.IsNull());
#ifdef _DEBUG
- if (!g_pConfig->ShouldGcCoverageOnMethod(pMD->m_pszDebugMethodName)) {
+ if (!g_pConfig->ShouldGcCoverageOnMethod(nativeCodeVersion.GetMethodDesc()->m_pszDebugMethodName)) {
return;
}
#endif
@@ -221,22 +223,23 @@ void SetupGcCoverage(MethodDesc* pMD, BYTE* methodStartPtr) {
// code, and since the rejitted method does not get instrumented
// we should be able to tolerate that the gc cover info does not
// match.
- if (pMD->m_GcCover)
+ if (nativeCodeVersion.GetGCCoverageInfo() != NULL)
{
return;
}
PCODE codeStart = (PCODE) methodStartPtr;
- SetupAndSprinkleBreakpointsForJittedMethod(pMD, codeStart);
+ SetupAndSprinkleBreakpointsForJittedMethod(nativeCodeVersion, codeStart);
}
#ifdef FEATURE_PREJIT
-void SetupGcCoverageForNativeMethod(MethodDesc* pMD,
+void SetupGcCoverageForNativeMethod(NativeCodeVersion nativeCodeVersion,
PCODE codeStart,
IJitManager::MethodRegionInfo& methodRegionInfo
)
{
+ _ASSERTE(!nativeCodeVersion.IsNull());
EECodeInfo codeInfo(codeStart);
_ASSERTE(codeInfo.IsValid());
@@ -244,7 +247,7 @@ void SetupGcCoverageForNativeMethod(MethodDesc* pMD,
_ASSERTE(PCODEToPINSTR(codeStart) == methodRegionInfo.hotStartAddress);
- SetupAndSprinkleBreakpoints(pMD,
+ SetupAndSprinkleBreakpoints(nativeCodeVersion,
&codeInfo,
methodRegionInfo,
TRUE
@@ -296,7 +299,7 @@ void SetupGcCoverageForNativeImage(Module* module)
IJitManager::MethodRegionInfo methodRegionInfo;
mi.GetMethodRegionInfo(&methodRegionInfo);
- SetupGcCoverageForNativeMethod(pMD, pMethodStart, methodRegionInfo);
+ SetupGcCoverageForNativeMethod(NativeCodeVersion(pMD), pMethodStart, methodRegionInfo);
}
}
#endif
@@ -1312,7 +1315,7 @@ bool IsGcCoverageInterrupt(LPVOID ip)
return false;
}
- GCCoverageInfo *gcCover = codeInfo.GetMethodDesc()->m_GcCover;
+ GCCoverageInfo *gcCover = codeInfo.GetNativeCodeVersion().GetGCCoverageInfo();
if (gcCover == nullptr)
{
return false;
@@ -1374,7 +1377,7 @@ BOOL OnGcCoverageInterrupt(PCONTEXT regs)
forceStack[1] = &pMD; // This is so I can see it fastchecked
forceStack[2] = &offset; // This is so I can see it fastchecked
- GCCoverageInfo* gcCover = pMD->m_GcCover;
+ GCCoverageInfo* gcCover = codeInfo.GetNativeCodeVersion().GetGCCoverageInfo();
forceStack[3] = &gcCover; // This is so I can see it fastchecked
if (gcCover == 0)
return(FALSE); // we aren't doing code gcCoverage on this function
@@ -1408,7 +1411,7 @@ BOOL OnGcCoverageInterrupt(PCONTEXT regs)
#ifdef _DEBUG
if (!g_pConfig->SkipGCCoverage(pMD->GetModule()->GetSimpleName()))
#endif
- DoGcStress(regs, pMD);
+ DoGcStress(regs, codeInfo.GetNativeCodeVersion());
#endif // !USE_REDIRECT_FOR_GCSTRESS
@@ -1426,22 +1429,22 @@ FORCEINLINE void UpdateGCStressInstructionWithoutGC ()
/****************************************************************************/
-void DoGcStress (PCONTEXT regs, MethodDesc *pMD)
+void DoGcStress (PCONTEXT regs, NativeCodeVersion nativeCodeVersion)
{
PCODE controlPc = GetIP(regs);
PBYTE instrPtr = reinterpret_cast<PBYTE>(PCODEToPINSTR(controlPc));
- if (!pMD)
+ if (nativeCodeVersion.IsNull())
{
- pMD = ExecutionManager::GetCodeMethodDesc(controlPc);
- if (!pMD)
+ nativeCodeVersion = ExecutionManager::GetNativeCodeVersion(controlPc);
+ if (nativeCodeVersion.IsNull())
return;
}
- GCCoverageInfo *gcCover = pMD->m_GcCover;
+ GCCoverageInfo *gcCover = nativeCodeVersion.GetGCCoverageInfo();
EECodeInfo codeInfo(controlPc);
- _ASSERTE(codeInfo.GetMethodDesc() == pMD);
+ _ASSERTE(codeInfo.GetNativeCodeVersion() == nativeCodeVersion);
DWORD offset = codeInfo.GetRelOffset();
Thread *pThread = GetThread();
@@ -1769,17 +1772,9 @@ void DoGcStress (PCONTEXT regs, MethodDesc *pMD)
gcFrame.Init(pThread, (OBJECTREF*)retValRegs, numberOfRegs, TRUE);
}
- if (gcCover->lastMD != pMD)
- {
- LOG((LF_GCROOTS, LL_INFO100000, "GCCOVER: Doing GC at method %s::%s offset 0x%x\n",
- pMD->m_pszDebugClassName, pMD->m_pszDebugMethodName, offset));
- gcCover->lastMD =pMD;
- }
- else
- {
- LOG((LF_GCROOTS, LL_EVERYTHING, "GCCOVER: Doing GC at method %s::%s offset 0x%x\n",
- pMD->m_pszDebugClassName, pMD->m_pszDebugMethodName, offset));
- }
+ MethodDesc *pMD = nativeCodeVersion.GetMethodDesc();
+ LOG((LF_GCROOTS, LL_EVERYTHING, "GCCOVER: Doing GC at method %s::%s offset 0x%x\n",
+ pMD->m_pszDebugClassName, pMD->m_pszDebugMethodName, offset));
//-------------------------------------------------------------------------
// Do the actual stress work
diff --git a/src/vm/gccover.h b/src/vm/gccover.h
index e560c0d28d..42b093f4ce 100644
--- a/src/vm/gccover.h
+++ b/src/vm/gccover.h
@@ -22,7 +22,6 @@ class GCCoverageInfo {
public:
IJitManager::MethodRegionInfo methodRegion;
BYTE* curInstr; // The last instruction that was able to execute
- MethodDesc* lastMD; // Used to quickly figure out the culprite
// Following 6 variables are for prolog / epilog walking coverage
ICodeManager* codeMan; // CodeMan for this method
@@ -61,6 +60,8 @@ public:
};
+typedef DPTR(GCCoverageInfo) PTR_GCCoverageInfo; // see code:GCCoverageInfo::savedCode
+
#ifdef _MSC_VER
#pragma warning(pop)
#endif // _MSC_VER
diff --git a/src/vm/jitinterface.cpp b/src/vm/jitinterface.cpp
index 884257b6a4..e667ddd0a6 100644
--- a/src/vm/jitinterface.cpp
+++ b/src/vm/jitinterface.cpp
@@ -14263,6 +14263,30 @@ TADDR EECodeInfo::GetStartAddress()
return m_pJM->JitTokenToStartAddress(m_methodToken);
}
+NativeCodeVersion EECodeInfo::GetNativeCodeVersion()
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ }
+ CONTRACTL_END;
+
+ PTR_MethodDesc pMD = PTR_MethodDesc(GetMethodDesc());
+ if (pMD == NULL)
+ {
+ return NativeCodeVersion();
+ }
+
+#ifdef FEATURE_CODE_VERSIONING
+ CodeVersionManager *pCodeVersionManager = pMD->GetCodeVersionManager();
+ CodeVersionManager::TableLockHolder lockHolder(pCodeVersionManager);
+ return pCodeVersionManager->GetNativeCodeVersion(pMD, PINSTRToPCODE(GetStartAddress()));
+#else
+ return NativeCodeVersion(pMD);
+#endif
+}
+
#if defined(WIN64EXCEPTIONS)
// ----------------------------------------------------------------------------
diff --git a/src/vm/jitinterface.h b/src/vm/jitinterface.h
index c5f7953596..70726b0b27 100644
--- a/src/vm/jitinterface.h
+++ b/src/vm/jitinterface.h
@@ -1648,10 +1648,10 @@ EXTERN_C void JIT_TailCallHelperStub_ReturnAddress();
void *GenFastGetSharedStaticBase(bool bCheckCCtor);
#ifdef HAVE_GCCOVER
-void SetupGcCoverage(MethodDesc* pMD, BYTE* nativeCode);
+void SetupGcCoverage(NativeCodeVersion nativeCodeVersion, BYTE* nativeCode);
void SetupGcCoverageForNativeImage(Module* module);
BOOL OnGcCoverageInterrupt(PT_CONTEXT regs);
-void DoGcStress (PT_CONTEXT regs, MethodDesc *pMD);
+void DoGcStress (PT_CONTEXT regs, NativeCodeVersion nativeCodeVersion);
#endif //HAVE_GCCOVER
EXTERN_C FCDECL2(LPVOID, ArrayStoreCheck, Object** pElement, PtrArray** pArray);
diff --git a/src/vm/prestub.cpp b/src/vm/prestub.cpp
index 0cbd0fc236..b76a018daf 100644
--- a/src/vm/prestub.cpp
+++ b/src/vm/prestub.cpp
@@ -1015,7 +1015,7 @@ PCODE MethodDesc::JitCompileCodeLocked(PrepareCodeConfig* pConfig, JitListLockEn
return pOtherCode;
}
- SetupGcCoverage(this, (BYTE*)pCode);
+ SetupGcCoverage(pConfig->GetCodeVersion(), (BYTE*)pCode);
// This thread should always win the publishing race
// since we're under a lock.
diff --git a/src/vm/threads.h b/src/vm/threads.h
index c4189126d3..a5666900d8 100644
--- a/src/vm/threads.h
+++ b/src/vm/threads.h
@@ -168,6 +168,7 @@ class CRWLock;
struct LockEntry;
class PendingTypeLoadHolder;
class PrepareCodeConfig;
+class NativeCodeVersion;
struct ThreadLocalBlock;
typedef DPTR(struct ThreadLocalBlock) PTR_ThreadLocalBlock;
@@ -3700,7 +3701,7 @@ private:
friend class NDirect; // Quick access to thread stub creation
#ifdef HAVE_GCCOVER
- friend void DoGcStress (PT_CONTEXT regs, MethodDesc *pMD); // Needs to call UnhijackThread
+ friend void DoGcStress (PT_CONTEXT regs, NativeCodeVersion nativeCodeVersion); // Needs to call UnhijackThread
#endif // HAVE_GCCOVER
ULONG m_ExternalRefCount;