Skip to content

Revert "Enable non-blittable struct returns on UnmanagedCallersOnly (#45625)" #46172

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
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
4 changes: 2 additions & 2 deletions src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ LWM(GetTypeForPrimitiveValueClass, DWORDLONG, DWORD)
LWM(GetTypeForPrimitiveNumericClass, DWORDLONG, DWORD)
LWM(GetUnboxedEntry, DWORDLONG, DLD);
LWM(GetUnBoxHelper, DWORDLONG, DWORD)
LWM(GetUnmanagedCallConv, DWORDLONG, DWORD)
LWM(GetVarArgsHandle, GetVarArgsHandleValue, DLDL)
LWM(GetVars, DWORDLONG, Agnostic_GetVars)
DENSELWM(HandleException, DWORD)
Expand All @@ -148,13 +149,12 @@ LWM(IsValidToken, DLD, DWORD)
LWM(IsValueClass, DWORDLONG, DWORD)
LWM(MergeClasses, DLDL, DWORDLONG)
LWM(IsMoreSpecificType, DLDL, DWORD)
LWM(PInvokeMarshalingRequired, MethodOrSigInfoValue, DWORD)
LWM(PInvokeMarshalingRequired, PInvokeMarshalingRequiredValue, DWORD)
LWM(ResolveToken, Agnostic_CORINFO_RESOLVED_TOKENin, ResolveTokenValue)
LWM(ResolveVirtualMethod, Agnostic_ResolveVirtualMethodKey, Agnostic_ResolveVirtualMethodResult)
LWM(TryResolveToken, Agnostic_CORINFO_RESOLVED_TOKENin, TryResolveTokenValue)
LWM(SatisfiesClassConstraints, DWORDLONG, DWORD)
LWM(SatisfiesMethodConstraints, DLDL, DWORD)
LWM(GetUnmanagedCallConv, MethodOrSigInfoValue, DD)


#undef LWM
Expand Down
99 changes: 37 additions & 62 deletions src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1625,6 +1625,35 @@ bool MethodContext::repIsIntrinsicType(CORINFO_CLASS_HANDLE cls)
return result;
}

void MethodContext::recGetUnmanagedCallConv(CORINFO_METHOD_HANDLE method, CorInfoUnmanagedCallConv result)
{
if (GetUnmanagedCallConv == nullptr)
GetUnmanagedCallConv = new LightWeightMap<DWORDLONG, DWORD>();

GetUnmanagedCallConv->Add((DWORDLONG)method, result);
DEBUG_REC(dmpGetUnmanagedCallConv((DWORDLONG)method, (DWORD)result));
}
void MethodContext::dmpGetUnmanagedCallConv(DWORDLONG key, DWORD result)
{
printf("GetUnmanagedCallConv key ftn-%016llX, value res-%u", key, result);
}
CorInfoUnmanagedCallConv MethodContext::repGetUnmanagedCallConv(CORINFO_METHOD_HANDLE method)
{
if ((GetUnmanagedCallConv == nullptr) || (GetUnmanagedCallConv->GetIndex((DWORDLONG)method) == -1))
{
#ifdef sparseMC
LogDebug("Sparse - repGetUnmanagedCallConv returning CORINFO_UNMANAGED_CALLCONV_STDCALL");
return CORINFO_UNMANAGED_CALLCONV_STDCALL;
#else
LogException(EXCEPTIONCODE_MC, "Found a null GetUnmanagedCallConv. Probably missing a fatTrigger for %016llX.",
(DWORDLONG)method);
#endif
}
CorInfoUnmanagedCallConv result = (CorInfoUnmanagedCallConv)GetUnmanagedCallConv->Get((DWORDLONG)method);
DEBUG_REP(dmpGetUnmanagedCallConv((DWORDLONG)method, (DWORD)result));
return result;
}

