Beispiel #1
0
        private uint GetEnumTypeIndex(TypeDesc type)
        {
            System.Diagnostics.Debug.Assert(type.IsEnum, "GetEnumTypeIndex was called with wrong type");
            DefType defType = type as DefType;

            System.Diagnostics.Debug.Assert(defType != null, "GetEnumTypeIndex was called with non def type");
            List <FieldDesc> fieldsDescriptors = new List <FieldDesc>();

            foreach (var field in defType.GetFields())
            {
                if (field.IsLiteral)
                {
                    fieldsDescriptors.Add(field);
                }
            }
            EnumTypeDescriptor enumTypeDescriptor = new EnumTypeDescriptor
            {
                ElementCount = (ulong)fieldsDescriptors.Count,
                ElementType  = GetPrimitiveTypeIndex(defType.UnderlyingType),
                Name         = _objectWriter.GetMangledName(type),
            };

            EnumRecordTypeDescriptor[] typeRecords = new EnumRecordTypeDescriptor[enumTypeDescriptor.ElementCount];
            for (int i = 0; i < fieldsDescriptors.Count; ++i)
            {
                FieldDesc field = fieldsDescriptors[i];
                EnumRecordTypeDescriptor recordTypeDescriptor;
                recordTypeDescriptor.Value = GetEnumRecordValue(field);
                recordTypeDescriptor.Name  = field.Name;
                typeRecords[i]             = recordTypeDescriptor;
            }
            uint typeIndex = _objectWriter.GetEnumTypeIndex(enumTypeDescriptor, typeRecords);

            return(typeIndex);
        }
        public uint GetClassTypeIndex(TypeDesc type, bool needsCompleteType)
        {
            DefType defType = type as DefType;

            System.Diagnostics.Debug.Assert(defType != null, "GetClassTypeIndex was called with non def type");
            ClassTypeDescriptor classTypeDescriptor = new ClassTypeDescriptor();

            classTypeDescriptor.IsStruct    = type.IsValueType ? 1 : 0;
            classTypeDescriptor.Name        = defType.Name;
            classTypeDescriptor.UniqueName  = defType.GetFullName();
            classTypeDescriptor.BaseClassId = 0;
            if (type.HasBaseType && !type.IsValueType)
            {
                classTypeDescriptor.BaseClassId = GetVariableTypeIndex(defType.BaseType, false);
            }
            uint typeIndex = _objectWriter.GetClassTypeIndex(classTypeDescriptor);

            _knownTypes[type] = typeIndex;

            List <DataFieldDescriptor> fieldsDescs = new List <DataFieldDescriptor>();

            foreach (var fieldDesc in defType.GetFields())
            {
                if (fieldDesc.HasRva || fieldDesc.IsLiteral)
                {
                    continue;
                }
                DataFieldDescriptor field = new DataFieldDescriptor();
                field.FieldTypeIndex = GetVariableTypeIndex(fieldDesc.FieldType, false);
                field.Offset         = fieldDesc.Offset.AsInt;
                field.Name           = fieldDesc.Name;
                fieldsDescs.Add(field);
            }

            DataFieldDescriptor[] fields = new DataFieldDescriptor[fieldsDescs.Count];
            for (int i = 0; i < fieldsDescs.Count; ++i)
            {
                fields[i] = fieldsDescs[i];
            }
            ClassFieldsTypeDescriptor fieldsDescriptor = new ClassFieldsTypeDescriptor();

            fieldsDescriptor.FieldsCount = fieldsDescs.Count;
            fieldsDescriptor.Size        = defType.GetElementSize().AsInt;

            uint completeTypeIndex = _objectWriter.GetCompleteClassTypeIndex(classTypeDescriptor, fieldsDescriptor, fields);

            _completeKnownTypes[type] = completeTypeIndex;

            if (needsCompleteType)
            {
                return(completeTypeIndex);
            }
            else
            {
                return(typeIndex);
            }
        }
Beispiel #3
0
        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
            }
        }
        private bool ContainsTypeLayoutUncached(TypeDesc type, HashSet <TypeDesc> recursionGuard)
        {
            if (type.IsValueType ||
                type.IsObject ||
                type.IsPrimitive ||
                type.IsEnum ||
                type.IsPointer ||
                type.IsFunctionPointer ||
                type.IsByRefLike ||
                type.IsCanonicalDefinitionType(CanonicalFormKind.Any))
            {
                return(true);
            }
            DefType defType = type.GetClosestDefType();

            if (!ContainsType(defType.GetTypeDefinition()))
            {
                return(false);
            }
            if (defType.BaseType != null && !ContainsTypeLayout(defType.BaseType, recursionGuard))
            {
                return(false);
            }
            foreach (TypeDesc genericArg in defType.Instantiation)
            {
                if (!ContainsTypeLayout(genericArg, recursionGuard))
                {
                    return(false);
                }
            }
            foreach (FieldDesc field in defType.GetFields())
            {
                if (!field.IsLiteral &&
                    !field.IsStatic &&
                    !field.HasRva &&
                    !ContainsTypeLayout(field.FieldType, recursionGuard))
                {
                    return(false);
                }
            }

            return(true);
        }
