Skip to content
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

[release/9.0-preview2] Revert "Support generic arguments for calli in CoreCLR (#97079)" #99016

Merged
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
112 changes: 19 additions & 93 deletions src/coreclr/vm/ceeload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4680,7 +4680,7 @@ PTR_VOID ReflectionModule::GetRvaField(RVA field) // virtual
//==========================================================================
// Enregisters a VASig.
//==========================================================================
VASigCookie *Module::GetVASigCookie(Signature vaSignature, const SigTypeContext* typeContext)
VASigCookie *Module::GetVASigCookie(Signature vaSignature)
{
CONTRACT(VASigCookie*)
{
Expand All @@ -4693,153 +4693,79 @@ VASigCookie *Module::GetVASigCookie(Signature vaSignature, const SigTypeContext*
}
CONTRACT_END;

Module* pLoaderModule = ClassLoader::ComputeLoaderModuleWorker(this, mdTokenNil, typeContext->m_classInst, typeContext->m_methodInst);
VASigCookie *pCookie = GetVASigCookieWorker(this, pLoaderModule, vaSignature, typeContext);

RETURN pCookie;
}

VASigCookie *Module::GetVASigCookieWorker(Module* pDefiningModule, Module* pLoaderModule, Signature vaSignature, const SigTypeContext* typeContext)
{
CONTRACT(VASigCookie*)
{
THROWS;
GC_TRIGGERS;
MODE_ANY;
POSTCONDITION(CheckPointer(RETVAL));
INJECT_FAULT(COMPlusThrowOM());
}
CONTRACT_END;

VASigCookieBlock *pBlock;
VASigCookie *pCookie;

pCookie = NULL;

// First, see if we already enregistered this sig.
// Note that we're outside the lock here, so be a bit careful with our logic
for (pBlock = pLoaderModule->m_pVASigCookieBlock; pBlock != NULL; pBlock = pBlock->m_Next)
for (pBlock = m_pVASigCookieBlock; pBlock != NULL; pBlock = pBlock->m_Next)
{
for (UINT i = 0; i < pBlock->m_numcookies; i++)
{
if (pBlock->m_cookies[i].signature.GetRawSig() == vaSignature.GetRawSig())
{
_ASSERTE(pBlock->m_cookies[i].classInst.GetNumArgs() == typeContext->m_classInst.GetNumArgs());
_ASSERTE(pBlock->m_cookies[i].methodInst.GetNumArgs() == typeContext->m_methodInst.GetNumArgs());

bool instMatch = true;

for (DWORD j = 0; j < pBlock->m_cookies[i].classInst.GetNumArgs(); j++)
{
if (pBlock->m_cookies[i].classInst[j] != typeContext->m_classInst[j])
{
instMatch = false;
break;
}
}

if (instMatch)
{
for (DWORD j = 0; j < pBlock->m_cookies[i].methodInst.GetNumArgs(); j++)
{
if (pBlock->m_cookies[i].methodInst[j] != typeContext->m_methodInst[j])
{
instMatch = false;
break;
}
}
}

if (instMatch)
{
pCookie = &(pBlock->m_cookies[i]);
break;
}
pCookie = &(pBlock->m_cookies[i]);
break;
}
}
}

if (!pCookie)
{
// If not, time to make a new one.

// Compute the size of args first, outside of the lock.

MetaSig metasig(vaSignature, pDefiningModule, typeContext);
// @TODO GENERICS: We may be calling a varargs method from a
// generic type/method. Using an empty context will make such a
// case cause an unexpected exception. To make this work,
// we need to create a specialized signature for every instantiation
SigTypeContext typeContext;

MetaSig metasig(vaSignature, this, &typeContext);
ArgIterator argit(&metasig);

// Upper estimate of the vararg size
DWORD sizeOfArgs = argit.SizeOfArgStack();

// Prepare instantiation
LoaderAllocator *pLoaderAllocator = pLoaderModule->GetLoaderAllocator();

DWORD classInstCount = typeContext->m_classInst.GetNumArgs();
DWORD methodInstCount = typeContext->m_methodInst.GetNumArgs();
pLoaderAllocator->EnsureInstantiation(pDefiningModule, typeContext->m_classInst);
pLoaderAllocator->EnsureInstantiation(pDefiningModule, typeContext->m_methodInst);

// enable gc before taking lock
{
CrstHolder ch(&pLoaderModule->m_Crst);
CrstHolder ch(&m_Crst);

// Note that we were possibly racing to create the cookie, and another thread
// may have already created it. We could put another check
// here, but it's probably not worth the effort, so we'll just take an
// occasional duplicate cookie instead.

// Is the first block in the list full?
if (pLoaderModule->m_pVASigCookieBlock && pLoaderModule->m_pVASigCookieBlock->m_numcookies
if (m_pVASigCookieBlock && m_pVASigCookieBlock->m_numcookies
< VASigCookieBlock::kVASigCookieBlockSize)
{
// Nope, reserve a new slot in the existing block.
pCookie = &(pLoaderModule->m_pVASigCookieBlock->m_cookies[pLoaderModule->m_pVASigCookieBlock->m_numcookies]);
pCookie = &(m_pVASigCookieBlock->m_cookies[m_pVASigCookieBlock->m_numcookies]);
}
else
{
// Yes, create a new block.
VASigCookieBlock *pNewBlock = new VASigCookieBlock();

pNewBlock->m_Next = pLoaderModule->m_pVASigCookieBlock;
pNewBlock->m_Next = m_pVASigCookieBlock;
pNewBlock->m_numcookies = 0;
pLoaderModule->m_pVASigCookieBlock = pNewBlock;
m_pVASigCookieBlock = pNewBlock;
pCookie = &(pNewBlock->m_cookies[0]);
}

// Now, fill in the new cookie (assuming we had enough memory to create one.)
pCookie->pModule = pDefiningModule;
pCookie->pModule = this;
pCookie->pNDirectILStub = NULL;
pCookie->sizeOfArgs = sizeOfArgs;
pCookie->signature = vaSignature;
pCookie->pLoaderModule = pLoaderModule;

AllocMemTracker amt;

if (classInstCount != 0)
{
TypeHandle* pClassInst = (TypeHandle*)(void*)amt.Track(pLoaderAllocator->GetHighFrequencyHeap()->AllocMem(S_SIZE_T(classInstCount) * S_SIZE_T(sizeof(TypeHandle))));
for (DWORD i = 0; i < classInstCount; i++)
{
pClassInst[i] = typeContext->m_classInst[i];
}
pCookie->classInst = Instantiation(pClassInst, classInstCount);
}

if (methodInstCount != 0)
{
TypeHandle* pMethodInst = (TypeHandle*)(void*)amt.Track(pLoaderAllocator->GetHighFrequencyHeap()->AllocMem(S_SIZE_T(methodInstCount) * S_SIZE_T(sizeof(TypeHandle))));
for (DWORD i = 0; i < methodInstCount; i++)
{
pMethodInst[i] = typeContext->m_methodInst[i];
}
pCookie->methodInst = Instantiation(pMethodInst, methodInstCount);
}

amt.SuppressRelease();

// Finally, now that it's safe for asynchronous readers to see it,
// update the count.
pLoaderModule->m_pVASigCookieBlock->m_numcookies++;
m_pVASigCookieBlock->m_numcookies++;
}
}

Expand Down
7 changes: 1 addition & 6 deletions src/coreclr/vm/ceeload.h
Original file line number Diff line number Diff line change
Expand Up @@ -338,10 +338,7 @@ struct VASigCookie
unsigned sizeOfArgs; // size of argument list
Volatile<PCODE> pNDirectILStub; // will be use if target is NDirect (tag == 0)
PTR_Module pModule;
PTR_Module pLoaderModule;
Signature signature;
Instantiation classInst;
Instantiation methodInst;
};

//
Expand Down Expand Up @@ -1363,9 +1360,7 @@ class Module : public ModuleBase
void NotifyEtwLoadFinished(HRESULT hr);

// Enregisters a VASig.
VASigCookie *GetVASigCookie(Signature vaSignature, const SigTypeContext* typeContext);
private:
static VASigCookie *GetVASigCookieWorker(Module* pDefiningModule, Module* pLoaderModule, Signature vaSignature, const SigTypeContext* typeContext);
VASigCookie *GetVASigCookie(Signature vaSignature);

public:
#ifndef DACCESS_COMPILE
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/vm/comdelegate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2019,7 +2019,7 @@ void COMDelegate::ThrowIfInvalidUnmanagedCallersOnlyUsage(MethodDesc* pMD)

// Arguments - Scenarios involving UnmanagedCallersOnly are handled during the jit.
bool unmanagedCallersOnlyRequiresMarshalling = false;
if (NDirect::MarshalingRequired(pMD, NULL, NULL, NULL, unmanagedCallersOnlyRequiresMarshalling))
if (NDirect::MarshalingRequired(pMD, NULL, NULL, unmanagedCallersOnlyRequiresMarshalling))
EX_THROW(EEResourceException, (kInvalidProgramException, W("InvalidProgram_NonBlittableTypes")));
}

Expand Down
33 changes: 8 additions & 25 deletions src/coreclr/vm/dllimport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ StubSigDesc::StubSigDesc(MethodDesc *pMD)
INDEBUG(InitDebugNames());
}

