diff options
author | Fadi Hanna <fadim@microsoft.com> | 2016-05-13 20:35:54 -0700 |
---|---|---|
committer | Fadi Hanna <fadim@microsoft.com> | 2016-05-13 20:35:54 -0700 |
commit | 97b4ff0b438261ba11b357008630076054a6f25d (patch) | |
tree | 320c32b25b556124cb354ab06a86c8f6ae806d98 /src/zap/zapinfo.cpp | |
parent | 5b065284dc57bc3a9eaee9f86b0df258b1d3d7af (diff) | |
download | coreclr-97b4ff0b438261ba11b357008630076054a6f25d.tar.gz coreclr-97b4ff0b438261ba11b357008630076054a6f25d.tar.bz2 coreclr-97b4ff0b438261ba11b357008630076054a6f25d.zip |
Initial implementation of generic dictionary access for R2R. (#4519)
For now, only TypeHandle dictionary entry slots are supported and encoded in a R2R version resilient format (the rest to come soon).
Support is only limited for x64 Windows platforms (rest is still TODO)
The basic idea: each dictionary access is initally a call to a DynamicHelper R2R cell that computes the dictionary signature, and patches the R2R cell address with an assembly stub that performs the dictionary lookup.
Diffstat (limited to 'src/zap/zapinfo.cpp')
-rw-r--r-- | src/zap/zapinfo.cpp | 118 |
1 files changed, 65 insertions, 53 deletions
diff --git a/src/zap/zapinfo.cpp b/src/zap/zapinfo.cpp index 79abbf7bc1..20b532fd07 100644 --- a/src/zap/zapinfo.cpp +++ b/src/zap/zapinfo.cpp @@ -1549,7 +1549,7 @@ CORINFO_METHOD_HANDLE ZapInfo::embedMethodHandle(CORINFO_METHOD_HANDLE handle, if (IsReadyToRunCompilation()) { - _ASSERTE(!"embedMethodHandle"); + // READYTORUN FUTURE: Handle this case correctly ThrowHR(E_NOTIMPL); } @@ -1597,7 +1597,8 @@ ZapInfo::embedGenericHandle(CORINFO_RESOLVED_TOKEN * pResolvedToken, if (pResult->lookup.lookupKind.needsRuntimeLookup) { - embedGenericSignature(&pResult->lookup); + if (!IsReadyToRunCompilation()) + embedGenericSignature(&pResult->lookup); if (pResult->handleType == CORINFO_HANDLETYPE_METHOD) { @@ -1681,7 +1682,7 @@ void ZapInfo::embedGenericSignature(CORINFO_LOOKUP * pLookup) if (IsReadyToRunCompilation()) { - m_zapper->Warning(W("ReadyToRun: embedGenericSignature not yet supported\n")); + UNREACHABLE_MSG("We should never get here for the ReadyToRun compilation."); ThrowHR(E_NOTIMPL); } @@ -2138,7 +2139,8 @@ void ZapInfo::getCallInfo(CORINFO_RESOLVED_TOKEN * pResolvedToken, { if (pResult->stubLookup.lookupKind.needsRuntimeLookup) { - embedGenericSignature(&pResult->stubLookup); + if (!IsReadyToRunCompilation()) + embedGenericSignature(&pResult->stubLookup); return; } @@ -2171,7 +2173,8 @@ void ZapInfo::getCallInfo(CORINFO_RESOLVED_TOKEN * pResolvedToken, case CORINFO_CALL_CODE_POINTER: _ASSERTE(pResult->codePointerLookup.lookupKind.needsRuntimeLookup); - embedGenericSignature(&pResult->codePointerLookup); + if (!IsReadyToRunCompilation()) + embedGenericSignature(&pResult->codePointerLookup); // There is no easy way to detect method referenced via generic lookups in generated code. // Report this method reference unconditionally. @@ -2212,23 +2215,15 @@ void ZapInfo::getCallInfo(CORINFO_RESOLVED_TOKEN * pResolvedToken, case CORINFO_VIRTUALCALL_LDVIRTFTN: #ifdef FEATURE_READYTORUN_COMPILER - if (IsReadyToRunCompilation()) + if (IsReadyToRunCompilation() && !pResult->exactContextNeedsRuntimeLookup) { - if ((pResult->classFlags & CORINFO_FLG_SHAREDINST) != 0 || - (pResult->methodFlags & CORINFO_FLG_SHAREDINST) != 0) - { - // READYTORUN: FUTURE: Generics - m_zapper->Warning(W("ReadyToRun: Generic dictionary lookup required\n")); - ThrowHR(E_NOTIMPL); - } - DWORD fAtypicalCallsite = (flags & CORINFO_CALLINFO_ATYPICAL_CALLSITE) ? CORINFO_HELP_READYTORUN_ATYPICAL_CALLSITE : 0; ZapImport * pImport = m_pImage->GetImportTable()->GetDynamicHelperCell( (CORCOMPILE_FIXUP_BLOB_KIND)(ENCODE_VIRTUAL_ENTRY | fAtypicalCallsite), pResult->hMethod, pResolvedToken); - pResult->codePointerLookup.constLookup.accessType = IAT_PVALUE; - pResult->codePointerLookup.constLookup.addr = pImport; + pResult->codePointerLookup.constLookup.accessType = IAT_PVALUE; + pResult->codePointerLookup.constLookup.addr = pImport; _ASSERTE(!pResult->sig.hasTypeArg()); } @@ -2248,9 +2243,10 @@ void ZapInfo::getCallInfo(CORINFO_RESOLVED_TOKEN * pResolvedToken, { if (pResult->exactContextNeedsRuntimeLookup) { - // READYTORUN: FUTURE: Generics - m_zapper->Warning(W("ReadyToRun: Generic dictionary lookup not yet supported\n")); - ThrowHR(E_NOTIMPL); + // Nothing to do... The generic handle lookup gets embedded in to the codegen + // during the jitting of the call. + // (Note: The generic lookup in R2R is performed by a call to a helper at runtime, not by + // codegen emitted at crossgen time) } else { @@ -3006,9 +3002,18 @@ void ZapInfo::getFieldInfo (CORINFO_RESOLVED_TOKEN * pResolvedToken, break; case CORINFO_FIELD_STATIC_GENERICS_STATIC_HELPER: - // READYTORUN: FUTURE: Generics - m_zapper->Warning(W("ReadyToRun: Shared generic static field access not yet supported\n")); - ThrowHR(E_NOTIMPL); + { + // Nothing to do... The generic handle lookup gets embedded in to the codegen + // during the jitting of the field lookup. + // (Note: The generic lookup in R2R is performed by a call to a helper at runtime, not by + // codegen emitted at crossgen time) + // TODO: replace the call to the generic lookup helper and the call to the static helper function + // with a single call to a R2R cell that performs: + // 1) Generic handle lookup + // 2) Computes the statics base address + // 3) Generates a stub for subsequent lookups that includes dictionary access + // (For perf reasons) + } break; case CORINFO_FIELD_STATIC_ADDRESS: // field at given address @@ -3354,6 +3359,9 @@ unsigned ZapInfo::getClassNumInstanceFields(CORINFO_CLASS_HANDLE cls) CorInfoHelpFunc ZapInfo::getNewHelper(CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_METHOD_HANDLE callerHandle) { + if (IsReadyToRunCompilation()) + return CORINFO_HELP_NEWFAST; + classMustBeLoadedBeforeCodeIsRun(pResolvedToken->hClass); return m_pEEJitInfo->getNewHelper(pResolvedToken, callerHandle); } @@ -3385,20 +3393,24 @@ CorInfoHelpFunc ZapInfo::getUnBoxHelper(CORINFO_CLASS_HANDLE cls) CorInfoHelpFunc ZapInfo::getCastingHelper(CORINFO_RESOLVED_TOKEN * pResolvedToken, bool fThrowing) { + if (IsReadyToRunCompilation()) + return (fThrowing ? CORINFO_HELP_CHKCASTANY : CORINFO_HELP_ISINSTANCEOFANY); + return m_pEEJitInfo->getCastingHelper(pResolvedToken, fThrowing); } CorInfoHelpFunc ZapInfo::getNewArrHelper(CORINFO_CLASS_HANDLE arrayCls) { + if (IsReadyToRunCompilation()) + return CORINFO_HELP_NEWARR_1_DIRECT; + return m_pEEJitInfo->getNewArrHelper(arrayCls); } -bool ZapInfo::getReadyToRunHelper( - CORINFO_RESOLVED_TOKEN * pResolvedToken, - CORINFO_LOOKUP_KIND * pGenericLookupKind, - CorInfoHelpFunc id, - CORINFO_CONST_LOOKUP * pLookup - ) +bool ZapInfo::getReadyToRunHelper(CORINFO_RESOLVED_TOKEN * pResolvedToken, + CORINFO_LOOKUP_KIND * pGenericLookupKind, + CorInfoHelpFunc id, + CORINFO_CONST_LOOKUP * pLookup) { #ifdef FEATURE_READYTORUN_COMPILER _ASSERTE(IsReadyToRunCompilation()); @@ -3412,55 +3424,35 @@ bool ZapInfo::getReadyToRunHelper( { case CORINFO_HELP_READYTORUN_NEW: if ((getClassAttribs(pResolvedToken->hClass) & CORINFO_FLG_SHAREDINST) != 0) - { - // READYTORUN: FUTURE: Generics - m_zapper->Warning(W("ReadyToRun: Generic dictionary lookup required\n")); - ThrowHR(E_NOTIMPL); - } + return false; // Requires runtime lookup. pImport = m_pImage->GetImportTable()->GetDynamicHelperCell( (CORCOMPILE_FIXUP_BLOB_KIND)(ENCODE_NEW_HELPER | fAtypicalCallsite), pResolvedToken->hClass); break; case CORINFO_HELP_READYTORUN_NEWARR_1: if ((getClassAttribs(pResolvedToken->hClass) & CORINFO_FLG_SHAREDINST) != 0) - { - // READYTORUN: FUTURE: Generics - m_zapper->Warning(W("ReadyToRun: Generic dictionary lookup required\n")); - ThrowHR(E_NOTIMPL); - } + return false; // Requires runtime lookup. pImport = m_pImage->GetImportTable()->GetDynamicHelperCell( (CORCOMPILE_FIXUP_BLOB_KIND)(ENCODE_NEW_ARRAY_HELPER | fAtypicalCallsite), pResolvedToken->hClass); break; case CORINFO_HELP_READYTORUN_ISINSTANCEOF: if ((getClassAttribs(pResolvedToken->hClass) & CORINFO_FLG_SHAREDINST) != 0) - { - // READYTORUN: FUTURE: Generics - m_zapper->Warning(W("ReadyToRun: Generic dictionary lookup required\n")); - ThrowHR(E_NOTIMPL); - } + return false; // Requires runtime lookup. pImport = m_pImage->GetImportTable()->GetDynamicHelperCell( (CORCOMPILE_FIXUP_BLOB_KIND)(ENCODE_ISINSTANCEOF_HELPER | fAtypicalCallsite), pResolvedToken->hClass); break; case CORINFO_HELP_READYTORUN_CHKCAST: if ((getClassAttribs(pResolvedToken->hClass) & CORINFO_FLG_SHAREDINST) != 0) - { - // READYTORUN: FUTURE: Generics - m_zapper->Warning(W("ReadyToRun: Generic dictionary lookup required\n")); - ThrowHR(E_NOTIMPL); - } + return false; // Requires runtime lookup. pImport = m_pImage->GetImportTable()->GetDynamicHelperCell( (CORCOMPILE_FIXUP_BLOB_KIND)(ENCODE_CHKCAST_HELPER | fAtypicalCallsite), pResolvedToken->hClass); break; case CORINFO_HELP_READYTORUN_STATIC_BASE: if ((getClassAttribs(pResolvedToken->hClass) & CORINFO_FLG_SHAREDINST) != 0) - { - // READYTORUN: FUTURE: Generics - m_zapper->Warning(W("ReadyToRun: Generic dictionary lookup required\n")); - ThrowHR(E_NOTIMPL); - } + return false; // Requires runtime lookup. if (m_pImage->GetCompileInfo()->IsInCurrentVersionBubble(m_pEEJitInfo->getClassModule(pResolvedToken->hClass))) { pImport = m_pImage->GetImportTable()->GetDynamicHelperCell( @@ -3474,6 +3466,26 @@ bool ZapInfo::getReadyToRunHelper( } break; + case CORINFO_HELP_READYTORUN_GENERIC_HANDLE: + _ASSERTE(pGenericLookupKind != NULL && pGenericLookupKind->needsRuntimeLookup); + if (pGenericLookupKind->runtimeLookupKind == CORINFO_LOOKUP_METHODPARAM) + { + pImport = m_pImage->GetImportTable()->GetDictionaryLookupCell( + (CORCOMPILE_FIXUP_BLOB_KIND)(ENCODE_DICTIONARY_LOOKUP_METHOD | fAtypicalCallsite), pResolvedToken, pGenericLookupKind); + } + else if (pGenericLookupKind->runtimeLookupKind == CORINFO_LOOKUP_THISOBJ) + { + pImport = m_pImage->GetImportTable()->GetDictionaryLookupCell( + (CORCOMPILE_FIXUP_BLOB_KIND)(ENCODE_DICTIONARY_LOOKUP_THISOBJ | fAtypicalCallsite), pResolvedToken, pGenericLookupKind); + } + else + { + _ASSERTE(pGenericLookupKind->runtimeLookupKind == CORINFO_LOOKUP_CLASSPARAM); + pImport = m_pImage->GetImportTable()->GetDictionaryLookupCell( + (CORCOMPILE_FIXUP_BLOB_KIND)(ENCODE_DICTIONARY_LOOKUP_TYPE | fAtypicalCallsite), pResolvedToken, pGenericLookupKind); + } + break; + default: _ASSERTE(false); ThrowHR(E_NOTIMPL); |