Beispiel #5
0
        /// <summary>
        /// Get an enumerable list of the fields used for dynamic gc layout calculation.
        /// </summary>
        private IEnumerable <FieldDesc> GetFieldsForGCLayout()
        {
            DefType defType = (DefType)TypeBeingBuilt;

            IEnumerable <FieldDesc> fields;

            if (defType.ComputeTemplate(false) != null)
            {
                // we have native layout and a template. Use the NativeLayoutFields as that is the only complete
                // description of the fields available. (There may be metadata fields, but those aren't guaranteed
                // to be a complete set of fields due to reflection reduction.
                NativeLayoutFieldAlgorithm.EnsureFieldLayoutLoadedForGenericType(defType);
                fields = defType.NativeLayoutFields;
            }
            else
            {
                // The metadata case. We're loading the type from regular metadata, so use the regular metadata fields
                fields = defType.GetFields();
            }

            return(fields);
        }
            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);
            }
Beispiel #7
0
        private uint GetClassTypeIndex(TypeDesc type, bool needsCompleteType)
        {
            DefType defType = type as DefType;

            System.Diagnostics.Debug.Assert(defType != null, "GetClassTypeIndex was called with non def type");
            ClassTypeDescriptor classTypeDescriptor = new ClassTypeDescriptor
            {
                IsStruct    = type.IsValueType ? 1 : 0,
                Name        = _objectWriter.GetMangledName(type),
                BaseClassId = 0
            };

            uint typeIndex = _objectWriter.GetClassTypeIndex(classTypeDescriptor);

            _knownTypes[type] = typeIndex;

            if (type.HasBaseType && !type.IsValueType)
            {
                classTypeDescriptor.BaseClassId = GetTypeIndex(defType.BaseType, true);
            }

            List <DataFieldDescriptor> fieldsDescs        = new List <DataFieldDescriptor>();
            List <DataFieldDescriptor> nonGcStaticFields  = new List <DataFieldDescriptor>();
            List <DataFieldDescriptor> gcStaticFields     = new List <DataFieldDescriptor>();
            List <DataFieldDescriptor> threadStaticFields = new List <DataFieldDescriptor>();

            bool isCanonical = defType.IsCanonicalSubtype(CanonicalFormKind.Any);

            foreach (var fieldDesc in defType.GetFields())
            {
                if (fieldDesc.HasRva || fieldDesc.IsLiteral)
                {
                    continue;
                }

                if (isCanonical && fieldDesc.IsStatic)
                {
                    continue;
                }

                LayoutInt           fieldOffset     = fieldDesc.Offset;
                int                 fieldOffsetEmit = fieldOffset.IsIndeterminate ? 0xBAAD : fieldOffset.AsInt;
                DataFieldDescriptor field           = new DataFieldDescriptor
                {
                    FieldTypeIndex = GetVariableTypeIndex(GetFieldDebugType(fieldDesc), false),
                    Offset         = (ulong)fieldOffsetEmit,
                    Name           = fieldDesc.Name
                };

                if (fieldDesc.IsStatic)
                {
                    if (fieldDesc.IsThreadStatic)
                    {
                        threadStaticFields.Add(field);
                    }
                    else if (fieldDesc.HasGCStaticBase)
                    {
                        gcStaticFields.Add(field);
                    }
                    else
                    {
                        nonGcStaticFields.Add(field);
                    }
                }
                else
                {
                    fieldsDescs.Add(field);
                }
            }

            InsertStaticFieldRegionMember(fieldsDescs, defType, nonGcStaticFields, WindowsNodeMangler.NonGCStaticMemberName, "__type_" + WindowsNodeMangler.NonGCStaticMemberName, false);
            InsertStaticFieldRegionMember(fieldsDescs, defType, gcStaticFields, WindowsNodeMangler.GCStaticMemberName, "__type_" + WindowsNodeMangler.GCStaticMemberName, Abi == TargetAbi.CoreRT);
            InsertStaticFieldRegionMember(fieldsDescs, defType, threadStaticFields, WindowsNodeMangler.ThreadStaticMemberName, "__type_" + WindowsNodeMangler.ThreadStaticMemberName, Abi == TargetAbi.CoreRT);

            DataFieldDescriptor[] fields = new DataFieldDescriptor[fieldsDescs.Count];
            for (int i = 0; i < fieldsDescs.Count; ++i)
            {
                fields[i] = fieldsDescs[i];
            }

            LayoutInt elementSize     = defType.GetElementSize();
            int       elementSizeEmit = elementSize.IsIndeterminate ? 0xBAAD : elementSize.AsInt;
            ClassFieldsTypeDescriptor fieldsDescriptor = new ClassFieldsTypeDescriptor
            {
                Size        = (ulong)elementSizeEmit,
                FieldsCount = fieldsDescs.Count
            };

            uint completeTypeIndex = _objectWriter.GetCompleteClassTypeIndex(classTypeDescriptor, fieldsDescriptor, fields);

            _completeKnownTypes[type] = completeTypeIndex;

            if (needsCompleteType)
            {
                return(completeTypeIndex);
            }
            else
            {
                return(typeIndex);
            }
        }
        private uint GetClassTypeIndex(TypeDesc type, bool needsCompleteType)
        {
            DefType defType = type as DefType;

            System.Diagnostics.Debug.Assert(defType != null, "GetClassTypeIndex was called with non def type");
            ClassTypeDescriptor classTypeDescriptor = new ClassTypeDescriptor
            {
                IsStruct     = type.IsValueType ? 1 : 0,
                Name         = _objectWriter.GetMangledName(type),
                BaseClassId  = 0,
                InstanceSize = 0
            };

            uint typeIndex = _objectWriter.GetClassTypeIndex(classTypeDescriptor);

            _knownTypes[type] = typeIndex;

            if (!defType.InstanceByteCount.IsIndeterminate)
            {
                classTypeDescriptor.InstanceSize = (ulong)defType.InstanceByteCount.AsInt;
            }

            if (type.HasBaseType && !type.IsValueType)
            {
                classTypeDescriptor.BaseClassId = GetTypeIndex(defType.BaseType, true);
            }

            List <DataFieldDescriptor>       fieldsDescs        = new List <DataFieldDescriptor>();
            List <DataFieldDescriptor>       nonGcStaticFields  = new List <DataFieldDescriptor>();
            List <DataFieldDescriptor>       gcStaticFields     = new List <DataFieldDescriptor>();
            List <DataFieldDescriptor>       threadStaticFields = new List <DataFieldDescriptor>();
            List <StaticDataFieldDescriptor> staticsDescs       = new List <StaticDataFieldDescriptor>();

            string nonGcStaticDataName  = NodeFactory.NameMangler.NodeMangler.NonGCStatics(type);
            string gcStaticDataName     = NodeFactory.NameMangler.NodeMangler.GCStatics(type);
            string threadStaticDataName = NodeFactory.NameMangler.NodeMangler.ThreadStatics(type);
            bool   IsCoreRTAbi          = Abi == TargetAbi.CoreRT;

            bool isCanonical = defType.IsCanonicalSubtype(CanonicalFormKind.Any);

            foreach (var fieldDesc in defType.GetFields())
            {
                if (fieldDesc.HasRva || fieldDesc.IsLiteral)
                {
                    continue;
                }

                if (isCanonical && fieldDesc.IsStatic)
                {
                    continue;
                }

                LayoutInt           fieldOffset     = fieldDesc.Offset;
                int                 fieldOffsetEmit = fieldOffset.IsIndeterminate ? 0xBAAD : fieldOffset.AsInt;
                DataFieldDescriptor field           = new DataFieldDescriptor
                {
                    FieldTypeIndex = GetVariableTypeIndex(GetFieldDebugType(fieldDesc), false),
                    Offset         = (ulong)fieldOffsetEmit,
                    Name           = fieldDesc.Name
                };

                if (fieldDesc.IsStatic)
                {
                    if (NodeFactory.Target.OperatingSystem != TargetOS.Windows)
                    {
                        StaticDataFieldDescriptor staticDesc = new StaticDataFieldDescriptor
                        {
                            StaticOffset = (ulong)fieldOffsetEmit
                        };

                        // Mark field as static
                        field.Offset = 0xFFFFFFFF;

                        if (fieldDesc.IsThreadStatic)
                        {
                            staticDesc.StaticDataName       = threadStaticDataName;
                            staticDesc.IsStaticDataInObject = IsCoreRTAbi ? 1 : 0;
                        }
                        else if (fieldDesc.HasGCStaticBase)
                        {
                            staticDesc.StaticDataName       = gcStaticDataName;
                            staticDesc.IsStaticDataInObject = IsCoreRTAbi ? 1 : 0;
                        }
                        else
                        {
                            staticDesc.StaticDataName       = nonGcStaticDataName;
                            staticDesc.IsStaticDataInObject = 0;
                        }

                        staticsDescs.Add(staticDesc);
                    }

                    if (fieldDesc.IsThreadStatic)
                    {
                        threadStaticFields.Add(field);
                    }
                    else if (fieldDesc.HasGCStaticBase)
                    {
                        gcStaticFields.Add(field);
                    }
                    else
                    {
                        nonGcStaticFields.Add(field);
                    }
                }
                else
                {
                    fieldsDescs.Add(field);
                }
            }

            if (NodeFactory.Target.OperatingSystem == TargetOS.Windows)
            {
                InsertStaticFieldRegionMember(fieldsDescs, defType, nonGcStaticFields, WindowsNodeMangler.NonGCStaticMemberName, "__type_" + WindowsNodeMangler.NonGCStaticMemberName, false);
                InsertStaticFieldRegionMember(fieldsDescs, defType, gcStaticFields, WindowsNodeMangler.GCStaticMemberName, "__type_" + WindowsNodeMangler.GCStaticMemberName, IsCoreRTAbi);
                InsertStaticFieldRegionMember(fieldsDescs, defType, threadStaticFields, WindowsNodeMangler.ThreadStaticMemberName, "__type_" + WindowsNodeMangler.ThreadStaticMemberName, IsCoreRTAbi);
            }
            else
            {
                fieldsDescs.AddRange(nonGcStaticFields);
                fieldsDescs.AddRange(gcStaticFields);
                fieldsDescs.AddRange(threadStaticFields);
            }

            DataFieldDescriptor[] fields = new DataFieldDescriptor[fieldsDescs.Count];
            for (int i = 0; i < fieldsDescs.Count; ++i)
            {
                fields[i] = fieldsDescs[i];
            }

            StaticDataFieldDescriptor[] statics = new StaticDataFieldDescriptor[staticsDescs.Count];
            for (int i = 0; i < staticsDescs.Count; ++i)
            {
                statics[i] = staticsDescs[i];
            }

            LayoutInt elementSize     = defType.GetElementSize();
            int       elementSizeEmit = elementSize.IsIndeterminate ? 0xBAAD : elementSize.AsInt;
            ClassFieldsTypeDescriptor fieldsDescriptor = new ClassFieldsTypeDescriptor
            {
                Size        = (ulong)elementSizeEmit,
                FieldsCount = fieldsDescs.Count,
            };

            uint completeTypeIndex = _objectWriter.GetCompleteClassTypeIndex(classTypeDescriptor, fieldsDescriptor, fields, statics);

            _completeKnownTypes[type] = completeTypeIndex;

            if (needsCompleteType)
            {
                return(completeTypeIndex);
            }
            else
            {
                return(typeIndex);
            }
        }
