new intrinsic type support (#15340)
authorFei Peng <fei.peng@intel.com>
Thu, 7 Dec 2017 04:01:18 +0000 (20:01 -0800)
committerJan Kotas <jkotas@microsoft.com>
Thu, 7 Dec 2017 04:01:18 +0000 (23:01 -0500)
23 files changed:
src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h
src/ToolBox/superpmi/superpmi-shared/lwmlist.h
src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp
src/ToolBox/superpmi/superpmi-shared/methodcontext.h
src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp
src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp
src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp
src/ToolBox/superpmi/superpmi/icorjitinfo.cpp
src/debug/daccess/nidump.cpp
src/inc/corinfo.h
src/jit/ICorJitInfo_API_names.h
src/jit/ICorJitInfo_API_wrapper.hpp
src/jit/compiler.h
src/jit/simd.cpp
src/mscorlib/shared/System/Runtime/CompilerServices/IntrinsicAttribute.cs
src/mscorlib/src/System/Runtime/Intrinsics/Vector128.cs
src/mscorlib/src/System/Runtime/Intrinsics/Vector256.cs
src/vm/jitinterface.cpp
src/vm/jitinterface.h
src/vm/methodtable.h
src/vm/methodtablebuilder.cpp
src/zap/zapinfo.cpp
src/zap/zapinfo.h

index 5c6dc4f..e0a5886 100644 (file)
@@ -271,6 +271,10 @@ CorInfoType asCorInfoType(CORINFO_CLASS_HANDLE cls);
 // for completeness
 const char* getClassName(CORINFO_CLASS_HANDLE cls);
 
+const char* getClassNameFromMetadata(CORINFO_CLASS_HANDLE cls, const char** namespaceName);
+
+CORINFO_CLASS_HANDLE getTypeInstantiationArgument(CORINFO_CLASS_HANDLE cls, unsigned index);
+
 // Append a (possibly truncated) representation of the type cls to the preallocated buffer ppBuf of length pnBufLen
 // If fNamespace=TRUE, include the namespace/enclosing classes
 // If fFullInst=TRUE (regardless of fNamespace and fAssembly), include namespace and assembly for any type parameters
index b0cb7ad..467d28a 100644 (file)
@@ -68,6 +68,8 @@ LWM(GetClassDomainID, DWORDLONG, DLD)
 LWM(GetClassGClayout, DWORDLONG, Agnostic_GetClassGClayout)
 LWM(GetClassModuleIdForStatics, DWORDLONG, Agnostic_GetClassModuleIdForStatics)
 LWM(GetClassName, DWORDLONG, DWORD)
+LWM(GetClassNameFromMetadata, DLD, DD)
+LWM(GetTypeInstantiationArgument, DWORDLONG, DWORDLONG)
 LWM(GetClassNumInstanceFields, DWORDLONG, DWORD)
 LWM(GetClassSize, DWORDLONG, DWORD)
 LWM(GetCookieForPInvokeCalliSig, GetCookieForPInvokeCalliSigValue, DLDL)
index 3a9f48f..581b228 100644 (file)
@@ -5683,6 +5683,113 @@ const char* MethodContext::repGetClassName(CORINFO_CLASS_HANDLE cls)
     return name;
 }
 
