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/zapimport.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/zapimport.cpp')
-rw-r--r-- | src/zap/zapimport.cpp | 69 |
1 files changed, 65 insertions, 4 deletions
diff --git a/src/zap/zapimport.cpp b/src/zap/zapimport.cpp index c0ea82743a..37226fcc41 100644 --- a/src/zap/zapimport.cpp +++ b/src/zap/zapimport.cpp @@ -1697,7 +1697,22 @@ public: CORCOMPILE_FIXUP_BLOB_KIND GetKind() { - return (CORCOMPILE_FIXUP_BLOB_KIND)(int)GetHandle(); + int kind = (int)GetHandle(); + + if ((kind & 1) == 1) + { + return (CORCOMPILE_FIXUP_BLOB_KIND)(kind >> 1); + } + else + { + _ASSERTE( + (GetBlob()->GetSize() > 0) && ( + GetBlob()->GetData()[0] == ENCODE_DICTIONARY_LOOKUP_THISOBJ || + GetBlob()->GetData()[0] == ENCODE_DICTIONARY_LOOKUP_METHOD || + GetBlob()->GetData()[0] == ENCODE_DICTIONARY_LOOKUP_TYPE)); + + return (CORCOMPILE_FIXUP_BLOB_KIND)GetBlob()->GetData()[0]; + } } virtual void EncodeSignature(ZapImportTable * pTable, SigBuilder * pSigBuilder) @@ -1728,6 +1743,9 @@ static ReadyToRunHelper GetDelayLoadHelperForDynamicHelper(CORCOMPILE_FIXUP_BLOB case ENCODE_THREAD_STATIC_BASE_GC_HELPER: case ENCODE_CCTOR_TRIGGER: case ENCODE_FIELD_ADDRESS: + case ENCODE_DICTIONARY_LOOKUP_THISOBJ: + case ENCODE_DICTIONARY_LOOKUP_TYPE: + case ENCODE_DICTIONARY_LOOKUP_METHOD: return READYTORUN_HELPER_DelayLoad_Helper; case ENCODE_CHKCAST_HELPER: @@ -1773,9 +1791,52 @@ void ZapImportSectionSignatures::PlaceDynamicHelperCell(ZapImport * pImport) m_pImage->GetImportTable()->PlaceImportBlob(pCell); } +ZapImport * ZapImportTable::GetDictionaryLookupCell(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_LOOKUP_KIND * pLookup) +{ + _ASSERTE(pLookup->needsRuntimeLookup); + + SigBuilder sigBuilder; + + sigBuilder.AppendData(kind & ~CORINFO_HELP_READYTORUN_ATYPICAL_CALLSITE); + + if ((kind & ~CORINFO_HELP_READYTORUN_ATYPICAL_CALLSITE) == ENCODE_DICTIONARY_LOOKUP_THISOBJ) + { + CORINFO_CLASS_HANDLE hClassContext = GetJitInfo()->getMethodClass(pResolvedToken->tokenContext); + GetCompileInfo()->EncodeClass(m_pImage->GetModuleHandle(), hClassContext, &sigBuilder, NULL, NULL); + } + + switch (pLookup->runtimeLookupFlags) + { + case READYTORUN_FIXUP_TypeHandle: + { + if (pResolvedToken->pTypeSpec == NULL) + { + _ASSERTE(!"Invalid IL that directly references __Canon"); + ThrowHR(E_NOTIMPL); + } + + sigBuilder.AppendData(ENCODE_TYPE_HANDLE); + if (pResolvedToken->tokenType == CORINFO_TOKENKIND_Newarr) + sigBuilder.AppendElementType(ELEMENT_TYPE_SZARRAY); + sigBuilder.AppendBlob((PVOID)pResolvedToken->pTypeSpec, pResolvedToken->cbTypeSpec); + } + break; + + // TODO: support for the rest of the dictionary signature kinds + + default: + _ASSERTE(!"Invalid R2R fixup kind!"); + ThrowHR(E_NOTIMPL); + } + + _ASSERTE(((DWORD)pResolvedToken->tokenContext & 1) == 0); + + return GetImportForSignature<ZapDynamicHelperCell, ZapNodeType_DynamicHelperCell>((void*)pResolvedToken->tokenContext, &sigBuilder); +} + ZapImport * ZapImportTable::GetDynamicHelperCell(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_CLASS_HANDLE handle) { - ZapImport * pImport = GetImport<ZapDynamicHelperCell, ZapNodeType_DynamicHelperCell>((void *)kind, handle); + ZapImport * pImport = GetImport<ZapDynamicHelperCell, ZapNodeType_DynamicHelperCell>((void *)(uintptr_t)((kind << 1) | 1), handle); if (!pImport->HasBlob()) { @@ -1805,7 +1866,7 @@ ZapImport * ZapImportTable::GetDynamicHelperCell(CORCOMPILE_FIXUP_BLOB_KIND kind GetCompileInfo()->EncodeClass(m_pImage->GetModuleHandle(), delegateType, &sigBuilder, NULL, NULL); } - return GetImportForSignature<ZapDynamicHelperCell, ZapNodeType_DynamicHelperCell>((void *)kind, &sigBuilder); + return GetImportForSignature<ZapDynamicHelperCell, ZapNodeType_DynamicHelperCell>((void *)(uintptr_t)((kind << 1) | 1), &sigBuilder); } ZapImport * ZapImportTable::GetDynamicHelperCell(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_FIELD_HANDLE handle, CORINFO_RESOLVED_TOKEN * pResolvedToken) @@ -1815,7 +1876,7 @@ ZapImport * ZapImportTable::GetDynamicHelperCell(CORCOMPILE_FIXUP_BLOB_KIND kind EncodeField((CORCOMPILE_FIXUP_BLOB_KIND)(kind & ~CORINFO_HELP_READYTORUN_ATYPICAL_CALLSITE), handle, &sigBuilder, pResolvedToken); - return GetImportForSignature<ZapDynamicHelperCell, ZapNodeType_DynamicHelperCell>((void *)kind, &sigBuilder); + return GetImportForSignature<ZapDynamicHelperCell, ZapNodeType_DynamicHelperCell>((void *)(uintptr_t)((kind << 1) | 1), &sigBuilder); } class ZapIndirectHelperThunk : public ZapImport |