diff options
-rw-r--r-- | src/vm/class.cpp | 14 | ||||
-rw-r--r-- | src/vm/methodtable.cpp | 37 | ||||
-rw-r--r-- | src/vm/methodtablebuilder.cpp | 33 |
3 files changed, 69 insertions, 15 deletions
diff --git a/src/vm/class.cpp b/src/vm/class.cpp index 99156ffb59..1bbf9b674b 100644 --- a/src/vm/class.cpp +++ b/src/vm/class.cpp @@ -1722,6 +1722,20 @@ EEClass::CheckForHFA() if (HasExplicitFieldOffsetLayout()) return false; + // The SIMD Intrinsic types are meant to be handled specially and should not be treated as HFA + if (GetMethodTable()->IsIntrinsicType()) + { + LPCUTF8 namespaceName; + LPCUTF8 className = GetMethodTable()->GetFullyQualifiedNameInfo(&namespaceName); + + if ((strcmp(className, "Vector256`1") == 0) || (strcmp(className, "Vector128`1") == 0) || + (strcmp(className, "Vector64`1") == 0)) + { + assert(strcmp(namespaceName, "System.Runtime.Intrinsics") == 0); + return false; + } + } + CorElementType hfaType = ELEMENT_TYPE_END; FieldDesc *pFieldDescList = GetFieldDescList(); diff --git a/src/vm/methodtable.cpp b/src/vm/methodtable.cpp index 24c69cfb01..76d490d251 100644 --- a/src/vm/methodtable.cpp +++ b/src/vm/methodtable.cpp @@ -2340,6 +2340,25 @@ bool MethodTable::ClassifyEightBytesWithManagedLayout(SystemVStructRegisterPassi nestingLevel * 5, "", this->GetDebugClassName())); return false; } + + // The SIMD Intrinsic types are meant to be handled specially and should not be passed as struct registers + if (IsIntrinsicType()) + { + LPCUTF8 namespaceName; + LPCUTF8 className = GetFullyQualifiedNameInfo(&namespaceName); + + if ((strcmp(className, "Vector256`1") == 0) || (strcmp(className, "Vector128`1") == 0) || + (strcmp(className, "Vector64`1") == 0)) + { + assert(strcmp(namespaceName, "System.Runtime.Intrinsics") == 0); + + LOG((LF_JIT, LL_EVERYTHING, "%*s**** ClassifyEightBytesWithManagedLayout: struct %s is a SIMD intrinsic type; will not be enregistered\n", + nestingLevel * 5, "", this->GetDebugClassName())); + + return false; + } + } + #ifdef _DEBUG LOG((LF_JIT, LL_EVERYTHING, "%*s**** Classify %s (%p), startOffset %d, total struct size %d\n", nestingLevel * 5, "", this->GetDebugClassName(), this, startOffsetOfStruct, helperPtr->structSize)); @@ -2619,6 +2638,24 @@ bool MethodTable::ClassifyEightBytesWithNativeLayout(SystemVStructRegisterPassin return false; } + // The SIMD Intrinsic types are meant to be handled specially and should not be passed as struct registers + if (IsIntrinsicType()) + { + LPCUTF8 namespaceName; + LPCUTF8 className = GetFullyQualifiedNameInfo(&namespaceName); + + if ((strcmp(className, "Vector256`1") == 0) || (strcmp(className, "Vector128`1") == 0) || + (strcmp(className, "Vector64`1") == 0)) + { + assert(strcmp(namespaceName, "System.Runtime.Intrinsics") == 0); + + LOG((LF_JIT, LL_EVERYTHING, "%*s**** ClassifyEightBytesWithNativeLayout: struct %s is a SIMD intrinsic type; will not be enregistered\n", + nestingLevel * 5, "", this->GetDebugClassName())); + + return false; + } + } + #ifdef _DEBUG LOG((LF_JIT, LL_EVERYTHING, "%*s**** Classify for native struct %s (%p), startOffset %d, total struct size %d\n", nestingLevel * 5, "", this->GetDebugClassName(), this, startOffsetOfStruct, helperPtr->structSize)); diff --git a/src/vm/methodtablebuilder.cpp b/src/vm/methodtablebuilder.cpp index 725fb2d863..d25fc95054 100644 --- a/src/vm/methodtablebuilder.cpp +++ b/src/vm/methodtablebuilder.cpp @@ -1844,6 +1844,24 @@ MethodTableBuilder::BuildMethodTableThrowing( pMT->SetIsByRefLike(); } + // If this type is marked by [Intrinsic] attribute, it may be specially treated by the runtime/compiler + // Currently, only SIMD types have [Intrinsic] attribute + // + // We check this here, before the SystemVAmd64CheckForPass[Native]StructInRegister calls to ensure the SIMD + // intrinsics are not enregistered incorrectly. + 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(); + } + } + if (IsValueClass()) { if (bmtFP->NumInstanceFieldBytes != totalDeclaredFieldSize || HasOverLayedField()) @@ -2025,21 +2043,6 @@ MethodTableBuilder::BuildMethodTableThrowing( pMT->SetICastable(); } #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 |