void MethodContext::recAsCorInfoType(CORINFO_CLASS_HANDLE cls, CorInfoType result)
{
if (AsCorInfoType == nullptr)
Expand Down Expand Up @@ -3743,10 +3772,10 @@ void MethodContext::recPInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method,
bool result)
{
if (PInvokeMarshalingRequired == nullptr)
PInvokeMarshalingRequired = new LightWeightMap<MethodOrSigInfoValue, DWORD>();
PInvokeMarshalingRequired = new LightWeightMap<PInvokeMarshalingRequiredValue, DWORD>();

MethodOrSigInfoValue key;
ZeroMemory(&key, sizeof(MethodOrSigInfoValue)); // We use the input structs as a key and use memcmp to
PInvokeMarshalingRequiredValue key;
ZeroMemory(&key, sizeof(PInvokeMarshalingRequiredValue)); // We use the input structs as a key and use memcmp to
// compare.. so we need to zero out padding too

key.method = CastHandle(method);
Expand All @@ -3757,7 +3786,7 @@ void MethodContext::recPInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method,
PInvokeMarshalingRequired->Add(key, (DWORD)result);
DEBUG_REC(dmpPInvokeMarshalingRequired(key, (DWORD)result));
}
void MethodContext::dmpPInvokeMarshalingRequired(const MethodOrSigInfoValue& key, DWORD value)
void MethodContext::dmpPInvokeMarshalingRequired(const PInvokeMarshalingRequiredValue& key, DWORD value)
{
printf("PInvokeMarshalingRequired key mth-%016llX scp-%016llX sig-%u, value res-%u", key.method, key.scope,
key.pSig_Index, value);
Expand All @@ -3768,9 +3797,9 @@ bool MethodContext::repPInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, C
if (PInvokeMarshalingRequired == nullptr) // so when we replay checked on free, we throw from lwm
return TRUE; // TODO-Cleanup: hackish...

MethodOrSigInfoValue key;
ZeroMemory(&key, sizeof(MethodOrSigInfoValue)); // We use the input structs as a key and use memcmp to
// compare.. so we need to zero out padding too
PInvokeMarshalingRequiredValue key;
ZeroMemory(&key, sizeof(PInvokeMarshalingRequiredValue)); // We use the input structs as a key and use memcmp to
// compare.. so we need to zero out padding too

key.method = CastHandle(method);
key.pSig_Index = (DWORD)PInvokeMarshalingRequired->Contains((unsigned char*)callSiteSig->pSig, callSiteSig->cbSig);
Expand All @@ -3782,60 +3811,6 @@ bool MethodContext::repPInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, C
return value;
}

void MethodContext::recGetUnmanagedCallConv(CORINFO_METHOD_HANDLE method,
CORINFO_SIG_INFO* callSiteSig,
CorInfoCallConvExtension result,
bool suppressGCTransitionResult)
{
if (GetUnmanagedCallConv == nullptr)
GetUnmanagedCallConv = new LightWeightMap<MethodOrSigInfoValue, DD>();

MethodOrSigInfoValue key;
ZeroMemory(&key, sizeof(MethodOrSigInfoValue)); // We use the input structs as a key and use memcmp to
// compare.. so we need to zero out padding too

key.method = CastHandle(method);
key.pSig_Index = (DWORD)PInvokeMarshalingRequired->AddBuffer((unsigned char*)callSiteSig->pSig, callSiteSig->cbSig);
key.cbSig = (DWORD)callSiteSig->cbSig;
key.scope = CastHandle(callSiteSig->scope);

GetUnmanagedCallConv->Add(key, { (DWORD)result, (DWORD)suppressGCTransitionResult });
DEBUG_REC(dmpGetUnmanagedCallConv(key, { (DWORD)result, (DWORD)suppressGCTransitionResult }));
}
void MethodContext::dmpGetUnmanagedCallConv(const MethodOrSigInfoValue& key, DD value)
{
printf("GetUnmanagedCallConv key mth-%016llX scp-%016llX sig-%u, value res-%u,%u", key.method, key.scope,
key.pSig_Index, value.A, value.B);
}
// Note the jit interface implementation seems to only care about scope and pSig from callSiteSig
CorInfoCallConvExtension MethodContext::repGetUnmanagedCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig, bool* pSuppressGCTransition)
{
if (GetUnmanagedCallConv == nullptr)
{
#ifdef sparseMC
LogDebug("Sparse - repGetUnmanagedCallConv returning CorInfoCallConvExtension::Managed");
return CorInfoCallConvExtension::Managed;
#else
LogException(EXCEPTIONCODE_MC, "Found a null GetUnmGetUnmanagedCallConvanagedCallConv. Probably missing a fatTrigger for %016llX.",
CastHandle(method));
#endif
}

MethodOrSigInfoValue key;
ZeroMemory(&key, sizeof(MethodOrSigInfoValue)); // We use the input structs as a key and use memcmp to
// compare.. so we need to zero out padding too

key.method = CastHandle(method);
key.pSig_Index = (DWORD)GetUnmanagedCallConv->Contains((unsigned char*)callSiteSig->pSig, callSiteSig->cbSig);
key.cbSig = (DWORD)callSiteSig->cbSig;
key.scope = CastHandle(callSiteSig->scope);

DD value = GetUnmanagedCallConv->Get(key);
DEBUG_REP(dmpGetUnmanagedCallConv(key, value));
*pSuppressGCTransition = value.B != 0;
return (CorInfoCallConvExtension)value.A;
}