Beispiel #9
0
            private FieldAndOffset[] CreateDynamicLayout(DefType defType, EcmaModule module)
            {
                List <FieldAndOffset> fieldsForType = null;
                int pointerSize = module.Context.Target.PointerSize;

                // In accordance with CoreCLR runtime conventions,
                // index 0 corresponds to regular statics, index 1 to thread-local statics.
                int[][] nonGcStaticsCount = new int[StaticIndexCount][]
                {
                    new int[TargetDetails.MaximumLog2PrimitiveSize + 1],
                    new int[TargetDetails.MaximumLog2PrimitiveSize + 1],
                };

                int[] gcPointerCount = new int[StaticIndexCount];
                int[] gcBoxedCount   = new int[StaticIndexCount];

                foreach (FieldDesc field in defType.GetFields())
                {
                    FieldDefinition fieldDef = module.MetadataReader.GetFieldDefinition(((EcmaField)field.GetTypicalFieldDefinition()).Handle);
                    if ((fieldDef.Attributes & (FieldAttributes.Static | FieldAttributes.Literal)) == FieldAttributes.Static)
                    {
                        int  index = (IsFieldThreadStatic(in fieldDef, module.MetadataReader) ? StaticIndexThreadLocal : StaticIndexRegular);
                        int  alignment;
                        int  size;
                        bool isGcPointerField;
                        bool isGcBoxedField;

                        CorElementType corElementType;
                        EntityHandle   valueTypeHandle;

                        GetFieldElementTypeAndValueTypeHandle(in fieldDef, module.MetadataReader, out corElementType, out valueTypeHandle);

                        GetElementTypeInfo(module, field, valueTypeHandle, corElementType, pointerSize, out alignment, out size, out isGcPointerField, out isGcBoxedField);
                        if (isGcPointerField)
                        {
                            gcPointerCount[index]++;
                        }
                        else if (isGcBoxedField)
                        {
                            gcBoxedCount[index]++;
                        }
                        if (size != 0)
                        {
                            int log2Size = GetLog2Size(size);
                            nonGcStaticsCount[index][log2Size]++;
                        }
                    }
                }

                int nonGcInitialOffset;

                switch (pointerSize)
                {
                case 4:
                    nonGcInitialOffset = DomainLocalModuleNormalDynamicEntryOffsetOfDataBlob32Bit;
                    break;

                case 8:
                    nonGcInitialOffset = DomainLocalModuleNormalDynamicEntryOffsetOfDataBlob64Bit;
                    break;

                default:
                    throw new NotImplementedException();
                }

                LayoutInt[] nonGcStaticFieldOffsets = new LayoutInt[StaticIndexCount]
                {
                    new LayoutInt(nonGcInitialOffset),
                    new LayoutInt(nonGcInitialOffset),
                };

                LayoutInt[][] nonGcStatics = new LayoutInt[StaticIndexCount][]
                {
                    new LayoutInt[TargetDetails.MaximumLog2PrimitiveSize + 1],
                    new LayoutInt[TargetDetails.MaximumLog2PrimitiveSize + 1],
                };

                for (int log2Size = TargetDetails.MaximumLog2PrimitiveSize; log2Size >= 0; log2Size--)
                {
                    for (int index = 0; index < StaticIndexCount; index++)
                    {
                        LayoutInt offset = nonGcStaticFieldOffsets[index];
                        nonGcStatics[index][log2Size] = offset;
                        offset += new LayoutInt(nonGcStaticsCount[index][log2Size] << log2Size);
                        nonGcStaticFieldOffsets[index] = offset;
                    }
                }

                LayoutInt[] gcBoxedFieldOffsets   = new LayoutInt[StaticIndexCount];
                LayoutInt[] gcPointerFieldOffsets = new LayoutInt[StaticIndexCount]
                {
                    new LayoutInt(gcBoxedCount[StaticIndexRegular] * pointerSize),
                    new LayoutInt(gcBoxedCount[StaticIndexThreadLocal] * pointerSize)
                };

                foreach (FieldDesc field in defType.GetFields())
                {
                    FieldDefinitionHandle fieldDefHandle = ((EcmaField)field.GetTypicalFieldDefinition()).Handle;
                    FieldDefinition       fieldDef       = module.MetadataReader.GetFieldDefinition(fieldDefHandle);
                    if ((fieldDef.Attributes & (FieldAttributes.Static | FieldAttributes.Literal)) == FieldAttributes.Static)
                    {
                        int  index = (IsFieldThreadStatic(in fieldDef, module.MetadataReader) ? StaticIndexThreadLocal : StaticIndexRegular);
                        int  alignment;
                        int  size;
                        bool isGcPointerField;
                        bool isGcBoxedField;

                        CorElementType corElementType;
                        EntityHandle   valueTypeHandle;

                        GetFieldElementTypeAndValueTypeHandle(in fieldDef, module.MetadataReader, out corElementType, out valueTypeHandle);

                        GetElementTypeInfo(module, field, valueTypeHandle, corElementType, pointerSize, out alignment, out size, out isGcPointerField, out isGcBoxedField);

                        LayoutInt offset = LayoutInt.Zero;

                        if (size != 0)
                        {
                            int log2Size = GetLog2Size(size);
                            offset = nonGcStatics[index][log2Size];
                            nonGcStatics[index][log2Size] += new LayoutInt(1 << log2Size);
                        }
                        if (isGcPointerField)
                        {
                            offset = gcPointerFieldOffsets[index];
                            gcPointerFieldOffsets[index] += new LayoutInt(pointerSize);
                        }
                        else if (isGcBoxedField)
                        {
                            offset = gcBoxedFieldOffsets[index];
                            gcBoxedFieldOffsets[index] += new LayoutInt(pointerSize);
                        }

                        if (fieldsForType == null)
                        {
                            fieldsForType = new List <FieldAndOffset>();
                        }
                        fieldsForType.Add(new FieldAndOffset(field, offset));
                    }
                }

                return(fieldsForType == null ? null : fieldsForType.ToArray());
            }