From 99153528e68e3f186ff4297a0faaf327d76e1300 Mon Sep 17 00:00:00 2001 From: Fadi Hanna Date: Thu, 4 Aug 2016 12:51:18 -0700 Subject: [PATCH] Adding support to the following generic dictionary entry slots for R2R: (dotnet/coreclr#6291) DeclaringTypeHandleSlot ConstrainedMethodEntrySlot Commit migrated from https://github.com/dotnet/coreclr/commit/010f42a541f9d1e787774a538d9b923a506ea8f2 --- src/coreclr/src/inc/corcompile.h | 1 + src/coreclr/src/inc/corinfo.h | 5 +++-- src/coreclr/src/inc/readytorun.h | 1 + src/coreclr/src/vm/genericdict.cpp | 34 +++++++++++++++++++++------------- src/coreclr/src/vm/jitinterface.cpp | 25 ++++++++++++------------- src/coreclr/src/vm/zapsig.cpp | 12 ++++++++++-- src/coreclr/src/zap/zapimport.cpp | 17 +++++++++++++---- src/coreclr/src/zap/zapreadytorun.cpp | 2 ++ 8 files changed, 63 insertions(+), 34 deletions(-) diff --git a/src/coreclr/src/inc/corcompile.h b/src/coreclr/src/inc/corcompile.h index 965de28..223f0f5 100644 --- a/src/coreclr/src/inc/corcompile.h +++ b/src/coreclr/src/inc/corcompile.h @@ -732,6 +732,7 @@ enum CORCOMPILE_FIXUP_BLOB_KIND ENCODE_DELEGATE_CTOR, + ENCODE_DECLARINGTYPE_HANDLE, ENCODE_MODULE_HANDLE = 0x50, /* Module token */ ENCODE_STATIC_FIELD_ADDRESS, /* For accessing a static field */ diff --git a/src/coreclr/src/inc/corinfo.h b/src/coreclr/src/inc/corinfo.h index baae699..7302f4a 100644 --- a/src/coreclr/src/inc/corinfo.h +++ b/src/coreclr/src/inc/corinfo.h @@ -1311,9 +1311,10 @@ struct CORINFO_LOOKUP_KIND bool needsRuntimeLookup; CORINFO_RUNTIME_LOOKUP_KIND runtimeLookupKind; - // The 'runtimeLookupFlags' field is just for internal VM / ZAP communication, - // not to be used by the JIT. + // The 'runtimeLookupFlags' and 'runtimeLookupArgs' fields + // are just for internal VM / ZAP communication, not to be used by the JIT. WORD runtimeLookupFlags; + void * runtimeLookupArgs; } ; #else diff --git a/src/coreclr/src/inc/readytorun.h b/src/coreclr/src/inc/readytorun.h index fbcfc22..9204862 100644 --- a/src/coreclr/src/inc/readytorun.h +++ b/src/coreclr/src/inc/readytorun.h @@ -166,6 +166,7 @@ enum ReadyToRunFixupKind READYTORUN_FIXUP_Check_FieldOffset = 0x2B, READYTORUN_FIXUP_DelegateCtor = 0x2C, /* optimized delegate ctor */ + READYTORUN_FIXUP_DeclaringTypeHandle = 0x2D, }; // diff --git a/src/coreclr/src/vm/genericdict.cpp b/src/coreclr/src/vm/genericdict.cpp index 4aca9e1..c93e583 100644 --- a/src/coreclr/src/vm/genericdict.cpp +++ b/src/coreclr/src/vm/genericdict.cpp @@ -689,11 +689,12 @@ Dictionary::PopulateEntry( CORCOMPILE_FIXUP_BLOB_KIND signatureKind = (CORCOMPILE_FIXUP_BLOB_KIND)CorSigUncompressData(pBlob); switch (signatureKind) { - case ENCODE_TYPE_HANDLE: kind = TypeHandleSlot; break; - case ENCODE_FIELD_HANDLE: kind = FieldDescSlot; break; - case ENCODE_METHOD_HANDLE: kind = MethodDescSlot; break; - case ENCODE_METHOD_ENTRY: kind = MethodEntrySlot; break; - case ENCODE_VIRTUAL_ENTRY: kind = DispatchStubAddrSlot; break; + case ENCODE_DECLARINGTYPE_HANDLE: kind = DeclaringTypeHandleSlot; break; + case ENCODE_TYPE_HANDLE: kind = TypeHandleSlot; break; + case ENCODE_FIELD_HANDLE: kind = FieldDescSlot; break; + case ENCODE_METHOD_HANDLE: kind = MethodDescSlot; break; + case ENCODE_METHOD_ENTRY: kind = MethodEntrySlot; break; + case ENCODE_VIRTUAL_ENTRY: kind = DispatchStubAddrSlot; break; default: _ASSERTE(!"Unexpected CORCOMPILE_FIXUP_BLOB_KIND"); @@ -856,6 +857,9 @@ Dictionary::PopulateEntry( { IfFailThrow(ptr.GetData(&methodFlags)); + if (methodFlags & ENCODE_METHOD_SIG_Constrained) + kind = ConstrainedMethodEntrySlot; + isInstantiatingStub = ((methodFlags & ENCODE_METHOD_SIG_InstantiatingStub) != 0) || (kind == MethodEntrySlot); isUnboxingStub = ((methodFlags & ENCODE_METHOD_SIG_UnboxingStub) != 0); fMethodNeedsInstantiation = ((methodFlags & ENCODE_METHOD_SIG_MethodInstantiation) != 0); @@ -916,12 +920,6 @@ Dictionary::PopulateEntry( _ASSERT(!ownerType.IsNull() && !nonExpansive); pOwnerMT = ownerType.GetMethodTable(); - if (methodFlags & ENCODE_METHOD_SIG_Constrained) - { - _ASSERTE(!"ReadyToRun: Constrained methods dictionary entries not yet supported."); - ThrowHR(COR_E_BADIMAGEFORMAT); - } - if (kind == DispatchStubAddrSlot && pMethod->IsVtableMethod()) { fRequiresDispatchStub = TRUE; @@ -1087,9 +1085,19 @@ Dictionary::PopulateEntry( if (kind == ConstrainedMethodEntrySlot) { - // TODO: READYTORUN: Support for constrained method entry slots - _ASSERT(!isReadyToRunModule); + if (isReadyToRunModule) + { + _ASSERTE((methodFlags & ENCODE_METHOD_SIG_Constrained) == ENCODE_METHOD_SIG_Constrained); + constraintType = ptr.GetTypeHandleThrowing( + pZapSigContext->pInfoModule, + &typeContext, + ClassLoader::LoadTypes, + CLASS_LOADED, + FALSE, + NULL, + pZapSigContext); + } _ASSERTE(!constraintType.IsNull()); MethodDesc *pResolvedMD = constraintType.GetMethodTable()->TryResolveConstraintMethodApprox(ownerType, pMethod); diff --git a/src/coreclr/src/vm/jitinterface.cpp b/src/coreclr/src/vm/jitinterface.cpp index 59172fe..b016d20 100644 --- a/src/coreclr/src/vm/jitinterface.cpp +++ b/src/coreclr/src/vm/jitinterface.cpp @@ -3134,28 +3134,37 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr #if defined(_TARGET_ARM_) ThrowHR(E_NOTIMPL); /* TODO - NYI */ #endif + pResultLookup->lookupKind.runtimeLookupArgs = NULL; + switch (entryKind) { + case DeclaringTypeHandleSlot: + _ASSERTE(pTemplateMD != NULL); + pResultLookup->lookupKind.runtimeLookupArgs = pTemplateMD->GetMethodTable(); + pResultLookup->lookupKind.runtimeLookupFlags = READYTORUN_FIXUP_DeclaringTypeHandle; + break; + case TypeHandleSlot: pResultLookup->lookupKind.runtimeLookupFlags = READYTORUN_FIXUP_TypeHandle; break; case MethodDescSlot: case MethodEntrySlot: + case ConstrainedMethodEntrySlot: case DispatchStubAddrSlot: { if (pTemplateMD != (MethodDesc*)pResolvedToken->hMethod) ThrowHR(E_NOTIMPL); - if (((MethodDesc*)pResolvedToken->hMethod)->GetMethodTable_NoLogging() != (MethodTable*)pResolvedToken->hClass) - ThrowHR(E_NOTIMPL); if (entryKind == MethodDescSlot) pResultLookup->lookupKind.runtimeLookupFlags = READYTORUN_FIXUP_MethodHandle; - else if (entryKind == MethodEntrySlot) + else if (entryKind == MethodEntrySlot || entryKind == ConstrainedMethodEntrySlot) pResultLookup->lookupKind.runtimeLookupFlags = READYTORUN_FIXUP_MethodEntry; else pResultLookup->lookupKind.runtimeLookupFlags = READYTORUN_FIXUP_VirtualEntry; + pResultLookup->lookupKind.runtimeLookupArgs = pConstrainedResolvedToken; + break; } @@ -3163,10 +3172,6 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr pResultLookup->lookupKind.runtimeLookupFlags = READYTORUN_FIXUP_FieldHandle; break; - case DeclaringTypeHandleSlot: - case ConstrainedMethodEntrySlot: - ThrowHR(E_NOTIMPL); - default: _ASSERTE(!"Unknown dictionary entry kind!"); IfFailThrow(E_FAIL); @@ -5283,12 +5288,6 @@ void CEEInfo::getCallInfo( // For reference types, the constrained type does not affect method resolution DictionaryEntryKind entryKind = (!constrainedType.IsNull() && constrainedType.IsValueType()) ? ConstrainedMethodEntrySlot : MethodEntrySlot; - if (IsReadyToRunCompilation() && pConstrainedResolvedToken != NULL) - { - // READYTORUN: FUTURE: Constrained generic calls - ThrowHR(E_NOTIMPL); - } - ComputeRuntimeLookupForSharedGenericToken(entryKind, pResolvedToken, pConstrainedResolvedToken, diff --git a/src/coreclr/src/vm/zapsig.cpp b/src/coreclr/src/vm/zapsig.cpp index c619610..4a9a8c0 100644 --- a/src/coreclr/src/vm/zapsig.cpp +++ b/src/coreclr/src/vm/zapsig.cpp @@ -1368,8 +1368,16 @@ BOOL ZapSig::EncodeMethod( #ifdef FEATURE_READYTORUN_COMPILER if ((methodFlags & ENCODE_METHOD_SIG_Constrained) != 0) { - if (!zapSig.GetSignatureForTypeHandle(TypeHandle(pConstrainedResolvedToken->hClass), pSigBuilder)) - return FALSE; + if (fEncodeUsingResolvedTokenSpecStreams && pConstrainedResolvedToken->pTypeSpec != NULL) + { + _ASSERTE(pConstrainedResolvedToken->cbTypeSpec > 0); + pSigBuilder->AppendBlob((PVOID)pConstrainedResolvedToken->pTypeSpec, pConstrainedResolvedToken->cbTypeSpec); + } + else + { + if (!zapSig.GetSignatureForTypeHandle(TypeHandle(pConstrainedResolvedToken->hClass), pSigBuilder)) + return FALSE; + } } #endif diff --git a/src/coreclr/src/zap/zapimport.cpp b/src/coreclr/src/zap/zapimport.cpp index 400ea78..47d0def 100644 --- a/src/coreclr/src/zap/zapimport.cpp +++ b/src/coreclr/src/zap/zapimport.cpp @@ -1808,6 +1808,7 @@ ZapImport * ZapImportTable::GetDictionaryLookupCell(CORCOMPILE_FIXUP_BLOB_KIND k switch (pLookup->runtimeLookupFlags) { case READYTORUN_FIXUP_TypeHandle: + case READYTORUN_FIXUP_DeclaringTypeHandle: { if (pResolvedToken->pTypeSpec == NULL) { @@ -1815,7 +1816,17 @@ ZapImport * ZapImportTable::GetDictionaryLookupCell(CORCOMPILE_FIXUP_BLOB_KIND k ThrowHR(E_NOTIMPL); } - sigBuilder.AppendData(ENCODE_TYPE_HANDLE); + if (pLookup->runtimeLookupFlags == READYTORUN_FIXUP_DeclaringTypeHandle) + { + _ASSERTE(pLookup->runtimeLookupArgs != NULL); + sigBuilder.AppendData(ENCODE_DECLARINGTYPE_HANDLE); + GetCompileInfo()->EncodeClass(m_pImage->GetModuleHandle(), (CORINFO_CLASS_HANDLE)pLookup->runtimeLookupArgs, &sigBuilder, NULL, NULL); + } + else + { + sigBuilder.AppendData(ENCODE_TYPE_HANDLE); + } + if (pResolvedToken->tokenType == CORINFO_TOKENKIND_Newarr) sigBuilder.AppendElementType(ELEMENT_TYPE_SZARRAY); sigBuilder.AppendBlob((PVOID)pResolvedToken->pTypeSpec, pResolvedToken->cbTypeSpec); @@ -1827,7 +1838,7 @@ ZapImport * ZapImportTable::GetDictionaryLookupCell(CORCOMPILE_FIXUP_BLOB_KIND k break; case READYTORUN_FIXUP_MethodEntry: - EncodeMethod(ENCODE_METHOD_ENTRY, pResolvedToken->hMethod, &sigBuilder, pResolvedToken, NULL, TRUE); + EncodeMethod(ENCODE_METHOD_ENTRY, pResolvedToken->hMethod, &sigBuilder, pResolvedToken, (CORINFO_RESOLVED_TOKEN*)pLookup->runtimeLookupArgs, TRUE); break; case READYTORUN_FIXUP_VirtualEntry: @@ -1838,8 +1849,6 @@ ZapImport * ZapImportTable::GetDictionaryLookupCell(CORCOMPILE_FIXUP_BLOB_KIND k EncodeField(ENCODE_FIELD_HANDLE, pResolvedToken->hField, &sigBuilder, pResolvedToken, TRUE); break; - // TODO: support for the rest of the dictionary signature kinds - default: _ASSERTE(!"Invalid R2R fixup kind!"); ThrowHR(E_NOTIMPL); diff --git a/src/coreclr/src/zap/zapreadytorun.cpp b/src/coreclr/src/zap/zapreadytorun.cpp index 7a9a802..ea42a25 100644 --- a/src/coreclr/src/zap/zapreadytorun.cpp +++ b/src/coreclr/src/zap/zapreadytorun.cpp @@ -515,6 +515,8 @@ static_assert_no_msg((int)READYTORUN_FIXUP_Check_FieldOffset == (int)ENC static_assert_no_msg((int)READYTORUN_FIXUP_DelegateCtor == (int)ENCODE_DELEGATE_CTOR); +static_assert_no_msg((int)READYTORUN_FIXUP_DeclaringTypeHandle == (int)ENCODE_DECLARINGTYPE_HANDLE); + // // READYTORUN_EXCEPTION // -- 2.7.4