void MethodContext::recFindSig(CORINFO_MODULE_HANDLE moduleHandle,
unsigned sigTOK,
CORINFO_CONTEXT_HANDLE context,
Expand Down Expand Up @@ -5316,7 +5291,7 @@ void MethodContext::recGetLikelyClass(CORINFO_METHOD_HANDLE ftnHnd, CORINFO_CLAS
}
void MethodContext::dmpGetLikelyClass(const Agnostic_GetLikelyClass& key, const Agnostic_GetLikelyClassResult& value)
{
printf("GetLikelyClass key ftn-%016llX base-%016llX il-%u, class-%016llX likelihood-%u numberOfClasses-%u",
printf("GetLikelyClass key ftn-%016llX base-%016llX il-%u, class-%016llX likelihood-%u numberOfClasses-%u",
key.ftnHnd, key.baseHnd, key.ilOffset, value.classHnd, value.likelihood, value.numberOfClasses);
}
CORINFO_CLASS_HANDLE MethodContext::repGetLikelyClass(CORINFO_METHOD_HANDLE ftnHnd, CORINFO_CLASS_HANDLE baseHnd, UINT32 ilOffset, UINT32* pLikelihood, UINT32* pNumberOfClasses)
Expand Down
12 changes: 6 additions & 6 deletions src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ class MethodContext
DWORD sigTOK;
DWORDLONG context;
};
struct MethodOrSigInfoValue
struct PInvokeMarshalingRequiredValue
{
DWORDLONG method;
DWORD pSig_Index;
Expand Down Expand Up @@ -730,6 +730,10 @@ class MethodContext
void dmpGetIntrinsicID(DWORDLONG key, DD value);
CorInfoIntrinsics repGetIntrinsicID(CORINFO_METHOD_HANDLE method, bool* pMustExpand);

void recGetUnmanagedCallConv(CORINFO_METHOD_HANDLE method, CorInfoUnmanagedCallConv result);
void dmpGetUnmanagedCallConv(DWORDLONG key, DWORD result);
CorInfoUnmanagedCallConv repGetUnmanagedCallConv(CORINFO_METHOD_HANDLE method);

void recAsCorInfoType(CORINFO_CLASS_HANDLE cls, CorInfoType result);
void dmpAsCorInfoType(DWORDLONG key, DWORD value);
CorInfoType repAsCorInfoType(CORINFO_CLASS_HANDLE cls);
Expand Down Expand Up @@ -999,13 +1003,9 @@ class MethodContext
CORINFO_CLASS_HANDLE repEmbedClassHandle(CORINFO_CLASS_HANDLE handle, void** ppIndirection);

void recPInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig, bool result);
void dmpPInvokeMarshalingRequired(const MethodOrSigInfoValue& key, DWORD value);
void dmpPInvokeMarshalingRequired(const PInvokeMarshalingRequiredValue& key, DWORD value);
bool repPInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig);

void recGetUnmanagedCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig, CorInfoCallConvExtension result, bool suppressGCTransitionResult);
void dmpGetUnmanagedCallConv(const MethodOrSigInfoValue& key, DD value);
CorInfoCallConvExtension repGetUnmanagedCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig, bool* pSuppressGCTransition);

void recFindSig(CORINFO_MODULE_HANDLE module,
unsigned sigTOK,
CORINFO_CONTEXT_HANDLE context,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -289,15 +289,12 @@ bool interceptor_ICJI::isIntrinsicType(CORINFO_CLASS_HANDLE classHnd)
return temp;
}

