diff options
author | Simon Nattress <simonn@microsoft.com> | 2018-09-04 20:13:37 +0300 |
---|---|---|
committer | Simon Nattress <simonn@microsoft.com> | 2018-09-04 20:13:37 +0300 |
commit | 6a1658b5cfd9809755553659abb7586d53b06eb3 (patch) | |
tree | 43f0d1295901cb2c0a2d233fbca992ccdd360714 /src/Common | |
parent | 473e0dba00cfd48390aea31d39b2d8072d487b9e (diff) |
Support separate blocks for Gc / Non-Gc thread statics in the managed type system. This is used in the Cross-plat AOT compiler for CoreCLR ready-to-run.
[tfs-changeset: 1712607]
Diffstat (limited to 'src/Common')
6 files changed, 59 insertions, 19 deletions
diff --git a/src/Common/src/TypeSystem/Common/DefType.FieldLayout.cs b/src/Common/src/TypeSystem/Common/DefType.FieldLayout.cs index 497701812..7f5638607 100644 --- a/src/Common/src/TypeSystem/Common/DefType.FieldLayout.cs +++ b/src/Common/src/TypeSystem/Common/DefType.FieldLayout.cs @@ -55,7 +55,8 @@ namespace Internal.TypeSystem { public StaticsBlock NonGcStatics; public StaticsBlock GcStatics; - public StaticsBlock ThreadStatics; + public StaticsBlock ThreadNonGcStatics; + public StaticsBlock ThreadGcStatics; } ThreadSafeFlags _fieldLayoutFlags; @@ -217,10 +218,42 @@ namespace Internal.TypeSystem } /// <summary> + /// How many bytes must be allocated to represent the non GC visible thread static fields + /// of this type. + /// </summary> + public LayoutInt ThreadNonGcStaticFieldSize + { + get + { + if (!_fieldLayoutFlags.HasFlags(FieldLayoutFlags.ComputedStaticRegionLayout)) + { + ComputeStaticFieldLayout(StaticLayoutKind.StaticRegionSizes); + } + return _staticBlockInfo == null ? LayoutInt.Zero : _staticBlockInfo.ThreadNonGcStatics.Size; + } + } + + /// <summary> + /// What is the alignment required for allocating the non GC visible thread static fields + /// of this type. + /// </summary> + public LayoutInt ThreadNonGcStaticFieldAlignment + { + get + { + if (!_fieldLayoutFlags.HasFlags(FieldLayoutFlags.ComputedStaticRegionLayout)) + { + ComputeStaticFieldLayout(StaticLayoutKind.StaticRegionSizes); + } + return _staticBlockInfo == null ? LayoutInt.Zero : _staticBlockInfo.ThreadNonGcStatics.LargestAlignment; + } + } + + /// <summary> /// How many bytes must be allocated to represent the (potentially GC visible) thread static /// fields of this type. /// </summary> - public LayoutInt ThreadStaticFieldSize + public LayoutInt ThreadGcStaticFieldSize { get { @@ -228,7 +261,7 @@ namespace Internal.TypeSystem { ComputeStaticFieldLayout(StaticLayoutKind.StaticRegionSizes); } - return _staticBlockInfo == null ? LayoutInt.Zero : _staticBlockInfo.ThreadStatics.Size; + return _staticBlockInfo == null ? LayoutInt.Zero : _staticBlockInfo.ThreadGcStatics.Size; } } @@ -236,7 +269,7 @@ namespace Internal.TypeSystem /// What is the alignment required for allocating the (potentially GC visible) thread static /// fields of this type. /// </summary> - public LayoutInt ThreadStaticFieldAlignment + public LayoutInt ThreadGcStaticFieldAlignment { get { @@ -244,7 +277,7 @@ namespace Internal.TypeSystem { ComputeStaticFieldLayout(StaticLayoutKind.StaticRegionSizes); } - return _staticBlockInfo == null ? LayoutInt.Zero : _staticBlockInfo.ThreadStatics.LargestAlignment; + return _staticBlockInfo == null ? LayoutInt.Zero : _staticBlockInfo.ThreadGcStatics.LargestAlignment; } } @@ -328,13 +361,15 @@ namespace Internal.TypeSystem if ((computedStaticLayout.NonGcStatics.Size != LayoutInt.Zero) || (computedStaticLayout.GcStatics.Size != LayoutInt.Zero) || - (computedStaticLayout.ThreadStatics.Size != LayoutInt.Zero)) + (computedStaticLayout.ThreadNonGcStatics.Size != LayoutInt.Zero) || + (computedStaticLayout.ThreadGcStatics.Size != LayoutInt.Zero)) { var staticBlockInfo = new StaticBlockInfo { NonGcStatics = computedStaticLayout.NonGcStatics, GcStatics = computedStaticLayout.GcStatics, - ThreadStatics = computedStaticLayout.ThreadStatics + ThreadNonGcStatics = computedStaticLayout.ThreadNonGcStatics, + ThreadGcStatics = computedStaticLayout.ThreadGcStatics }; _staticBlockInfo = staticBlockInfo; } diff --git a/src/Common/src/TypeSystem/Common/FieldDesc.FieldLayout.cs b/src/Common/src/TypeSystem/Common/FieldDesc.FieldLayout.cs index 4f095421c..4452e8d6e 100644 --- a/src/Common/src/TypeSystem/Common/FieldDesc.FieldLayout.cs +++ b/src/Common/src/TypeSystem/Common/FieldDesc.FieldLayout.cs @@ -33,16 +33,13 @@ namespace Internal.TypeSystem } /// <summary> - /// For static fields, represents whether or not the field is held in the GC or non GC statics region - /// Does not apply to thread static fields. + /// For static fields, represents whether or not the field is held in the GC or non GC statics region. /// </summary> public bool HasGCStaticBase { get { - // If this assert fires then make sure the caller checks the IsThreadStatic attribute - // of FieldDesc before checking its HasGCStaticBase property. - Debug.Assert(IsStatic && !IsThreadStatic); + Debug.Assert(IsStatic); return Context.ComputeHasGCStaticBase(this); } } diff --git a/src/Common/src/TypeSystem/Common/FieldLayoutAlgorithm.cs b/src/Common/src/TypeSystem/Common/FieldLayoutAlgorithm.cs index eee09f1b3..720c80a65 100644 --- a/src/Common/src/TypeSystem/Common/FieldLayoutAlgorithm.cs +++ b/src/Common/src/TypeSystem/Common/FieldLayoutAlgorithm.cs @@ -101,7 +101,8 @@ namespace Internal.TypeSystem { public StaticsBlock NonGcStatics; public StaticsBlock GcStatics; - public StaticsBlock ThreadStatics; + public StaticsBlock ThreadNonGcStatics; + public StaticsBlock ThreadGcStatics; /// <summary> /// If Offsets is non-null, then all field based layout is complete. diff --git a/src/Common/src/TypeSystem/Common/MetadataFieldLayoutAlgorithm.cs b/src/Common/src/TypeSystem/Common/MetadataFieldLayoutAlgorithm.cs index 5092f8a07..94074e1d8 100644 --- a/src/Common/src/TypeSystem/Common/MetadataFieldLayoutAlgorithm.cs +++ b/src/Common/src/TypeSystem/Common/MetadataFieldLayoutAlgorithm.cs @@ -185,7 +185,8 @@ namespace Internal.TypeSystem ComputedStaticFieldLayout result; result.GcStatics = new StaticsBlock(); result.NonGcStatics = new StaticsBlock(); - result.ThreadStatics = new StaticsBlock(); + result.ThreadGcStatics = new StaticsBlock(); + result.ThreadNonGcStatics = new StaticsBlock(); if (numStaticFields == 0) { @@ -231,7 +232,12 @@ namespace Internal.TypeSystem private ref StaticsBlock GetStaticsBlockForField(ref ComputedStaticFieldLayout layout, FieldDesc field) { if (field.IsThreadStatic) - return ref layout.ThreadStatics; + { + if (field.HasGCStaticBase) + return ref layout.ThreadGcStatics; + else + return ref layout.ThreadNonGcStatics; + } else if (field.HasGCStaticBase) return ref layout.GcStatics; else diff --git a/src/Common/src/TypeSystem/Common/UniversalCanonLayoutAlgorithm.cs b/src/Common/src/TypeSystem/Common/UniversalCanonLayoutAlgorithm.cs index f6c475abd..42eb4197f 100644 --- a/src/Common/src/TypeSystem/Common/UniversalCanonLayoutAlgorithm.cs +++ b/src/Common/src/TypeSystem/Common/UniversalCanonLayoutAlgorithm.cs @@ -45,7 +45,8 @@ namespace Internal.TypeSystem { 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 }, + ThreadNonGcStatics = new StaticsBlock() { Size = LayoutInt.Zero, LargestAlignment = LayoutInt.Zero }, + ThreadGcStatics = new StaticsBlock() { Size = LayoutInt.Zero, LargestAlignment = LayoutInt.Zero }, Offsets = Array.Empty<FieldAndOffset>() }; } diff --git a/src/Common/src/TypeSystem/Common/Utilities/GCPointerMap.Algorithm.cs b/src/Common/src/TypeSystem/Common/Utilities/GCPointerMap.Algorithm.cs index 95ec0f63e..8f9a1cd34 100644 --- a/src/Common/src/TypeSystem/Common/Utilities/GCPointerMap.Algorithm.cs +++ b/src/Common/src/TypeSystem/Common/Utilities/GCPointerMap.Algorithm.cs @@ -61,11 +61,11 @@ namespace Internal.TypeSystem /// </summary> public static GCPointerMap FromThreadStaticLayout(DefType type) { - GCPointerMapBuilder builder = new GCPointerMapBuilder(type.ThreadStaticFieldSize.AsInt, type.Context.Target.PointerSize); + GCPointerMapBuilder builder = new GCPointerMapBuilder(type.ThreadGcStaticFieldSize.AsInt, type.Context.Target.PointerSize); foreach (FieldDesc field in type.GetFields()) { - if (!field.IsStatic || field.HasRva || field.IsLiteral || !field.IsThreadStatic) + if (!field.IsStatic || field.HasRva || field.IsLiteral || !field.IsThreadStatic || !field.HasGCStaticBase) continue; TypeDesc fieldType = field.FieldType; @@ -85,7 +85,7 @@ namespace Internal.TypeSystem } } - Debug.Assert(builder.ToGCMap().Size * type.Context.Target.PointerSize >= type.ThreadStaticFieldSize.AsInt); + Debug.Assert(builder.ToGCMap().Size * type.Context.Target.PointerSize >= type.ThreadGcStaticFieldSize.AsInt); return builder.ToGCMap(); } |