Get exact class during devirtualization by AndyAyersMS · Pull Request #45526 · dotnet/runtime · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 1 addition & 1 deletion src/coreclr/src/ToolBox/superpmi/superpmi-shared/lwmlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ LWM(MergeClasses, DLDL, DWORDLONG)
LWM(IsMoreSpecificType, DLDL, DWORD)
LWM(PInvokeMarshalingRequired, PInvokeMarshalingRequiredValue, DWORD)
LWM(ResolveToken, Agnostic_CORINFO_RESOLVED_TOKENin, ResolveTokenValue)
LWM(ResolveVirtualMethod, Agnostic_ResolveVirtualMethod, DWORDLONG)
LWM(ResolveVirtualMethod, Agnostic_ResolveVirtualMethodKey, Agnostic_ResolveVirtualMethodResult)
LWM(TryResolveToken, Agnostic_CORINFO_RESOLVED_TOKENin, TryResolveTokenValue)
LWM(SatisfiesClassConstraints, DWORDLONG, DWORD)
LWM(SatisfiesMethodConstraints, DLDL, DWORD)
Expand Down
54 changes: 28 additions & 26 deletions src/coreclr/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3073,49 +3073,51 @@ void MethodContext::repGetMethodVTableOffset(CORINFO_METHOD_HANDLE method,
DEBUG_REP(dmpGetMethodVTableOffset((DWORDLONG)method, value));
}

void MethodContext::recResolveVirtualMethod(CORINFO_METHOD_HANDLE virtMethod,
CORINFO_CLASS_HANDLE implClass,
CORINFO_CONTEXT_HANDLE ownerType,
CORINFO_METHOD_HANDLE result)
void MethodContext::recResolveVirtualMethod(CORINFO_DEVIRTUALIZATION_INFO * info, bool returnValue)
{
if (ResolveVirtualMethod == nullptr)
{
ResolveVirtualMethod = new LightWeightMap<Agnostic_ResolveVirtualMethod, DWORDLONG>();
ResolveVirtualMethod = new LightWeightMap<Agnostic_ResolveVirtualMethodKey, Agnostic_ResolveVirtualMethodResult>();
}

Agnostic_ResolveVirtualMethod key;
key.virtualMethod = (DWORDLONG)virtMethod;
key.implementingClass = (DWORDLONG)implClass;
key.ownerType = (DWORDLONG)ownerType;
ResolveVirtualMethod->Add(key, (DWORDLONG)result);
DEBUG_REC(dmpResolveVirtualMethod(key, (DWORDLONG)result));
Agnostic_ResolveVirtualMethodKey key;
key.virtualMethod = (DWORDLONG)info->virtualMethod;
key.objClass = (DWORDLONG)info->objClass;
key.context = (DWORDLONG)info->context;
Agnostic_ResolveVirtualMethodResult result;
result.returnValue = returnValue;
result.devirtualizedMethod = (DWORDLONG)info->devirtualizedMethod;
result.requiresInstMethodTableArg = info->requiresInstMethodTableArg;
result.exactContext = (DWORDLONG)info->exactContext;
ResolveVirtualMethod->Add(key, result);
DEBUG_REC(dmpResolveVirtualMethod(key, result));
}

void MethodContext::dmpResolveVirtualMethod(const Agnostic_ResolveVirtualMethod& key, DWORDLONG value)
void MethodContext::dmpResolveVirtualMethod(const Agnostic_ResolveVirtualMethodKey& key, const Agnostic_ResolveVirtualMethodResult& result)
{
printf("ResolveVirtualMethod virtMethod-%016llX, implClass-%016llX, ownerType--%016llX, result-%016llX",
key.virtualMethod, key.implementingClass, key.ownerType, value);
printf("ResolveVirtualMethod virtMethod-%016llX, objClass-%016llX, context-%016llX :: returnValue-%d, devirtMethod-%016llX, requiresInstArg-%d, exactContext-%016llX",
key.virtualMethod, key.objClass, key.context, result.returnValue, result.devirtualizedMethod, result.requiresInstMethodTableArg, result.exactContext);
}