// return the entry point calling convention for any of the following
// - a P/Invoke
// - a method marked with UnmanagedCallersOnly
// - a function pointer with the CORINFO_CALLCONV_UNMANAGED calling convention.
CorInfoCallConvExtension interceptor_ICJI::getUnmanagedCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig, bool* pSuppressGCTransition)
// return the unmanaged calling convention for a PInvoke
CorInfoUnmanagedCallConv interceptor_ICJI::getUnmanagedCallConv(CORINFO_METHOD_HANDLE method)
{
mc->cr->AddCall("getUnmanagedCallConv");
CorInfoCallConvExtension temp = original_ICorJitInfo->getUnmanagedCallConv(method, callSiteSig, pSuppressGCTransition);
mc->recGetUnmanagedCallConv(method, callSiteSig, temp, *pSuppressGCTransition);
CorInfoUnmanagedCallConv temp = original_ICorJitInfo->getUnmanagedCallConv(method);
mc->recGetUnmanagedCallConv(method, temp);
return temp;
}

Expand Down Expand Up @@ -2049,7 +2046,7 @@ HRESULT interceptor_ICJI::getMethodBlockCounts(CORINFO_METHOD_HANDLE ftnHnd,

// Get the likely implementing class for a virtual call or interface call made by ftnHnd
// at the indicated IL offset. baseHnd is the interface class or base class for the method
// being called.
// being called.
CORINFO_CLASS_HANDLE interceptor_ICJI::getLikelyClass(CORINFO_METHOD_HANDLE ftnHnd,
CORINFO_CLASS_HANDLE baseHnd,
UINT32 ilOffset,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,13 +162,11 @@ bool interceptor_ICJI::isIntrinsicType(
return original_ICorJitInfo->isIntrinsicType(classHnd);
}

CorInfoCallConvExtension interceptor_ICJI::getUnmanagedCallConv(
CORINFO_METHOD_HANDLE method,
CORINFO_SIG_INFO* callSiteSig,
bool* pSuppressGCTransition)
CorInfoUnmanagedCallConv interceptor_ICJI::getUnmanagedCallConv(
CORINFO_METHOD_HANDLE method)
{
mcs->AddCall("getUnmanagedCallConv");
return original_ICorJitInfo->getUnmanagedCallConv(method, callSiteSig, pSuppressGCTransition);
return original_ICorJitInfo->getUnmanagedCallConv(method);
}

bool interceptor_ICJI::pInvokeMarshalingRequired(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,12 +144,10 @@ bool interceptor_ICJI::isIntrinsicType(
return original_ICorJitInfo->isIntrinsicType(classHnd);
}

CorInfoCallConvExtension interceptor_ICJI::getUnmanagedCallConv(
CORINFO_METHOD_HANDLE method,
CORINFO_SIG_INFO* callSiteSig,
bool* pSuppressGCTransition)
CorInfoUnmanagedCallConv interceptor_ICJI::getUnmanagedCallConv(
CORINFO_METHOD_HANDLE method)
{
return original_ICorJitInfo->getUnmanagedCallConv(method, callSiteSig, pSuppressGCTransition);
return original_ICorJitInfo->getUnmanagedCallConv(method);
}

bool interceptor_ICJI::pInvokeMarshalingRequired(
Expand Down
11 changes: 4 additions & 7 deletions src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,14 +218,11 @@ bool MyICJI::isIntrinsicType(CORINFO_CLASS_HANDLE classHnd)
return jitInstance->mc->repIsIntrinsicType(classHnd) ? true : false;
}

// return the entry point calling convention for any of the following
// - a P/Invoke
// - a method marked with UnmanagedCallersOnly
// - a function pointer with the CORINFO_CALLCONV_UNMANAGED calling convention.
CorInfoCallConvExtension MyICJI::getUnmanagedCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig, bool* pSuppressGCTransition)
// return the unmanaged calling convention for a PInvoke
CorInfoUnmanagedCallConv MyICJI::getUnmanagedCallConv(CORINFO_METHOD_HANDLE method)
{
jitInstance->mc->cr->AddCall("getUnmanagedCallConv");
return jitInstance->mc->repGetUnmanagedCallConv(method, callSiteSig, pSuppressGCTransition);
return jitInstance->mc->repGetUnmanagedCallConv(method);
}

// return if any marshaling is required for PInvoke methods. Note that
Expand Down Expand Up @@ -1806,7 +1803,7 @@ HRESULT MyICJI::getMethodBlockCounts(CORINFO_METHOD_HANDLE ftnHnd,

// Get the likely implementing class for a virtual call or interface call made by ftnHnd
// at the indicated IL offset. baseHnd is the interface class or base class for the method
// being called.
// being called.
CORINFO_CLASS_HANDLE MyICJI::getLikelyClass(CORINFO_METHOD_HANDLE ftnHnd,
CORINFO_CLASS_HANDLE baseHnd,
UINT32 ilOffset,
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/debug/daccess/nidump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7350,6 +7350,7 @@ static NativeImageDumper::EnumMnemonics g_NDirectFlags[] =
NDF_ENTRY(kStdCall),
NDF_ENTRY(kThisCall),
NDF_ENTRY(kIsQCall),
NDF_ENTRY(kStdCallWithRetBuf),
#undef NDF_ENTRY
};
NativeImageDumper::EnumMnemonics NativeImageDumper::s_IMDFlags[] =
Expand Down
26 changes: 15 additions & 11 deletions src/coreclr/inc/corhdr.h
Original file line number Diff line number Diff line change
Expand Up @@ -954,21 +954,11 @@ typedef enum CorSerializationType
// Calling convention flags.
//

typedef enum CorUnmanagedCallingConvention
{
IMAGE_CEE_UNMANAGED_CALLCONV_C = 0x1,
IMAGE_CEE_UNMANAGED_CALLCONV_STDCALL = 0x2,
IMAGE_CEE_UNMANAGED_CALLCONV_THISCALL = 0x3,
IMAGE_CEE_UNMANAGED_CALLCONV_FASTCALL = 0x4,
} CorUnmanagedCallingConvention;

typedef enum CorCallingConvention
{
IMAGE_CEE_CS_CALLCONV_DEFAULT = 0x0,
IMAGE_CEE_CS_CALLCONV_C = IMAGE_CEE_UNMANAGED_CALLCONV_C,
IMAGE_CEE_CS_CALLCONV_STDCALL = IMAGE_CEE_UNMANAGED_CALLCONV_STDCALL,
IMAGE_CEE_CS_CALLCONV_THISCALL = IMAGE_CEE_UNMANAGED_CALLCONV_THISCALL,
IMAGE_CEE_CS_CALLCONV_FASTCALL = IMAGE_CEE_UNMANAGED_CALLCONV_FASTCALL,

IMAGE_CEE_CS_CALLCONV_VARARG = 0x5,
IMAGE_CEE_CS_CALLCONV_FIELD = 0x6,
IMAGE_CEE_CS_CALLCONV_LOCAL_SIG = 0x7,
Expand All @@ -989,6 +979,20 @@ typedef enum CorCallingConvention

#define IMAGE_CEE_CS_CALLCONV_INSTANTIATION IMAGE_CEE_CS_CALLCONV_GENERICINST

typedef enum CorUnmanagedCallingConvention
{
IMAGE_CEE_UNMANAGED_CALLCONV_C = 0x1,
IMAGE_CEE_UNMANAGED_CALLCONV_STDCALL = 0x2,
IMAGE_CEE_UNMANAGED_CALLCONV_THISCALL = 0x3,
IMAGE_CEE_UNMANAGED_CALLCONV_FASTCALL = 0x4,

IMAGE_CEE_CS_CALLCONV_C = IMAGE_CEE_UNMANAGED_CALLCONV_C,
IMAGE_CEE_CS_CALLCONV_STDCALL = IMAGE_CEE_UNMANAGED_CALLCONV_STDCALL,
IMAGE_CEE_CS_CALLCONV_THISCALL = IMAGE_CEE_UNMANAGED_CALLCONV_THISCALL,
IMAGE_CEE_CS_CALLCONV_FASTCALL = IMAGE_CEE_UNMANAGED_CALLCONV_FASTCALL,

} CorUnmanagedCallingConvention;


typedef enum CorArgType
{
Expand Down
Loading