Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/ILCompiler.Compiler/src/Compiler/UserDefinedTypeDescriptor.cs')
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/UserDefinedTypeDescriptor.cs135
1 files changed, 119 insertions, 16 deletions
diff --git a/src/ILCompiler.Compiler/src/Compiler/UserDefinedTypeDescriptor.cs b/src/ILCompiler.Compiler/src/Compiler/UserDefinedTypeDescriptor.cs
index c91a1f08e..7427c4981 100644
--- a/src/ILCompiler.Compiler/src/Compiler/UserDefinedTypeDescriptor.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/UserDefinedTypeDescriptor.cs
@@ -81,7 +81,9 @@ namespace ILCompiler
descriptor.ReturnType = GetVariableTypeIndex(DebuggerCanonicalize(signature.ReturnType));
descriptor.ThisAdjust = 0;
descriptor.CallingConvention = 0x4; // Near fastcall
- descriptor.TypeIndexOfThisPointer = signature.IsStatic ? (uint)PrimitiveTypeDescriptor.TYPE_ENUM.T_VOID : GetThisTypeIndex(method.OwningType);
+ descriptor.TypeIndexOfThisPointer = signature.IsStatic ?
+ GetPrimitiveTypeIndex(method.OwningType.Context.GetWellKnownType(WellKnownType.Void)) :
+ GetThisTypeIndex(method.OwningType);
descriptor.ContainingClass = GetTypeIndex(method.OwningType, true);
try
@@ -139,7 +141,7 @@ namespace ILCompiler
uint variableTypeIndex = 0;
if (type.IsPrimitive)
{
- variableTypeIndex = PrimitiveTypeDescriptor.GetPrimitiveTypeIndex(type);
+ variableTypeIndex = GetPrimitiveTypeIndex(type);
}
else
{
@@ -180,6 +182,10 @@ namespace ILCompiler
variableTypeIndex = GetEnumTypeIndex(type);
GetTypeIndex(type, false); // Ensure regular structure record created
+
+ _enumTypes[type] = variableTypeIndex;
+
+ return variableTypeIndex;
}
variableTypeIndex = GetTypeIndex(type, needsCompleteIndex);
@@ -290,7 +296,7 @@ namespace ILCompiler
EnumTypeDescriptor enumTypeDescriptor = new EnumTypeDescriptor
{
ElementCount = (ulong)fieldsDescriptors.Count,
- ElementType = PrimitiveTypeDescriptor.GetPrimitiveTypeIndex(defType.UnderlyingType),
+ ElementType = GetPrimitiveTypeIndex(defType.UnderlyingType),
Name = _objectWriter.GetMangledName(type),
};
EnumRecordTypeDescriptor[] typeRecords = new EnumRecordTypeDescriptor[enumTypeDescriptor.ElementCount];
@@ -381,33 +387,69 @@ namespace ILCompiler
return 0;
}
- TypeDesc GetFieldDebugType(FieldDesc field)
+ bool ShouldUseCanonicalTypeRecord(TypeDesc type)
{
- TypeDesc type = field.FieldType;
-
// TODO: check the type's generic complexity
- if (NodeFactory.LazyGenericsPolicy.UsesLazyGenerics(type))
+ return type.GetGenericDepth() > NodeFactory.TypeSystemContext.GenericsConfig.MaxGenericDepthOfDebugRecord;
+ }
+
+ TypeDesc GetDebugType(TypeDesc type)
+ {
+ TypeDesc typeGenericComplexityInfo = type;
+
+ // Strip off pointer, array, and byref details.
+ while (typeGenericComplexityInfo is ParameterizedType paramType) {
+ typeGenericComplexityInfo = paramType.ParameterType;
+ }
+
+ // Types that have some canonical subtypes types should always be represented in normalized canonical form to the binder.
+ // Also, to avoid infinite generic recursion issues, attempt to use canonical form for fields with high generic complexity.
+ if (type.IsCanonicalSubtype(CanonicalFormKind.Specific) || (typeGenericComplexityInfo is DefType defType) && ShouldUseCanonicalTypeRecord(defType))
{
type = type.ConvertToCanonForm(CanonicalFormKind.Specific);
+
+ // Re-check if the canonical subtype has acceptable generic complexity
+ typeGenericComplexityInfo = type;
+
+ while (typeGenericComplexityInfo is ParameterizedType paramType) {
+ typeGenericComplexityInfo = paramType.ParameterType;
+ }
+
+ if ((typeGenericComplexityInfo is DefType canonDefType) && ShouldUseCanonicalTypeRecord(canonDefType))
+ {
+ type = type.ConvertToCanonForm(CanonicalFormKind.Universal);
+ }
}
return type;
}
+ TypeDesc GetFieldDebugType(FieldDesc field)
+ {
+ return GetDebugType(field.FieldType);
+ }
+
private uint GetClassTypeIndex(TypeDesc type, bool needsCompleteType)
{
- DefType defType = type as DefType;
+ TypeDesc debugType = GetDebugType(type);
+ DefType defType = debugType as DefType;
System.Diagnostics.Debug.Assert(defType != null, "GetClassTypeIndex was called with non def type");
ClassTypeDescriptor classTypeDescriptor = new ClassTypeDescriptor
{
IsStruct = type.IsValueType ? 1 : 0,
- Name = _objectWriter.GetMangledName(type),
- BaseClassId = 0
+ Name = _objectWriter.GetMangledName(defType),
+ BaseClassId = 0,
+ InstanceSize = 0
};
uint typeIndex = _objectWriter.GetClassTypeIndex(classTypeDescriptor);
_knownTypes[type] = typeIndex;
+ if (!defType.InstanceByteCount.IsIndeterminate)
+ {
+ classTypeDescriptor.InstanceSize = (ulong)defType.InstanceByteCount.AsInt;
+ }
+
if (type.HasBaseType && !type.IsValueType)
{
classTypeDescriptor.BaseClassId = GetTypeIndex(defType.BaseType, true);
@@ -417,6 +459,12 @@ namespace ILCompiler
List<DataFieldDescriptor> nonGcStaticFields = new List<DataFieldDescriptor>();
List<DataFieldDescriptor> gcStaticFields = new List<DataFieldDescriptor>();
List<DataFieldDescriptor> threadStaticFields = new List<DataFieldDescriptor>();
+ List<StaticDataFieldDescriptor> staticsDescs = new List<StaticDataFieldDescriptor>();
+
+ string nonGcStaticDataName = NodeFactory.NameMangler.NodeMangler.NonGCStatics(type);
+ string gcStaticDataName = NodeFactory.NameMangler.NodeMangler.GCStatics(type);
+ string threadStaticDataName = NodeFactory.NameMangler.NodeMangler.ThreadStatics(type);
+ bool IsCoreRTAbi = Abi == TargetAbi.CoreRT;
bool isCanonical = defType.IsCanonicalSubtype(CanonicalFormKind.Any);
@@ -439,6 +487,30 @@ namespace ILCompiler
if (fieldDesc.IsStatic)
{
+ if (NodeFactory.Target.OperatingSystem != TargetOS.Windows)
+ {
+ StaticDataFieldDescriptor staticDesc = new StaticDataFieldDescriptor
+ {
+ StaticOffset = (ulong)fieldOffsetEmit
+ };
+
+ // Mark field as static
+ field.Offset = 0xFFFFFFFF;
+
+ if (fieldDesc.IsThreadStatic) {
+ staticDesc.StaticDataName = threadStaticDataName;
+ staticDesc.IsStaticDataInObject = IsCoreRTAbi ? 1 : 0;
+ } else if (fieldDesc.HasGCStaticBase) {
+ staticDesc.StaticDataName = gcStaticDataName;
+ staticDesc.IsStaticDataInObject = IsCoreRTAbi ? 1 : 0;
+ } else {
+ staticDesc.StaticDataName = nonGcStaticDataName;
+ staticDesc.IsStaticDataInObject = 0;
+ }
+
+ staticsDescs.Add(staticDesc);
+ }
+
if (fieldDesc.IsThreadStatic)
threadStaticFields.Add(field);
else if (fieldDesc.HasGCStaticBase)
@@ -452,9 +524,18 @@ namespace ILCompiler
}
}
- InsertStaticFieldRegionMember(fieldsDescs, defType, nonGcStaticFields, WindowsNodeMangler.NonGCStaticMemberName, "__type_" + WindowsNodeMangler.NonGCStaticMemberName, false);
- InsertStaticFieldRegionMember(fieldsDescs, defType, gcStaticFields, WindowsNodeMangler.GCStaticMemberName, "__type_" + WindowsNodeMangler.GCStaticMemberName, Abi == TargetAbi.CoreRT);
- InsertStaticFieldRegionMember(fieldsDescs, defType, threadStaticFields, WindowsNodeMangler.ThreadStaticMemberName, "__type_" + WindowsNodeMangler.ThreadStaticMemberName, Abi == TargetAbi.CoreRT);
+ if (NodeFactory.Target.OperatingSystem == TargetOS.Windows)
+ {
+ InsertStaticFieldRegionMember(fieldsDescs, defType, nonGcStaticFields, WindowsNodeMangler.NonGCStaticMemberName, "__type_" + WindowsNodeMangler.NonGCStaticMemberName, false);
+ InsertStaticFieldRegionMember(fieldsDescs, defType, gcStaticFields, WindowsNodeMangler.GCStaticMemberName, "__type_" + WindowsNodeMangler.GCStaticMemberName, IsCoreRTAbi);
+ InsertStaticFieldRegionMember(fieldsDescs, defType, threadStaticFields, WindowsNodeMangler.ThreadStaticMemberName, "__type_" + WindowsNodeMangler.ThreadStaticMemberName, IsCoreRTAbi);
+ }
+ else
+ {
+ fieldsDescs.AddRange(nonGcStaticFields);
+ fieldsDescs.AddRange(gcStaticFields);
+ fieldsDescs.AddRange(threadStaticFields);
+ }
DataFieldDescriptor[] fields = new DataFieldDescriptor[fieldsDescs.Count];
for (int i = 0; i < fieldsDescs.Count; ++i)
@@ -462,15 +543,21 @@ namespace ILCompiler
fields[i] = fieldsDescs[i];
}
+ StaticDataFieldDescriptor[] statics = new StaticDataFieldDescriptor[staticsDescs.Count];
+ for (int i = 0; i < staticsDescs.Count; ++i)
+ {
+ statics[i] = staticsDescs[i];
+ }
+
LayoutInt elementSize = defType.GetElementSize();
int elementSizeEmit = elementSize.IsIndeterminate ? 0xBAAD : elementSize.AsInt;
ClassFieldsTypeDescriptor fieldsDescriptor = new ClassFieldsTypeDescriptor
{
Size = (ulong)elementSizeEmit,
- FieldsCount = fieldsDescs.Count
+ FieldsCount = fieldsDescs.Count,
};
- uint completeTypeIndex = _objectWriter.GetCompleteClassTypeIndex(classTypeDescriptor, fieldsDescriptor, fields);
+ uint completeTypeIndex = _objectWriter.GetCompleteClassTypeIndex(classTypeDescriptor, fieldsDescriptor, fields, statics);
_completeKnownTypes[type] = completeTypeIndex;
if (needsCompleteType)
@@ -502,7 +589,7 @@ namespace ILCompiler
classTypeDescriptor.BaseClassId = GetTypeIndex(defType.Context.GetWellKnownType(WellKnownType.Object), true);
}
- uint staticFieldRegionTypeIndex = _objectWriter.GetCompleteClassTypeIndex(classTypeDescriptor, fieldsDescriptor, staticFields.ToArray());
+ uint staticFieldRegionTypeIndex = _objectWriter.GetCompleteClassTypeIndex(classTypeDescriptor, fieldsDescriptor, staticFields.ToArray(), null);
uint staticFieldRegionSymbolTypeIndex = staticFieldRegionTypeIndex;
// This means that access to this static region is done via a double indirection
@@ -530,6 +617,21 @@ namespace ILCompiler
}
}
+ private uint GetPrimitiveTypeIndex(TypeDesc type)
+ {
+ Debug.Assert(type.IsPrimitive, "it is not a primitive type");
+
+ uint typeIndex;
+
+ if (_primitiveTypes.TryGetValue(type, out typeIndex))
+ return typeIndex;
+
+ typeIndex = _objectWriter.GetPrimitiveTypeIndex(type);
+ _primitiveTypes[type] = typeIndex;
+
+ return typeIndex;
+ }
+
private ITypesDebugInfoWriter _objectWriter;
private Dictionary<TypeDesc, uint> _knownTypes = new Dictionary<TypeDesc, uint>();
private Dictionary<TypeDesc, uint> _completeKnownTypes = new Dictionary<TypeDesc, uint>();
@@ -538,6 +640,7 @@ namespace ILCompiler
private Dictionary<TypeDesc, uint> _enumTypes = new Dictionary<TypeDesc, uint>();
private Dictionary<TypeDesc, uint> _byRefTypes = new Dictionary<TypeDesc, uint>();
private Dictionary<TypeDesc, uint> _thisTypes = new Dictionary<TypeDesc, uint>();
+ private Dictionary<TypeDesc, uint> _primitiveTypes = new Dictionary<TypeDesc, uint>();
private Dictionary<MethodDesc, uint> _methodIndices = new Dictionary<MethodDesc, uint>();
private Dictionary<MethodDesc, uint> _methodIdIndices = new Dictionary<MethodDesc, uint>();