CORINFO_METHOD_HANDLE MethodContext::repResolveVirtualMethod(CORINFO_METHOD_HANDLE virtMethod,
CORINFO_CLASS_HANDLE implClass,
CORINFO_CONTEXT_HANDLE ownerType)
bool MethodContext::repResolveVirtualMethod(CORINFO_DEVIRTUALIZATION_INFO * info)
{
Agnostic_ResolveVirtualMethod key;
key.virtualMethod = (DWORDLONG)virtMethod;
key.implementingClass = (DWORDLONG)implClass;
key.ownerType = (DWORDLONG)ownerType;
Agnostic_ResolveVirtualMethodKey key;
key.virtualMethod = (DWORDLONG)info->virtualMethod;
key.objClass = (DWORDLONG)info->objClass;
key.context = (DWORDLONG)info->context;

AssertCodeMsg(ResolveVirtualMethod != nullptr, EXCEPTIONCODE_MC,
"No ResolveVirtualMap map for %016llX-%016llX-%016llX", key.virtualMethod, key.implementingClass,
key.ownerType);
"No ResolveVirtualMap map for %016llX-%016llX-%016llX", key.virtualMethod, key.objClass, key.context);
AssertCodeMsg(ResolveVirtualMethod->GetIndex(key) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX-%016llx-%016llX",
key.virtualMethod, key.implementingClass, key.ownerType);
DWORDLONG result = ResolveVirtualMethod->Get(key);
key.virtualMethod, key.objClass, key.context);

Agnostic_ResolveVirtualMethodResult result = ResolveVirtualMethod->Get(key);
DEBUG_REP(dmpResolveVirtualMethod(key, result));
info->devirtualizedMethod = (CORINFO_METHOD_HANDLE) result.devirtualizedMethod;
info->requiresInstMethodTableArg = result.requiresInstMethodTableArg;
info->exactContext = (CORINFO_CONTEXT_HANDLE) result.exactContext;

return (CORINFO_METHOD_HANDLE)result;
return result.returnValue;
}

void MethodContext::recGetUnboxedEntry(CORINFO_METHOD_HANDLE ftn,
Expand Down
27 changes: 15 additions & 12 deletions src/coreclr/src/ToolBox/superpmi/superpmi-shared/methodcontext.h
Original file line number Diff line number Diff line change
Expand Up @@ -507,11 +507,19 @@ class MethodContext
DWORD result;
};

struct Agnostic_ResolveVirtualMethod
struct Agnostic_ResolveVirtualMethodKey
{
DWORDLONG virtualMethod;
DWORDLONG implementingClass;
DWORDLONG ownerType;
DWORDLONG objClass;
DWORDLONG context;
};

struct Agnostic_ResolveVirtualMethodResult
{
bool returnValue;
DWORDLONG devirtualizedMethod;
bool requiresInstMethodTableArg;
DWORDLONG exactContext;
};

struct ResolveTokenValue
Expand Down Expand Up @@ -927,14 +935,9 @@ class MethodContext
unsigned* offsetAfterIndirection,
bool* isRelative);

void recResolveVirtualMethod(CORINFO_METHOD_HANDLE virtMethod,
CORINFO_CLASS_HANDLE implClass,
CORINFO_CONTEXT_HANDLE ownerType,
CORINFO_METHOD_HANDLE result);
void dmpResolveVirtualMethod(const Agnostic_ResolveVirtualMethod& key, DWORDLONG value);
CORINFO_METHOD_HANDLE repResolveVirtualMethod(CORINFO_METHOD_HANDLE virtMethod,
CORINFO_CLASS_HANDLE implClass,
CORINFO_CONTEXT_HANDLE ownerType);
void recResolveVirtualMethod(CORINFO_DEVIRTUALIZATION_INFO * info, bool returnValue);
void dmpResolveVirtualMethod(const Agnostic_ResolveVirtualMethodKey& key, const Agnostic_ResolveVirtualMethodResult& value);
bool repResolveVirtualMethod(CORINFO_DEVIRTUALIZATION_INFO * info);