StubSigDesc::StubSigDesc(MethodDesc* pMD, const Signature& sig, Module* pModule, Module* pLoaderModule)
StubSigDesc::StubSigDesc(MethodDesc* pMD, const Signature& sig, Module* pModule)
{
CONTRACTL
{
Expand All @@ -135,13 +135,13 @@ StubSigDesc::StubSigDesc(MethodDesc* pMD, const Signature& sig, Module* pModule,
m_tkMethodDef = pMD->GetMemberDef();
SigTypeContext::InitTypeContext(pMD, &m_typeContext);
m_pMetadataModule = pMD->GetModule();
m_pLoaderModule = pLoaderModule == NULL ? pMD->GetLoaderModule() : pLoaderModule; // Used for ILStubCache selection and MethodTable creation.
m_pLoaderModule = pMD->GetLoaderModule(); // Used for ILStubCache selection and MethodTable creation.
}
else
{
m_tkMethodDef = mdMethodDefNil;
m_pMetadataModule = m_pModule;
m_pLoaderModule = pLoaderModule == NULL ? m_pModule : pLoaderModule;
m_pLoaderModule = m_pModule;
}

INDEBUG(InitDebugNames());
Expand Down Expand Up @@ -3180,7 +3180,6 @@ BOOL NDirect::MarshalingRequired(
_In_opt_ MethodDesc* pMD,
_In_opt_ PCCOR_SIGNATURE pSig,
_In_opt_ Module* pModule,
_In_opt_ SigTypeContext* pTypeContext,
_In_ bool unmanagedCallersOnlyRequiresMarshalling)
{
CONTRACTL
Expand Down Expand Up @@ -3261,6 +3260,8 @@ BOOL NDirect::MarshalingRequired(
mdParamDef *pParamTokenArray = (mdParamDef *)_alloca(numArgs * sizeof(mdParamDef));
IMDInternalImport *pMDImport = pModule->GetMDImport();

SigTypeContext emptyTypeContext;

mdMethodDef methodToken = mdMethodDefNil;
if (pMD != NULL)
{
Expand Down Expand Up @@ -3320,7 +3321,7 @@ BOOL NDirect::MarshalingRequired(
case ELEMENT_TYPE_VALUETYPE:
case ELEMENT_TYPE_GENERICINST:
{
TypeHandle hndArgType = arg.GetTypeHandleThrowing(pModule, pTypeContext);
TypeHandle hndArgType = arg.GetTypeHandleThrowing(pModule, &emptyTypeContext);
bool isValidGeneric = IsValidForGenericMarshalling(hndArgType.GetMethodTable(), false, runtimeMarshallingEnabled);
if(!hndArgType.IsValueType() || !isValidGeneric)
return true;
Expand Down Expand Up @@ -4191,10 +4192,8 @@ namespace
pHashParams,
pParams->m_dwStubFlags,
pParams->m_pModule,
pParams->m_pLoaderModule,
pParams->m_sig.GetRawSig(),
pParams->m_sig.GetRawSigLen(),
pParams->m_pTypeContext,
pamTracker,
bILStubCreator,
pLastMD);
Expand Down Expand Up @@ -5042,21 +5041,6 @@ namespace
}
else
{
if (!pSigDesc->m_typeContext.IsEmpty())
{
// For generic calli, we only support blittable types
if (SF_IsCALLIStub(dwStubFlags)
&& NDirect::MarshalingRequired(NULL, pStubMD->GetSig(), pSigDesc->m_pModule, &pSigDesc->m_typeContext))
{
COMPlusThrow(kMarshalDirectiveException, IDS_EE_BADMARSHAL_GENERICS_RESTRICTION);
}
// We don't want to support generic varargs, so block it
else if (SF_IsVarArgStub(dwStubFlags))
{
COMPlusThrow(kNotSupportedException, BFA_GENCODE_NOT_BE_VARARG);
}
}

CreateNDirectStubWorker(pss,
pSigDesc,
nlType,
Expand Down Expand Up @@ -6043,7 +6027,7 @@ PCODE GetILStubForCalli(VASigCookie *pVASigCookie, MethodDesc *pMD)
}
}

LoaderHeap *pHeap = pVASigCookie->pLoaderModule->GetLoaderAllocator()->GetHighFrequencyHeap();
LoaderHeap *pHeap = pVASigCookie->pModule->GetLoaderAllocator()->GetHighFrequencyHeap();
PCOR_SIGNATURE new_sig = (PCOR_SIGNATURE)(void *)pHeap->AllocMem(S_SIZE_T(signature.GetRawSigLen()));
CopyMemory(new_sig, signature.GetRawSig(), signature.GetRawSigLen());

Expand Down Expand Up @@ -6081,8 +6065,7 @@ PCODE GetILStubForCalli(VASigCookie *pVASigCookie, MethodDesc *pMD)
nlType = nltAnsi;
}

StubSigDesc sigDesc(pMD, signature, pVASigCookie->pModule, pVASigCookie->pLoaderModule);
sigDesc.InitTypeContext(pVASigCookie->classInst, pVASigCookie->methodInst);
StubSigDesc sigDesc(pMD, signature, pVASigCookie->pModule);

MethodDesc* pStubMD = NDirect::CreateCLRToNativeILStub(&sigDesc,
nlType,
Expand Down
18 changes: 3 additions & 15 deletions src/coreclr/vm/dllimport.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ struct StubSigDesc
{
public:
StubSigDesc(MethodDesc* pMD);
StubSigDesc(MethodDesc* pMD, const Signature& sig, Module* pModule, Module* pLoaderModule = NULL);
StubSigDesc(MethodTable* pMT, const Signature& sig, Module* pModule);
StubSigDesc(const Signature& sig, Module* pModule);
StubSigDesc(MethodDesc* pMD, const Signature& sig, Module* m_pModule);
StubSigDesc(MethodTable* pMT, const Signature& sig, Module* m_pModule);
StubSigDesc(const Signature& sig, Module* m_pModule);

MethodDesc *m_pMD;
MethodTable *m_pMT;
Expand Down Expand Up @@ -56,17 +56,6 @@ struct StubSigDesc
}
}
#endif // _DEBUG

#ifndef DACCESS_COMPILE
void InitTypeContext(Instantiation classInst, Instantiation methodInst)
{
LIMITED_METHOD_CONTRACT;

_ASSERTE(m_typeContext.IsEmpty());

m_typeContext = SigTypeContext(classInst, methodInst);
}
#endif
};

//=======================================================================
Expand Down Expand Up @@ -103,7 +92,6 @@ class NDirect
_In_opt_ MethodDesc* pMD,
_In_opt_ PCCOR_SIGNATURE pSig = NULL,
_In_opt_ Module* pModule = NULL,
_In_opt_ SigTypeContext* pTypeContext = NULL,
_In_ bool unmanagedCallersOnlyRequiresMarshalling = true);

static void PopulateNDirectMethodDesc(_Inout_ NDirectMethodDesc* pNMD);
Expand Down
21 changes: 9 additions & 12 deletions src/coreclr/vm/ilstubcache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -500,10 +500,8 @@ MethodDesc* ILStubCache::GetStubMethodDesc(
ILStubHashBlob* pHashBlob,
DWORD dwStubFlags,
Module* pSigModule,
Module* pSigLoaderModule,
PCCOR_SIGNATURE pSig,
DWORD cbSig,
SigTypeContext* pTypeContext,
AllocMemTracker* pamTracker,
bool& bILStubCreator,
MethodDesc *pLastMD)
Expand Down Expand Up @@ -540,23 +538,22 @@ MethodDesc* ILStubCache::GetStubMethodDesc(
// Couldn't find it, let's make a new one.
//

if (pSigLoaderModule == NULL)
Module *pContainingModule = pSigModule;
if (pTargetMD != NULL)
{
pSigLoaderModule = (pTargetMD != NULL) ? pTargetMD->GetLoaderModule() : pSigModule;
// loader module may be different from signature module for generic targets
pContainingModule = pTargetMD->GetLoaderModule();
}

MethodTable *pStubMT = GetOrCreateStubMethodTable(pContainingModule);

SigTypeContext typeContext;
if (pTypeContext == NULL)
if (pTargetMD != NULL)
{
if (pTargetMD != NULL)
{
SigTypeContext::InitTypeContext(pTargetMD, &typeContext);
}
pTypeContext = &typeContext;
SigTypeContext::InitTypeContext(pTargetMD, &typeContext);
}

MethodTable *pStubMT = GetOrCreateStubMethodTable(pSigLoaderModule);
pMD = ILStubCache::CreateNewMethodDesc(m_pAllocator->GetHighFrequencyHeap(), pStubMT, dwStubFlags, pSigModule, pSig, cbSig, pTypeContext, pamTracker);
pMD = ILStubCache::CreateNewMethodDesc(m_pAllocator->GetHighFrequencyHeap(), pStubMT, dwStubFlags, pSigModule, pSig, cbSig, &typeContext, pamTracker);

if (SF_IsSharedStub(dwStubFlags))
{
Expand Down
Loading
Loading