+void MethodContext::recGetClassNameFromMetadata(CORINFO_CLASS_HANDLE cls,
+                                                char*               className,
+                                                const char**        namespaceName)
+{
+    if (GetClassNameFromMetadata == nullptr)
+        GetClassNameFromMetadata = new LightWeightMap<DLD, DD>();
+    DD value;
+    DLD key;
+    key.A = (DWORDLONG)cls;
+    key.B = (namespaceName != nullptr);
+
+    if (className != nullptr)
+        value.A = 
+            GetClassNameFromMetadata->AddBuffer((unsigned char*)className, (DWORD)strlen(className) + 1);
+    else
+        value.A = (DWORD)-1;
+
+    if ((namespaceName != nullptr) && (*namespaceName != nullptr))
+        value.B =
+            GetClassNameFromMetadata->AddBuffer((unsigned char*)*namespaceName, (DWORD)strlen(*namespaceName) + 1);
+    else
+        value.B = (DWORD)-1;
+
+    GetClassNameFromMetadata->Add(key, value);
+    DEBUG_REC(dmpGetClassNameFromMetadata(key, value));
+}
+
+void MethodContext::dmpGetClassNameFromMetadata(DLD key, DD value)
+{
+    unsigned char* className     = (unsigned char*)GetClassNameFromMetadata->GetBuffer(value.A);
+    unsigned char* namespaceName = (unsigned char*)GetClassNameFromMetadata->GetBuffer(value.B);
+    printf("GetClassNameFromMetadata key - classNonNull-%u namespaceNonNull-%u, value "
+           "class-'%s', namespace-'%s'",
+           key.A, key.B, className, namespaceName);
+    GetClassNameFromMetadata->Unlock();
+}
+
+const char* MethodContext::repGetClassNameFromMetadata(CORINFO_CLASS_HANDLE cls, const char** namespaceName)
+{
+    const char* result = nullptr;
+    DD         value;
+    DLD        key;
+    key.A = (DWORDLONG)cls;
+    key.B = (namespaceName != nullptr);
+
+    int itemIndex = -1;
+    if (GetClassNameFromMetadata != nullptr)
+        itemIndex = GetClassNameFromMetadata->GetIndex(key);
+    if (itemIndex < 0)
+    {
+        if (namespaceName != nullptr)
+        {
+            *namespaceName = nullptr;
+        }
+    }
+    else
+    {
+        value  = GetClassNameFromMetadata->Get(key);
+        result = (const char*)GetClassNameFromMetadata->GetBuffer(value.A);
+
+        if (namespaceName != nullptr)
+        {
+            *namespaceName = (const char*)GetClassNameFromMetadata->GetBuffer(value.B);
+        }
+    }
+    DEBUG_REP(dmpGetClassNameFromMetadata(key, value));
+    return result;
+}
+
+void MethodContext::recGetTypeInstantiationArgument(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE result, unsigned index)
+{
+    if (GetTypeInstantiationArgument == nullptr)
+        GetTypeInstantiationArgument = new LightWeightMap<DWORDLONG, DWORDLONG>();
+
+    DWORDLONG key = (DWORDLONG)cls;
+
+    GetTypeInstantiationArgument->Add(key, (DWORDLONG)result);
+    DEBUG_REC(dmpGetTypeInstantiationArgument(key, (DWORDLONG)result));
+}
+
+void MethodContext::dmpGetTypeInstantiationArgument(DWORDLONG key, DWORDLONG value)
+{
+    printf("GetTypeInstantiationArgument key - classNonNull-%u, value NonNull-%u", key, value);
+    GetTypeInstantiationArgument->Unlock();
+}
+
+
+CORINFO_CLASS_HANDLE MethodContext::repGetTypeInstantiationArgument(CORINFO_CLASS_HANDLE cls, unsigned index)
+{
+    CORINFO_CLASS_HANDLE result = nullptr;
+    DWORDLONG            value;
+    DWORDLONG            key;
+    key = (DWORDLONG)cls;
+
+    int itemIndex = -1;
+    if (GetTypeInstantiationArgument != nullptr)
+        itemIndex = GetTypeInstantiationArgument->GetIndex(key);
+    if (itemIndex >= 0)
+    {
+        value = GetTypeInstantiationArgument->Get(key);
+        result = (CORINFO_CLASS_HANDLE)value;
+    }
+    
+    DEBUG_REP(dmpGetTypeInstantiationArgument(key, value));
+    return result;
+}
+
 void MethodContext::recAppendClassName(
     CORINFO_CLASS_HANDLE cls, BOOL fNamespace, BOOL fFullInst, BOOL fAssembly, const WCHAR* result)
 {
index 582a26f..1174f07 100644 (file)
@@ -1222,6 +1222,16 @@ public:
     void dmpGetClassName(DWORDLONG key, DWORD value);
     const char* repGetClassName(CORINFO_CLASS_HANDLE cls);
 
+    void recGetClassNameFromMetadata(CORINFO_CLASS_HANDLE cls,
+                                     char*                className,
+                                     const char**         namespaceName);
+    void dmpGetClassNameFromMetadata(DLD key, DD value);
+    const char* repGetClassNameFromMetadata(CORINFO_CLASS_HANDLE cls, const char** namespaceName);
+
+    void recGetTypeInstantiationArgument(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE result, unsigned index);
+    void dmpGetTypeInstantiationArgument(DWORDLONG key, DWORDLONG value);
+    CORINFO_CLASS_HANDLE repGetTypeInstantiationArgument(CORINFO_CLASS_HANDLE cls, unsigned index);
+
     void recAppendClassName(
         CORINFO_CLASS_HANDLE cls, BOOL fNamespace, BOOL fFullInst, BOOL fAssembly, const WCHAR* result);
     void dmpAppendClassName(const Agnostic_AppendClassName& key, DWORD value);
@@ -1273,7 +1283,7 @@ private:
 };
 
 // ********************* Please keep this up-to-date to ease adding more ***************
