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); }
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 ThreadGcStatics = default(StaticsBlock), ThreadNonGcStatics = default(StaticsBlock), }; return(staticLayout); }
private ComputedStaticFieldLayout ParseStaticRegionSizesFromNativeLayout(TypeDesc type) { LayoutInt nonGcDataSize = LayoutInt.Zero; LayoutInt gcDataSize = LayoutInt.Zero; LayoutInt threadDataSize = LayoutInt.Zero; 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 = new LayoutInt(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 = new LayoutInt(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 = new LayoutInt(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); }
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.ThreadGcStatics = new StaticsBlock() { Size = position[(int)NativeFormat.FieldStorage.TLSStatic], LargestAlignment = DefType.MaximumAlignmentPossible }; layout.ThreadNonGcStatics = new StaticsBlock() { Size = LayoutInt.Zero, LargestAlignment = LayoutInt.Zero }; } int curStaticField = 0; foreach (NativeLayoutFieldDesc field in type.NativeLayoutFields) { if (field.IsStatic) { layout.Offsets[curStaticField] = new FieldAndOffset(field, fieldOffsets[curStaticField]); curStaticField++; } } return(layout); }
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.LayoutPointerSize) { layout.GcStatics.Size = LayoutInt.Zero; } if (layout.ThreadGcStatics.Size == context.Target.LayoutPointerSize) { layout.ThreadGcStatics.Size = LayoutInt.Zero; } // CoreRT makes no distinction between Gc / non-Gc thread statics. All are placed into ThreadGcStatics since thread statics // are typically rare. Debug.Assert(layout.ThreadNonGcStatics.Size == LayoutInt.Zero); }
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.LayoutPointerSize; layout.ThreadGcStatics.Size = context.Target.LayoutPointerSize; }
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; } }
protected override void PrepareRuntimeSpecificStaticFieldLayout(TypeSystemContext context, ref ComputedStaticFieldLayout layout) { LayoutInt offset = GetGCStaticFieldOffset(context); layout.GcStatics.Size = offset; layout.ThreadGcStatics.Size = offset; }