Skip to content
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
44 changes: 44 additions & 0 deletions src/coreclr/interpreter/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1072,6 +1072,50 @@ void InterpCompiler::BuildGCInfo(InterpMethod *pInterpMethod)

gcInfoEncoder->SetCodeLength(ConvertOffset(m_methodCodeSize));

GENERIC_CONTEXTPARAM_TYPE paramType;

switch (m_methodInfo->options & CORINFO_GENERICS_CTXT_MASK)
{
case CORINFO_GENERICS_CTXT_FROM_METHODDESC:
paramType = GENERIC_CONTEXTPARAM_MD;
break;
case CORINFO_GENERICS_CTXT_FROM_METHODTABLE:
paramType = GENERIC_CONTEXTPARAM_MT;
break;
case CORINFO_GENERICS_CTXT_FROM_THIS:
case 0:
paramType = GENERIC_CONTEXTPARAM_NONE;
break;
default:
paramType = GENERIC_CONTEXTPARAM_NONE;
assert(!"Unexpected generic context parameter type");
break;
}

gcInfoEncoder->SetSizeOfStackOutgoingAndScratchArea(0);

if (m_compHnd->getMethodAttribs(m_methodInfo->ftn) & CORINFO_FLG_SHAREDINST)
{
if ((m_methodInfo->options & CORINFO_GENERICS_CTXT_MASK) != CORINFO_GENERICS_CTXT_FROM_THIS)
{
assert(paramType != GENERIC_CONTEXTPARAM_NONE);

int32_t genericArgStackOffset = m_pVars[getParamArgIndex()].offset;
INTERP_DUMP("SetGenericsInstContextStackSlot at %u\n", (unsigned)genericArgStackOffset);
gcInfoEncoder->SetPrologSize(4); // Size of 1 instruction
gcInfoEncoder->SetStackBaseRegister(0);
gcInfoEncoder->SetGenericsInstContextStackSlot(genericArgStackOffset, paramType);
}
else
{
assert((paramType == GENERIC_CONTEXTPARAM_NONE));
}
}
else
{
assert((paramType == GENERIC_CONTEXTPARAM_NONE));
}

INTERP_DUMP("Allocating gcinfo slots for %u vars\n", m_varsSize);

for (int pass = 0; pass < 2; pass++)
Expand Down
57 changes: 57 additions & 0 deletions src/coreclr/vm/codeman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3358,6 +3358,63 @@ PTR_EXCEPTION_CLAUSE_TOKEN EECodeGenManager::GetNextEHClause(EH_CLAUSE_ENUMERATO
}

#ifndef DACCESS_COMPILE

#ifdef FEATURE_INTERPRETER
TypeHandle InterpreterJitManager::ResolveEHClause(EE_ILEXCEPTION_CLAUSE* pEHClause,
CrawlFrame *pCf)
{
// We don't want to use a runtime contract here since this codepath is used during
// the processing of a hard SO. Contracts use a significant amount of stack
// which we can't afford for those cases.
STATIC_CONTRACT_THROWS;
STATIC_CONTRACT_GC_TRIGGERS;

TypeHandle thResolved = EECodeGenManager::ResolveEHClause(pEHClause, pCf);

if (thResolved.IsSharedByGenericInstantiations())
{
_ASSERTE(!HasCachedTypeHandle(pEHClause));

GenericParamContextType paramContextType = pCf->GetCodeManager()->GetParamContextType(pCf->GetRegisterSet(), pCf->GetCodeInfo());
_ASSERTE(SafeToReportGenericParamContext(pCf));
if (SafeToReportGenericParamContext(pCf))
{
MethodDesc *pMD = pCf->GetFunction();
TypeHandle declaringType = (TypeHandle)pMD->GetMethodTable();

// Handle the case where the method is a static shared generic method and we need to keep the type
// of the generic parameters alive
if (paramContextType == GENERIC_PARAM_CONTEXT_METHODDESC)
{
pMD = dac_cast<PTR_MethodDesc>(pCf->GetParamTypeArg());
declaringType = (TypeHandle)pMD->GetMethodTable();
}
else if (paramContextType == GENERIC_PARAM_CONTEXT_METHODTABLE)
{
declaringType = (TypeHandle)dac_cast<PTR_MethodTable>(pCf->GetParamTypeArg());
}
else
{
_ASSERTE(paramContextType == GENERIC_PARAM_CONTEXT_THIS);
GCX_COOP();
declaringType = (TypeHandle)dac_cast<PTR_MethodTable>(pCf->GetExactGenericArgsToken());
}

_ASSERTE(!declaringType.IsNull());

SigTypeContext typeContext(pMD, declaringType);

Module* pModule = pMD->GetModule();

thResolved = ClassLoader::LoadTypeDefOrRefOrSpecThrowing(pModule, pEHClause->ClassToken, &typeContext,
ClassLoader::ReturnNullIfNotFound);
}
}

return thResolved;
}
#endif // FEATURE_INTERPRETER

