Exemplo n.º 1
0
        public override ValueTypeShapeCharacteristics ComputeValueTypeShapeCharacteristics(DefType type)
        {
            if (!type.IsValueType)
            {
                return(ValueTypeShapeCharacteristics.None);
            }

            ValueTypeShapeCharacteristics result = ComputeHomogeneousFloatAggregateCharacteristic(type);

            // TODO: System V AMD64 characteristics (https://github.com/dotnet/corert/issues/158)

            return(result);
        }
Exemplo n.º 2
0
 private void ComputeValueTypeShapeCharacteristics()
 {
     _valueTypeShapeCharacteristics = this.Context.GetLayoutAlgorithmForType(this).ComputeValueTypeShapeCharacteristics(this);
     _fieldLayoutFlags.AddFlags(FieldLayoutFlags.ComputedValueTypeShapeCharacteristics);
 }
Exemplo n.º 3
0
        public unsafe override ValueTypeShapeCharacteristics ComputeValueTypeShapeCharacteristics(DefType type)
        {
            // Use this constant to make the code below more laconic
            const ValueTypeShapeCharacteristics NotHA = ValueTypeShapeCharacteristics.None;

            Debug.Assert(type.IsValueType);

            TargetArchitecture targetArch = type.Context.Target.Architecture;

            if ((targetArch != TargetArchitecture.ARM) && (targetArch != TargetArchitecture.ARM64))
            {
                return(NotHA);
            }

            if (!type.IsValueType)
            {
                return(NotHA);
            }

            // There is no reason to compute the entire field layout for the HA type/flag if
            // the template type is not a universal generic type (information stored in rare flags on the EEType)
            TypeDesc templateType = type.ComputeTemplate(false);

            if (templateType != null && !templateType.IsCanonicalSubtype(CanonicalFormKind.Universal))
            {
                EEType *pEETemplate = templateType.GetRuntimeTypeHandle().ToEETypePtr();
                if (!pEETemplate->IsHFA)
                {
                    return(NotHA);
                }

                if (pEETemplate->RequiresAlign8)
                {
                    return(ValueTypeShapeCharacteristics.Float64Aggregate);
                }
                else
                {
                    return(ValueTypeShapeCharacteristics.Float32Aggregate);
                }
            }

            // Once this is done, the NativeLayoutFields on the type are initialized
            EnsureFieldLayoutLoadedForGenericType((DefType)type);
            Debug.Assert(type.NativeLayoutFields != null);

            // Empty types are not HA
            if (type.NativeLayoutFields.Length == 0)
            {
                return(NotHA);
            }

            // Find the common HA element type if any
            ValueTypeShapeCharacteristics haResultType = NotHA;

            for (int i = 0; i < type.NativeLayoutFields.Length; i++)
            {
                TypeDesc fieldType = type.NativeLayoutFields[i].FieldType;
                if (type.NativeLayoutFields[i].FieldStorage != NativeFormat.FieldStorage.Instance)
                {
                    continue;
                }

                // If a field isn't a DefType, then this type cannot be a HA type
                if (!(fieldType is DefType fieldDefType))
                {
                    return(NotHA);
                }

                // HA types cannot contain non-HA types
                ValueTypeShapeCharacteristics haFieldType = fieldDefType.ValueTypeShapeCharacteristics & ValueTypeShapeCharacteristics.AggregateMask;
                if (haFieldType == NotHA)
                {
                    return(NotHA);
                }

                if (haResultType == NotHA)
                {
                    haResultType = haFieldType;
                }
                else if (haResultType != haFieldType)
                {
                    return(NotHA); // If the field doesn't have the same HA type as the one we've looked at before, the type cannot be HA
                }
            }

            // If we didn't find any instance fields, then this can't be a HA type
            if (haResultType == NotHA)
            {
                return(NotHA);
            }

            int haElementSize = haResultType switch
            {
                ValueTypeShapeCharacteristics.Float32Aggregate => 4,
                ValueTypeShapeCharacteristics.Float64Aggregate => 8,
                ValueTypeShapeCharacteristics.Vector64Aggregate => 8,
                ValueTypeShapeCharacteristics.Vector128Aggregate => 16,
                _ => throw new ArgumentOutOfRangeException()
            };

            // Note that we check the total size, but do not perform any checks on number of fields:
            // - Type of fields can be HA valuetype itself
            // - Managed C++ HFA valuetypes have just one <alignment member> of type float to signal that
            //   the valuetype is HFA and explicitly specified size
            int maxSize = haElementSize * type.Context.Target.MaxHomogeneousAggregateElementCount;

            if (type.InstanceFieldSize.AsInt > maxSize)
            {
                return(NotHA);
            }

            return(haResultType);
        }
    }
Exemplo n.º 4
0
 private void ComputeValueTypeShapeCharacteristics()
 {
     _valueTypeShapeCharacteristics = this.Context.GetLayoutAlgorithmForType(this).ComputeValueTypeShapeCharacteristics(this);
     _fieldLayoutFlags.AddFlags(FieldLayoutFlags.ComputedValueTypeShapeCharacteristics);
 }