-// Highest packet number: 165
+// Highest packet number: 167
 // *************************************************************************************
 enum mcPackets
 {
@@ -1337,6 +1347,8 @@ enum mcPackets
     Packet_GetClassGClayout                              = 43,
     Packet_GetClassModuleIdForStatics                    = 44,
     Packet_GetClassName                                  = 45,
+    Packet_GetClassNameFromMetadata                      = 166, // Added 12/4/17
+    Packet_GetTypeInstantiationArgument                  = 167, // Added 12/4/17
     Packet_GetClassNumInstanceFields                     = 46,
     Packet_GetClassSize                                  = 47,
     Packet_GetIntConfigValue                             = 151, // Added 2/12/2015
index fe5f557..b6bc4fa 100644 (file)
@@ -550,6 +550,22 @@ const char* interceptor_ICJI::getClassName(CORINFO_CLASS_HANDLE cls)
     return result;
 }
 
+const char* interceptor_ICJI::getClassNameFromMetadata(CORINFO_CLASS_HANDLE cls, const char** namespaceName)
+{
+    mc->cr->AddCall("getClassNameFromMetadata");
+    const char* temp = original_ICorJitInfo->getClassNameFromMetadata(cls, namespaceName);
+    mc->recGetClassNameFromMetadata(cls, (char*)temp, namespaceName);
+    return temp;
+}
+
+CORINFO_CLASS_HANDLE interceptor_ICJI::getTypeInstantiationArgument(CORINFO_CLASS_HANDLE cls, unsigned index)
+{
+    mc->cr->AddCall("getTypeInstantiationArgument");
+    CORINFO_CLASS_HANDLE temp = original_ICorJitInfo->getTypeInstantiationArgument(cls, index);
+    mc->recGetTypeInstantiationArgument(cls, temp, index);
+    return temp;
+}
+
 // Append a (possibly truncated) representation of the type cls to the preallocated buffer ppBuf of length pnBufLen
 // If fNamespace=TRUE, include the namespace/enclosing classes
 // If fFullInst=TRUE (regardless of fNamespace and fAssembly), include namespace and assembly for any type parameters
index a9e5761..91d6b33 100644 (file)
@@ -405,6 +405,18 @@ const char* interceptor_ICJI::getClassName(CORINFO_CLASS_HANDLE cls)
     return original_ICorJitInfo->getClassName(cls);
 }
 
+const char* interceptor_ICJI::getClassNameFromMetadata(CORINFO_CLASS_HANDLE cls, const char** namespaceName)
+{
+    mcs->AddCall("getClassNameFromMetadata");
+    return original_ICorJitInfo->getClassNameFromMetadata(cls, namespaceName);
+}
+
+CORINFO_CLASS_HANDLE interceptor_ICJI::getTypeInstantiationArgument(CORINFO_CLASS_HANDLE cls, unsigned index)
+{
+    mcs->AddCall("getTypeInstantiationArgument");
+    return original_ICorJitInfo->getTypeInstantiationArgument(cls, index);
+}
+
 // Append a (possibly truncated) representation of the type cls to the preallocated buffer ppBuf of length pnBufLen
 // If fNamespace=TRUE, include the namespace/enclosing classes
 // If fFullInst=TRUE (regardless of fNamespace and fAssembly), include namespace and assembly for any type parameters
index d7ca029..d23f727 100644 (file)
@@ -364,6 +364,16 @@ const char* interceptor_ICJI::getClassName(CORINFO_CLASS_HANDLE cls)
     return original_ICorJitInfo->getClassName(cls);
 }
 
