// 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
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)
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)
{
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);
};
// ********************* Please keep this up-to-date to ease adding more ***************
-// Highest packet number: 165
+// Highest packet number: 167
// *************************************************************************************
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
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
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
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
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
MTFLAG2_ENTRY(IsZapped),
MTFLAG2_ENTRY(IsPreRestored),
MTFLAG2_ENTRY(HasModuleDependencies),
+ MTFLAG2_ENTRY(IsIntrinsicType),
MTFLAG2_ENTRY(RequiresDispatchTokenFat),
MTFLAG2_ENTRY(HasCctor),
MTFLAG2_ENTRY(HasCCWTemplate),
#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 }
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////
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
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
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)
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,
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());
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;
{
// 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
{
}
// 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 {}
}
// 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 {}
}
if (pClass->IsSealed())
ret |= CORINFO_FLG_FINAL;
+
+ if (pMT->IsIntrinsicType())
+ ret |= CORINFO_FLG_INTRINSIC_TYPE;
}
return ret;
}
/*********************************************************************/
+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 {
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,
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()
{
enum_flag_HasModuleDependencies = 0x0080,
- // enum_Unused = 0x0100,
+ enum_flag_IsIntrinsicType = 0x0100,
enum_flag_RequiresDispatchTokenFat = 0x0200,
{
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
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);
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,