public override ComputedInstanceFieldLayout ComputeInstanceLayout(DefType type, InstanceLayoutKind layoutKind) { if (!type.IsTemplateUniversal() && (layoutKind == InstanceLayoutKind.TypeOnly)) { // Non universal generics can just use the template's layout DefType template = (DefType)type.ComputeTemplate(); return(_noMetadataFieldLayoutAlgorithm.ComputeInstanceLayout(template, InstanceLayoutKind.TypeOnly)); } // Only needed for universal generics, or when looking up an offset for a field for a universal generic LowLevelList <int> fieldOffsets; int[] position = ComputeTypeSizeAndAlignment(type, FieldLoadState.Instance, out fieldOffsets); int numInstanceFields = 0; foreach (NativeLayoutFieldDesc field in type.NativeLayoutFields) { if (!field.IsStatic) { numInstanceFields++; } } int byteCountAlignment = position[InstanceAlignmentEntry]; byteCountAlignment = type.Context.Target.GetObjectAlignment(byteCountAlignment); ComputedInstanceFieldLayout layout = new ComputedInstanceFieldLayout() { Offsets = new FieldAndOffset[numInstanceFields], ByteCountAlignment = byteCountAlignment, ByteCountUnaligned = position[(int)NativeFormat.FieldStorage.Instance], PackValue = 0 // TODO, as we add more metadata handling logic, find out if its necessary to use a meaningful value here }; if (!type.IsValueType) { layout.FieldAlignment = type.Context.Target.PointerSize; layout.FieldSize = type.Context.Target.PointerSize; } else { layout.FieldAlignment = position[InstanceAlignmentEntry]; layout.FieldSize = MemoryHelpers.AlignUp(position[(int)NativeFormat.FieldStorage.Instance], layout.FieldAlignment); } int curInstanceField = 0; foreach (NativeLayoutFieldDesc field in type.NativeLayoutFields) { if (!field.IsStatic) { layout.Offsets[curInstanceField] = new FieldAndOffset(field, fieldOffsets[curInstanceField]); curInstanceField++; } } return(layout); }
public override ComputedInstanceFieldLayout ComputeInstanceLayout(DefType defType, InstanceLayoutKind layoutKind) { TargetDetails targetDetails = defType.Context.Target; ComputedInstanceFieldLayout layoutFromMetadata = _fallbackAlgorithm.ComputeInstanceLayout(defType, layoutKind); LayoutInt instanceFieldSize; if (targetDetails.MaximumSimdVectorLength == SimdVectorLength.Vector128Bit) { instanceFieldSize = new LayoutInt(16); } else if (targetDetails.MaximumSimdVectorLength == SimdVectorLength.Vector256Bit) { instanceFieldSize = new LayoutInt(32); } else { Debug.Assert(targetDetails.MaximumSimdVectorLength == SimdVectorLength.None); return(layoutFromMetadata); } return(new ComputedInstanceFieldLayout { ByteCountUnaligned = instanceFieldSize, ByteCountAlignment = layoutFromMetadata.ByteCountAlignment, FieldAlignment = layoutFromMetadata.FieldAlignment, FieldSize = instanceFieldSize, Offsets = layoutFromMetadata.Offsets, }); }
public override ComputedInstanceFieldLayout ComputeInstanceLayout(DefType defType, InstanceLayoutKind layoutKind) { Debug.Assert(IsIntegerType(defType)); string name = defType.Name; Debug.Assert((name == "Int128") || (name == "UInt128")); ComputedInstanceFieldLayout layoutFromMetadata = _fallbackAlgorithm.ComputeInstanceLayout(defType, layoutKind); if (defType.Context.Target.IsWindows || (defType.Context.Target.PointerSize == 4)) { return(layoutFromMetadata); } // 64-bit Unix systems follow the System V ABI and have a 16-byte packing requirement for Int128/UInt128 return(new ComputedInstanceFieldLayout { ByteCountUnaligned = layoutFromMetadata.ByteCountUnaligned, ByteCountAlignment = layoutFromMetadata.ByteCountAlignment, FieldAlignment = new LayoutInt(16), FieldSize = layoutFromMetadata.FieldSize, Offsets = layoutFromMetadata.Offsets, LayoutAbiStable = true }); }
public override ComputedInstanceFieldLayout ComputeInstanceLayout(DefType defType, InstanceLayoutKind layoutKind) { Debug.Assert(IsIntegerType(defType)); string name = defType.Name; Debug.Assert((name == "Int128") || (name == "UInt128")); ComputedInstanceFieldLayout layoutFromMetadata = _fallbackAlgorithm.ComputeInstanceLayout(defType, layoutKind); // 32bit platforms use standard metadata layout engine if (defType.Context.Target.Architecture == TargetArchitecture.ARM) { layoutFromMetadata.LayoutAbiStable = false; // Int128 parameter passing ABI is unstable at this time layoutFromMetadata.IsInt128OrHasInt128Fields = true; return(layoutFromMetadata); } // 64-bit Unix systems follow the System V ABI and have a 16-byte packing requirement for Int128/UInt128 return(new ComputedInstanceFieldLayout { ByteCountUnaligned = layoutFromMetadata.ByteCountUnaligned, ByteCountAlignment = layoutFromMetadata.ByteCountAlignment, FieldAlignment = new LayoutInt(16), FieldSize = layoutFromMetadata.FieldSize, Offsets = layoutFromMetadata.Offsets, LayoutAbiStable = false, // Int128 parameter passing ABI is unstable at this time IsInt128OrHasInt128Fields = true }); }
public override ComputedInstanceFieldLayout ComputeInstanceLayout(DefType defType, InstanceLayoutKind layoutKind) { Debug.Assert(IsVectorType(defType)); LayoutInt alignment; string name = defType.Name; if (name == "Vector64`1") { alignment = new LayoutInt(8); } else if (name == "Vector128`1") { if (defType.Context.Target.Architecture == TargetArchitecture.ARM) { // The Procedure Call Standard for ARM defaults to 8-byte alignment for __m128 alignment = new LayoutInt(8); } else { alignment = new LayoutInt(16); } } else { Debug.Assert(name == "Vector256`1"); if (defType.Context.Target.Architecture == TargetArchitecture.ARM) { // No such type exists for the Procedure Call Standard for ARM. We will default // to the same alignment as __m128, which is supported by the ABI. alignment = new LayoutInt(8); } else if (defType.Context.Target.Architecture == TargetArchitecture.ARM64) { // The Procedure Call Standard for ARM 64-bit (with SVE support) defaults to // 16-byte alignment for __m256. alignment = new LayoutInt(16); } else { alignment = new LayoutInt(32); } } ComputedInstanceFieldLayout layoutFromMetadata = _fallbackAlgorithm.ComputeInstanceLayout(defType, layoutKind); return(new ComputedInstanceFieldLayout { ByteCountUnaligned = layoutFromMetadata.ByteCountUnaligned, ByteCountAlignment = layoutFromMetadata.ByteCountAlignment, FieldAlignment = alignment, FieldSize = layoutFromMetadata.FieldSize, Offsets = layoutFromMetadata.Offsets, LayoutAbiStable = _vectorAbiIsStable }); }
public override ComputedInstanceFieldLayout ComputeInstanceLayout(DefType type, InstanceLayoutKind layoutKind) { DefType similarSpecifiedVector = GetSimilarVector(type); if (similarSpecifiedVector == null) { List <FieldAndOffset> fieldsAndOffsets = new List <FieldAndOffset>(); foreach (FieldDesc field in type.GetFields()) { if (!field.IsStatic) { fieldsAndOffsets.Add(new FieldAndOffset(field, LayoutInt.Indeterminate)); } } ComputedInstanceFieldLayout instanceLayout = new ComputedInstanceFieldLayout() { FieldSize = LayoutInt.Indeterminate, FieldAlignment = LayoutInt.Indeterminate, ByteCountUnaligned = LayoutInt.Indeterminate, ByteCountAlignment = LayoutInt.Indeterminate, Offsets = fieldsAndOffsets.ToArray(), LayoutAbiStable = false, }; return(instanceLayout); } else { ComputedInstanceFieldLayout layoutFromMetadata = _fallbackAlgorithm.ComputeInstanceLayout(type, layoutKind); ComputedInstanceFieldLayout layoutFromSimilarIntrinsicVector = _vectorFallbackAlgorithm.ComputeInstanceLayout(similarSpecifiedVector, layoutKind); // TODO, enable this code when we switch Vector<T> to follow the same calling convention as its matching similar intrinsic vector #if MATCHING_HARDWARE_VECTOR return(new ComputedInstanceFieldLayout { ByteCountUnaligned = layoutFromSimilarIntrinsicVector.ByteCountUnaligned, ByteCountAlignment = layoutFromSimilarIntrinsicVector.ByteCountAlignment, FieldAlignment = layoutFromSimilarIntrinsicVector.FieldAlignment, FieldSize = layoutFromSimilarIntrinsicVector.FieldSize, Offsets = layoutFromMetadata.Offsets, LayoutAbiStable = _vectorAbiIsStable, }); #else return(new ComputedInstanceFieldLayout { ByteCountUnaligned = layoutFromSimilarIntrinsicVector.ByteCountUnaligned, ByteCountAlignment = layoutFromMetadata.ByteCountAlignment, FieldAlignment = layoutFromMetadata.FieldAlignment, FieldSize = layoutFromSimilarIntrinsicVector.FieldSize, Offsets = layoutFromMetadata.Offsets, LayoutAbiStable = _vectorAbiIsStable, }); #endif } }
/// <summary> /// Reads the minimal information about type layout encoded in the /// EEType. That doesn't include field information. /// </summary> public unsafe override ComputedInstanceFieldLayout ComputeInstanceLayout(DefType type, InstanceLayoutKind layoutKind) { // If we need the field information, delegate to the native layout algorithm or metadata algorithm if (layoutKind != InstanceLayoutKind.TypeOnly) { if (type.HasNativeLayout) { return(s_nativeLayoutFieldAlgorithm.ComputeInstanceLayout(type, layoutKind)); } else { return(_metadataFieldLayoutAlgorithm.ComputeInstanceLayout(type, layoutKind)); } } type.RetrieveRuntimeTypeHandleIfPossible(); Debug.Assert(!type.RuntimeTypeHandle.IsNull()); EEType *eeType = type.RuntimeTypeHandle.ToEETypePtr(); ComputedInstanceFieldLayout layout = new ComputedInstanceFieldLayout() { ByteCountAlignment = new LayoutInt(IntPtr.Size), ByteCountUnaligned = new LayoutInt(eeType->IsInterface ? IntPtr.Size : checked ((int)eeType->FieldByteCountNonGCAligned)), FieldAlignment = new LayoutInt(eeType->FieldAlignmentRequirement), Offsets = (layoutKind == InstanceLayoutKind.TypeOnly) ? null : Array.Empty <FieldAndOffset>(), // No fields in EETypes PackValue = 0, // This isn't explicitly encoded, though FieldSize should take it into account // TODO, as we add more metadata handling logic, find out if its necessary. }; if (eeType->IsValueType) { int valueTypeSize = checked ((int)eeType->ValueTypeSize); layout.FieldSize = new LayoutInt(valueTypeSize); } else { layout.FieldSize = new LayoutInt(IntPtr.Size); } if ((eeType->RareFlags & EETypeRareFlags.RequiresAlign8Flag) == EETypeRareFlags.RequiresAlign8Flag) { layout.ByteCountAlignment = new LayoutInt(8); } return(layout); }
public override ComputedInstanceFieldLayout ComputeInstanceLayout(DefType defType, InstanceLayoutKind layoutKind) { TargetDetails targetDetails = defType.Context.Target; ComputedInstanceFieldLayout layoutFromMetadata = _fallbackAlgorithm.ComputeInstanceLayout(defType, layoutKind); // System.Object has an EEType field in the standard AOT version used in this repo. // Make sure that we always use the CoreCLR version which (currently) has no fields. Debug.Assert(0 == layoutFromMetadata.Offsets.Length, "Incompatible system library. The CoreCLR System.Private.CoreLib must be used when compiling in ready-to-run mode."); return(new ComputedInstanceFieldLayout { ByteCountUnaligned = targetDetails.LayoutPointerSize, ByteCountAlignment = targetDetails.LayoutPointerSize, FieldAlignment = layoutFromMetadata.FieldAlignment, FieldSize = layoutFromMetadata.FieldSize, Offsets = layoutFromMetadata.Offsets, }); }
public override ComputedInstanceFieldLayout ComputeInstanceLayout(DefType type, InstanceLayoutKind layoutKind) { List <FieldAndOffset> fieldsAndOffsets = new List <FieldAndOffset>(); foreach (FieldDesc field in type.GetFields()) { if (!field.IsStatic) { fieldsAndOffsets.Add(new FieldAndOffset(field, LayoutInt.Indeterminate)); } } ComputedInstanceFieldLayout instanceLayout = new ComputedInstanceFieldLayout() { FieldSize = LayoutInt.Indeterminate, FieldAlignment = LayoutInt.Indeterminate, ByteCountUnaligned = LayoutInt.Indeterminate, ByteCountAlignment = LayoutInt.Indeterminate, Offsets = fieldsAndOffsets.ToArray(), }; return(instanceLayout); }