+const char* interceptor_ICJI::getClassNameFromMetadata(CORINFO_CLASS_HANDLE cls, const char** namespaceName)
+{
+    return original_ICorJitInfo->getClassNameFromMetadata(cls, namespaceName);
+}
+
+CORINFO_CLASS_HANDLE interceptor_ICJI::getTypeInstantiationArgument(CORINFO_CLASS_HANDLE cls, unsigned index)
+{
+    return original_ICorJitInfo->getTypeInstantiationArgument(cls, index);
+}
+
 // Append a (possibly truncated) representation of the type cls to the preallocated buffer ppBuf of length pnBufLen
 // If fNamespace=TRUE, include the namespace/enclosing classes
 // If fFullInst=TRUE (regardless of fNamespace and fAssembly), include namespace and assembly for any type parameters
index fc5677c..81ff74d 100644 (file)
@@ -436,6 +436,20 @@ const char* MyICJI::getClassName(CORINFO_CLASS_HANDLE cls)
     return result;
 }
 
+const char* MyICJI::getClassNameFromMetadata(CORINFO_CLASS_HANDLE cls, const char** namespaceName)
+{
+    jitInstance->mc->cr->AddCall("getClassNameFromMetadata");
+    const char* result = jitInstance->mc->repGetClassNameFromMetadata(cls, namespaceName);
+    return result;
+}
+
+CORINFO_CLASS_HANDLE MyICJI::getTypeInstantiationArgument(CORINFO_CLASS_HANDLE cls, unsigned index)
+{
+    jitInstance->mc->cr->AddCall("getTypeInstantiationArgument");
+    CORINFO_CLASS_HANDLE result = jitInstance->mc->repGetTypeInstantiationArgument(cls, index);
+    return result;
+}
+
 // Append a (possibly truncated) representation of the type cls to the preallocated buffer ppBuf of length pnBufLen
 // If fNamespace=TRUE, include the namespace/enclosing classes
 // If fFullInst=TRUE (regardless of fNamespace and fAssembly), include namespace and assembly for any type parameters
index f1ee6f1..b780405 100644 (file)
@@ -5608,6 +5608,7 @@ NativeImageDumper::EnumMnemonics s_MTFlags2[] =
     MTFLAG2_ENTRY(IsZapped),
     MTFLAG2_ENTRY(IsPreRestored),
     MTFLAG2_ENTRY(HasModuleDependencies),
+    MTFLAG2_ENTRY(IsIntrinsicType),
     MTFLAG2_ENTRY(RequiresDispatchTokenFat),
     MTFLAG2_ENTRY(HasCctor),
     MTFLAG2_ENTRY(HasCCWTemplate),
index cd48999..264cde6 100644 (file)
@@ -213,11 +213,11 @@ TODO: Talk about initializing strutures before use
     #define SELECTANY extern __declspec(selectany)
 #endif
 
-SELECTANY const GUID JITEEVersionIdentifier = { /* b6af83a1-ca48-46c6-b7b0-5d7d6a79a5c5 */
-    0xb6af83a1,
-    0xca48,
-    0x46c6,
-    {0xb7, 0xb0, 0x5d, 0x7d, 0x6a, 0x79, 0xa5, 0xc5}
+SELECTANY const GUID JITEEVersionIdentifier = { /* EBEE9A84-63C3-4610-9E4F-05491D335D67 */
+    0xebee9a84, 
+    0x63c3, 
+    0x4610, 
+    { 0x9e, 0x4f, 0x5, 0x49, 0x1d, 0x33, 0x5d, 0x67 } 
 };
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -809,7 +809,7 @@ enum CorInfoFlag
     CORINFO_FLG_VIRTUAL               = 0x00000040,
 //  CORINFO_FLG_UNUSED                = 0x00000080,
     CORINFO_FLG_NATIVE                = 0x00000100,
-//  CORINFO_FLG_UNUSED                = 0x00000200,
+    CORINFO_FLG_INTRINSIC_TYPE        = 0x00000200, // This type is marked by [Intrinsic]
     CORINFO_FLG_ABSTRACT              = 0x00000400,
 
     CORINFO_FLG_EnC                   = 0x00000800, // member was added by Edit'n'Continue
@@ -2281,6 +2281,21 @@ public:
             CORINFO_CLASS_HANDLE    cls
             ) = 0;
 
