Коммит
c8a9707235
|
@ -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,10 @@ namespace Internal.TypeSystem
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// How many bytes must be allocated to represent the (potentially GC visible) thread static
|
||||
/// fields of this type.
|
||||
/// How many bytes must be allocated to represent the non GC visible thread static fields
|
||||
/// of this type.
|
||||
/// </summary>
|
||||
public LayoutInt ThreadStaticFieldSize
|
||||
public LayoutInt ThreadNonGcStaticFieldSize
|
||||
{
|
||||
get
|
||||
{
|
||||
|
@ -228,7 +229,39 @@ namespace Internal.TypeSystem
|
|||
{
|
||||
ComputeStaticFieldLayout(StaticLayoutKind.StaticRegionSizes);
|
||||
}
|
||||
return _staticBlockInfo == null ? LayoutInt.Zero : _staticBlockInfo.ThreadStatics.Size;
|
||||
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 ThreadGcStaticFieldSize
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_fieldLayoutFlags.HasFlags(FieldLayoutFlags.ComputedStaticRegionLayout))
|
||||
{
|
||||
ComputeStaticFieldLayout(StaticLayoutKind.StaticRegionSizes);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>()
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -212,7 +212,7 @@ namespace Internal.IL
|
|||
TypeSystemContext context = elementType.Context;
|
||||
MetadataType helperType = context.SystemModule.GetKnownType("Internal.IntrinsicSupport", "EqualityComparerHelpers");
|
||||
|
||||
MethodDesc methodToCall = null;
|
||||
MethodDesc methodToCall;
|
||||
if (elementType.IsEnum)
|
||||
{
|
||||
methodToCall = helperType.GetKnownMethod("EnumOnlyEquals", null).MakeInstantiatedMethod(elementType);
|
||||
|
@ -230,17 +230,14 @@ namespace Internal.IL
|
|||
methodToCall = helperType.GetKnownMethod("StructOnlyNormalEquals", null).MakeInstantiatedMethod(elementType);
|
||||
}
|
||||
|
||||
if (methodToCall != null)
|
||||
return new ILStubMethodIL(method, new byte[]
|
||||
{
|
||||
return new ILStubMethodIL(method, new byte[]
|
||||
{
|
||||
(byte)ILOpcode.ldarg_0,
|
||||
(byte)ILOpcode.ldarg_1,
|
||||
(byte)ILOpcode.call, 1, 0, 0, 0,
|
||||
(byte)ILOpcode.ret
|
||||
},
|
||||
Array.Empty<LocalVariableDefinition>(), new object[] { methodToCall });
|
||||
}
|
||||
(byte)ILOpcode.ldarg_0,
|
||||
(byte)ILOpcode.ldarg_1,
|
||||
(byte)ILOpcode.call, 1, 0, 0, 0,
|
||||
(byte)ILOpcode.ret
|
||||
},
|
||||
Array.Empty<LocalVariableDefinition>(), new object[] { methodToCall });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -366,7 +366,7 @@ namespace ILCompiler
|
|||
Debug.Assert(!type.IsGenericDefinition);
|
||||
|
||||
MetadataType metadataType = type as MetadataType;
|
||||
if (metadataType != null && metadataType.ThreadStaticFieldSize.AsInt > 0)
|
||||
if (metadataType != null && metadataType.ThreadGcStaticFieldSize.AsInt > 0)
|
||||
{
|
||||
_graph.AddRoot(_factory.TypeThreadStaticIndex(metadataType), reason);
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@ using System.Collections.Generic;
|
|||
|
||||
using Internal.TypeSystem;
|
||||
|
||||
using Debug = System.Diagnostics.Debug;
|
||||
|
||||
namespace ILCompiler
|
||||
{
|
||||
internal class CompilerMetadataFieldLayoutAlgorithm : MetadataFieldLayoutAlgorithm
|
||||
|
@ -15,7 +17,7 @@ namespace ILCompiler
|
|||
{
|
||||
// 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.ThreadStatics.Size = context.Target.LayoutPointerSize;
|
||||
layout.ThreadGcStatics.Size = context.Target.LayoutPointerSize;
|
||||
}
|
||||
|
||||
protected override void FinalizeRuntimeSpecificStaticFieldLayout(TypeSystemContext context, ref ComputedStaticFieldLayout layout)
|
||||
|
@ -26,10 +28,14 @@ namespace ILCompiler
|
|||
{
|
||||
layout.GcStatics.Size = LayoutInt.Zero;
|
||||
}
|
||||
if (layout.ThreadStatics.Size == context.Target.LayoutPointerSize)
|
||||
if (layout.ThreadGcStatics.Size == context.Target.LayoutPointerSize)
|
||||
{
|
||||
layout.ThreadStatics.Size = LayoutInt.Zero;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -424,6 +424,9 @@ namespace ILCompiler
|
|||
{
|
||||
Debug.Assert(field.IsStatic);
|
||||
|
||||
if (field.IsThreadStatic)
|
||||
return true;
|
||||
|
||||
TypeDesc fieldType = field.FieldType;
|
||||
if (fieldType.IsValueType)
|
||||
return ((DefType)fieldType).ContainsGCPointers;
|
||||
|
|
|
@ -982,7 +982,7 @@ namespace ILCompiler.DependencyAnalysis
|
|||
yield return new DependencyListEntry(GetStaticsNode(context, out ignored), "type gc static info");
|
||||
}
|
||||
|
||||
if (_type.GetClosestDefType().ThreadStaticFieldSize.AsInt > 0)
|
||||
if (_type.GetClosestDefType().ThreadGcStaticFieldSize.AsInt > 0)
|
||||
{
|
||||
BagElementKind ignored;
|
||||
yield return new DependencyListEntry(GetThreadStaticsNode(context, out ignored), "type thread static info");
|
||||
|
@ -1201,9 +1201,9 @@ namespace ILCompiler.DependencyAnalysis
|
|||
layoutInfo.AppendUnsigned(staticDescBagType, gcStaticsSymbolIndex);
|
||||
}
|
||||
|
||||
if (closestDefType.ThreadStaticFieldSize.AsInt != 0)
|
||||
if (closestDefType.ThreadGcStaticFieldSize.AsInt != 0)
|
||||
{
|
||||
layoutInfo.AppendUnsigned(BagElementKind.ThreadStaticDataSize, checked((uint)closestDefType.ThreadStaticFieldSize.AsInt));
|
||||
layoutInfo.AppendUnsigned(BagElementKind.ThreadStaticDataSize, checked((uint)closestDefType.ThreadGcStaticFieldSize.AsInt));
|
||||
BagElementKind threadStaticDescBagType;
|
||||
ISymbolNode threadStaticsDescSymbol = GetThreadStaticsNode(factory, out threadStaticDescBagType);
|
||||
uint threadStaticsSymbolIndex = factory.MetadataManager.NativeLayoutInfo.StaticsReferences.GetIndex(threadStaticsDescSymbol);
|
||||
|
|
|
@ -70,7 +70,7 @@ namespace ILCompiler.DependencyAnalysis
|
|||
dependencies.Add(factory.Indirection(factory.TypeNonGCStaticsSymbol(metadataType)), "Non-GC statics indirection for StaticsInfoHashtable");
|
||||
}
|
||||
|
||||
if (metadataType.ThreadStaticFieldSize.AsInt > 0)
|
||||
if (metadataType.ThreadGcStaticFieldSize.AsInt > 0)
|
||||
{
|
||||
if (factory.Target.Abi == TargetAbi.ProjectN)
|
||||
{
|
||||
|
@ -116,7 +116,7 @@ namespace ILCompiler.DependencyAnalysis
|
|||
ISymbolNode nonGCStaticIndirection = factory.Indirection(factory.TypeNonGCStaticsSymbol(metadataType));
|
||||
bag.AppendUnsigned(BagElementKind.NonGcStaticData, _nativeStaticsReferences.GetIndex(nonGCStaticIndirection));
|
||||
}
|
||||
if (metadataType.ThreadStaticFieldSize.AsInt > 0)
|
||||
if (metadataType.ThreadGcStaticFieldSize.AsInt > 0)
|
||||
{
|
||||
if (factory.Target.Abi == TargetAbi.ProjectN)
|
||||
{
|
||||
|
|
|
@ -58,7 +58,7 @@ namespace ILCompiler.DependencyAnalysis
|
|||
{
|
||||
ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly);
|
||||
builder.RequireInitialPointerAlignment();
|
||||
builder.EmitZeros(_type.ThreadStaticFieldSize.AsInt);
|
||||
builder.EmitZeros(_type.ThreadGcStaticFieldSize.AsInt);
|
||||
builder.AddSymbol(this);
|
||||
return builder.ToObjectData();
|
||||
}
|
||||
|
|
|
@ -545,7 +545,7 @@ namespace ILCompiler
|
|||
}
|
||||
}
|
||||
|
||||
if (metadataType.ThreadStaticFieldSize.AsInt > 0)
|
||||
if (metadataType.ThreadGcStaticFieldSize.AsInt > 0)
|
||||
{
|
||||
dependencies.Add(((UtcNodeFactory)factory).TypeThreadStaticsOffsetSymbol(metadataType), "Thread statics for ReflectionFieldMap entry");
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace TypeSystemTests
|
|||
{
|
||||
// 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.ThreadStatics.Size = context.Target.LayoutPointerSize;
|
||||
layout.ThreadGcStatics.Size = context.Target.LayoutPointerSize;
|
||||
}
|
||||
|
||||
protected override void FinalizeRuntimeSpecificStaticFieldLayout(TypeSystemContext context, ref ComputedStaticFieldLayout layout)
|
||||
|
@ -26,9 +26,9 @@ namespace TypeSystemTests
|
|||
{
|
||||
layout.GcStatics.Size = LayoutInt.Zero;
|
||||
}
|
||||
if (layout.ThreadStatics.Size == context.Target.LayoutPointerSize)
|
||||
if (layout.ThreadGcStatics.Size == context.Target.LayoutPointerSize)
|
||||
{
|
||||
layout.ThreadStatics.Size = LayoutInt.Zero;
|
||||
layout.ThreadGcStatics.Size = LayoutInt.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -110,6 +110,9 @@ namespace TypeSystemTests
|
|||
{
|
||||
Debug.Assert(field.IsStatic);
|
||||
|
||||
if (field.IsThreadStatic)
|
||||
return true;
|
||||
|
||||
TypeDesc fieldType = field.FieldType;
|
||||
if (fieldType.IsValueType)
|
||||
return ((DefType)fieldType).ContainsGCPointers;
|
||||
|
|
|
@ -200,8 +200,8 @@ namespace TypeSystemTests
|
|||
Assert.Equal(LayoutInt.Zero, context.UniversalCanonType.GCStaticFieldSize);
|
||||
Assert.Equal(LayoutInt.Zero, context.UniversalCanonType.NonGCStaticFieldAlignment);
|
||||
Assert.Equal(LayoutInt.Zero, context.UniversalCanonType.NonGCStaticFieldSize);
|
||||
Assert.Equal(LayoutInt.Zero, context.UniversalCanonType.ThreadStaticFieldAlignment);
|
||||
Assert.Equal(LayoutInt.Zero, context.UniversalCanonType.ThreadStaticFieldSize);
|
||||
Assert.Equal(LayoutInt.Zero, context.UniversalCanonType.ThreadGcStaticFieldAlignment);
|
||||
Assert.Equal(LayoutInt.Zero, context.UniversalCanonType.ThreadGcStaticFieldSize);
|
||||
}
|
||||
[Fact]
|
||||
public void TestLayoutOfUniversalCanonType()
|
||||
|
|
|
@ -120,7 +120,8 @@ namespace Internal.Runtime.TypeLoader
|
|||
{
|
||||
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 };
|
||||
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;
|
||||
|
@ -179,7 +180,8 @@ namespace Internal.Runtime.TypeLoader
|
|||
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 },
|
||||
ThreadGcStatics = new StaticsBlock() { Size = threadDataSize, LargestAlignment = DefType.MaximumAlignmentPossible },
|
||||
ThreadNonGcStatics = new StaticsBlock() { Size = LayoutInt.Zero, LargestAlignment = LayoutInt.Zero },
|
||||
};
|
||||
|
||||
return staticLayout;
|
||||
|
|
|
@ -83,7 +83,8 @@ namespace Internal.Runtime.TypeLoader
|
|||
GcStatics = default(StaticsBlock),
|
||||
NonGcStatics = default(StaticsBlock),
|
||||
Offsets = Array.Empty<FieldAndOffset>(), // No fields are considered to exist for completely NoMetadataTypes
|
||||
ThreadStatics = default(StaticsBlock),
|
||||
ThreadGcStatics = default(StaticsBlock),
|
||||
ThreadNonGcStatics = default(StaticsBlock),
|
||||
};
|
||||
return staticLayout;
|
||||
}
|
||||
|
|
|
@ -507,7 +507,7 @@ namespace Internal.Runtime.TypeLoader
|
|||
DefType defType = TypeBeingBuilt as DefType;
|
||||
if (defType != null && !defType.IsGenericDefinition)
|
||||
{
|
||||
return defType.ThreadStaticFieldSize.AsInt;
|
||||
return defType.ThreadGcStaticFieldSize.AsInt;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -532,7 +532,7 @@ namespace Internal.Runtime.TypeLoader
|
|||
public uint NumSealedVTableEntries;
|
||||
public int[] GenericVarianceFlags;
|
||||
|
||||
// Sentinel static to allow us to initializae _instanceLayout to something
|
||||
// Sentinel static to allow us to initialize _instanceLayout to something
|
||||
// and then detect that InstanceGCLayout should return null
|
||||
private static LowLevelList<bool> s_emptyLayout = new LowLevelList<bool>();
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче