Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 45 additions & 10 deletions docs/design/datacontracts/CodeVersions.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,15 @@ internal struct NativeCodeVersionHandle
}
```

```csharp
public enum CodeVersionSource : uint
{
Unknown,
ReJIT,
EnC,
}
```

Comment thread
rcj1 marked this conversation as resolved.
```csharp
// Return a handle to the active version of the IL code for a given method descriptor
public virtual ILCodeVersionHandle GetActiveILCodeVersion(TargetPointer methodDesc);
Expand Down Expand Up @@ -58,6 +67,12 @@ public virtual bool TryGetInstrumentedILMap(ILCodeVersionHandle ilCodeVersionHan

// Gets the optimization tier for a native code version
public virtual OptimizationTier GetOptimizationTier(NativeCodeVersionHandle codeVersionHandle);

// Gets what produced an IL code version (ReJIT, EnC, or Unknown for the default version)
public virtual CodeVersionSource GetSource(ILCodeVersionHandle ilCodeVersionHandle);

// Gets the EnC version number of an IL code version
public virtual TargetNUInt GetEnCVersion(ILCodeVersionHandle ilCodeVersionHandle);
```

### Extension Methods
Expand All @@ -81,10 +96,12 @@ See [code versioning](../features/code-versioning.md) for a general overview and
| `ILCodeVersioningState` | `ActiveVersionModule` | `pointer` | if the active version is synthetic or unknown, the pointer to the Module that defines the method |
| `ILCodeVersioningState` | `ActiveVersionNode` | `pointer` | if the active version is explicit, the NativeCodeVersionNode for the active version |
| `ILCodeVersioningState` | `FirstVersionNode` | `pointer` | pointer to the first ILCodeVersionNode |
| `ILCodeVersionNode` | `EnCVersion` | `nuint` | for an EnC version, the EnC (edit) version number this node corresponds to |
| `ILCodeVersionNode` | `ILAddress` | `pointer` | Address of IL corresponding to ILCodeVersionNode |
| `ILCodeVersionNode` | `InstrumentedILMap` | `InstrumentedILOffsetMapping` | Embedded InstrumentedILOffsetMapping describing the instrumented IL offset mapping |
| `ILCodeVersionNode` | `Next` | `pointer` | Pointer to the next ILCodeVersionNode |
| `ILCodeVersionNode` | `VersionId` | `nuint` | ReJIT ID of the IL code version node |
| `ILCodeVersionNode` | `Source` | `uint32` | a CodeVersionSource value indicating what produced this version (ReJIT, EnC, or unknown) |
| `ILCodeVersionNode` | `VersionId` | `nuint` | Unique IL code version ID of the IL code version node (used as a ReJIT ID when Source is ReJIT) |
| `InstrumentedILOffsetMapping` | `Count` | `uint32` | Number of instrumented IL offset map entries |
| `InstrumentedILOffsetMapping` | `Map` | `pointer` | Pointer to the array of instrumented IL offset map entries |
| `MethodDescVersioningState` | `Flags` | `uint8` | MethodDescVersioningStateFlags flags, see below |
Expand All @@ -111,7 +128,6 @@ _None._
| `RuntimeTypeSystem` |
<!-- END GENERATED: usage contract=CodeVersions version=c1 -->


The flag indicates that the default version of the code for a method desc is active:
```csharp
internal enum MethodDescVersioningStateFlags : byte
Expand All @@ -138,6 +154,11 @@ private enum ILCodeVersionKind
}
```

### Contract Constants:

| Constant Name | Value | Description |
| --- | --- | --- |
| `CorDB_DEFAULT_ENC_FUNCTION_VERSION` | 1 | The EnC version number of the original (unedited) IL. The synthetic default IL code version, and any version not produced by EnC, is treated as having this version. |

Implementation of CodeVersionHandles

Expand Down Expand Up @@ -358,14 +379,6 @@ bool ICodeVersions.CodeVersionManagerSupportsMethod(TargetPointer methodDescAddr
return false;
if (rts.IsCollectibleMethod(md))
return false;
TargetPointer mtAddr = rts.GetMethodTable(md);
TypeHandle mt = rts.GetTypeHandle(mtAddr);
TargetPointer modAddr = rts.GetModule(mt);
ILoader loader = _target.Contracts.Loader;
ModuleHandle mod = loader.GetModuleHandleFromModulePtr(modAddr);
ModuleFlags modFlags = loader.GetFlags(mod);
if (modFlags.HasFlag(ModuleFlags.EditAndContinue))
return false;
return true;
}
```
Expand Down Expand Up @@ -412,6 +425,28 @@ bool ICodeVersions.HasDefaultIL(ILCodeVersionHandle ilCodeVersionHandle)
}
```

### Getting what produced an IL code version

```csharp
CodeVersionSource ICodeVersions.GetSource(ILCodeVersionHandle ilCodeVersionHandle)
{
if (!ilCodeVersionHandle.IsExplicit)
return CodeVersionSource.Unknown;
return // node Source
}
```

### Getting the EnC version of an IL code version

```csharp
TargetNUInt ICodeVersions.GetEnCVersion(ILCodeVersionHandle ilCodeVersionHandle)
{
if (!ilCodeVersionHandle.IsExplicit)
return new TargetNUInt(CorDB_DEFAULT_ENC_FUNCTION_VERSION);
return AsNode(ilCodeVersionHandle).EnCVersion;
}
```

### Getting the instrumented IL offset mapping
```csharp
bool ICodeVersions.TryGetInstrumentedILMap(ILCodeVersionHandle ilCodeVersionHandle, out uint mapEntryCount, out TargetPointer mapEntries)
Expand Down
2 changes: 1 addition & 1 deletion docs/design/datacontracts/ReJIT.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ IEnumerable<TargetNUInt> GetRejitIds(TargetPointer methodDesc)
| --- | --- | --- | --- |
| `ILCodeVersionNode` | `Deoptimized` | `uint32` | whether this IL code version has been deoptimized |
| `ILCodeVersionNode` | `RejitState` | `uint32` | a RejitFlags value |
| `ILCodeVersionNode` | `VersionId` | `nuint` | ReJIT ID of the IL code version node |
| `ILCodeVersionNode` | `VersionId` | `nuint` | Unique IL code version ID of the IL code version node (used as a ReJIT ID when Source is ReJIT) |
| `ProfControlBlock` | `GlobalEventMask` | `uint64` | an ICorProfiler COR_PRF_MONITOR value |
| `ProfControlBlock` | `RejitOnAttachEnabled` | `uint8` | cached value of the ProfAPI_RejitOnAttach configuration knob |