+    // Return class name as in metadata, or nullptr if there is none.
+    // Suitable for non-debugging use.
+    virtual const char* getClassNameFromMetadata (
+            CORINFO_CLASS_HANDLE    cls,
+            const char            **namespaceName   /* OUT */
+            ) = 0;
+
+    // Return the type argument of the instantiated generic class,
+    // which is specified by the index
+    virtual CORINFO_CLASS_HANDLE getTypeInstantiationArgument(
+            CORINFO_CLASS_HANDLE cls, 
+            unsigned             index
+            ) = 0;
+    
+
     // Append a (possibly truncated) representation of the type cls to the preallocated buffer ppBuf of length pnBufLen
     // If fNamespace=TRUE, include the namespace/enclosing classes
     // If fFullInst=TRUE (regardless of fNamespace and fAssembly), include namespace and assembly for any type parameters
index 620e0dc..0a8117d 100644 (file)
@@ -37,6 +37,8 @@ DEF_CLR_API(isValidStringRef)
 DEF_CLR_API(shouldEnforceCallvirtRestriction)
 DEF_CLR_API(asCorInfoType)
 DEF_CLR_API(getClassName)
+DEF_CLR_API(getClassNameFromMetadata)
+DEF_CLR_API(getTypeInstantiationArgument)
 DEF_CLR_API(appendClassName)
 DEF_CLR_API(isValueClass)
 DEF_CLR_API(canInlineTypeCheckWithObjectVTable)
index 3ab72b9..f298ea9 100644 (file)
@@ -356,6 +356,22 @@ const char* WrapICorJitInfo::getClassName(CORINFO_CLASS_HANDLE    cls)
     return result;
 }
 
+const char* WrapICorJitInfo::getClassNameFromMetadata(CORINFO_CLASS_HANDLE cls, const char** namespaceName)
+{
+    API_ENTER(getClassNameFromMetadata);
+    const char* result = wrapHnd->getClassNameFromMetadata(cls, namespaceName);
+    API_LEAVE(getClassNameFromMetadata);
+    return result;
+}
+
+CORINFO_CLASS_HANDLE WrapICorJitInfo::getTypeInstantiationArgument(CORINFO_CLASS_HANDLE cls, unsigned index)
+{
+    API_ENTER(getTypeInstantiationArgument);
+    CORINFO_CLASS_HANDLE result = wrapHnd->getTypeInstantiationArgument(cls, index);
+    API_LEAVE(getTypeInstantiationArgument);
+    return result;
+}
+
 int WrapICorJitInfo::appendClassName(
             __deref_inout_ecount(*pnBufLen) WCHAR** ppBuf,
             int* pnBufLen,
index c4eaeb0..fbc52fa 100644 (file)
@@ -7503,6 +7503,21 @@ private:
         return info.compCompHnd->isInSIMDModule(clsHnd);
     }
 
+    bool isIntrinsicType(CORINFO_CLASS_HANDLE clsHnd)
+    {
+        return (info.compCompHnd->getClassAttribs(clsHnd) & CORINFO_FLG_INTRINSIC_TYPE) != 0;
+    }
+
+    const char* getClassNameFromMetadata(CORINFO_CLASS_HANDLE cls, const char** namespaceName)
+    {
+        return info.compCompHnd->getClassNameFromMetadata(cls, namespaceName);
+    }
+
+    CORINFO_CLASS_HANDLE getTypeInstantiationArgument(CORINFO_CLASS_HANDLE cls, unsigned index)
+    {
+        return info.compCompHnd->getTypeInstantiationArgument(cls, index);
+    }
+
     bool isSIMDClass(typeInfo* pTypeInfo)
     {
         return pTypeInfo->IsStruct() && isSIMDClass(pTypeInfo->GetClassHandleForValueClass());
index 3b11043..3123555 100644 (file)
@@ -129,6 +129,14 @@ var_types Compiler::getBaseTypeAndSizeOfSIMDType(CORINFO_CLASS_HANDLE typeHnd, u
         return TYP_UNKNOWN;
     }
 
+#if FEATURE_HW_INTRINSICS && DEBUG
+    if (isIntrinsicType(typeHnd))
+    {
+        JITDUMP("\nFound Vector Type: %s with base type %s\n", getClassNameFromMetadata(typeHnd, nullptr),
+                getClassNameFromMetadata(getTypeInstantiationArgument(typeHnd, 0), nullptr));
+    }
+#endif
+
     // fast path search using cached type handles of important types
     var_types simdBaseType = TYP_UNKNOWN;
     unsigned  size         = 0;
index dd01bac..381b4c6 100644 (file)
@@ -6,7 +6,8 @@ namespace System.Runtime.CompilerServices
 {
     // Calls to methods or references to fields marked with this attribute may be replaced at
     // some call sites with jit intrinsic expansions.
-    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Field, Inherited = false)]
+    // Types marked with this attribute may be specially treated by the rumtime/compiler.
+    [AttributeUsage(AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Field, Inherited = false)]
     internal sealed class IntrinsicAttribute : Attribute
     {
     }
