Beispiel #1
0
        internal void ComputeStaticFieldLayout(StaticLayoutKind layoutKind)
        {
            if (_fieldLayoutFlags.HasFlags(FieldLayoutFlags.ComputedStaticFieldsLayout | FieldLayoutFlags.ComputedStaticRegionLayout))
            {
                return;
            }

            var computedStaticLayout = this.Context.GetLayoutAlgorithmForType(this).ComputeStaticFieldLayout(this, layoutKind);

            if ((computedStaticLayout.NonGcStatics.Size != 0) ||
                (computedStaticLayout.GcStatics.Size != 0) ||
                (computedStaticLayout.ThreadStatics.Size != 0))
            {
                var staticBlockInfo = new StaticBlockInfo
                {
                    NonGcStatics  = computedStaticLayout.NonGcStatics,
                    GcStatics     = computedStaticLayout.GcStatics,
                    ThreadStatics = computedStaticLayout.ThreadStatics
                };
                _staticBlockInfo = staticBlockInfo;
            }

            if (computedStaticLayout.Offsets != null)
            {
                foreach (var fieldAndOffset in computedStaticLayout.Offsets)
                {
                    Debug.Assert(fieldAndOffset.Field.OwningType == this);
                    fieldAndOffset.Field.InitializeOffset(fieldAndOffset.Offset);
                }
                _fieldLayoutFlags.AddFlags(FieldLayoutFlags.ComputedStaticFieldsLayout);
            }

            _fieldLayoutFlags.AddFlags(FieldLayoutFlags.ComputedStaticRegionLayout);
        }
        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.ThreadGcStatics    = new StaticsBlock();
            result.ThreadNonGcStatics = new StaticsBlock();

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

            result.Offsets = new FieldAndOffset[numStaticFields];

            TypeSystemContext context = type.Context;

            PrepareRuntimeSpecificStaticFieldLayout(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))
                {
                    ThrowHelper.ThrowTypeLoadException(ExceptionStringID.ClassLoadGeneral, type);
                }

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

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

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

                index++;
            }
Beispiel #3
0
 public override ComputedStaticFieldLayout ComputeStaticFieldLayout(DefType type, StaticLayoutKind layoutKind)
 {
     return(_fallbackAlgorithm.ComputeStaticFieldLayout(type, layoutKind));
 }
 /// <summary>
 /// Compute the static field layout for a DefType. Must not depend on static field layout for any other type.
 /// </summary>
 public abstract ComputedStaticFieldLayout ComputeStaticFieldLayout(DefType type, StaticLayoutKind layoutKind);
        public override ComputedStaticFieldLayout ComputeStaticFieldLayout(DefType type, StaticLayoutKind layoutKind)
        {
            // We can only reach this for pre-created types where we actually need field information
            // In that case, fall through to one of the other field layout algorithms.
            if (type.HasNativeLayout)
            {
                return(s_nativeLayoutFieldAlgorithm.ComputeStaticFieldLayout(type, layoutKind));
            }
            else if (type is MetadataType)
            {
                return(_metadataFieldLayoutAlgorithm.ComputeStaticFieldLayout(type, layoutKind));
            }

            // No statics information available
            ComputedStaticFieldLayout staticLayout = new ComputedStaticFieldLayout()
            {
                GcStatics     = default(StaticsBlock),
                NonGcStatics  = default(StaticsBlock),
                Offsets       = Array.Empty <FieldAndOffset>(), // No fields are considered to exist for completely NoMetadataTypes
                ThreadStatics = default(StaticsBlock),
            };

            return(staticLayout);
        }
        public unsafe 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;

                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;
        }
Beispiel #7
0
        public override ComputedStaticFieldLayout ComputeStaticFieldLayout(DefType defType, StaticLayoutKind layoutKind)
        {
            ComputedStaticFieldLayout layout = new ComputedStaticFieldLayout();

            if (defType.GetTypeDefinition() is EcmaType ecmaType)
            {
                // ECMA types are the only ones that can have statics
                ModuleFieldLayout moduleFieldLayout = _moduleFieldLayoutMap.GetOrCreateValue(ecmaType.EcmaModule);
                layout.GcStatics          = moduleFieldLayout.GcStatics;
                layout.NonGcStatics       = moduleFieldLayout.NonGcStatics;
                layout.ThreadGcStatics    = moduleFieldLayout.ThreadGcStatics;
                layout.ThreadNonGcStatics = moduleFieldLayout.ThreadNonGcStatics;
                if (defType is EcmaType nonGenericType)
                {
                    OffsetsForType offsetsForType;
                    if (moduleFieldLayout.TypeOffsets.TryGetValue(nonGenericType.Handle, out offsetsForType))
                    {
                        layout.Offsets = _moduleFieldLayoutMap.CalculateTypeLayout(defType, moduleFieldLayout.Module, offsetsForType);
                    }
                }
                else if (defType is InstantiatedType instantiatedType)
                {
                    layout.Offsets = _moduleFieldLayoutMap.GetOrAddDynamicLayout(defType, moduleFieldLayout);
                }
                else
                {
                    throw new NotImplementedException();
                }
            }
            return(layout);
        }
