protected override void FinalizeRuntimeSpecificStaticFieldLayout(TypeSystemContext context, ref ComputedStaticFieldLayout layout)
 {
     // If the size of GCStatics is equal to the size set in PrepareRuntimeSpecificStaticFieldLayout, we
     // don't have any GC statics
     if (layout.GcStatics.Size == context.Target.PointerSize)
     {
         layout.GcStatics.Size = 0;
     }
 }
 /// <summary>
 /// Called during static field layout to finish static block layout
 /// </summary>
 protected virtual void FinalizeRuntimeSpecificStaticFieldLayout(TypeSystemContext context, ref ComputedStaticFieldLayout layout)
 {
 }
 protected override void PrepareRuntimeSpecificStaticFieldLayout(TypeSystemContext context, ref ComputedStaticFieldLayout layout)
 {
     // GC statics start with a pointer to the "EEType" that signals the size and GCDesc to the GC
     layout.GcStatics.Size = context.Target.PointerSize;
 }
Beispiel #4
0
 /// <summary>
 /// Called during static field layout to finish static block layout
 /// </summary>
 protected virtual void FinalizeRuntimeSpecificStaticFieldLayout(TypeSystemContext context, ref ComputedStaticFieldLayout layout)
 {
 }
        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;
        }
        private ComputedStaticFieldLayout ParseStaticRegionSizesFromNativeLayout(TypeDesc type)
        {
            int nonGcDataSize = 0;
            int gcDataSize = 0;
            int threadDataSize = 0;

            TypeBuilderState state = type.GetOrCreateTypeBuilderState();
            NativeParser typeInfoParser = state.GetParserForNativeLayoutInfo();

            BagElementKind kind;
            while ((kind = typeInfoParser.GetBagElementKind()) != BagElementKind.End)
            {
                switch (kind)
                {
                    case BagElementKind.NonGcStaticDataSize:
                        TypeLoaderLogger.WriteLine("Found BagElementKind.NonGcStaticDataSize");
                        // Use checked typecast to int to ensure there aren't any overflows/truncations (size value used in allocation of memory later)
                        nonGcDataSize = checked((int)typeInfoParser.GetUnsigned());
                        break;

                    case BagElementKind.GcStaticDataSize:
                        TypeLoaderLogger.WriteLine("Found BagElementKind.GcStaticDataSize");
                        // Use checked typecast to int to ensure there aren't any overflows/truncations (size value used in allocation of memory later)
                        gcDataSize = checked((int)typeInfoParser.GetUnsigned());
                        break;

                    case BagElementKind.ThreadStaticDataSize:
                        TypeLoaderLogger.WriteLine("Found BagElementKind.ThreadStaticDataSize");
                        // Use checked typecast to int to ensure there aren't any overflows/truncations (size value used in allocation of memory later)
                        threadDataSize = checked((int)typeInfoParser.GetUnsigned());
                        break;

                    default:
                        typeInfoParser.SkipInteger();
                        break;
                }
            }

            ComputedStaticFieldLayout staticLayout = new ComputedStaticFieldLayout()
            {
                GcStatics = new StaticsBlock() { Size = gcDataSize, LargestAlignment = DefType.MaximumAlignmentPossible },
                NonGcStatics = new StaticsBlock() { Size = nonGcDataSize, LargestAlignment = DefType.MaximumAlignmentPossible },
                Offsets = null, // We're not computing field offsets here, so return null
                ThreadStatics = new StaticsBlock() { Size = threadDataSize, LargestAlignment = DefType.MaximumAlignmentPossible },
            };

            return staticLayout;
        }