index 8e32f1a..bfc1a2c 100644 (file)
@@ -2,10 +2,12 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
+using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 
 namespace System.Runtime.Intrinsics
 {
+    [Intrinsic]
     [StructLayout(LayoutKind.Sequential, Size = 16)]
     public struct Vector128<T> where T : struct {}
 }
index ba1e11d..f7015bd 100644 (file)
@@ -2,10 +2,12 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
+using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 
 namespace System.Runtime.Intrinsics
 {
+    [Intrinsic]
     [StructLayout(LayoutKind.Sequential, Size = 32)]
     public struct Vector256<T> where T : struct {}
 }
index 94abe3a..349700a 100644 (file)
@@ -4029,6 +4029,9 @@ DWORD CEEInfo::getClassAttribsInternal (CORINFO_CLASS_HANDLE clsHnd)
 
         if (pClass->IsSealed())
             ret |= CORINFO_FLG_FINAL;
+
+        if (pMT->IsIntrinsicType())
+            ret |= CORINFO_FLG_INTRINSIC_TYPE;
     }
 
     return ret;
@@ -6641,6 +6644,61 @@ const char* CEEInfo::getMethodNameFromMetadata(CORINFO_METHOD_HANDLE ftnHnd, con
 }
 
 /*********************************************************************/