Beispiel #8
0
        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.ThreadStatics = new StaticsBlock()
                {
                    Size = position[(int)NativeFormat.FieldStorage.TLSStatic], LargestAlignment = DefType.MaximumAlignmentPossible
                };
            }

            int curStaticField = 0;

            foreach (NativeLayoutFieldDesc field in type.NativeLayoutFields)
            {
                if (field.IsStatic)
                {
                    layout.Offsets[curStaticField] = new FieldAndOffset(field, fieldOffsets[curStaticField]);
                    curStaticField++;
                }
            }

            return(layout);
        }
Beispiel #9
0
 public unsafe override ComputedStaticFieldLayout ComputeStaticFieldLayout(DefType defType, StaticLayoutKind layoutKind)
 {
     // Static field layout for a RuntimeDeterminedType is not a supported operation
     throw new NotSupportedException();
 }
 public override ComputedStaticFieldLayout ComputeStaticFieldLayout(DefType type, StaticLayoutKind layoutKind)
 {
     return(new ComputedStaticFieldLayout()
     {
         NonGcStatics = new StaticsBlock()
         {
             Size = LayoutInt.Zero, LargestAlignment = LayoutInt.Zero
         },
         GcStatics = new StaticsBlock()
         {
             Size = LayoutInt.Zero, LargestAlignment = LayoutInt.Zero
         },
         ThreadStatics = new StaticsBlock()
         {
             Size = LayoutInt.Zero, LargestAlignment = LayoutInt.Zero
         },
         Offsets = Array.Empty <FieldAndOffset>()
     });
 }
Beispiel #11
0
 /// <summary>
 /// Compute the static field layout for a DefType. Must not depend on static field layout for any other type.
 /// </summary>
 public abstract ComputedStaticFieldLayout ComputeStaticFieldLayout(DefType type, StaticLayoutKind layoutKind);
        public unsafe 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;
                }

                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);
        }
        public override ComputedStaticFieldLayout ComputeStaticFieldLayout(DefType type, StaticLayoutKind layoutKind)
        {
            if (!type.IsTemplateUniversal() && (layoutKind == StaticLayoutKind.StaticRegionSizes))
            {
                return ParseStaticRegionSizesFromNativeLayout(type);
            }

            LowLevelList<int> fieldOffsets;
            int[] 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.ThreadStatics = new StaticsBlock() { Size = position[(int)NativeFormat.FieldStorage.TLSStatic], LargestAlignment = DefType.MaximumAlignmentPossible };
            }

            int curStaticField = 0;
            foreach (NativeLayoutFieldDesc field in type.NativeLayoutFields)
            {
                if (field.IsStatic)
                {
                    layout.Offsets[curStaticField] = new FieldAndOffset(field, fieldOffsets[curStaticField]);
                    curStaticField++;
                }
            }

            return layout;
        }
Beispiel #14
0
        internal void ComputeStaticFieldLayout(StaticLayoutKind layoutKind)
        {
            if (_fieldLayoutFlags.HasFlags(FieldLayoutFlags.ComputedStaticFieldsLayout | FieldLayoutFlags.ComputedStaticRegionLayout))
                return;

            var computedStaticLayout = this.Context.GetLayoutAlgorithmForType(this).ComputeStaticFieldLayout(this, layoutKind);

            if ((computedStaticLayout.NonGcStatics.Size != 0) ||
                (computedStaticLayout.GcStatics.Size != 0) ||
                (computedStaticLayout.ThreadStatics.Size != 0))
            {
                var staticBlockInfo = new StaticBlockInfo
                {
                    NonGcStatics = computedStaticLayout.NonGcStatics,
                    GcStatics = computedStaticLayout.GcStatics,
                    ThreadStatics = computedStaticLayout.ThreadStatics
                };
                _staticBlockInfo = staticBlockInfo;
            }

            if (computedStaticLayout.Offsets != null)
            {
                foreach (var fieldAndOffset in computedStaticLayout.Offsets)
                {
                    Debug.Assert(fieldAndOffset.Field.OwningType == this);
                    fieldAndOffset.Field.InitializeOffset(fieldAndOffset.Offset);
                }
                _fieldLayoutFlags.AddFlags(FieldLayoutFlags.ComputedStaticFieldsLayout);
            }

            _fieldLayoutFlags.AddFlags(FieldLayoutFlags.ComputedStaticRegionLayout);
        }