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); }
internal static void EnsureFieldLayoutLoadedForGenericType(DefType type) { if (type.NativeLayoutFields != null) { return; } if (!type.IsTemplateUniversal()) { // We can hit this case where the template of type in question is not a universal canonical type. // Example: // BaseType<T> { ... } // DerivedType<T, U> : BaseType<T> { ... } // and an instantiation like DerivedType<string, int>. In that case, BaseType<string> will have a non-universal // template type, and requires special handling to compute its size and field layout. EnsureFieldLayoutLoadedForNonUniversalType(type); } else { TypeBuilderState state = type.GetOrCreateTypeBuilderState(); NativeParser typeInfoParser = state.GetParserForNativeLayoutInfo(); NativeParser fieldLayoutParser = typeInfoParser.GetParserForBagElementKind(BagElementKind.FieldLayout); EnsureFieldLayoutLoadedForUniversalType(type, state.NativeLayoutInfo.LoadContext, fieldLayoutParser); } }
public override ComputedStaticFieldLayout ComputeStaticFieldLayout(DefType type, StaticLayoutKind layoutKind) { if (!type.IsTemplateUniversal() && (layoutKind == StaticLayoutKind.StaticRegionSizes)) { return(ParseStaticRegionSizesFromNativeLayout(type)); } LowLevelList <LayoutInt> fieldOffsets; LayoutInt[] position = ComputeTypeSizeAndAlignment(type, FieldLoadState.Statics, out fieldOffsets); int numStaticFields = 0; foreach (NativeLayoutFieldDesc field in type.NativeLayoutFields) { if (field.IsStatic) { numStaticFields++; } } ComputedStaticFieldLayout layout = new ComputedStaticFieldLayout(); layout.Offsets = new FieldAndOffset[numStaticFields]; if (numStaticFields > 0) { layout.GcStatics = new StaticsBlock() { Size = position[(int)NativeFormat.FieldStorage.GCStatic], LargestAlignment = DefType.MaximumAlignmentPossible }; layout.NonGcStatics = new StaticsBlock() { Size = position[(int)NativeFormat.FieldStorage.NonGCStatic], LargestAlignment = DefType.MaximumAlignmentPossible }; layout.ThreadGcStatics = new StaticsBlock() { Size = position[(int)NativeFormat.FieldStorage.TLSStatic], LargestAlignment = DefType.MaximumAlignmentPossible }; layout.ThreadNonGcStatics = new StaticsBlock() { Size = LayoutInt.Zero, LargestAlignment = LayoutInt.Zero }; } int curStaticField = 0; foreach (NativeLayoutFieldDesc field in type.NativeLayoutFields) { if (field.IsStatic) { layout.Offsets[curStaticField] = new FieldAndOffset(field, fieldOffsets[curStaticField]); curStaticField++; } } return(layout); }