Skip to content
9 changes: 3 additions & 6 deletions src/coreclr/inc/corinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -1151,7 +1151,6 @@ struct CORINFO_CONST_LOOKUP
// IAT_PVALUE --> "addr" stores a pointer to a location which will hold the real handle
// IAT_RELPVALUE --> "addr" stores a relative pointer to a location which will hold the real handle
// IAT_PPVALUE --> "addr" stores a double indirection to a location which will hold the real handle

InfoAccessType accessType;
union
{
Expand Down Expand Up @@ -1598,17 +1597,15 @@ struct CORINFO_DEVIRTUALIZATION_INFO
// - details on the computation done by the jit host
// - If pResolvedTokenDevirtualizedMethod is not set to NULL and targeting an R2R image
// use it as the parameter to getCallInfo
// - isInstantiatingStub is set to TRUE if the devirtualized method is a generic method instantiating stub
// - needsMethodContext is set TRUE if the devirtualized method may require a method context
// (in which case the method handle and context will be a generic method)
// - instParamLookup contains all the information necessary to pass the instantiation parameter for
// the devirtualized method. A constant lookup with IAT_VALUE with a nullptr handle indicates no instantiation parameter is needed.
//
CORINFO_METHOD_HANDLE devirtualizedMethod;
CORINFO_CONTEXT_HANDLE exactContext;
CORINFO_DEVIRTUALIZATION_DETAIL detail;
CORINFO_RESOLVED_TOKEN resolvedTokenDevirtualizedMethod;
CORINFO_RESOLVED_TOKEN resolvedTokenDevirtualizedUnboxedMethod;
bool isInstantiatingStub;
bool needsMethodContext;
CORINFO_LOOKUP instParamLookup;
};

//----------------------------------------------------------------------------
Expand Down
10 changes: 5 additions & 5 deletions src/coreclr/inc/jiteeversionguid.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@

#include <minipal/guid.h>

constexpr GUID JITEEVersionIdentifier = { /* 1516acb8-ac41-4dcb-9840-f39ee25ffa73 */
0x1516acb8,
0xac41,
0x4dcb,
{0x98, 0x40, 0xf3, 0x9e, 0xe2, 0x5f, 0xfa, 0x73}
constexpr GUID JITEEVersionIdentifier = { /* fc5f63e7-921b-4091-b920-8df8d7b872c1 */
0xfc5f63e7,
0x921b,
0x4091,
{0xb9, 0x20, 0x8d, 0xf8, 0xd7, 0xb8, 0x72, 0xc1}
};

#endif // JIT_EE_VERSIONING_GUID_H
16 changes: 7 additions & 9 deletions src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -6861,13 +6861,11 @@ class Compiler
GenTree* fgCreateCallDispatcherAndGetResult(GenTreeCall* origCall,
CORINFO_METHOD_HANDLE callTargetStubHnd,
CORINFO_METHOD_HANDLE dispatcherHnd);
GenTree* getLookupTree(CORINFO_RESOLVED_TOKEN* pResolvedToken,
CORINFO_LOOKUP* pLookup,
GenTreeFlags handleFlags,
void* compileTimeHandle);
GenTree* getRuntimeLookupTree(CORINFO_RESOLVED_TOKEN* pResolvedToken,
CORINFO_LOOKUP* pLookup,
void* compileTimeHandle);
GenTree* getLookupTree(CORINFO_LOOKUP* pLookup,
GenTreeFlags handleFlags,
void* compileTimeHandle);
GenTree* getRuntimeLookupTree(CORINFO_LOOKUP* pLookup,
void* compileTimeHandle);
GenTree* getVirtMethodPointerTree(GenTree* thisPtr,
CORINFO_RESOLVED_TOKEN* pResolvedToken,
CORINFO_CALL_INFO* pCallInfo);
Expand Down Expand Up @@ -7763,8 +7761,8 @@ class Compiler
unsigned methodAttr,
unsigned classAttr,
unsigned likelihood,
bool arrayInterface,
bool instantiatingStub,
bool needsMethodContext,
CORINFO_METHOD_HANDLE instantiatingStub,
CORINFO_METHOD_HANDLE originalMethodHandle,
CORINFO_CONTEXT_HANDLE originalContextHandle);
Comment thread
hez2010 marked this conversation as resolved.

