/// <summary> /// Computes the GC pointer map of the thread static region of the type. /// </summary> public static GCPointerMap FromThreadStaticLayout(DefType type) { GCPointerMapBuilder builder = new GCPointerMapBuilder(type.ThreadStaticFieldSize, type.Context.Target.PointerSize); foreach (FieldDesc field in type.GetFields()) { if (!field.IsStatic || field.HasRva || field.IsLiteral || !field.IsThreadStatic) continue; TypeDesc fieldType = field.FieldType; if (fieldType.IsGCPointer) { builder.MarkGCPointer(field.Offset); } else if (fieldType.IsValueType) { var fieldDefType = (DefType)fieldType; if (fieldDefType.ContainsGCPointers) { GCPointerMapBuilder innerBuilder = builder.GetInnerBuilder(field.Offset, fieldDefType.InstanceByteCount); FromInstanceLayoutHelper(ref innerBuilder, fieldDefType); } } } return builder.ToGCMap(); }
private static void FromInstanceLayoutHelper(ref GCPointerMapBuilder builder, DefType type) { if (!type.IsValueType && type.HasBaseType) { DefType baseType = type.BaseType; GCPointerMapBuilder baseLayoutBuilder = builder.GetInnerBuilder(0, baseType.InstanceByteCount.AsInt); FromInstanceLayoutHelper(ref baseLayoutBuilder, baseType); } foreach (FieldDesc field in type.GetFields()) { if (field.IsStatic) { continue; } TypeDesc fieldType = field.FieldType; if (fieldType.IsGCPointer) { builder.MarkGCPointer(field.Offset.AsInt); } else if (fieldType.IsValueType) { var fieldDefType = (DefType)fieldType; if (fieldDefType.ContainsGCPointers) { GCPointerMapBuilder innerBuilder = builder.GetInnerBuilder(field.Offset.AsInt, fieldDefType.InstanceByteCount.AsInt); FromInstanceLayoutHelper(ref innerBuilder, fieldDefType); } } } }
/// <summary> /// Computes the GC pointer map of the thread static region of the type. /// </summary> public static GCPointerMap FromThreadStaticLayout(DefType type) { GCPointerMapBuilder builder = new GCPointerMapBuilder(type.ThreadStaticFieldSize.AsInt, type.Context.Target.PointerSize); foreach (FieldDesc field in type.GetFields()) { if (!field.IsStatic || field.HasRva || field.IsLiteral || !field.IsThreadStatic) { continue; } TypeDesc fieldType = field.FieldType; if (fieldType.IsGCPointer) { builder.MarkGCPointer(field.Offset.AsInt); } else if (fieldType.IsValueType) { var fieldDefType = (DefType)fieldType; if (fieldDefType.ContainsGCPointers) { GCPointerMapBuilder innerBuilder = builder.GetInnerBuilder(field.Offset.AsInt, fieldDefType.InstanceByteCount.AsInt); FromInstanceLayoutHelper(ref innerBuilder, fieldDefType); } } } Debug.Assert(builder.ToGCMap().Size *type.Context.Target.PointerSize >= type.ThreadStaticFieldSize.AsInt); return(builder.ToGCMap()); }
public override bool ComputeContainsPointers(DefType type) { bool someFieldContainsPointers = false; foreach (var field in type.GetFields()) { if (field.IsStatic) { continue; } TypeDesc fieldType = field.FieldType; if (fieldType.IsValueType) { if (fieldType.IsPrimitive) { continue; } if (((MetadataType)fieldType).ContainsPointers) { someFieldContainsPointers = true; break; } } else if (fieldType is DefType || fieldType is ArrayType || fieldType.IsByRef) { someFieldContainsPointers = true; break; } } return(someFieldContainsPointers); }
public override DefType ComputeHomogeneousFloatAggregateElementType(DefType type) { if (!type.IsHfa) { return(null); } if (type.IsWellKnownType(WellKnownType.Double) || type.IsWellKnownType(WellKnownType.Single)) { return(type); } for (;;) { Debug.Assert(type.IsValueType); // All HFA fields have to be of the same HFA type, so we can just return the type of the first field TypeDesc firstFieldType = null; foreach (var field in type.GetFields()) { if (field.IsStatic) { continue; } firstFieldType = field.FieldType; break; } Debug.Assert(firstFieldType != null, "Why is IsHfa true on this type?"); switch (firstFieldType.Category) { case TypeFlags.Single: case TypeFlags.Double: return((DefType)firstFieldType); case TypeFlags.ValueType: // Drill into the struct and find the type of its first field type = (DefType)firstFieldType; break; default: Debug.Assert(false, "Why is IsHfa true on this type?"); return(null); } } }
public override bool ComputeContainsPointers(DefType type) { bool someFieldContainsPointers = false; foreach (var field in type.GetFields()) { if (field.IsStatic) continue; TypeDesc fieldType = field.FieldType; if (fieldType.IsValueType) { if (fieldType.IsPrimitive) continue; if (((MetadataType)fieldType).ContainsPointers) { someFieldContainsPointers = true; break; } } else if (fieldType is DefType || fieldType is ArrayType || fieldType.IsByRef) { someFieldContainsPointers = true; break; } } return someFieldContainsPointers; }
private static void FromInstanceLayoutHelper(ref GCPointerMapBuilder builder, DefType type) { if (!type.IsValueType && type.HasBaseType) { DefType baseType = type.BaseType; GCPointerMapBuilder baseLayoutBuilder = builder.GetInnerBuilder(0, baseType.InstanceByteCount); FromInstanceLayoutHelper(ref baseLayoutBuilder, baseType); } foreach (FieldDesc field in type.GetFields()) { if (field.IsStatic) continue; TypeDesc fieldType = field.FieldType; if (fieldType.IsGCPointer) { builder.MarkGCPointer(field.Offset); } else if (fieldType.IsValueType) { var fieldDefType = (DefType)fieldType; if (fieldDefType.ContainsGCPointers) { GCPointerMapBuilder innerBuilder = builder.GetInnerBuilder(field.Offset, fieldDefType.InstanceByteCount); FromInstanceLayoutHelper(ref innerBuilder, fieldDefType); } } } }
public override DefType ComputeHomogeneousFloatAggregateElementType(DefType type) { if (!type.IsHfa) return null; if (type.IsWellKnownType(WellKnownType.Double) || type.IsWellKnownType(WellKnownType.Single)) return type; for (;;) { Debug.Assert(type.IsValueType); // All HFA fields have to be of the same HFA type, so we can just return the type of the first field TypeDesc firstFieldType = null; foreach (var field in type.GetFields()) { if (field.IsStatic) continue; firstFieldType = field.FieldType; break; } Debug.Assert(firstFieldType != null, "Why is IsHfa true on this type?"); switch (firstFieldType.Category) { case TypeFlags.Single: case TypeFlags.Double: return (DefType)firstFieldType; case TypeFlags.ValueType: // Drill into the struct and find the type of its first field type = (DefType)firstFieldType; break; default: Debug.Assert(false, "Why is IsHfa true on this type?"); return null; } } }