Adding support to the following generic dictionary entry slots for R2R: (dotnet/corec...
authorFadi Hanna <fadim@microsoft.com>
Thu, 4 Aug 2016 19:51:18 +0000 (12:51 -0700)
committerGitHub <noreply@github.com>
Thu, 4 Aug 2016 19:51:18 +0000 (12:51 -0700)
DeclaringTypeHandleSlot
ConstrainedMethodEntrySlot

Commit migrated from https://github.com/dotnet/coreclr/commit/010f42a541f9d1e787774a538d9b923a506ea8f2

src/coreclr/src/inc/corcompile.h
src/coreclr/src/inc/corinfo.h
src/coreclr/src/inc/readytorun.h
src/coreclr/src/vm/genericdict.cpp
src/coreclr/src/vm/jitinterface.cpp
src/coreclr/src/vm/zapsig.cpp
src/coreclr/src/zap/zapimport.cpp
src/coreclr/src/zap/zapreadytorun.cpp

index 965de28..223f0f5 100644 (file)
@@ -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 */
index baae699..7302f4a 100644 (file)
@@ -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
index fbcfc22..9204862 100644 (file)
@@ -166,6 +166,7 @@ enum ReadyToRunFixupKind
     READYTORUN_FIXUP_Check_FieldOffset          = 0x2B,
 
     READYTORUN_FIXUP_DelegateCtor               = 0x2C, /* optimized delegate ctor */
+    READYTORUN_FIXUP_DeclaringTypeHandle        = 0x2D,
 };
 
 //
index 4aca9e1..c93e583 100644 (file)
@@ -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);
index 59172fe..b016d20 100644 (file)
@@ -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,
index c619610..4a9a8c0 100644 (file)
@@ -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
 
index 400ea78..47d0def 100644 (file)
@@ -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);
index 7a9a802..ea42a25 100644 (file)
@@ -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
 //