Expand Down
207 changes: 114 additions & 93 deletions src/coreclr/jit/importercalls.cpp

Large diffs are not rendered by default.

19 changes: 5 additions & 14 deletions src/coreclr/jit/morph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5463,18 +5463,14 @@ GenTree* Compiler::fgCreateCallDispatcherAndGetResult(GenTreeCall* orig
// getLookupTree: get a lookup tree
//
// Arguments:
// pResolvedToken - resolved token of the call
// pLookup - the lookup to get the tree for
// handleFlags - flags to set on the result node
// compileTimeHandle - compile-time handle corresponding to the lookup
//
// Return Value:
// A node representing the lookup tree
//
GenTree* Compiler::getLookupTree(CORINFO_RESOLVED_TOKEN* pResolvedToken,
CORINFO_LOOKUP* pLookup,
GenTreeFlags handleFlags,
void* compileTimeHandle)
GenTree* Compiler::getLookupTree(CORINFO_LOOKUP* pLookup, GenTreeFlags handleFlags, void* compileTimeHandle)
{
if (!pLookup->lookupKind.needsRuntimeLookup)
{
Expand All @@ -5497,26 +5493,21 @@ GenTree* Compiler::getLookupTree(CORINFO_RESOLVED_TOKEN* pResolvedToken,
return gtNewIconEmbHndNode(handle, pIndirection, handleFlags, compileTimeHandle);
}

return getRuntimeLookupTree(pResolvedToken, pLookup, compileTimeHandle);
return getRuntimeLookupTree(pLookup, compileTimeHandle);
}

//------------------------------------------------------------------------
// getRuntimeLookupTree: get a tree for a runtime lookup
//
// Arguments:
// pResolvedToken - resolved token of the call
// pLookup - the lookup to get the tree for
// compileTimeHandle - compile-time handle corresponding to the lookup
//
// Return Value:
// A node representing the runtime lookup tree
//
GenTree* Compiler::getRuntimeLookupTree(CORINFO_RESOLVED_TOKEN* pResolvedToken,
CORINFO_LOOKUP* pLookup,
void* compileTimeHandle)
GenTree* Compiler::getRuntimeLookupTree(CORINFO_LOOKUP* pLookup, void* compileTimeHandle)
{
assert(!compIsForInlining());

CORINFO_RUNTIME_LOOKUP* pRuntimeLookup = &pLookup->runtimeLookup;

// If pRuntimeLookup->indirections is equal to CORINFO_USEHELPER, it specifies that a run-time helper should be
Expand Down Expand Up @@ -5637,8 +5628,8 @@ GenTree* Compiler::getTokenHandleTree(CORINFO_RESOLVED_TOKEN* pResolvedToken, bo
//
info.compCompHnd->embedGenericHandle(pResolvedToken, parent, info.compMethodHnd, &embedInfo);

GenTree* result = getLookupTree(pResolvedToken, &embedInfo.lookup, gtTokenToIconFlags(pResolvedToken->token),
embedInfo.compileTimeHandle);
GenTree* result =
getLookupTree(&embedInfo.lookup, gtTokenToIconFlags(pResolvedToken->token), embedInfo.compileTimeHandle);

// If we have a result and it requires runtime lookup, wrap it in a runtime lookup node.
if ((result != nullptr) && embedInfo.lookup.lookupKind.needsRuntimeLookup)
Expand Down
4 changes: 1 addition & 3 deletions src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1351,8 +1351,7 @@ private bool resolveVirtualMethod(CORINFO_DEVIRTUALIZATION_INFO* info)
info->devirtualizedMethod = null;
info->exactContext = null;
info->detail = CORINFO_DEVIRTUALIZATION_DETAIL.CORINFO_DEVIRTUALIZATION_UNKNOWN;
info->isInstantiatingStub = false;
info->needsMethodContext = false;
info->instParamLookup = default(CORINFO_LOOKUP);

TypeDesc objType = HandleToObject(info->objClass);

Expand Down Expand Up @@ -1497,7 +1496,6 @@ private bool resolveVirtualMethod(CORINFO_DEVIRTUALIZATION_INFO* info)
#endif
info->detail = CORINFO_DEVIRTUALIZATION_DETAIL.CORINFO_DEVIRTUALIZATION_SUCCESS;
info->devirtualizedMethod = ObjectToHandle(impl);
info->isInstantiatingStub = false;
info->exactContext = contextFromType(owningType);

return true;
Expand Down
10 changes: 3 additions & 7 deletions src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1189,19 +1189,15 @@ public unsafe struct CORINFO_DEVIRTUALIZATION_INFO
// invariant is `resolveVirtualMethod(...) == (devirtualizedMethod != nullptr)`.
// - exactContext is set to wrapped CORINFO_CLASS_HANDLE of devirt'ed method table.
// - detail describes the computation done by the jit host
// - isInstantiatingStub is set to TRUE if the devirtualized method is a method instantiation stub
// - needsMethodContext is set TRUE if the devirtualized method may require a method context
// (in which case the method handle and context will be a generic method)
// - instParamLookup contains all the information necessary to pass the instantiation parameter for
// the devirtualized method.
//
public CORINFO_METHOD_STRUCT_* devirtualizedMethod;
public CORINFO_CONTEXT_STRUCT* exactContext;
public CORINFO_DEVIRTUALIZATION_DETAIL detail;
public CORINFO_RESOLVED_TOKEN resolvedTokenDevirtualizedMethod;
public CORINFO_RESOLVED_TOKEN resolvedTokenDevirtualizedUnboxedMethod;
public byte _isInstantiatingStub;
public bool isInstantiatingStub { get { return _isInstantiatingStub != 0; } set { _isInstantiatingStub = value ? (byte)1 : (byte)0; } }
public byte _needsMethodContext;
public bool needsMethodContext { get { return _needsMethodContext != 0; } set { _needsMethodContext = value ? (byte)1 : (byte)0; } }
public CORINFO_LOOKUP instParamLookup;
}

//----------------------------------------------------------------------------
Expand Down
3 changes: 1 addition & 2 deletions src/coreclr/tools/superpmi/superpmi-shared/agnostic.h
Original file line number Diff line number Diff line change
Expand Up @@ -688,12 +688,11 @@ struct Agnostic_ResolveVirtualMethodResult
{
bool returnValue;
DWORDLONG devirtualizedMethod;
bool isInstantiatingStub;
bool needsMethodContext;
DWORDLONG exactContext;
DWORD detail;
Agnostic_CORINFO_RESOLVED_TOKEN resolvedTokenDevirtualizedMethod;
Agnostic_CORINFO_RESOLVED_TOKEN resolvedTokenDevirtualizedUnboxedMethod;
Agnostic_CORINFO_LOOKUP instParamLookup;
};

struct Agnostic_GetInstantiatedEntryResult
Expand Down
13 changes: 5 additions & 8 deletions src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3259,10 +3259,9 @@ void MethodContext::recResolveVirtualMethod(CORINFO_DEVIRTUALIZATION_INFO * info
Agnostic_ResolveVirtualMethodResult result;
result.returnValue = returnValue;
result.devirtualizedMethod = CastHandle(info->devirtualizedMethod);
result.isInstantiatingStub = info->isInstantiatingStub;
result.exactContext = CastHandle(info->exactContext);
result.detail = (DWORD)info->detail;
result.needsMethodContext = info->needsMethodContext;
result.instParamLookup = SpmiRecordsHelper::StoreAgnostic_CORINFO_LOOKUP(&info->instParamLookup);

if (returnValue)
{
Expand All @@ -3287,15 +3286,14 @@ void MethodContext::dmpResolveVirtualMethod(const Agnostic_ResolveVirtualMethodK
key.context,
key.pResolvedTokenVirtualMethodNonNull,
key.pResolvedTokenVirtualMethodNonNull ? SpmiDumpHelper::DumpAgnostic_CORINFO_RESOLVED_TOKEN(key.pResolvedTokenVirtualMethod).c_str() : "???");
printf(", value returnValue-%s, devirtMethod-%016" PRIX64 ", instantiatingStub-%s, needsMethodContext-%s, exactContext-%016" PRIX64 ", detail-%d, tokDvMeth{%s}, tokDvUnboxMeth{%s}",
printf(", value returnValue-%s, devirtMethod-%016" PRIX64 ", exactContext-%016" PRIX64 ", detail-%d, tokDvMeth{%s}, tokDvUnboxMeth{%s}, instParamLookup{%s}",
result.returnValue ? "true" : "false",
result.devirtualizedMethod,
result.isInstantiatingStub ? "true" : "false",
result.needsMethodContext ? "true" : "false",
result.exactContext,
result.detail,
result.returnValue ? SpmiDumpHelper::DumpAgnostic_CORINFO_RESOLVED_TOKEN(result.resolvedTokenDevirtualizedMethod).c_str() : "???",
result.returnValue ? SpmiDumpHelper::DumpAgnostic_CORINFO_RESOLVED_TOKEN(result.resolvedTokenDevirtualizedUnboxedMethod).c_str() : "???");
result.returnValue ? SpmiDumpHelper::DumpAgnostic_CORINFO_RESOLVED_TOKEN(result.resolvedTokenDevirtualizedUnboxedMethod).c_str() : "???",
SpmiDumpHelper::DumpAgnostic_CORINFO_LOOKUP(result.instParamLookup).c_str());
}

bool MethodContext::repResolveVirtualMethod(CORINFO_DEVIRTUALIZATION_INFO * info)
Expand All @@ -3315,10 +3313,9 @@ bool MethodContext::repResolveVirtualMethod(CORINFO_DEVIRTUALIZATION_INFO * info
DEBUG_REP(dmpResolveVirtualMethod(key, result));

info->devirtualizedMethod = (CORINFO_METHOD_HANDLE) result.devirtualizedMethod;
info->isInstantiatingStub = result.isInstantiatingStub;
info->needsMethodContext = result.needsMethodContext;
info->exactContext = (CORINFO_CONTEXT_HANDLE) result.exactContext;
info->detail = (CORINFO_DEVIRTUALIZATION_DETAIL) result.detail;
info->instParamLookup = SpmiRecordsHelper::RestoreCORINFO_LOOKUP(result.instParamLookup);
if (result.returnValue)
{
info->resolvedTokenDevirtualizedMethod = SpmiRecordsHelper::Restore_CORINFO_RESOLVED_TOKEN(&result.resolvedTokenDevirtualizedMethod, ResolveToken);
Expand Down
41 changes: 16 additions & 25 deletions src/coreclr/vm/jitinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3017,7 +3017,7 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr
MethodDesc* pContextMD = pCallerMD;
MethodTable* pContextMT = pContextMD->GetMethodTable();

// There is a pathological case where invalid IL refereces __Canon type directly, but there is no dictionary availabled to store the lookup.
// There is a pathological case where invalid IL references __Canon type directly, but there is no dictionary available to store the lookup.
if (!pContextMD->IsSharedByGenericInstantiations())
COMPlusThrow(kInvalidProgramException);

Expand Down Expand Up @@ -8615,8 +8615,10 @@ bool CEEInfo::resolveVirtualMethodHelper(CORINFO_DEVIRTUALIZATION_INFO * info)
info->detail = CORINFO_DEVIRTUALIZATION_UNKNOWN;
memset(&info->resolvedTokenDevirtualizedMethod, 0, sizeof(info->resolvedTokenDevirtualizedMethod));
memset(&info->resolvedTokenDevirtualizedUnboxedMethod, 0, sizeof(info->resolvedTokenDevirtualizedUnboxedMethod));
Comment thread
hez2010 marked this conversation as resolved.
Comment thread
hez2010 marked this conversation as resolved.
info->isInstantiatingStub = false;
info->needsMethodContext = false;
memset(&info->instParamLookup, 0, sizeof(info->instParamLookup));
info->instParamLookup.lookupKind.needsRuntimeLookup = false;
info->instParamLookup.constLookup.accessType = IAT_VALUE;
info->instParamLookup.constLookup.handle = NULL;

MethodDesc* pBaseMD = GetMethod(info->virtualMethod);
MethodTable* pBaseMT = pBaseMD->GetMethodTable();
Expand Down Expand Up @@ -8852,12 +8854,9 @@ bool CEEInfo::resolveVirtualMethodHelper(CORINFO_DEVIRTUALIZATION_INFO * info)
// This is generic virtual method devirtualization.
if (!isArray && pBaseMD->HasMethodInstantiation())
{
pDevirtMD = pDevirtMD->FindOrCreateAssociatedMethodDesc(
pDevirtMD, pExactMT, pExactMT->IsValueType() && !pDevirtMD->IsStatic(), pBaseMD->GetMethodInstantiation(), true);

// We still can't handle shared generic methods because we don't have
// the right generic context for runtime lookup.
// TODO: Remove this limitation.
MethodDesc* pPrimaryMD = pDevirtMD;
pDevirtMD = MethodDesc::FindOrCreateAssociatedMethodDesc(
pPrimaryMD, pExactMT, pExactMT->IsValueType() && !pPrimaryMD->IsStatic(), pBaseMD->GetMethodInstantiation(), true);
if (pDevirtMD->IsSharedByGenericMethodInstantiations())
{
info->detail = CORINFO_DEVIRTUALIZATION_FAILED_CANON;
Expand All @@ -8867,32 +8866,24 @@ bool CEEInfo::resolveVirtualMethodHelper(CORINFO_DEVIRTUALIZATION_INFO * info)
isGenericVirtual = true;
}

// Success! Pass back the results.
//
if (isArray)
if (!info->instParamLookup.lookupKind.needsRuntimeLookup && (isArray || isGenericVirtual) && pDevirtMD->IsInstantiatingStub())
{
// Note if array devirtualization produced an instantiation stub
// so jit can try and inline it.
//
info->isInstantiatingStub = pDevirtMD->IsInstantiatingStub();
info->exactContext = MAKE_METHODCONTEXT((CORINFO_METHOD_HANDLE) pDevirtMD);
info->needsMethodContext = true;
info->instParamLookup.constLookup.handle = (CORINFO_GENERIC_HANDLE)pDevirtMD;
info->instParamLookup.constLookup.accessType = IAT_VALUE;
}
else if (isGenericVirtual)

if (isArray || isGenericVirtual)
{
// We don't support shared generic methods yet so this should always be false
info->needsMethodContext = false;
// We don't produce an instantiating stub
info->isInstantiatingStub = false;
info->exactContext = MAKE_METHODCONTEXT((CORINFO_METHOD_HANDLE) pDevirtMD);
pDevirtMD = pDevirtMD->IsInstantiatingStub() ? pDevirtMD->GetWrappedMethodDesc() : pDevirtMD;
}
else
{
info->exactContext = MAKE_CLASSCONTEXT((CORINFO_CLASS_HANDLE) pExactMT);
info->isInstantiatingStub = false;
info->needsMethodContext = false;
}

// Success! Pass back the results.
//
info->devirtualizedMethod = (CORINFO_METHOD_HANDLE) pDevirtMD;
info->detail = CORINFO_DEVIRTUALIZATION_SUCCESS;

Expand Down
Loading
Loading