diff options
author | Andrew Au <cshung@gmail.com> | 2019-01-11 08:34:21 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-01-11 08:34:21 -0800 |
commit | bbd812d77d6d0b79e6f00025de906b4e1ac93c7e (patch) | |
tree | fef6344f36ffd8b4404c8826bb4e8ef5dd971ac6 /src/debug/ee | |
parent | dabe2b8f49479fc3c2958c97e6b1472c2d40af0f (diff) | |
download | coreclr-bbd812d77d6d0b79e6f00025de906b4e1ac93c7e.tar.gz coreclr-bbd812d77d6d0b79e6f00025de906b4e1ac93c7e.tar.bz2 coreclr-bbd812d77d6d0b79e6f00025de906b4e1ac93c7e.zip |
Flowing the nativeCodeVersion to DebuggerJitInfo (#21925)
Diffstat (limited to 'src/debug/ee')
-rw-r--r-- | src/debug/ee/controller.cpp | 38 | ||||
-rw-r--r-- | src/debug/ee/debugger.cpp | 30 | ||||
-rw-r--r-- | src/debug/ee/debugger.h | 8 | ||||
-rw-r--r-- | src/debug/ee/frameinfo.cpp | 2 | ||||
-rw-r--r-- | src/debug/ee/functioninfo.cpp | 52 |
5 files changed, 67 insertions, 63 deletions
diff --git a/src/debug/ee/controller.cpp b/src/debug/ee/controller.cpp index a0d78b48b6..494f66beb6 100644 --- a/src/debug/ee/controller.cpp +++ b/src/debug/ee/controller.cpp @@ -644,7 +644,7 @@ DebuggerControllerPatch *DebuggerPatchTable::AddPatchForAddress(DebuggerControll LOG((LF_CORDB,LL_INFO10000,"AddPatchForAddress w/ version 0x%04x, " "pid:0x%x\n", dji->m_methodInfo->GetCurrentEnCVersion(), patch->pid)); - _ASSERTE( fd==NULL || fd == dji->m_fd ); + _ASSERTE( fd==NULL || fd == dji->m_nativeCodeVersion.GetMethodDesc() ); } SortPatchIntoPatchList(&patch); @@ -1865,7 +1865,7 @@ BOOL DebuggerController::AddBindAndActivateILSlavePatch(DebuggerControllerPatch // code bodies. _ASSERTE(master->offset == 0); INDEBUG(BOOL fOk = ) - AddBindAndActivatePatchForMethodDesc(dji->m_fd, dji, + AddBindAndActivatePatchForMethodDesc(dji->m_nativeCodeVersion.GetMethodDesc(), dji, 0, PATCH_KIND_IL_SLAVE, LEAF_MOST_FRAME, m_pAppDomain); _ASSERTE(fOk); @@ -1892,7 +1892,7 @@ BOOL DebuggerController::AddBindAndActivateILSlavePatch(DebuggerControllerPatch if (!fExact && (masterILOffset != 0)) { LOG((LF_CORDB, LL_INFO10000, "DC::BP:Failed to bind patch at IL offset 0x%p in %s::%s\n", - masterILOffset, dji->m_fd->m_pszDebugClassName, dji->m_fd->m_pszDebugMethodName)); + masterILOffset, dji->m_nativeCodeVersion.GetMethodDesc()->m_pszDebugClassName, dji->m_nativeCodeVersion.GetMethodDesc()->m_pszDebugMethodName)); continue; } @@ -1902,7 +1902,7 @@ BOOL DebuggerController::AddBindAndActivateILSlavePatch(DebuggerControllerPatch } INDEBUG(BOOL fOk = ) - AddBindAndActivatePatchForMethodDesc(dji->m_fd, dji, + AddBindAndActivatePatchForMethodDesc(dji->m_nativeCodeVersion.GetMethodDesc(), dji, offsetNative, PATCH_KIND_IL_SLAVE, LEAF_MOST_FRAME, m_pAppDomain); _ASSERTE(fOk); @@ -1982,7 +1982,7 @@ BOOL DebuggerController::AddILPatch(AppDomain * pAppDomain, Module *module, DebuggerJitInfo *dji = it.Current(); _ASSERTE(dji->m_jitComplete); if (dji->m_encVersion == encVersion && - (pMethodDescFilter == NULL || pMethodDescFilter == dji->m_fd)) + (pMethodDescFilter == NULL || pMethodDescFilter == dji->m_nativeCodeVersion.GetMethodDesc())) { fVersionMatch = TRUE; @@ -2062,7 +2062,7 @@ BOOL DebuggerController::AddBindAndActivateNativeManagedPatch(MethodDesc * fd, CONTRACTL_END; // For non-dynamic methods, we always expect to have a DJI, but just in case, we don't want the assert to AV. - _ASSERTE((dji == NULL) || (fd == dji->m_fd)); + _ASSERTE((dji == NULL) || (fd == dji->m_nativeCodeVersion.GetMethodDesc())); _ASSERTE(g_patches != NULL); return DebuggerController::AddBindAndActivatePatchForMethodDesc(fd, dji, offsetNative, PATCH_KIND_NATIVE_MANAGED, fp, pAppDomain); } @@ -2187,7 +2187,7 @@ void DebuggerController::RemovePatchesFromModule(Module *pModule, AppDomain *pAp { DebuggerJitInfo * dji = patch->GetDJI(); - _ASSERTE(patch->key.module == dji->m_fd->GetModule()); + _ASSERTE(patch->key.module == dji->m_nativeCodeVersion.GetMethodDesc()->GetModule()); // It is not necessary to check for m_fd->GetModule() here. It will // be covered by other module unload notifications issued for the appdomain. @@ -2243,11 +2243,11 @@ bool DebuggerController::ModuleHasPatches( Module* pModule ) { DebuggerJitInfo * dji = patch->GetDJI(); - _ASSERTE(patch->key.module == dji->m_fd->GetModule()); + _ASSERTE(patch->key.module == dji->m_nativeCodeVersion.GetMethodDesc()->GetModule()); // It may be sufficient to just check m_pLoaderModule here. Since this is used for debug-only // check, we will check for m_fd->GetModule() as well to catch more potential problems. - if ( (dji->m_pLoaderModule == pModule) || (dji->m_fd->GetModule() == pModule) ) + if ( (dji->m_pLoaderModule == pModule) || (dji->m_nativeCodeVersion.GetMethodDesc()->GetModule() == pModule) ) { return true; } @@ -3912,8 +3912,8 @@ void DebuggerController::DispatchMethodEnter(void * pIP, FramePointer fp) } LOG((LF_CORDB, LL_INFO100000, "DC::DispatchMethodEnter for '%s::%s'\n", - dji->m_fd->m_pszDebugClassName, - dji->m_fd->m_pszDebugMethodName)); + dji->m_nativeCodeVersion.GetMethodDesc()->m_pszDebugClassName, + dji->m_nativeCodeVersion.GetMethodDesc()->m_pszDebugMethodName)); ControllerLockHolder lockController; @@ -6661,7 +6661,7 @@ bool DebuggerStepper::SetRangesFromIL(DebuggerJitInfo *dji, COR_DEBUG_STEP_RANGE // Note: we used to pass in the IP from the active frame to GetJitInfo, but there seems to be no value in that, and // it was causing problems creating a stepper while sitting in ndirect stubs after we'd returned from the unmanaged // function that had been called. - MethodDesc *fd = dji->m_fd; + MethodDesc *fd = dji->m_nativeCodeVersion.GetMethodDesc(); // The "+1" is for internal use, when we need to // set an intermediate patch in pitched code. Isn't @@ -7151,7 +7151,7 @@ TP_RESULT DebuggerStepper::TriggerPatch(DebuggerControllerPatch *patch, dji = g_pDebugger->GetJitInfoFromAddr((TADDR) traceManagerRetAddr); MethodDesc * mdNative = (dji == NULL) ? - g_pEEInterface->GetNativeCodeMethodDesc(dac_cast<PCODE>(traceManagerRetAddr)) : dji->m_fd; + g_pEEInterface->GetNativeCodeMethodDesc(dac_cast<PCODE>(traceManagerRetAddr)) : dji->m_nativeCodeVersion.GetMethodDesc(); _ASSERTE(mdNative != NULL); // Find the method that the return is to. @@ -7299,7 +7299,7 @@ void DebuggerStepper::TriggerMethodEnter(Thread * thread, _ASSERTE(!IsFrozen()); - MethodDesc * pDesc = dji->m_fd; + MethodDesc * pDesc = dji->m_nativeCodeVersion.GetMethodDesc(); LOG((LF_CORDB, LL_INFO10000, "DJMCStepper::TME, desc=%p, addr=%p\n", pDesc, ip)); @@ -7664,7 +7664,7 @@ void DebuggerStepper::PrepareForSendEvent(StackTraceTicket ticket) dmi = dji->m_methodInfo; CONSISTENCY_CHECK_MSGF(dmi->IsJMCFunction(), ("JMC stepper %p stopping in non-jmc method, MD=%p, '%s::%s'", - this, dji->m_fd, dji->m_fd->m_pszDebugClassName, dji->m_fd->m_pszDebugMethodName)); + this, dji->m_nativeCodeVersion.GetMethodDesc(), dji->m_nativeCodeVersion.GetMethodDesc()->m_pszDebugClassName, dji->m_nativeCodeVersion.GetMethodDesc()->m_pszDebugMethodName)); } @@ -7940,7 +7940,7 @@ void DebuggerJMCStepper::TriggerMethodEnter(Thread * thread, _ASSERTE(!IsFrozen()); - MethodDesc * pDesc = dji->m_fd; + MethodDesc * pDesc = dji->m_nativeCodeVersion.GetMethodDesc(); LOG((LF_CORDB, LL_INFO10000, "DJMCStepper::TME, desc=%p, addr=%p\n", pDesc, ip)); @@ -8663,7 +8663,7 @@ DebuggerEnCBreakpoint::DebuggerEnCBreakpoint(SIZE_T offset, { _ASSERTE( jitInfo != NULL ); // Add and activate the specified patch - AddBindAndActivateNativeManagedPatch(jitInfo->m_fd, jitInfo, offset, LEAF_MOST_FRAME, pAppDomain); + AddBindAndActivateNativeManagedPatch(jitInfo->m_nativeCodeVersion.GetMethodDesc(), jitInfo, offset, LEAF_MOST_FRAME, pAppDomain); LOG((LF_ENC,LL_INFO1000, "DEnCBPDEnCBP::adding %S patch!\n", fTriggerType == REMAP_PENDING ? W("remap pending") : W("remap complete"))); } @@ -8743,7 +8743,7 @@ TP_RESULT DebuggerEnCBreakpoint::TriggerPatch(DebuggerControllerPatch *patch, // what we are executing right now. DebuggerJitInfo *pJitInfo = m_jitInfo; _ASSERTE(pJitInfo); - _ASSERTE(pJitInfo->m_fd == pFD); + _ASSERTE(pJitInfo->m_nativeCodeVersion.GetMethodDesc() == pFD); // Grab the context for this thread. This is the context that was // passed to COMPlusFrameHandler. @@ -8902,7 +8902,7 @@ DebuggerContinuableExceptionBreakpoint::DebuggerContinuableExceptionBreakpoint(T { _ASSERTE( jitInfo != NULL ); // Add a native patch at the specified native offset, which is where we are going to resume execution. - AddBindAndActivateNativeManagedPatch(jitInfo->m_fd, jitInfo, nativeOffset, LEAF_MOST_FRAME, pAppDomain); + AddBindAndActivateNativeManagedPatch(jitInfo->m_nativeCodeVersion.GetMethodDesc(), jitInfo, nativeOffset, LEAF_MOST_FRAME, pAppDomain); } //--------------------------------------------------------------------------------------- diff --git a/src/debug/ee/debugger.cpp b/src/debug/ee/debugger.cpp index 573653a915..b753d33104 100644 --- a/src/debug/ee/debugger.cpp +++ b/src/debug/ee/debugger.cpp @@ -2629,7 +2629,7 @@ DebuggerMethodInfo *Debugger::CreateMethodInfo(Module *module, mdMethodDef md) // <TODO>@Todo If we're passed 0 for the newAddress param, the jit has been // cancelled & should be undone.</TODO> ******************************************************************************/ -void Debugger::JITComplete(MethodDesc* fd, TADDR newAddress) +void Debugger::JITComplete(NativeCodeVersion nativeCodeVersion, TADDR newAddress) { CONTRACTL @@ -2642,6 +2642,8 @@ void Debugger::JITComplete(MethodDesc* fd, TADDR newAddress) } CONTRACTL_END; + MethodDesc* fd = nativeCodeVersion.GetMethodDesc(); + LOG((LF_CORDB, LL_INFO100000, "D::JITComplete: md:0x%x (%s::%s), address:0x%x.\n", fd, fd->m_pszDebugClassName, fd->m_pszDebugMethodName, newAddress)); @@ -2667,7 +2669,7 @@ void Debugger::JITComplete(MethodDesc* fd, TADDR newAddress) goto Exit; } BOOL jiWasCreated = FALSE; - DebuggerJitInfo * ji = dmi->CreateInitAndAddJitInfo(fd, newAddress, &jiWasCreated); + DebuggerJitInfo * ji = dmi->CreateInitAndAddJitInfo(nativeCodeVersion, newAddress, &jiWasCreated); if (!jiWasCreated) { // we've already been notified about this code, no work remains. @@ -2881,7 +2883,7 @@ DebuggerJitInfo *Debugger::GetJitInfoWorker(MethodDesc *fd, const BYTE *pbAddr, // Note the call to GetLatestJitInfo() will lazily create the first DJI if we don't already have one. for (; dji != NULL; dji = dji->m_prevJitInfo) { - if (PTR_TO_TADDR(dji->m_fd) == PTR_HOST_TO_TADDR(fd)) + if (PTR_TO_TADDR(dji->m_nativeCodeVersion.GetMethodDesc()) == PTR_HOST_TO_TADDR(fd)) { break; } @@ -2898,7 +2900,7 @@ DebuggerJitInfo *Debugger::GetJitInfoWorker(MethodDesc *fd, const BYTE *pbAddr, LOG((LF_CORDB, LL_INFO1000, "D::GJI: for md:0x%x (%s::%s), got dmi:0x%x, dji:0x%x, latest dji:0x%x, latest fd:0x%x, prev dji:0x%x\n", fd, fd->m_pszDebugClassName, fd->m_pszDebugMethodName, dmi, dji, (dmi ? dmi->GetLatestJitInfo_NoCreate() : 0), - ((dmi && dmi->GetLatestJitInfo_NoCreate()) ? dmi->GetLatestJitInfo_NoCreate()->m_fd:0), + ((dmi && dmi->GetLatestJitInfo_NoCreate()) ? dmi->GetLatestJitInfo_NoCreate()->m_nativeCodeVersion.GetMethodDesc():0), (dji?dji->m_prevJitInfo:0))); if ((dji != NULL) && (pbAddr != NULL)) @@ -3208,10 +3210,10 @@ CodeRegionInfo CodeRegionInfo::GetCodeRegionInfo(DebuggerJitInfo *dji, MethodDes CodeRegionInfo codeRegionInfo; // Use method desc from dji if present - if (dji && dji->m_fd) + if (dji && dji->m_nativeCodeVersion.GetMethodDesc()) { - _ASSERTE(!md || md == dji->m_fd); - md = dji->m_fd; + _ASSERTE(!md || md == dji->m_nativeCodeVersion.GetMethodDesc()); + md = dji->m_nativeCodeVersion.GetMethodDesc(); } if (!addr) @@ -3988,7 +3990,7 @@ HRESULT Debugger::ShuffleVariablesGet(DebuggerJitInfo *dji, rgVal1, rgVal2)); - GetVariablesFromOffset(dji->m_fd, + GetVariablesFromOffset(dji->m_nativeCodeVersion.GetMethodDesc(), dji->GetVarNativeInfoCount(), dji->GetVarNativeInfo(), offsetFrom, @@ -4051,7 +4053,7 @@ HRESULT Debugger::ShuffleVariablesSet(DebuggerJitInfo *dji, (*prgVal1), (*prgVal2))); - HRESULT hr = SetVariablesAtOffset(dji->m_fd, + HRESULT hr = SetVariablesAtOffset(dji->m_nativeCodeVersion.GetMethodDesc(), dji->GetVarNativeInfoCount(), dji->GetVarNativeInfo(), offsetTo, @@ -4915,7 +4917,7 @@ HRESULT Debugger::MapAndBindFunctionPatches(DebuggerJitInfo *djiNew, SO_NOT_MAINLINE; THROWS; CALLED_IN_DEBUGGERDATALOCK_HOLDER_SCOPE_MAY_GC_TRIGGERS_CONTRACT; - PRECONDITION(!djiNew || djiNew->m_fd == fd); + PRECONDITION(!djiNew || djiNew->m_nativeCodeVersion.GetMethodDesc() == fd); } CONTRACTL_END; @@ -4964,7 +4966,7 @@ HRESULT Debugger::MapAndBindFunctionPatches(DebuggerJitInfo *djiNew, // If the patch only applies in certain generic instances, don't bind it // elsewhere. - if(dcp->pMethodDescFilter != NULL && dcp->pMethodDescFilter != djiNew->m_fd) + if(dcp->pMethodDescFilter != NULL && dcp->pMethodDescFilter != djiNew->m_nativeCodeVersion.GetMethodDesc()) { LOG((LF_CORDB, LL_INFO10000, "Patch not in this generic instance\n")); continue; @@ -5177,7 +5179,7 @@ HRESULT Debugger::MapPatchToDJI( DebuggerControllerPatch *dcp,DebuggerJitInfo *d // We have an unbound native patch (eg. for PatchTrace), lets try to bind and activate it dcp->SetDJI(djiTo); LOG((LF_CORDB, LL_EVERYTHING, "trying to bind patch... could be problem\n")); - if (DebuggerController::BindPatch(dcp, djiTo->m_fd, NULL)) + if (DebuggerController::BindPatch(dcp, djiTo->m_nativeCodeVersion.GetMethodDesc(), NULL)) { DebuggerController::ActivatePatch(dcp); LOG((LF_CORDB, LL_INFO1000, "Application went fine!\n" )); @@ -6337,7 +6339,7 @@ void Debugger::LockAndSendEnCRemapEvent(DebuggerJitInfo * dji, SIZE_T currentIP, if (CORDBUnrecoverableError(this)) return; - MethodDesc * pFD = dji->m_fd; + MethodDesc * pFD = dji->m_nativeCodeVersion.GetMethodDesc(); // Note that the debugger lock is reentrant, so we may or may not hold it already. Thread *thread = g_pEEInterface->GetThread(); @@ -12856,7 +12858,7 @@ void Debugger::GetVarInfo(MethodDesc * fd, // [IN] method of interest { ji = GetLatestJitInfoFromMethodDesc(fd); } - _ASSERTE(fd == ji->m_fd); + _ASSERTE(fd == ji->m_nativeCodeVersion.GetMethodDesc()); PREFIX_ASSUME(ji != NULL); diff --git a/src/debug/ee/debugger.h b/src/debug/ee/debugger.h index f2271d20d5..1f824c7f58 100644 --- a/src/debug/ee/debugger.h +++ b/src/debug/ee/debugger.h @@ -1013,7 +1013,7 @@ public: // Creating the Jit-infos. DebuggerJitInfo *FindOrCreateInitAndAddJitInfo(MethodDesc* fd, PCODE startAddr); - DebuggerJitInfo *CreateInitAndAddJitInfo(MethodDesc* fd, TADDR startAddr, BOOL* jitInfoWasCreated); + DebuggerJitInfo *CreateInitAndAddJitInfo(NativeCodeVersion nativeCodeVersion, TADDR startAddr, BOOL* jitInfoWasCreated); void DeleteJitInfo(DebuggerJitInfo *dji); @@ -1418,7 +1418,7 @@ private: class DebuggerJitInfo { public: - PTR_MethodDesc m_fd; + NativeCodeVersion m_nativeCodeVersion; // Loader module is used to control life-time of DebufferJitInfo. Ideally, we would refactor the code to use LoaderAllocator here // instead because of it is what the VM actually uses to track the life time. It would make the debugger interface less chatty. @@ -1524,7 +1524,7 @@ public: #ifndef DACCESS_COMPILE - DebuggerJitInfo(DebuggerMethodInfo *minfo, MethodDesc *fd); + DebuggerJitInfo(DebuggerMethodInfo *minfo, NativeCodeVersion nativeCodeVersion); ~DebuggerJitInfo(); #endif // #ifdef DACCESS_COMPILE @@ -1974,7 +1974,7 @@ public: void FuncEvalComplete(Thread *pThread, DebuggerEval *pDE); DebuggerMethodInfo *CreateMethodInfo(Module *module, mdMethodDef md); - void JITComplete(MethodDesc* fd, TADDR newAddress); + void JITComplete(NativeCodeVersion nativeCodeVersion, TADDR newAddress); HRESULT RequestFavor(FAVORCALLBACK fp, void * pData); diff --git a/src/debug/ee/frameinfo.cpp b/src/debug/ee/frameinfo.cpp index f8f8932cd8..4c0ef2ba74 100644 --- a/src/debug/ee/frameinfo.cpp +++ b/src/debug/ee/frameinfo.cpp @@ -608,7 +608,7 @@ DebuggerJitInfo * FrameInfo::GetJitInfoFromFrame() _ASSERTE(this->md != NULL); ji = g_pDebugger->GetJitInfo(this->md, (const BYTE*)GetControlPC(&(this->registers))); _ASSERTE(ji != NULL); - _ASSERTE(ji->m_fd == this->md); + _ASSERTE(ji->m_nativeCodeVersion.GetMethodDesc() == this->md); } EX_CATCH { diff --git a/src/debug/ee/functioninfo.cpp b/src/debug/ee/functioninfo.cpp index 8cd13b7372..5898d208de 100644 --- a/src/debug/ee/functioninfo.cpp +++ b/src/debug/ee/functioninfo.cpp @@ -248,9 +248,9 @@ int DebuggerJitInfo::GetFuncletIndex(CORDB_ADDRESS offsetOrAddr, GetFuncletIndex #define ADJUST_MAP_ENTRY(_map, _wantFirst) #endif // _WIN64 -DebuggerJitInfo::DebuggerJitInfo(DebuggerMethodInfo *minfo, MethodDesc *fd) : - m_fd(fd), - m_pLoaderModule(fd->GetLoaderModule()), +DebuggerJitInfo::DebuggerJitInfo(DebuggerMethodInfo *minfo, NativeCodeVersion nativeCodeVersion) : + m_nativeCodeVersion(nativeCodeVersion), + m_pLoaderModule(nativeCodeVersion.GetMethodDesc()->GetLoaderModule()), m_jitComplete(false), #ifdef EnC_SUPPORTED m_encBreakpointsApplied(false), @@ -287,7 +287,7 @@ DebuggerJitInfo::DebuggerJitInfo(DebuggerMethodInfo *minfo, MethodDesc *fd) : // Debugger doesn't track LightWeight codegen methods. // We should never even be creating a DJI for one. - _ASSERTE(!m_fd->IsDynamicMethod()); + _ASSERTE(!m_nativeCodeVersion.GetMethodDesc()->IsDynamicMethod()); } DebuggerILToNativeMap *DebuggerJitInfo::MapILOffsetToMapEntry(SIZE_T offset, BOOL *exact, BOOL fWantFirst) @@ -880,7 +880,6 @@ DebuggerJitInfo::~DebuggerJitInfo() // Trash pointers to garbage. // Don't null out since there may be runtime checks against NULL. // Set to a non-null random pointer value that will cause an immediate AV on deref. - m_fd = (MethodDesc*) 0x1; m_methodInfo = (DebuggerMethodInfo*) 0x1; m_prevJitInfo = (DebuggerJitInfo*) 0x01; m_nextJitInfo = (DebuggerJitInfo*) 0x01; @@ -917,7 +916,7 @@ void DebuggerJitInfo::LazyInitBounds() // Should have already been jitted _ASSERTE(this->m_jitComplete); - MethodDesc * mdesc = this->m_fd; + MethodDesc * mdesc = this->m_nativeCodeVersion.GetMethodDesc(); DebugInfoRequest request; _ASSERTE(this->m_addrOfCode != NULL); // must have address to disambguate the Enc cases. @@ -939,8 +938,6 @@ void DebuggerJitInfo::LazyInitBounds() LOG((LF_CORDB,LL_EVERYTHING, "DJI::LazyInitBounds: this=0x%x GetBoundariesAndVars success=0x%x\n", this, fSuccess)); - // SetBoundaries uses the CodeVersionManager, need to take it now for lock ordering reasons - CodeVersionManager::TableLockHolder lockHolder(m_fd->GetCodeVersionManager()); Debugger::DebuggerDataLockHolder debuggerDataLockHolder(g_pDebugger); if (!m_fAttemptInit) @@ -1006,7 +1003,7 @@ CHECK DebuggerJitInfo::Invariant() const LIMITED_METHOD_CONTRACT; CHECK((m_sequenceMapCount == 0) == (m_sequenceMap == NULL)); CHECK(m_methodInfo != NULL); - CHECK(m_fd != NULL); + CHECK(m_nativeCodeVersion.GetMethodDesc() != NULL); CHECK_OK; } @@ -1067,13 +1064,9 @@ void DebuggerJitInfo::SetBoundaries(ULONG32 cMap, ICorDebugInfo::OffsetMapping * // Pick a unique initial value (-10) so that the 1st doesn't accidentally match. int ilPrevOld = -10; - _ASSERTE(m_fd->GetCodeVersionManager()->LockOwnedByCurrentThread()); - CodeVersionManager *pCodeVersionManager = m_fd->GetCodeVersionManager(); InstrumentedILOffsetMapping mapping; - NativeCodeVersion nativeVersion = pCodeVersionManager->GetNativeCodeVersion(m_fd, (PCODE)CORDB_ADDRESS_TO_PTR(m_addrOfCode)); - _ASSERTE(!nativeVersion.IsNull()); - ILCodeVersion ilVersion = nativeVersion.GetILCodeVersion(); + ILCodeVersion ilVersion = m_nativeCodeVersion.GetILCodeVersion(); if (!ilVersion.IsDefaultVersion()) { // Did the current rejit provide a map? @@ -1088,6 +1081,7 @@ void DebuggerJitInfo::SetBoundaries(ULONG32 cMap, ICorDebugInfo::OffsetMapping * // If a ReJIT hasn't happened, check for a profiler provided map. mapping = m_methodInfo->GetRuntimeModule()->GetInstrumentedILOffsetMapping(m_methodInfo->m_token); } + // // <TODO>@todo perf: we could do the vast majority of this @@ -1539,7 +1533,7 @@ DebuggerJitInfo * DebuggerMethodInfo::FindJitInfo(MethodDesc * pMD, DebuggerJitInfo * pCheck = m_latestJitInfo; while (pCheck != NULL) { - if ( (pCheck->m_fd == dac_cast<PTR_MethodDesc>(pMD)) && + if ( (pCheck->m_nativeCodeVersion.GetMethodDesc() == dac_cast<PTR_MethodDesc>(pMD)) && (pCheck->m_addrOfCode == addrNativeStartAddr) ) { return pCheck; @@ -1616,15 +1610,21 @@ DebuggerJitInfo *DebuggerMethodInfo::FindOrCreateInitAndAddJitInfo(MethodDesc* f // The DJI may already be populated in the cache, if so CreateInitAndAddJitInfo is a no-op and that is fine. // CreateInitAndAddJitInfo takes a lock and checks the list again, which makes this thread-safe. + + CodeVersionManager::TableLockHolder lockHolder(fd->GetCodeVersionManager()); + CodeVersionManager *pCodeVersionManager = fd->GetCodeVersionManager(); + NativeCodeVersion nativeCodeVersion = pCodeVersionManager->GetNativeCodeVersion(fd, startAddr); + _ASSERTE(!nativeCodeVersion.IsNull()); + BOOL jitInfoWasCreated; - return CreateInitAndAddJitInfo(fd, startAddr, &jitInfoWasCreated); + return CreateInitAndAddJitInfo(nativeCodeVersion, startAddr, &jitInfoWasCreated); } // Create a DJI around a method-desc. The EE already has all the information we need for a DJI, // the DJI just serves as a cache of the information for the debugger. // Caller makes no guarantees about whether the DJI is already in the table. (Caller should avoid this if // it knows it's in the table, but b/c we can't expect caller to synchronize w/ the other threads). -DebuggerJitInfo *DebuggerMethodInfo::CreateInitAndAddJitInfo(MethodDesc* fd, TADDR startAddr, BOOL* jitInfoWasCreated) +DebuggerJitInfo *DebuggerMethodInfo::CreateInitAndAddJitInfo(NativeCodeVersion nativeCodeVersion, TADDR startAddr, BOOL* jitInfoWasCreated) { CONTRACTL { @@ -1635,6 +1635,8 @@ DebuggerJitInfo *DebuggerMethodInfo::CreateInitAndAddJitInfo(MethodDesc* fd, TAD } CONTRACTL_END; + MethodDesc* fd = nativeCodeVersion.GetMethodDesc(); + _ASSERTE(fd != NULL); // May or may-not be jitted, that's why we passed in the start addr & size explicitly. @@ -1649,7 +1651,7 @@ DebuggerJitInfo *DebuggerMethodInfo::CreateInitAndAddJitInfo(MethodDesc* fd, TAD } - DebuggerJitInfo *dji = new (interopsafe) DebuggerJitInfo(this, fd); + DebuggerJitInfo *dji = new (interopsafe) DebuggerJitInfo(this, nativeCodeVersion); _ASSERTE(dji != NULL); // throws on oom error _ASSERTE(dji->m_methodInfo == this); // this should be set @@ -1672,7 +1674,7 @@ DebuggerJitInfo *DebuggerMethodInfo::CreateInitAndAddJitInfo(MethodDesc* fd, TAD // We need to ensure that another thread didn't go in and add this exact same DJI? { - DebuggerJitInfo * pResult = FindJitInfo(dji->m_fd, (TADDR)dji->m_addrOfCode); + DebuggerJitInfo * pResult = FindJitInfo(dji->m_nativeCodeVersion.GetMethodDesc(), (TADDR)dji->m_addrOfCode); if (pResult != NULL) { // Found! @@ -1700,7 +1702,7 @@ DebuggerJitInfo *DebuggerMethodInfo::CreateInitAndAddJitInfo(MethodDesc* fd, TAD LOG((LF_CORDB,LL_INFO10000,"DMI:CAAJI: DJI version 0x%04x for %s\n", GetCurrentEnCVersion(), - dji->m_fd->m_pszDebugMethodName)); + dji->m_nativeCodeVersion.GetMethodDesc()->m_pszDebugMethodName)); } else { @@ -1857,7 +1859,7 @@ void DebuggerMethodInfo::DJIIterator::Next(BOOL fFirst /*=FALSE*/) continue; //Obey the methodDesc filter if it is provided - if ((m_pMethodDescFilter != NULL) && (m_pMethodDescFilter != m_pCurrent->m_fd)) + if ((m_pMethodDescFilter != NULL) && (m_pMethodDescFilter != m_pCurrent->m_nativeCodeVersion.GetMethodDesc())) continue; // Skip modules that are unloaded, but still hanging around. Note that we can't use DebuggerModule for this check @@ -2101,7 +2103,7 @@ void DebuggerMethodInfo::CreateDJIsForMethodDesc(MethodDesc * pMethodDesc) // The DJI may already be populated in the cache, if so CreateInitAndAdd is // a no-op and that is fine. BOOL unusedDjiWasCreated; - CreateInitAndAddJitInfo(pMethodDesc, codeAddr, &unusedDjiWasCreated); + CreateInitAndAddJitInfo(*itr, codeAddr, &unusedDjiWasCreated); } } } @@ -2384,7 +2386,7 @@ PTR_DebuggerJitInfo DebuggerMethodInfo::GetLatestJitInfo(MethodDesc *mdesc) CONTRACTL_END; - if (m_latestJitInfo && m_latestJitInfo->m_fd == mdesc && !m_latestJitInfo->m_fd->HasClassOrMethodInstantiation()) + if (m_latestJitInfo && m_latestJitInfo->m_nativeCodeVersion.GetMethodDesc() == mdesc && !m_latestJitInfo->m_nativeCodeVersion.GetMethodDesc()->HasClassOrMethodInstantiation()) return m_latestJitInfo; // This ensures that there is an entry in the DJI list for this particular MethodDesc. @@ -2550,9 +2552,9 @@ DebuggerJitInfo::EnumMemoryRegions(CLRDataEnumMemoryFlags flags) if (flags != CLRDATA_ENUM_MEM_MINI && flags != CLRDATA_ENUM_MEM_TRIAGE) { - if (m_fd.IsValid()) + if (m_nativeCodeVersion.GetMethodDesc().IsValid()) { - m_fd->EnumMemoryRegions(flags); + m_nativeCodeVersion.GetMethodDesc()->EnumMemoryRegions(flags); } DacEnumMemoryRegion(PTR_TO_TADDR(GetSequenceMap()), |