Merge pull request #6291 from dotnet/nmirror

Merge nmirror to master
This commit is contained in:
Jan Kotas 2018-09-04 18:35:36 -07:00 коммит произвёл GitHub
Родитель bdd0b15d92 3577e093ce
Коммит c8a9707235
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
20 изменённых файлов: 105 добавлений и 53 удалений

Просмотреть файл

@ -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>();