void recGetUnboxedEntry(CORINFO_METHOD_HANDLE ftn, bool* requiresInstMethodTableArg, CORINFO_METHOD_HANDLE result);
void dmpGetUnboxedEntry(DWORDLONG key, DLD value);
Expand Down Expand Up @@ -1378,7 +1381,7 @@ class MethodContext
};

// ********************* Please keep this up-to-date to ease adding more ***************
// Highest packet number: 182
// Highest packet number: 184
// *************************************************************************************
enum mcPackets
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,16 +230,11 @@ void interceptor_ICJI::getMethodVTableOffset(CORINFO_METHOD_HANDLE method,
mc->recGetMethodVTableOffset(method, offsetOfIndirection, offsetAfterIndirection, isRelative);
}

// Find the virtual method in implementingClass that overrides virtualMethod.
// Return null if devirtualization is not possible.
CORINFO_METHOD_HANDLE interceptor_ICJI::resolveVirtualMethod(CORINFO_METHOD_HANDLE virtualMethod,
CORINFO_CLASS_HANDLE implementingClass,
CORINFO_CONTEXT_HANDLE ownerType)
bool interceptor_ICJI::resolveVirtualMethod(CORINFO_DEVIRTUALIZATION_INFO * info)
{
mc->cr->AddCall("resolveVirtualMethod");
CORINFO_METHOD_HANDLE result =
original_ICorJitInfo->resolveVirtualMethod(virtualMethod, implementingClass, ownerType);
mc->recResolveVirtualMethod(virtualMethod, implementingClass, ownerType, result);
bool result = original_ICorJitInfo->resolveVirtualMethod(info);
mc->recResolveVirtualMethod(info, result);
return result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,13 +117,11 @@ void interceptor_ICJI::getMethodVTableOffset(
original_ICorJitInfo->getMethodVTableOffset(method, offsetOfIndirection, offsetAfterIndirection, isRelative);
}

CORINFO_METHOD_HANDLE interceptor_ICJI::resolveVirtualMethod(
CORINFO_METHOD_HANDLE virtualMethod,
CORINFO_CLASS_HANDLE implementingClass,
CORINFO_CONTEXT_HANDLE ownerType)
bool interceptor_ICJI::resolveVirtualMethod(
CORINFO_DEVIRTUALIZATION_INFO* info)
{
mcs->AddCall("resolveVirtualMethod");
return original_ICorJitInfo->resolveVirtualMethod(virtualMethod, implementingClass, ownerType);
return original_ICorJitInfo->resolveVirtualMethod(info);
}

CORINFO_METHOD_HANDLE interceptor_ICJI::getUnboxedEntry(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,10 @@ void interceptor_ICJI::getMethodVTableOffset(
original_ICorJitInfo->getMethodVTableOffset(method, offsetOfIndirection, offsetAfterIndirection, isRelative);
}

CORINFO_METHOD_HANDLE interceptor_ICJI::resolveVirtualMethod(
CORINFO_METHOD_HANDLE virtualMethod,
CORINFO_CLASS_HANDLE implementingClass,
CORINFO_CONTEXT_HANDLE ownerType)
bool interceptor_ICJI::resolveVirtualMethod(
CORINFO_DEVIRTUALIZATION_INFO* info)
{
return original_ICorJitInfo->resolveVirtualMethod(virtualMethod, implementingClass, ownerType);
return original_ICorJitInfo->resolveVirtualMethod(info);
}

CORINFO_METHOD_HANDLE interceptor_ICJI::getUnboxedEntry(
Expand Down
9 changes: 2 additions & 7 deletions src/coreclr/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,15 +171,10 @@ void MyICJI::getMethodVTableOffset(CORINFO_METHOD_HANDLE method,
jitInstance->mc->repGetMethodVTableOffset(method, offsetOfIndirection, offsetAfterIndirection, isRelative);
}

// Find the virtual method in implementingClass that overrides virtualMethod.
// Return null if devirtualization is not possible.
CORINFO_METHOD_HANDLE MyICJI::resolveVirtualMethod(CORINFO_METHOD_HANDLE virtualMethod,
CORINFO_CLASS_HANDLE implementingClass,
CORINFO_CONTEXT_HANDLE ownerType)
bool MyICJI::resolveVirtualMethod(CORINFO_DEVIRTUALIZATION_INFO * info)
{
jitInstance->mc->cr->AddCall("resolveVirtualMethod");
CORINFO_METHOD_HANDLE result =
jitInstance->mc->repResolveVirtualMethod(virtualMethod, implementingClass, ownerType);
bool result = jitInstance->mc->repResolveVirtualMethod(info);
return result;
}

Expand Down
36 changes: 26 additions & 10 deletions src/coreclr/src/inc/corinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -1579,6 +1579,27 @@ struct CORINFO_CALL_INFO
BOOL wrapperDelegateInvoke;
};

struct CORINFO_DEVIRTUALIZATION_INFO
{
//
// [In] arguments of resolveVirtualMethod
//
CORINFO_METHOD_HANDLE virtualMethod;
CORINFO_CLASS_HANDLE objClass;
CORINFO_CONTEXT_HANDLE context;

//
// [Out] results of resolveVirtualMethod.
// - devirtualizedMethod is set to MethodDesc of devirt'ed method iff we were able to devirtualize.
// invariant is `resolveVirtualMethod(...) == (devirtualizedMethod != nullptr)`.
// - requiresInstMethodTableArg is set to TRUE if the devirtualized method requires a type handle arg.
// - exactContext is set to wrapped CORINFO_CLASS_HANDLE of devirt'ed method table.
//
CORINFO_METHOD_HANDLE devirtualizedMethod;
bool requiresInstMethodTableArg;
CORINFO_CONTEXT_HANDLE exactContext;
};

//----------------------------------------------------------------------------
// getFieldInfo and CORINFO_FIELD_INFO: The EE instructs the JIT about how to access a field

Expand Down Expand Up @@ -2011,17 +2032,12 @@ class ICorStaticInfo
bool* isRelative /* OUT */
) = 0;

// Find the virtual method in implementingClass that overrides virtualMethod,
// or the method in implementingClass that implements the interface method
// represented by virtualMethod.
// Finds the virtual method in info->objClass that overrides info->virtualMethod,
// or the method in info->objClass that implements the interface method
// represented by info->virtualMethod.
//
// Return null if devirtualization is not possible. Owner type is optional
// and provides additional context for shared interface devirtualization.
virtual CORINFO_METHOD_HANDLE resolveVirtualMethod(
CORINFO_METHOD_HANDLE virtualMethod, /* IN */
CORINFO_CLASS_HANDLE implementingClass, /* IN */
CORINFO_CONTEXT_HANDLE ownerType = NULL /* IN */
) = 0;
// Returns false if devirtualization is not possible.
virtual bool resolveVirtualMethod(CORINFO_DEVIRTUALIZATION_INFO * info) = 0;

// Get the unboxed entry point for a method, if possible.
virtual CORINFO_METHOD_HANDLE getUnboxedEntry(
Expand Down
10 changes: 5 additions & 5 deletions src/coreclr/src/inc/jiteeversionguid.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////

constexpr GUID JITEEVersionIdentifier = { /* 0d235fe4-65a1-487a-8553-c845496da901 */
0x0d235fe4,
0x65a1,
0x487a,
{0x85, 0x53, 0xc8, 0x45, 0x49, 0x6d, 0xa9, 0x01}
constexpr GUID JITEEVersionIdentifier = { /* 94cd1e55-a53b-4c6a-b697-46415b5d4204 */
0x94cd1e55,
0xa53b,
0x4c6a,
{0xb6, 0x97, 0x46, 0x41, 0x5b, 0x5d, 0x42, 0x04}
};

//////////////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down
8 changes: 3 additions & 5 deletions src/coreclr/src/jit/ICorJitInfo_API_wrapper.hpp
Loading