Skip to content
Open
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
1 change: 0 additions & 1 deletion src/coreclr/inc/corinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -1557,7 +1557,6 @@ enum CORINFO_DEVIRTUALIZATION_DETAIL
CORINFO_DEVIRTUALIZATION_FAILED_DUPLICATE_INTERFACE, // crossgen2 virtual method algorithm and runtime algorithm differ in the presence of duplicate interface implementations
CORINFO_DEVIRTUALIZATION_FAILED_DECL_NOT_REPRESENTABLE, // Decl method cannot be represented in R2R image
CORINFO_DEVIRTUALIZATION_FAILED_TYPE_EQUIVALENCE, // Support for type equivalence in devirtualization is not yet implemented in crossgen2
CORINFO_DEVIRTUALIZATION_FAILED_GENERIC_VIRTUAL, // Devirtualization of generic virtual methods is not yet implemented in crossgen2
CORINFO_DEVIRTUALIZATION_COUNT, // sentinel for maximum value
};

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 = { /* 976a4d6d-d1b2-4096-a3c9-46ddcae71196 */
0x976a4d6d,
0xd1b2,
0x4096,
{0xa3, 0xc9, 0x46, 0xdd, 0xca, 0xe7, 0x11, 0x96}
constexpr GUID JITEEVersionIdentifier = { /* c10e2acf-7c94-4c61-b895-5178602e0e1e */
0xc10e2acf,
0x7c94,
0x4c61,
{0xb8, 0x95, 0x51, 0x78, 0x60, 0x2e, 0x0e, 0x1e}
};

#endif // JIT_EE_VERSIONING_GUID_H
4 changes: 1 addition & 3 deletions src/coreclr/jit/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10476,7 +10476,7 @@ const char* Compiler::devirtualizationDetailToString(CORINFO_DEVIRTUALIZATION_DE
case CORINFO_DEVIRTUALIZATION_SUCCESS:
return "success";
case CORINFO_DEVIRTUALIZATION_FAILED_CANON:
return "object class was canonical";
return "object class or method was canonical";
case CORINFO_DEVIRTUALIZATION_FAILED_COM:
return "object class was com";
case CORINFO_DEVIRTUALIZATION_FAILED_CAST:
Expand Down Expand Up @@ -10510,8 +10510,6 @@ const char* Compiler::devirtualizationDetailToString(CORINFO_DEVIRTUALIZATION_DE
return "Decl method cannot be represented in R2R image";
case CORINFO_DEVIRTUALIZATION_FAILED_TYPE_EQUIVALENCE:
return "Support for type equivalence in devirtualization is not yet implemented in crossgen2";
case CORINFO_DEVIRTUALIZATION_FAILED_GENERIC_VIRTUAL:
return "Devirtualization of generic virtual methods is not yet implemented in crossgen2";
default:
return "undefined";
}
Expand Down
9 changes: 7 additions & 2 deletions src/coreclr/jit/gentree.h
Original file line number Diff line number Diff line change
Expand Up @@ -5269,8 +5269,13 @@ struct GenTreeCall final : public GenTree
}
bool IsGenericVirtual(Compiler* compiler) const
{
return (gtCallType == CT_INDIRECT && (gtCallAddr->IsHelperCall(compiler, CORINFO_HELP_VIRTUAL_FUNC_PTR) ||
gtCallAddr->IsHelperCall(compiler, CORINFO_HELP_GVMLOOKUP_FOR_SLOT)));
return (gtCallType == CT_INDIRECT &&
(gtCallAddr->IsHelperCall(compiler, CORINFO_HELP_VIRTUAL_FUNC_PTR) ||
gtCallAddr->IsHelperCall(compiler, CORINFO_HELP_GVMLOOKUP_FOR_SLOT)
#ifdef FEATURE_READYTORUN
|| gtCallAddr->IsHelperCall(compiler, CORINFO_HELP_READYTORUN_VIRTUAL_FUNC_PTR)
#endif
));
}

bool IsDevirtualizationCandidate(Compiler* compiler) const;
Expand Down
30 changes: 29 additions & 1 deletion src/coreclr/tools/Common/Compiler/DevirtualizationManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ protected virtual MethodDesc ResolveVirtualMethod(MethodDesc declMethod, DefType
{
devirtualizationDetail = CORINFO_DEVIRTUALIZATION_DETAIL.CORINFO_DEVIRTUALIZATION_UNKNOWN;

MethodDesc originalDeclMethod = declMethod;
MethodDesc impl;

if (declMethod.OwningType.IsInterface)
Expand Down Expand Up @@ -100,9 +101,19 @@ protected virtual MethodDesc ResolveVirtualMethod(MethodDesc declMethod, DefType
}

impl = implType.ResolveInterfaceMethodTargetWithVariance(declMethod);

if (impl != null)
{
impl = implType.FindVirtualFunctionTargetMethodOnObjectType(impl);

// We need to bring the original instantiation back so that we can still try devirtualizing
// when the method is a generic virtual method
if (impl != null && originalDeclMethod.HasInstantiation)
{
// We may end up with a method that has subsituted type parameters, so we need to instantiate
// on the method definition
impl = impl.GetMethodDefinition().MakeInstantiatedMethod(originalDeclMethod.Instantiation);
}
}
else
{
Expand Down Expand Up @@ -178,9 +189,19 @@ protected virtual MethodDesc ResolveVirtualMethod(MethodDesc declMethod, DefType
}

impl = implType.FindVirtualFunctionTargetMethodOnObjectType(declMethod);

// We need to bring the original instantiation back so that we can still try devirtualizing
// when the method is a generic virtual method
if (impl != null && originalDeclMethod.HasInstantiation)
{
// We may end up with a method that has subsituted type parameters, so we need to instantiate
// on the method definition
impl = impl.GetMethodDefinition().MakeInstantiatedMethod(originalDeclMethod.Instantiation);
}

if (impl != null && (impl != declMethod))
{
MethodDesc slotDefiningMethodImpl = MetadataVirtualMethodAlgorithm.FindSlotDefiningMethodForVirtualMethod(impl);
MethodDesc slotDefiningMethodImpl = MetadataVirtualMethodAlgorithm.FindSlotDefiningMethodForVirtualMethod(impl.GetMethodDefinition());
MethodDesc slotDefiningMethodDecl = MetadataVirtualMethodAlgorithm.FindSlotDefiningMethodForVirtualMethod(declMethod);

if (slotDefiningMethodImpl != slotDefiningMethodDecl)
Expand All @@ -198,6 +219,13 @@ protected virtual MethodDesc ResolveVirtualMethod(MethodDesc declMethod, DefType
}
}

if (impl != null && impl.HasInstantiation && originalDeclMethod.GetCanonMethodTarget(CanonicalFormKind.Specific).IsCanonicalMethod(CanonicalFormKind.Specific))
{
// We don't support devirtualization of shared generic virtual methods yet.
devirtualizationDetail = CORINFO_DEVIRTUALIZATION_DETAIL.CORINFO_DEVIRTUALIZATION_FAILED_CANON;
impl = null;
}

return impl;
}

Expand Down
7 changes: 0 additions & 7 deletions src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1340,13 +1340,6 @@ private bool resolveVirtualMethod(CORINFO_DEVIRTUALIZATION_INFO* info)
// Transform from the unboxing thunk to the normal method
decl = decl.IsUnboxingThunk() ? decl.GetUnboxedMethod() : decl;

if (decl.HasInstantiation)
{
// We cannot devirtualize generic virtual methods in AOT yet
info->detail = CORINFO_DEVIRTUALIZATION_DETAIL.CORINFO_DEVIRTUALIZATION_FAILED_GENERIC_VIRTUAL;
return false;
}

if ((info->context != null) && decl.OwningType.IsInterface)
{
TypeDesc ownerTypeDesc = typeFromContext(info->context);
Expand Down
3 changes: 1 addition & 2 deletions src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1122,7 +1122,7 @@ public enum CORINFO_DEVIRTUALIZATION_DETAIL
{
CORINFO_DEVIRTUALIZATION_UNKNOWN, // no details available
CORINFO_DEVIRTUALIZATION_SUCCESS, // devirtualization was successful
CORINFO_DEVIRTUALIZATION_FAILED_CANON, // object class was canonical
CORINFO_DEVIRTUALIZATION_FAILED_CANON, // object class or method was canonical
CORINFO_DEVIRTUALIZATION_FAILED_COM, // object class was com
CORINFO_DEVIRTUALIZATION_FAILED_CAST, // object class could not be cast to interface class
CORINFO_DEVIRTUALIZATION_FAILED_LOOKUP, // interface method could not be found
Expand All @@ -1138,7 +1138,6 @@ public enum CORINFO_DEVIRTUALIZATION_DETAIL
CORINFO_DEVIRTUALIZATION_FAILED_DUPLICATE_INTERFACE, // crossgen2 virtual method algorithm and runtime algorithm differ in the presence of duplicate interface implementations
CORINFO_DEVIRTUALIZATION_FAILED_DECL_NOT_REPRESENTABLE, // Decl method cannot be represented in R2R image
CORINFO_DEVIRTUALIZATION_FAILED_TYPE_EQUIVALENCE, // Support for type equivalence in devirtualization is not yet implemented in crossgen2
CORINFO_DEVIRTUALIZATION_FAILED_GENERIC_VIRTUAL, // Devirtualization of generic virtual methods is not yet implemented in crossgen2
CORINFO_DEVIRTUALIZATION_COUNT, // sentinel for maximum value
}

Expand Down
6 changes: 6 additions & 0 deletions src/coreclr/vm/jitinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14334,6 +14334,12 @@ BOOL LoadDynamicInfoEntry(Module *currentModule,
}
}

// Strip off method instantiation for comparison if the method is generic virtual.
if (pImplMethodCompiler != NULL && pDeclMethod->HasMethodInstantiation())
{
pImplMethodCompiler = pImplMethodCompiler->StripMethodInstantiation();
}

if (pImplMethodRuntime != pImplMethodCompiler)
{
if (kind == READYTORUN_FIXUP_Check_VirtualFunctionOverride)
Expand Down
Loading