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++; }
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; }
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) { 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); }
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>() }); }
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; }
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); }