From ee743a7bd51a327b692a557759c37553ac4760e2 Mon Sep 17 00:00:00 2001 From: Fei Peng Date: Wed, 6 Dec 2017 20:01:18 -0800 Subject: [PATCH] new intrinsic type support (#15340) --- .../superpmi/superpmi-shared/icorjitinfoimpl.h | 4 + src/ToolBox/superpmi/superpmi-shared/lwmlist.h | 2 + .../superpmi/superpmi-shared/methodcontext.cpp | 107 +++++++++++++++++++++ .../superpmi/superpmi-shared/methodcontext.h | 14 ++- .../superpmi-shim-collector/icorjitinfo.cpp | 16 +++ .../superpmi/superpmi-shim-counter/icorjitinfo.cpp | 12 +++ .../superpmi/superpmi-shim-simple/icorjitinfo.cpp | 10 ++ src/ToolBox/superpmi/superpmi/icorjitinfo.cpp | 14 +++ src/debug/daccess/nidump.cpp | 1 + src/inc/corinfo.h | 27 ++++-- src/jit/ICorJitInfo_API_names.h | 2 + src/jit/ICorJitInfo_API_wrapper.hpp | 16 +++ src/jit/compiler.h | 15 +++ src/jit/simd.cpp | 8 ++ .../Runtime/CompilerServices/IntrinsicAttribute.cs | 3 +- .../src/System/Runtime/Intrinsics/Vector128.cs | 2 + .../src/System/Runtime/Intrinsics/Vector256.cs | 2 + src/vm/jitinterface.cpp | 58 +++++++++++ src/vm/jitinterface.h | 2 + src/vm/methodtable.h | 14 ++- src/vm/methodtablebuilder.cpp | 17 +++- src/zap/zapinfo.cpp | 10 ++ src/zap/zapinfo.h | 2 + 23 files changed, 348 insertions(+), 10 deletions(-) diff --git a/src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h b/src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h index 5c6dc4f..e0a5886 100644 --- a/src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h +++ b/src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h @@ -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 diff --git a/src/ToolBox/superpmi/superpmi-shared/lwmlist.h b/src/ToolBox/superpmi/superpmi-shared/lwmlist.h index b0cb7ad..467d28a 100644 --- a/src/ToolBox/superpmi/superpmi-shared/lwmlist.h +++ b/src/ToolBox/superpmi/superpmi-shared/lwmlist.h @@ -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) diff --git a/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp b/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp index 3a9f48f..581b228 100644 --- a/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp @@ -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(); + 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 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) { diff --git a/src/ToolBox/superpmi/superpmi-shared/methodcontext.h b/src/ToolBox/superpmi/superpmi-shared/methodcontext.h index 582a26f..1174f07 100644 --- a/src/ToolBox/superpmi/superpmi-shared/methodcontext.h +++ b/src/ToolBox/superpmi/superpmi-shared/methodcontext.h @@ -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 diff --git a/src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp index fe5f557..b6bc4fa 100644 --- a/src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -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 diff --git a/src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp b/src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp index a9e5761..91d6b33 100644 --- a/src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp +++ b/src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp @@ -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 diff --git a/src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp b/src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp index d7ca029..d23f727 100644 --- a/src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp +++ b/src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp @@ -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 diff --git a/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp b/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp index fc5677c..81ff74d 100644 --- a/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp +++ b/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp @@ -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 diff --git a/src/debug/daccess/nidump.cpp b/src/debug/daccess/nidump.cpp index f1ee6f1..b780405 100644 --- a/src/debug/daccess/nidump.cpp +++ b/src/debug/daccess/nidump.cpp @@ -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), diff --git a/src/inc/corinfo.h b/src/inc/corinfo.h index cd48999..264cde6 100644 --- a/src/inc/corinfo.h +++ b/src/inc/corinfo.h @@ -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 diff --git a/src/jit/ICorJitInfo_API_names.h b/src/jit/ICorJitInfo_API_names.h index 620e0dc..0a8117d 100644 --- a/src/jit/ICorJitInfo_API_names.h +++ b/src/jit/ICorJitInfo_API_names.h @@ -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) diff --git a/src/jit/ICorJitInfo_API_wrapper.hpp b/src/jit/ICorJitInfo_API_wrapper.hpp index 3ab72b9..f298ea9 100644 --- a/src/jit/ICorJitInfo_API_wrapper.hpp +++ b/src/jit/ICorJitInfo_API_wrapper.hpp @@ -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, diff --git a/src/jit/compiler.h b/src/jit/compiler.h index c4eaeb0..fbc52fa 100644 --- a/src/jit/compiler.h +++ b/src/jit/compiler.h @@ -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()); diff --git a/src/jit/simd.cpp b/src/jit/simd.cpp index 3b11043..3123555 100644 --- a/src/jit/simd.cpp +++ b/src/jit/simd.cpp @@ -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; diff --git a/src/mscorlib/shared/System/Runtime/CompilerServices/IntrinsicAttribute.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/IntrinsicAttribute.cs index dd01bac..381b4c6 100644 --- a/src/mscorlib/shared/System/Runtime/CompilerServices/IntrinsicAttribute.cs +++ b/src/mscorlib/shared/System/Runtime/CompilerServices/IntrinsicAttribute.cs @@ -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 { } diff --git a/src/mscorlib/src/System/Runtime/Intrinsics/Vector128.cs b/src/mscorlib/src/System/Runtime/Intrinsics/Vector128.cs index 8e32f1a..bfc1a2c 100644 --- a/src/mscorlib/src/System/Runtime/Intrinsics/Vector128.cs +++ b/src/mscorlib/src/System/Runtime/Intrinsics/Vector128.cs @@ -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 where T : struct {} } diff --git a/src/mscorlib/src/System/Runtime/Intrinsics/Vector256.cs b/src/mscorlib/src/System/Runtime/Intrinsics/Vector256.cs index ba1e11d..f7015bd 100644 --- a/src/mscorlib/src/System/Runtime/Intrinsics/Vector256.cs +++ b/src/mscorlib/src/System/Runtime/Intrinsics/Vector256.cs @@ -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 where T : struct {} } diff --git a/src/vm/jitinterface.cpp b/src/vm/jitinterface.cpp index 94abe3a..349700a 100644 --- a/src/vm/jitinterface.cpp +++ b/src/vm/jitinterface.cpp @@ -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 { diff --git a/src/vm/jitinterface.h b/src/vm/jitinterface.h index 4b52d98..71872d3 100644 --- a/src/vm/jitinterface.h +++ b/src/vm/jitinterface.h @@ -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, diff --git a/src/vm/methodtable.h b/src/vm/methodtable.h index e5fd7fa..c231173 100644 --- a/src/vm/methodtable.h +++ b/src/vm/methodtable.h @@ -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, diff --git a/src/vm/methodtablebuilder.cpp b/src/vm/methodtablebuilder.cpp index adcf7bb..f34f8f4 100644 --- a/src/vm/methodtablebuilder.cpp +++ b/src/vm/methodtablebuilder.cpp @@ -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 diff --git a/src/zap/zapinfo.cpp b/src/zap/zapinfo.cpp index f0e9d9e..215f4a7 100644 --- a/src/zap/zapinfo.cpp +++ b/src/zap/zapinfo.cpp @@ -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); diff --git a/src/zap/zapinfo.h b/src/zap/zapinfo.h index 1c73d4a..621ffbd 100644 --- a/src/zap/zapinfo.h +++ b/src/zap/zapinfo.h @@ -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, -- 2.7.4