Expand Down
4 changes: 3 additions & 1 deletion docs/design/datacontracts/data-descriptor-meanings.json
Original file line number Diff line number Diff line change
Expand Up @@ -253,11 +253,13 @@
"ILCodeVersioningState.ActiveVersionNode": "if the active version is explicit, the NativeCodeVersionNode for the active version",
"ILCodeVersioningState.FirstVersionNode": "pointer to the first ILCodeVersionNode",
"ILCodeVersionNode.Deoptimized": "whether this IL code version has been deoptimized",
"ILCodeVersionNode.EnCVersion": "for an EnC version, the EnC (edit) version number this node corresponds to",
"ILCodeVersionNode.ILAddress": "Address of IL corresponding to ILCodeVersionNode",
"ILCodeVersionNode.InstrumentedILMap": "Embedded InstrumentedILOffsetMapping describing the instrumented IL offset mapping",
"ILCodeVersionNode.Next": "Pointer to the next ILCodeVersionNode",
"ILCodeVersionNode.RejitState": "a RejitFlags value",
"ILCodeVersionNode.VersionId": "ReJIT ID of the IL code version node",
"ILCodeVersionNode.Source": "a CodeVersionSource value indicating what produced this version (ReJIT, EnC, or unknown)",
"ILCodeVersionNode.VersionId": "Unique IL code version ID of the IL code version node (used as a ReJIT ID when Source is ReJIT)",
"ImageDataDirectory.Size": "Size of the data",
"ImageDataDirectory.VirtualAddress": "Virtual address of the image data directory",
"ImageDosHeader.Lfanew": "File offset of the PE signature and NT headers",
Expand Down
6 changes: 5 additions & 1 deletion src/coreclr/clrdefinitions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,13 @@ if(CLR_CMAKE_HOST_WIN32)
endif(CLR_CMAKE_HOST_WIN32)