TypeHandle EECodeGenManager::ResolveEHClause(EE_ILEXCEPTION_CLAUSE* pEHClause,
CrawlFrame *pCf)
{
Expand Down
7 changes: 7 additions & 0 deletions src/coreclr/vm/codeman.h
Original file line number Diff line number Diff line change
Expand Up @@ -2795,6 +2795,11 @@ class InterpreterJitManager final : public EECodeGenManager
OUT ICorDebugInfo::RichOffsetMapping** ppRichMappings,
OUT ULONG32* pNumRichMappings);

#ifndef DACCESS_COMPILE
virtual TypeHandle ResolveEHClause(EE_ILEXCEPTION_CLAUSE* pEHClause,
CrawlFrame *pCf);
#endif // #ifndef DACCESS_COMPILE

#if defined(FEATURE_EH_FUNCLETS)
virtual PTR_RUNTIME_FUNCTION LazyGetFunctionEntry(EECodeInfo * pCodeInfo)
{
Expand Down Expand Up @@ -3059,4 +3064,6 @@ inline TADDR InterpreterJitManager::JitTokenToStartAddress(const METHODTOKEN& Me

void ThrowOutOfMemoryWithinRange();

bool SafeToReportGenericParamContext(CrawlFrame* pCF);

#endif // !__CODEMAN_HPP__
35 changes: 30 additions & 5 deletions src/coreclr/vm/eetwain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2603,22 +2603,47 @@ bool InterpreterCodeManager::EnumGcRefs(PREGDISPLAY pContext,
OBJECTREF InterpreterCodeManager::GetInstance(PREGDISPLAY pContext,
EECodeInfo * pCodeInfo)
{
// Interpreter-TODO: Implement this
return NULL;
TADDR baseStackSlot = GetFP(pContext->pCurrentContext);
return *dac_cast<PTR_OBJECTREF>(baseStackSlot);
}

PTR_VOID InterpreterCodeManager::GetParamTypeArg(PREGDISPLAY pContext,
EECodeInfo * pCodeInfo)
{
// Interpreter-TODO: Implement this
LIMITED_METHOD_DAC_CONTRACT;

GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken();

InterpreterGcInfoDecoder gcInfoDecoder(
gcInfoToken,
GcInfoDecoderFlags (DECODE_GENERICS_INST_CONTEXT)
);

INT32 spOffsetGenericsContext = gcInfoDecoder.GetGenericsInstContextStackSlot();
if (spOffsetGenericsContext != NO_GENERICS_INST_CONTEXT)
{
TADDR baseStackSlot = GetFP(pContext->pCurrentContext);
TADDR taSlot = (TADDR)( spOffsetGenericsContext + baseStackSlot );
TADDR taExactGenericsToken = *PTR_TADDR(taSlot);
return PTR_VOID(taExactGenericsToken);
}
return NULL;
}

GenericParamContextType InterpreterCodeManager::GetParamContextType(PREGDISPLAY pContext,
EECodeInfo * pCodeInfo)
{
// Interpreter-TODO: Implement this
return GENERIC_PARAM_CONTEXT_NONE;
MethodDesc *pMD = pCodeInfo->GetMethodDesc();
GenericParamContextType paramContextType = GENERIC_PARAM_CONTEXT_NONE;

if (pMD->RequiresInstMethodDescArg())
paramContextType = GENERIC_PARAM_CONTEXT_METHODDESC;
else if (pMD->RequiresInstMethodTableArg())
paramContextType = GENERIC_PARAM_CONTEXT_METHODTABLE;
else if (pMD->AcquiresInstMethodTableFromThis())
paramContextType = GENERIC_PARAM_CONTEXT_THIS;

return paramContextType;
}

size_t InterpreterCodeManager::GetFunctionSize(GCInfoToken gcInfoToken)
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/vm/gcenv.ee.common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ unsigned FindFirstInterruptiblePoint(CrawlFrame* pCF, unsigned offs, unsigned en
// there's no context provided by the caller).
// See code:getMethodSigInternal
//
inline bool SafeToReportGenericParamContext(CrawlFrame* pCF)
bool SafeToReportGenericParamContext(CrawlFrame* pCF)
{
LIMITED_METHOD_CONTRACT;

Expand Down
Loading