+const char* CEEInfo::getClassNameFromMetadata(CORINFO_CLASS_HANDLE cls, const char** namespaceName)
+{
+    CONTRACTL {
+        SO_TOLERANT;
+        THROWS;
+        GC_TRIGGERS;
+        MODE_PREEMPTIVE;
+    } CONTRACTL_END;
+
+    const char* result = NULL;
+    const char* namespaceResult = NULL;
+
+    JIT_TO_EE_TRANSITION();
+    TypeHandle VMClsHnd(cls);
+
+    if (!VMClsHnd.IsTypeDesc())
+    {
+        result = VMClsHnd.AsMethodTable()->GetFullyQualifiedNameInfo(&namespaceResult);
+    }
+   
+    if (namespaceName != NULL)
+    {
+        *namespaceName = namespaceResult;
+    }
+
+    EE_TO_JIT_TRANSITION();
+    
+    return result;
+}
+
+/*********************************************************************/
+CORINFO_CLASS_HANDLE CEEInfo::getTypeInstantiationArgument(CORINFO_CLASS_HANDLE cls, unsigned index)
+{
+    CONTRACTL {
+        SO_TOLERANT;
+        THROWS;
+        GC_TRIGGERS;
+        MODE_PREEMPTIVE;
+    } CONTRACTL_END;
+
+    CORINFO_CLASS_HANDLE result = NULL;
+
+    JIT_TO_EE_TRANSITION_LEAF();
+
+    TypeHandle VMClsHnd(cls);
+    Instantiation inst = VMClsHnd.GetInstantiation();
+    TypeHandle typeArg = index < inst.GetNumArgs() ? inst[index] : NULL;
+    result = CORINFO_CLASS_HANDLE(typeArg.AsPtr());
+
+    EE_TO_JIT_TRANSITION_LEAF();
+    
+    return result;
+}
+
+/*********************************************************************/
 DWORD CEEInfo::getMethodAttribs (CORINFO_METHOD_HANDLE ftn)
 {
     CONTRACTL {
index 4b52d98..71872d3 100644 (file)
@@ -464,6 +464,8 @@ public:
     void LongLifetimeFree(void* obj);
     size_t getClassModuleIdForStatics(CORINFO_CLASS_HANDLE clsHnd, CORINFO_MODULE_HANDLE *pModuleHandle, void **ppIndirection);
     const char* getClassName (CORINFO_CLASS_HANDLE cls);
+    const char* getClassNameFromMetadata (CORINFO_CLASS_HANDLE cls, const char** namespaceName);
+    CORINFO_CLASS_HANDLE getTypeInstantiationArgument(CORINFO_CLASS_HANDLE cls, unsigned index);
     const char* getHelperName(CorInfoHelpFunc ftnNum);
     int appendClassName(__deref_inout_ecount(*pnBufLen) WCHAR** ppBuf,
                                   int* pnBufLen,
index e5fd7fa..c231173 100644 (file)
@@ -1398,6 +1398,18 @@ public:
         SetFlag(enum_flag_HasModuleDependencies);
     }
 
+    inline BOOL IsIntrinsicType()
+    {
+        LIMITED_METHOD_DAC_CONTRACT;;
+        return GetFlag(enum_flag_IsIntrinsicType);
+    }
+
+    inline void SetIsIntrinsicType()
+    {
+        LIMITED_METHOD_DAC_CONTRACT;;
+        SetFlag(enum_flag_IsIntrinsicType);
+    }
+
     // See the comment in code:MethodTable.DoFullyLoad for detailed description.
     inline BOOL DependsOnEquivalentOrForwardedStructs()
     {
@@ -4003,7 +4015,7 @@ private:
 
         enum_flag_HasModuleDependencies     = 0x0080,
 
-        // enum_Unused                      = 0x0100,
+        enum_flag_IsIntrinsicType           = 0x0100,
 
         enum_flag_RequiresDispatchTokenFat  = 0x0200,
 
index adcf7bb..f34f8f4 100644 (file)
@@ -2006,7 +2006,22 @@ MethodTableBuilder::BuildMethodTableThrowing(
     {
         pMT->SetICastable();
     }
-#endif // FEATURE_ICASTABLE            
+#endif // FEATURE_ICASTABLE       
+    // If this type is marked by [Intrinsic] attribute, it may be specially treated by the runtime/compiler
+    // Currently, only SIMD types have [Intrinsic] attribute
+    if ((GetModule()->IsSystem() || GetAssembly()->IsSIMDVectorAssembly()) && IsValueClass() && bmtGenerics->HasInstantiation())
+    {
+        HRESULT hr = GetMDImport()->GetCustomAttributeByName(bmtInternal->pType->GetTypeDefToken(), 
+            g_CompilerServicesIntrinsicAttribute, 
+            NULL, 
+            NULL);
+
+        if (hr == S_OK)
+        {
+            pMT->SetIsIntrinsicType();
+        }
+    }
 
     // Grow the typedef ridmap in advance as we can't afford to
     // fail once we set the resolve bit
index f0e9d9e..215f4a7 100644 (file)
@@ -3024,6 +3024,16 @@ const char* ZapInfo::getClassName(CORINFO_CLASS_HANDLE cls)
     return m_pEEJitInfo->getClassName(cls);
 }
 
+const char* ZapInfo::getClassNameFromMetadata(CORINFO_CLASS_HANDLE cls, const char** namespaceName)
+{
+    return m_pEEJitInfo->getClassNameFromMetadata(cls, namespaceName);
+}
+
+CORINFO_CLASS_HANDLE ZapInfo::getTypeInstantiationArgument(CORINFO_CLASS_HANDLE cls, unsigned index)
+{
+    return m_pEEJitInfo->getTypeInstantiationArgument(cls, index);
+}
+
 const char* ZapInfo::getHelperName(CorInfoHelpFunc func)
 {
     return m_pEEJitInfo->getHelperName(func);
index 1c73d4a..621ffbd 100644 (file)
@@ -505,6 +505,8 @@ public:
 
     CorInfoType asCorInfoType(CORINFO_CLASS_HANDLE cls);
     const char* getClassName(CORINFO_CLASS_HANDLE cls);
+    const char* getClassNameFromMetadata(CORINFO_CLASS_HANDLE cls, const char** namespaceName);
+    CORINFO_CLASS_HANDLE getTypeInstantiationArgument(CORINFO_CLASS_HANDLE cls, unsigned index);
     const char* getHelperName(CorInfoHelpFunc ftnNum);
     int appendClassName(__deref_inout_ecount(*pnBufLen) WCHAR** ppBuf, int* pnBufLen,
                                   CORINFO_CLASS_HANDLE    cls,