if (NOT ((CLR_CMAKE_TARGET_ARCH_I386 AND CLR_CMAKE_TARGET_UNIX) OR CLR_CMAKE_TARGET_ARCH_WASM))
set(FEATURE_METADATA_UPDATER 1)
add_compile_definitions(FEATURE_METADATA_UPDATER)
endif()

if (FEATURE_TIERED_COMPILATION OR FEATURE_REJIT OR FEATURE_METADATA_UPDATER)
add_compile_definitions(FEATURE_CODE_VERSIONING)
endif()
if(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64 OR (CLR_CMAKE_TARGET_ARCH_I386 AND CLR_CMAKE_TARGET_WIN32))
add_compile_definitions(FEATURE_REMAP_FUNCTION)
endif(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64 OR (CLR_CMAKE_TARGET_ARCH_I386 AND CLR_CMAKE_TARGET_WIN32))
Expand Down Expand Up @@ -189,7 +194,6 @@ endif(NOT CLR_CMAKE_HOST_ANDROID AND NOT CLR_CMAKE_TARGET_ARCH_WASM AND NOT CLR_
add_definitions(-DFEATURE_SYMDIFF)

if (FEATURE_TIERED_COMPILATION)
add_compile_definitions(FEATURE_CODE_VERSIONING)
add_compile_definitions(FEATURE_TIERED_COMPILATION)
endif(FEATURE_TIERED_COMPILATION)

Expand Down
115 changes: 78 additions & 37 deletions src/coreclr/debug/daccess/dacdbiimpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -968,10 +968,7 @@ mdSignature DacDbiInterfaceImpl::GetILCodeAndSigHelper(Module * pModule,
// If a MethodDesc is provided, it has to be consistent with the MethodDef token and the RVA.
_ASSERTE((pMD == NULL) || ((pMD->GetMemberDef() == mdMethodToken) && (pMD->GetRVA() == methodRVA)));

TADDR pTargetIL; // target address of start of IL blob

// This works for methods in dynamic modules, and methods overridden by a profiler.
pTargetIL = pModule->GetDynamicIL(mdMethodToken);
TADDR pTargetIL = pModule->GetDynamicIL(mdMethodToken);

// Method not overridden - get the original copy of the IL by going to the PE file/RVA
// If this is in a dynamic module then don't even attempt this since ReflectionModule::GetIL isn't
Expand Down Expand Up @@ -5351,46 +5348,37 @@ void DacDbiInterfaceImpl::LookupEnCVersions(Module* pModule,

_ASSERTE(pLatestEnCVersion != NULL);

// @dbgtodo inspection - once we do EnC, stop using DMIs.
// If the method wasn't EnCed, DMIs may not exist. And since this is DAC, we can't create them.
#ifdef FEATURE_CODE_VERSIONING
CodeVersionManager * pCodeVersionManager = pModule->GetCodeVersionManager();

// Latest EnC version: the active IL code version for this method.
ILCodeVersion activeILVersion = pCodeVersionManager->GetActiveILCodeVersion(dac_cast<PTR_Module>(pModule), mdMethod);
*pLatestEnCVersion = activeILVersion.IsNull()
? (SIZE_T)CorDB_DEFAULT_ENC_FUNCTION_VERSION
Comment thread
rcj1 marked this conversation as resolved.
: activeILVersion.GetEnCVersion();

// We may not have the memory for the DebuggerMethodInfos in a minidump.
// When dump debugging EnC information isn't very useful so just fallback
// to default version.
DebuggerMethodInfo * pDMI = NULL;
DebuggerJitInfo * pDJI = NULL;
EX_TRY_ALLOW_DATATARGET_MISSING_MEMORY
// Jitted-instance EnC version: the version the native code at pNativeStartAddress was built from.
if (pJittedInstanceEnCVersion != NULL)
{
if (g_pDebugger != NULL)
*pJittedInstanceEnCVersion = CorDB_DEFAULT_ENC_FUNCTION_VERSION;
if (pNativeStartAddress != (CORDB_ADDRESS)NULL)
{
pDMI = g_pDebugger->GetOrCreateMethodInfo(pModule, mdMethod);
if (pDMI != NULL)
NativeCodeVersion nativeCodeVersion = pCodeVersionManager->GetNativeCodeVersion(
dac_cast<PTR_MethodDesc>(pMD),
PINSTRToPCODE(CORDB_ADDRESS_TO_TADDR(pNativeStartAddress)));
if (!nativeCodeVersion.IsNull())
{
pDJI = pDMI->FindJitInfo(pMD, CORDB_ADDRESS_TO_TADDR(pNativeStartAddress));
*pJittedInstanceEnCVersion = nativeCodeVersion.GetILCodeVersion().GetEnCVersion();
}
}
}
EX_END_CATCH_ALLOW_DATATARGET_MISSING_MEMORY;
if (pDJI != NULL)
#else // !FEATURE_CODE_VERSIONING
*pLatestEnCVersion = CorDB_DEFAULT_ENC_FUNCTION_VERSION;
if (pJittedInstanceEnCVersion != NULL)
{
if (pJittedInstanceEnCVersion != NULL)
{
*pJittedInstanceEnCVersion = pDJI->m_encVersion;
}
*pLatestEnCVersion = pDMI->GetCurrentEnCVersion();
}
else
{
// If we have no DMI/DJI, then we must never have EnCed. So we can use default EnC info
// Several cases where we don't have a DMI/DJI:
// - LCG methods
// - method was never "touched" by debugger. (DJIs are created lazily).
if (pJittedInstanceEnCVersion != NULL)
{
*pJittedInstanceEnCVersion = CorDB_DEFAULT_ENC_FUNCTION_VERSION;
}
*pLatestEnCVersion = CorDB_DEFAULT_ENC_FUNCTION_VERSION;
*pJittedInstanceEnCVersion = CorDB_DEFAULT_ENC_FUNCTION_VERSION;
}
#endif // FEATURE_CODE_VERSIONING
}

// Get the address of the Debugger control block on the helper thread
Expand Down Expand Up @@ -6999,7 +6987,7 @@ HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::GetActiveRejitILCodeVersionNode(V
// manager's active IL version hasn't yet asked the profiler for the IL body to use, in which case we want to filter it
// out from the return in this method.
ILCodeVersion activeILVersion = pCodeVersionManager->GetActiveILCodeVersion(pModule, methodTk);
if (activeILVersion.IsNull() || activeILVersion.IsDefaultVersion() || activeILVersion.GetRejitState() != RejitFlags::kStateActive)
if (activeILVersion.IsNull() || activeILVersion.IsDefaultVersion() || activeILVersion.GetRejitState() != RejitFlags::kStateActive || activeILVersion.GetSource() != CodeVersionSource::kReJIT)
{
pVmILCodeVersionNode->SetDacTargetPtr(0);
}
Expand Down Expand Up @@ -7038,7 +7026,7 @@ HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::GetILCodeVersionNode(VMPTR_Native
#ifdef FEATURE_REJIT
NativeCodeVersionNode* pNativeCodeVersionNode = vmNativeCodeVersionNode.GetDacPtr();
ILCodeVersion ilCodeVersion = pNativeCodeVersionNode->GetILCodeVersion();
if (ilCodeVersion.IsDefaultVersion())
if (ilCodeVersion.IsDefaultVersion() || ilCodeVersion.GetSource() != CodeVersionSource::kReJIT)
{
pVmILCodeVersionNode->SetDacTargetPtr(0);
}
Expand All @@ -7054,6 +7042,59 @@ HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::GetILCodeVersionNode(VMPTR_Native
return S_OK;
}

HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::GetEnCILCodeAndSig(VMPTR_Module vmModule, mdMethodDef methodTk, SIZE_T enCVersion, TargetBuffer * pCodeInfo, mdSignature * pLocalSigToken)
{
DD_ENTER_MAY_THROW;
if (pCodeInfo == NULL || pLocalSigToken == NULL)
return E_INVALIDARG;

pCodeInfo->Clear();
*pLocalSigToken = mdSignatureNil;

PTR_Module pModule = vmModule.GetDacPtr();
CodeVersionManager * pCodeVersionManager = pModule->GetCodeVersionManager();

TADDR pTargetIL = 0; // target address of start of IL blob for the requested EnC version
{
CodeVersionManager::LockHolder codeVersioningLockHolder;

// Find the explicit EnC IL code version stamped with the requested EnC version. The default
// version has no explicit node (it represents the original, unedited IL), so it is skipped.
ILCodeVersionCollection ilCodeVersions = pCodeVersionManager->GetILCodeVersions(pModule, methodTk);
for (ILCodeVersionIterator cur = ilCodeVersions.Begin(), end = ilCodeVersions.End(); cur != end; cur++)
{
ILCodeVersion ilCodeVersion = *cur;
if (!ilCodeVersion.IsDefaultVersion() &&
ilCodeVersion.GetSource() == CodeVersionSource::kEnC &&
ilCodeVersion.GetEnCVersion() == enCVersion)
{
pTargetIL = dac_cast<TADDR>(ilCodeVersion.GetIL());
break;
}
}
}

if (pTargetIL != 0)
{
// Bring the IL blob over to the host and extract the code buffer and local var sig token.
// We need the target address of the IL itself (beyond the header), so we add the offset from
// the beginning of the host IL blob (the header) to the beginning of the IL to the target
// address of the blob.
COR_ILMETHOD * pHostIL = DacGetIlMethod(pTargetIL);
COR_ILMETHOD_DECODER header(pHostIL);

pCodeInfo->pAddress = pTargetIL + ((SIZE_T)(header.Code) - (SIZE_T)pHostIL);
pCodeInfo->cbSize = header.GetCodeSize();

if (header.LocalVarSigTok != mdTokenNil)
{
*pLocalSigToken = header.GetLocalVarSigTok();
}
}

return S_OK;
}

HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::GetILCodeVersionNodeData(VMPTR_ILCodeVersionNode vmILCodeVersionNode, DacSharedReJitInfo* pData)
{
DD_ENTER_MAY_THROW;
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/debug/daccess/dacdbiimpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ class DacDbiInterfaceImpl :
HRESULT STDMETHODCALLTYPE GetPEFileMDInternalRW(VMPTR_PEAssembly vmPEAssembly, OUT TADDR* pAddrMDInternalRW);
#ifdef FEATURE_CODE_VERSIONING
HRESULT STDMETHODCALLTYPE GetActiveRejitILCodeVersionNode(VMPTR_Module vmModule, mdMethodDef methodTk, OUT VMPTR_ILCodeVersionNode* pVmILCodeVersionNode);
HRESULT STDMETHODCALLTYPE GetEnCILCodeAndSig(VMPTR_Module vmModule, mdMethodDef methodTk, SIZE_T enCVersion, OUT TargetBuffer * pCodeInfo, OUT mdSignature * pLocalSigToken);
HRESULT STDMETHODCALLTYPE GetNativeCodeVersionNode(VMPTR_MethodDesc vmMethod, CORDB_ADDRESS codeStartAddress, OUT VMPTR_NativeCodeVersionNode* pVmNativeCodeVersionNode);
HRESULT STDMETHODCALLTYPE GetILCodeVersionNode(VMPTR_NativeCodeVersionNode vmNativeCodeVersionNode, VMPTR_ILCodeVersionNode* pVmILCodeVersionNode);
HRESULT STDMETHODCALLTYPE GetILCodeVersionNodeData(VMPTR_ILCodeVersionNode vmILCodeVersionNode, DacSharedReJitInfo* pData);
Expand Down
18 changes: 13 additions & 5 deletions src/coreclr/debug/daccess/request.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -926,9 +926,17 @@ HRESULT ClrDataAccess::GetThreadData(CLRDATA_ADDRESS threadAddr, struct DacpThre
#ifdef FEATURE_REJIT
void CopyNativeCodeVersionToReJitData(NativeCodeVersion nativeCodeVersion, NativeCodeVersion activeCodeVersion, DacpReJitData * pReJitData)
{
pReJitData->rejitID = nativeCodeVersion.GetILCodeVersion().GetVersionId();
pReJitData->NativeCodeAddr = GetInterpreterCodeFromEntryPointIfPresent(nativeCodeVersion.GetNativeCode());

if (nativeCodeVersion.GetILCodeVersion().GetSource() != CodeVersionSource::kReJIT)
{
pReJitData->flags = DacpReJitData::kActive;
pReJitData->rejitID = 0;
return;
}

pReJitData->rejitID = nativeCodeVersion.GetILCodeVersion().GetVersionId();

if (nativeCodeVersion != activeCodeVersion)
{
pReJitData->flags = DacpReJitData::kReverted;
Expand Down Expand Up @@ -4678,7 +4686,7 @@ HRESULT ClrDataAccess::GetPendingReJITID(CLRDATA_ADDRESS methodDesc, int *pRejit
CodeVersionManager* pCodeVersionManager = pMD->GetCodeVersionManager();
CodeVersionManager::LockHolder codeVersioningLockHolder;
ILCodeVersion ilVersion = pCodeVersionManager->GetActiveILCodeVersion(pMD);
if (ilVersion.IsNull())
if (ilVersion.IsNull() || ilVersion.GetSource() != CodeVersionSource::kReJIT)
{
hr = E_INVALIDARG;
}
Expand Down Expand Up @@ -4707,7 +4715,7 @@ HRESULT ClrDataAccess::GetReJITInformation(CLRDATA_ADDRESS methodDesc, int rejit
CodeVersionManager* pCodeVersionManager = pMD->GetCodeVersionManager();
CodeVersionManager::LockHolder codeVersioningLockHolder;
ILCodeVersion ilVersion = pCodeVersionManager->GetILCodeVersion(pMD, rejitId);
if (ilVersion.IsNull())
if (ilVersion.IsNull() || ilVersion.GetSource() != CodeVersionSource::kReJIT)
{
hr = E_INVALIDARG;
}
Expand Down Expand Up @@ -4766,7 +4774,7 @@ HRESULT ClrDataAccess::GetProfilerModifiedILInformation(CLRDATA_ADDRESS methodDe
CodeVersionManager* pCodeVersionManager = pMD->GetCodeVersionManager();
CodeVersionManager::LockHolder codeVersioningLockHolder;
ILCodeVersion ilVersion = pCodeVersionManager->GetActiveILCodeVersion(pMD);
if (ilVersion.GetRejitState() != RejitFlags::kStateActive || !ilVersion.HasDefaultIL())
if ((ilVersion.GetRejitState() != RejitFlags::kStateActive || !ilVersion.HasDefaultIL()) && ilVersion.GetSource() == CodeVersionSource::kReJIT)
{
pILData->type = DacpProfilerILData::ReJITModified;
pILData->rejitID = static_cast<ULONG>(pCodeVersionManager->GetActiveILCodeVersion(pMD).GetVersionId());
Expand Down Expand Up @@ -4818,7 +4826,7 @@ HRESULT ClrDataAccess::GetMethodsWithProfilerModifiedIL(CLRDATA_ADDRESS mod, CLR

TADDR pDynamicIL = pModule->GetDynamicIL(pMD->GetMemberDef());
ILCodeVersion ilVersion = pCodeVersionManager->GetActiveILCodeVersion(pMD);
if (ilVersion.GetRejitState() != RejitFlags::kStateActive || !ilVersion.HasDefaultIL() || pDynamicIL != (TADDR)NULL)
if ((ilVersion.GetRejitState() != RejitFlags::kStateActive || !ilVersion.HasDefaultIL() || pDynamicIL != (TADDR)NULL) && ilVersion.GetSource() == CodeVersionSource::kReJIT)
{
methodDescs[*pcMethodDescs] = PTR_CDADDR(pMD);
++(*pcMethodDescs);
Expand Down
Loading
Loading