private static ComputedInstanceFieldLayout ComputeSequentialFieldLayout(MetadataType type, int numInstanceFields) { var offsets = new FieldAndOffset[numInstanceFields]; // For types inheriting from another type, field offsets continue on from where they left off int cumulativeInstanceFieldPos = ComputeBytesUsedInParentType(type); int largestAlignmentRequirement = 1; int fieldOrdinal = 0; int packingSize = ComputePackingSize(type); foreach (var field in type.GetFields()) { if (field.IsStatic) { continue; } var fieldSizeAndAlignment = ComputeFieldSizeAndAlignment(field.FieldType, packingSize); if (fieldSizeAndAlignment.Alignment > largestAlignmentRequirement) { largestAlignmentRequirement = fieldSizeAndAlignment.Alignment; } cumulativeInstanceFieldPos = AlignmentHelper.AlignUp(cumulativeInstanceFieldPos, fieldSizeAndAlignment.Alignment); offsets[fieldOrdinal] = new FieldAndOffset(field, cumulativeInstanceFieldPos); cumulativeInstanceFieldPos = checked (cumulativeInstanceFieldPos + fieldSizeAndAlignment.Size); fieldOrdinal++; } if (type.IsValueType) { var layoutMetadata = type.GetClassLayout(); cumulativeInstanceFieldPos = Math.Max(cumulativeInstanceFieldPos, layoutMetadata.Size); } SizeAndAlignment instanceByteSizeAndAlignment; var instanceSizeAndAlignment = ComputeInstanceSize(type, cumulativeInstanceFieldPos, largestAlignmentRequirement, out instanceByteSizeAndAlignment); ComputedInstanceFieldLayout computedLayout = new ComputedInstanceFieldLayout(); computedLayout.FieldAlignment = instanceSizeAndAlignment.Alignment; computedLayout.FieldSize = instanceSizeAndAlignment.Size; computedLayout.ByteCountUnaligned = instanceByteSizeAndAlignment.Size; computedLayout.ByteCountAlignment = instanceByteSizeAndAlignment.Alignment; computedLayout.Offsets = offsets; return(computedLayout); }
private static ComputedInstanceFieldLayout ComputeSequentialFieldLayout(MetadataType type, int numInstanceFields) { var offsets = new FieldAndOffset[numInstanceFields]; // For types inheriting from another type, field offsets continue on from where they left off int cumulativeInstanceFieldPos = ComputeBytesUsedInParentType(type); int largestAlignmentRequirement = 1; int fieldOrdinal = 0; int packingSize = ComputePackingSize(type); foreach (var field in type.GetFields()) { if (field.IsStatic) continue; var fieldSizeAndAlignment = ComputeFieldSizeAndAlignment(field.FieldType, packingSize); if (fieldSizeAndAlignment.Alignment > largestAlignmentRequirement) largestAlignmentRequirement = fieldSizeAndAlignment.Alignment; cumulativeInstanceFieldPos = AlignmentHelper.AlignUp(cumulativeInstanceFieldPos, fieldSizeAndAlignment.Alignment); offsets[fieldOrdinal] = new FieldAndOffset(field, cumulativeInstanceFieldPos); cumulativeInstanceFieldPos = checked(cumulativeInstanceFieldPos + fieldSizeAndAlignment.Size); fieldOrdinal++; } if (type.IsValueType) { var layoutMetadata = type.GetClassLayout(); cumulativeInstanceFieldPos = Math.Max(cumulativeInstanceFieldPos, layoutMetadata.Size); } SizeAndAlignment instanceByteSizeAndAlignment; var instanceSizeAndAlignment = ComputeInstanceSize(type, cumulativeInstanceFieldPos, largestAlignmentRequirement, out instanceByteSizeAndAlignment); ComputedInstanceFieldLayout computedLayout = new ComputedInstanceFieldLayout(); computedLayout.FieldAlignment = instanceSizeAndAlignment.Alignment; computedLayout.FieldSize = instanceSizeAndAlignment.Size; computedLayout.ByteCountUnaligned = instanceByteSizeAndAlignment.Size; computedLayout.ByteCountAlignment = instanceByteSizeAndAlignment.Alignment; computedLayout.Offsets = offsets; return computedLayout; }
private static ComputedInstanceFieldLayout ComputeExplicitFieldLayout(MetadataType type, int numInstanceFields) { // Instance slice size is the total size of instance not including the base type. // It is calculated as the field whose offset and size add to the greatest value. int cumulativeInstanceFieldPos = type.HasBaseType && !type.IsValueType ? type.BaseType.InstanceByteCount : 0; int instanceSize = cumulativeInstanceFieldPos; var layoutMetadata = type.GetClassLayout(); int packingSize = ComputePackingSize(type); int largestAlignmentRequired = 1; var offsets = new FieldAndOffset[numInstanceFields]; int fieldOrdinal = 0; foreach (var fieldAndOffset in layoutMetadata.Offsets) { var fieldSizeAndAlignment = ComputeFieldSizeAndAlignment(fieldAndOffset.Field.FieldType, packingSize); if (fieldSizeAndAlignment.Alignment > largestAlignmentRequired) largestAlignmentRequired = fieldSizeAndAlignment.Alignment; if (fieldAndOffset.Offset == FieldAndOffset.InvalidOffset) throw new TypeLoadException(); int computedOffset = checked(fieldAndOffset.Offset + cumulativeInstanceFieldPos); switch (fieldAndOffset.Field.FieldType.Category) { case TypeFlags.Array: case TypeFlags.Class: { int offsetModulo = computedOffset % type.Context.Target.PointerSize; if (offsetModulo != 0) { // GC pointers MUST be aligned. if (offsetModulo == 4) { // We must be attempting to compile a 32bit app targeting a 64 bit platform. throw new TypeLoadException(); } else { // Its just wrong throw new TypeLoadException(); } } break; } } offsets[fieldOrdinal] = new FieldAndOffset(fieldAndOffset.Field, computedOffset); int fieldExtent = checked(computedOffset + fieldSizeAndAlignment.Size); if (fieldExtent > instanceSize) { instanceSize = fieldExtent; } fieldOrdinal++; } if (type.IsValueType && layoutMetadata.Size > instanceSize) { instanceSize = layoutMetadata.Size; } SizeAndAlignment instanceByteSizeAndAlignment; var instanceSizeAndAlignment = ComputeInstanceSize(type, instanceSize, largestAlignmentRequired, out instanceByteSizeAndAlignment); ComputedInstanceFieldLayout computedLayout = new ComputedInstanceFieldLayout(); computedLayout.FieldAlignment = instanceSizeAndAlignment.Alignment; computedLayout.FieldSize = instanceSizeAndAlignment.Size; computedLayout.ByteCountUnaligned = instanceByteSizeAndAlignment.Size; computedLayout.ByteCountAlignment = instanceByteSizeAndAlignment.Alignment; computedLayout.Offsets = offsets; return computedLayout; }
private static ComputedInstanceFieldLayout ComputeExplicitFieldLayout(MetadataType type, int numInstanceFields) { // Instance slice size is the total size of instance not including the base type. // It is calculated as the field whose offset and size add to the greatest value. int cumulativeInstanceFieldPos = type.HasBaseType && !type.IsValueType ? type.BaseType.InstanceByteCount : 0; int instanceSize = cumulativeInstanceFieldPos; var layoutMetadata = type.GetClassLayout(); int packingSize = ComputePackingSize(type); int largestAlignmentRequired = 1; var offsets = new FieldAndOffset[numInstanceFields]; int fieldOrdinal = 0; foreach (var fieldAndOffset in layoutMetadata.Offsets) { var fieldSizeAndAlignment = ComputeFieldSizeAndAlignment(fieldAndOffset.Field.FieldType, packingSize); if (fieldSizeAndAlignment.Alignment > largestAlignmentRequired) { largestAlignmentRequired = fieldSizeAndAlignment.Alignment; } if (fieldAndOffset.Offset == FieldAndOffset.InvalidOffset) { throw new TypeLoadException(); } int computedOffset = checked (fieldAndOffset.Offset + cumulativeInstanceFieldPos); switch (fieldAndOffset.Field.FieldType.Category) { case TypeFlags.Array: case TypeFlags.Class: { int offsetModulo = computedOffset % type.Context.Target.PointerSize; if (offsetModulo != 0) { // GC pointers MUST be aligned. if (offsetModulo == 4) { // We must be attempting to compile a 32bit app targeting a 64 bit platform. throw new TypeLoadException(); } else { // Its just wrong throw new TypeLoadException(); } } break; } } offsets[fieldOrdinal] = new FieldAndOffset(fieldAndOffset.Field, computedOffset); int fieldExtent = checked (computedOffset + fieldSizeAndAlignment.Size); if (fieldExtent > instanceSize) { instanceSize = fieldExtent; } fieldOrdinal++; } if (type.IsValueType && layoutMetadata.Size > instanceSize) { instanceSize = layoutMetadata.Size; } SizeAndAlignment instanceByteSizeAndAlignment; var instanceSizeAndAlignment = ComputeInstanceSize(type, instanceSize, largestAlignmentRequired, out instanceByteSizeAndAlignment); ComputedInstanceFieldLayout computedLayout = new ComputedInstanceFieldLayout(); computedLayout.FieldAlignment = instanceSizeAndAlignment.Alignment; computedLayout.FieldSize = instanceSizeAndAlignment.Size; computedLayout.ByteCountUnaligned = instanceByteSizeAndAlignment.Size; computedLayout.ByteCountAlignment = instanceByteSizeAndAlignment.Alignment; computedLayout.Offsets = offsets; return(computedLayout); }
private static ComputedInstanceFieldLayout ComputeExplicitFieldLayout(MetadataType type, int numInstanceFields) { // Instance slice size is the total size of instance not including the base type. // It is calculated as the field whose offset and size add to the greatest value. LayoutInt cumulativeInstanceFieldPos = type.HasBaseType && !type.IsValueType ? type.BaseType.InstanceByteCount : LayoutInt.Zero; LayoutInt instanceSize = cumulativeInstanceFieldPos; var layoutMetadata = type.GetClassLayout(); int packingSize = ComputePackingSize(type); LayoutInt largestAlignmentRequired = LayoutInt.One; var offsets = new FieldAndOffset[numInstanceFields]; int fieldOrdinal = 0; foreach (var fieldAndOffset in layoutMetadata.Offsets) { var fieldSizeAndAlignment = ComputeFieldSizeAndAlignment(fieldAndOffset.Field.FieldType, packingSize); largestAlignmentRequired = LayoutInt.Max(fieldSizeAndAlignment.Alignment, largestAlignmentRequired); if (fieldAndOffset.Offset == FieldAndOffset.InvalidOffset) { throw new TypeSystemException.TypeLoadException(ExceptionStringID.ClassLoadBadFormat, type); } LayoutInt computedOffset = fieldAndOffset.Offset + cumulativeInstanceFieldPos; if (fieldAndOffset.Field.FieldType.IsGCPointer && !computedOffset.IsIndeterminate) { int offsetModulo = computedOffset.AsInt % type.Context.Target.PointerSize; if (offsetModulo != 0) { // GC pointers MUST be aligned. throw new TypeSystemException.TypeLoadException(ExceptionStringID.ClassLoadExplicitLayout, type, fieldAndOffset.Offset.ToStringInvariant()); } } offsets[fieldOrdinal] = new FieldAndOffset(fieldAndOffset.Field, computedOffset); LayoutInt fieldExtent = computedOffset + fieldSizeAndAlignment.Size; instanceSize = LayoutInt.Max(fieldExtent, instanceSize); fieldOrdinal++; } if (type.IsValueType) { instanceSize = LayoutInt.Max(new LayoutInt(layoutMetadata.Size), instanceSize); } SizeAndAlignment instanceByteSizeAndAlignment; var instanceSizeAndAlignment = ComputeInstanceSize(type, instanceSize, largestAlignmentRequired, out instanceByteSizeAndAlignment); ComputedInstanceFieldLayout computedLayout = new ComputedInstanceFieldLayout(); computedLayout.FieldAlignment = instanceSizeAndAlignment.Alignment; computedLayout.FieldSize = instanceSizeAndAlignment.Size; computedLayout.ByteCountUnaligned = instanceByteSizeAndAlignment.Size; computedLayout.ByteCountAlignment = instanceByteSizeAndAlignment.Alignment; computedLayout.Offsets = offsets; return(computedLayout); }
private static ComputedInstanceFieldLayout ComputeExplicitFieldLayout(MetadataType type, int numInstanceFields) { // Instance slice size is the total size of instance not including the base type. // It is calculated as the field whose offset and size add to the greatest value. int cumulativeInstanceFieldPos = type.HasBaseType && !type.IsValueType ? type.BaseType.InstanceByteCount : 0; int instanceSize = cumulativeInstanceFieldPos; var layoutMetadata = type.GetClassLayout(); int packingSize = ComputePackingSize(type); int largestAlignmentRequired = 1; var offsets = new FieldAndOffset[numInstanceFields]; int fieldOrdinal = 0; foreach (var fieldAndOffset in layoutMetadata.Offsets) { var fieldSizeAndAlignment = ComputeFieldSizeAndAlignment(fieldAndOffset.Field.FieldType, packingSize); if (fieldSizeAndAlignment.Alignment > largestAlignmentRequired) largestAlignmentRequired = fieldSizeAndAlignment.Alignment; if (fieldAndOffset.Offset == FieldAndOffset.InvalidOffset) throw new TypeSystemException.TypeLoadException(ExceptionStringID.ClassLoadBadFormat, type); int computedOffset = checked(fieldAndOffset.Offset + cumulativeInstanceFieldPos); if (fieldAndOffset.Field.FieldType.IsGCPointer) { int offsetModulo = computedOffset % type.Context.Target.PointerSize; if (offsetModulo != 0) { // GC pointers MUST be aligned. throw new TypeSystemException.TypeLoadException(ExceptionStringID.ClassLoadExplicitLayout, type, fieldAndOffset.Offset.ToStringInvariant()); } } offsets[fieldOrdinal] = new FieldAndOffset(fieldAndOffset.Field, computedOffset); int fieldExtent = checked(computedOffset + fieldSizeAndAlignment.Size); if (fieldExtent > instanceSize) { instanceSize = fieldExtent; } fieldOrdinal++; } if (type.IsValueType && layoutMetadata.Size > instanceSize) { instanceSize = layoutMetadata.Size; } SizeAndAlignment instanceByteSizeAndAlignment; var instanceSizeAndAlignment = ComputeInstanceSize(type, instanceSize, largestAlignmentRequired, out instanceByteSizeAndAlignment); ComputedInstanceFieldLayout computedLayout = new ComputedInstanceFieldLayout(); computedLayout.FieldAlignment = instanceSizeAndAlignment.Alignment; computedLayout.FieldSize = instanceSizeAndAlignment.Size; computedLayout.ByteCountUnaligned = instanceByteSizeAndAlignment.Size; computedLayout.ByteCountAlignment = instanceByteSizeAndAlignment.Alignment; computedLayout.Offsets = offsets; return computedLayout; }