示例#1
0
        public override ComputedStaticFieldLayout ComputeStaticFieldLayout(DefType defType, StaticLayoutKind layoutKind)
        {
            MetadataType type            = (MetadataType)defType;
            int          numStaticFields = 0;

            foreach (var field in type.GetFields())
            {
                if (!field.IsStatic || field.HasRva || field.IsLiteral)
                {
                    continue;
                }

                numStaticFields++;
            }

            ComputedStaticFieldLayout result;

            result.GcStatics     = new StaticsBlock();
            result.NonGcStatics  = new StaticsBlock();
            result.ThreadStatics = new StaticsBlock();

            if (numStaticFields == 0)
            {
                result.Offsets = Array.Empty <FieldAndOffset>();
                return(result);
            }

            result.Offsets = new FieldAndOffset[numStaticFields];

            PrepareRuntimeSpecificStaticFieldLayout(type.Context, ref result);

            int index = 0;

            foreach (var field in type.GetFields())
            {
                // Nonstatic fields, literal fields, and RVA mapped fields don't participate in layout
                if (!field.IsStatic || field.HasRva || field.IsLiteral)
                {
                    continue;
                }

                TypeDesc fieldType = field.FieldType;
                if (fieldType.IsByRef || (fieldType.IsValueType && ((DefType)fieldType).IsByRefLike))
                {
                    throw new TypeSystemException.TypeLoadException(ExceptionStringID.ClassLoadGeneral, type);
                }

                ref StaticsBlock block            = ref GetStaticsBlockForField(ref result, field);
                SizeAndAlignment sizeAndAlignment = ComputeFieldSizeAndAlignment(fieldType, type.Context.Target.DefaultPackingSize);

                block.Size            = LayoutInt.AlignUp(block.Size, sizeAndAlignment.Alignment);
                result.Offsets[index] = new FieldAndOffset(field, block.Size);
                block.Size            = block.Size + sizeAndAlignment.Size;

                block.LargestAlignment = LayoutInt.Max(block.LargestAlignment, sizeAndAlignment.Alignment);

                index++;
            }
        private static SizeAndAlignment ComputeInstanceSize(MetadataType type, int count, int alignment, out SizeAndAlignment byteCount)
        {
            SizeAndAlignment result;

            int targetPointerSize = type.Context.Target.PointerSize;

            // Pad the length of structs to be 1 if they are empty so we have no zero-length structures
            if (type.IsValueType && count == 0)
            {
                count = 1;
            }

            if (type.IsValueType)
            {
                count = AlignmentHelper.AlignUp(count, alignment);
                result.Size = count;
                result.Alignment = alignment;
            }
            else
            {
                result.Size = targetPointerSize;
                result.Alignment = targetPointerSize;
                if (type.HasBaseType)
                    alignment = Math.Max(alignment, type.BaseType.InstanceByteAlignment);
            }

            // Determine the alignment needed by the type when allocated
            // This is target specific, and not just pointer sized due to 
            // 8 byte alignment requirements on ARM for longs and doubles
            alignment = type.Context.Target.GetObjectAlignment(alignment);

            byteCount.Size = count;
            byteCount.Alignment = alignment;

            return result;
        }
示例#3
0
        private static SizeAndAlignment ComputeInstanceSize(MetadataType type, int count, int alignment, out SizeAndAlignment byteCount)
        {
            SizeAndAlignment result;

            int targetPointerSize = type.Context.Target.PointerSize;

            // Pad the length of structs to be 1 if they are empty so we have no zero-length structures
            if (type.IsValueType && count == 0)
            {
                count = 1;
            }

            if (type.IsValueType)
            {
                count            = AlignmentHelper.AlignUp(count, alignment);
                result.Size      = count;
                result.Alignment = alignment;
            }
            else
            {
                result.Size      = targetPointerSize;
                result.Alignment = targetPointerSize;
                if (type.HasBaseType)
                {
                    alignment = Math.Max(alignment, type.BaseType.InstanceByteAlignment);
                }
            }

            // Determine the alignment needed by the type when allocated
            // This is target specific, and not just pointer sized due to
            // 8 byte alignment requirements on ARM for longs and doubles
            alignment = type.Context.Target.GetObjectAlignment(alignment);

            byteCount.Size      = count;
            byteCount.Alignment = alignment;

            return(result);
        }
示例#4
0
        public unsafe override ComputedStaticFieldLayout ComputeStaticFieldLayout(DefType defType)
        {
            MetadataType type            = (MetadataType)defType;
            int          numStaticFields = 0;

            foreach (var field in type.GetFields())
            {
                if (!field.IsStatic || field.HasRva || field.IsLiteral)
                {
                    continue;
                }

                numStaticFields++;
            }

            ComputedStaticFieldLayout result;

            result.GcStatics     = new StaticsBlock();
            result.NonGcStatics  = new StaticsBlock();
            result.ThreadStatics = new StaticsBlock();

            if (numStaticFields == 0)
            {
                result.Offsets = null;
                return(result);
            }

            result.Offsets = new FieldAndOffset[numStaticFields];

            PrepareRuntimeSpecificStaticFieldLayout(type.Context, ref result);

            int index = 0;

            foreach (var field in type.GetFields())
            {
                // Nonstatic fields, literal fields, and RVA mapped fields don't participate in layout
                if (!field.IsStatic || field.HasRva || field.IsLiteral)
                {
                    continue;
                }

                StaticsBlock *block =
                    field.IsThreadStatic ? &result.ThreadStatics :
                    field.HasGCStaticBase ? &result.GcStatics :
                    &result.NonGcStatics;

                SizeAndAlignment sizeAndAlignment = ComputeFieldSizeAndAlignment(field.FieldType, type.Context.Target.DefaultPackingSize);

                block->Size           = AlignmentHelper.AlignUp(block->Size, sizeAndAlignment.Alignment);
                result.Offsets[index] = new FieldAndOffset(field, block->Size);
                block->Size           = checked (block->Size + sizeAndAlignment.Size);

                block->LargestAlignment = Math.Max(block->LargestAlignment, sizeAndAlignment.Alignment);

                index++;
            }

            FinalizeRuntimeSpecificStaticFieldLayout(type.Context, ref result);

            return(result);
        }