return false;
}
+ public override bool ComputeIsUnsafeValueType(DefType type)
+ {
+ Debug.Assert(!_fallbackAlgorithm.ComputeIsUnsafeValueType(type));
+ return false;
+ }
+
public override ValueTypeShapeCharacteristics ComputeValueTypeShapeCharacteristics(DefType type)
{
if (type.Context.Target.Architecture == TargetArchitecture.ARM64 &&
if (metadataType.IsExplicitLayout || (metadataType.IsSequentialLayout && metadataType.GetClassLayout().Size != 0) || metadataType.IsWellKnownType(WellKnownType.TypedReference))
result |= CorInfoFlag.CORINFO_FLG_CUSTOMLAYOUT;
- // TODO
- // if (type.IsUnsafeValueType)
- // result |= CorInfoFlag.CORINFO_FLG_UNSAFE_VALUECLASS;
+ if (metadataType.IsUnsafeValueType)
+ result |= CorInfoFlag.CORINFO_FLG_UNSAFE_VALUECLASS;
}
if (type.IsCanonicalSubtype(CanonicalFormKind.Any))
/// True if the layout of the type is not stable for use in the ABI
/// </summary>
public const int ComputedInstanceLayoutAbiUnstable = 0x80;
+
+ /// <summary>
+ /// True if IsUnsafeValueType has been computed
+ /// </summary>
+ public const int ComputedIsUnsafeValueType = 0x100;
+
+ /// <summary>
+ /// True if type transitively has UnsafeValueTypeAttribute
+ /// </summary>
+ public const int IsUnsafeValueType = 0x200;
}
private class StaticBlockInfo
}
/// <summary>
+ /// Does a type transitively have any fields which are marked with System.Runtime.CompilerServices.UnsafeValueTypeAttribute
+ /// </summary>
+ public bool IsUnsafeValueType
+ {
+ get
+ {
+ if (!_fieldLayoutFlags.HasFlags(FieldLayoutFlags.ComputedIsUnsafeValueType))
+ {
+ ComputeIsUnsafeValueType();
+ }
+ return _fieldLayoutFlags.HasFlags(FieldLayoutFlags.IsUnsafeValueType);
+ }
+ }
+
+
+ /// <summary>
/// The number of bytes required to hold a field of this type
/// </summary>
public LayoutInt InstanceFieldSize
_fieldLayoutFlags.AddFlags(flagsToAdd);
}
+
+ public void ComputeIsUnsafeValueType()
+ {
+ if (_fieldLayoutFlags.HasFlags(FieldLayoutFlags.ComputedIsUnsafeValueType))
+ return;
+
+ int flagsToAdd = FieldLayoutFlags.ComputedIsUnsafeValueType;
+
+ if (this.Context.GetLayoutAlgorithmForType(this).ComputeIsUnsafeValueType(this))
+ {
+ flagsToAdd |= FieldLayoutFlags.IsUnsafeValueType;
+ }
+
+ _fieldLayoutFlags.AddFlags(flagsToAdd);
+ }
}
}
public abstract bool ComputeContainsGCPointers(DefType type);
/// <summary>
+ /// Compute whether the specified type is a value type that transitively has UnsafeValueTypeAttribute
+ /// </summary>
+ public abstract bool ComputeIsUnsafeValueType(DefType type);
+
+ /// <summary>
/// Compute the shape of a value type. The shape information is used to control code generation and allocation
/// (such as vectorization, passing the value type by value across method calls, or boxing alignment).
/// </summary>
return NotHA;
}
+ public override bool ComputeIsUnsafeValueType(DefType type)
+ {
+ if (!type.IsValueType)
+ return false;
+
+ MetadataType metadataType = (MetadataType)type;
+ if (metadataType.HasCustomAttribute("System.Runtime.CompilerServices", "UnsafeValueTypeAttribute"))
+ return true;
+
+ foreach (FieldDesc field in metadataType.GetFields())
+ {
+ if (field.IsStatic)
+ continue;
+
+ TypeDesc fieldType = field.FieldType;
+ if (!fieldType.IsValueType || fieldType.IsPrimitive)
+ continue;
+
+ if (((DefType)fieldType).IsUnsafeValueType)
+ return true;
+ }
+
+ return false;
+ }
+
private struct SizeAndAlignment
{
public LayoutInt Size;
};
}
+ public override bool ComputeIsUnsafeValueType(DefType type)
+ {
+ throw new NotSupportedException();
+ }
+
public override ComputedStaticFieldLayout ComputeStaticFieldLayout(DefType type, StaticLayoutKind layoutKind)
{
return new ComputedStaticFieldLayout()
return canonicalType.ValueTypeShapeCharacteristics;
}
+
+ public override bool ComputeIsUnsafeValueType(DefType type)
+ {
+ RuntimeDeterminedType runtimeDeterminedType = (RuntimeDeterminedType)type;
+ DefType canonicalType = runtimeDeterminedType.CanonicalType;
+
+ return canonicalType.IsUnsafeValueType;
+ }
}
}
return false;
}
+ public override bool ComputeIsUnsafeValueType(DefType type)
+ {
+ return false;
+ }
+
public override ComputedInstanceFieldLayout ComputeInstanceLayout(DefType type, InstanceLayoutKind layoutKind)
{
DefType similarSpecifiedVector = GetSimilarVector(type);
return false;
}
+ public override bool ComputeIsUnsafeValueType(DefType type)
+ {
+ return false;
+ }
+
public override ValueTypeShapeCharacteristics ComputeValueTypeShapeCharacteristics(DefType type)
{
return _fallbackAlgorithm.ComputeValueTypeShapeCharacteristics(type);