public unsafe override bool ComputeContainsGCPointers(DefType type) { if (type.IsTemplateCanonical()) { return(type.ComputeTemplate().RuntimeTypeHandle.ToEETypePtr()->HasGCPointers); } else { if (type.RetrieveRuntimeTypeHandleIfPossible()) { return(type.RuntimeTypeHandle.ToEETypePtr()->HasGCPointers); } return(type.GetOrCreateTypeBuilderState().InstanceGCLayout != null); } }
public unsafe override bool ComputeIsByRefLike(DefType type) { if (type.IsTemplateCanonical()) { return(type.ComputeTemplate().RuntimeTypeHandle.ToEETypePtr()->IsByRefLike); } else { if (type.RetrieveRuntimeTypeHandleIfPossible()) { return(type.RuntimeTypeHandle.ToEETypePtr()->IsByRefLike); } throw new NotImplementedException(); } }
/// <summary> /// Prepare the StaticGCLayout/ThreadStaticGCLayout/GcStaticDesc/ThreadStaticDesc fields by /// reading native layout or metadata as appropriate. This method should only be called for types which /// are actually to be created. /// </summary> public void PrepareStaticGCLayout() { if (!_staticGCLayoutPrepared) { _staticGCLayoutPrepared = true; DefType defType = TypeBeingBuilt as DefType; if (defType == null) { // Array/pointer types do not have static fields } else if (defType.IsTemplateCanonical()) { // Canonical templates get their layout directly from the NativeLayoutInfo. // Parse it and pull that info out here. NativeParser typeInfoParser = GetParserForNativeLayoutInfo(); BagElementKind kind; while ((kind = typeInfoParser.GetBagElementKind()) != BagElementKind.End) { switch (kind) { case BagElementKind.GcStaticDesc: GcStaticDesc = NativeLayoutInfo.LoadContext.GetGCStaticInfo(typeInfoParser.GetUnsigned()); break; case BagElementKind.ThreadStaticDesc: ThreadStaticDesc = NativeLayoutInfo.LoadContext.GetGCStaticInfo(typeInfoParser.GetUnsigned()); break; default: typeInfoParser.SkipInteger(); break; } } } else { // Compute GC layout boolean array from field information. IEnumerable <FieldDesc> fields = GetFieldsForGCLayout(); LowLevelList <bool> threadStaticLayout = null; LowLevelList <bool> gcStaticLayout = null; foreach (FieldDesc field in fields) { if (!field.IsStatic) { continue; } if (field.IsLiteral) { continue; } LowLevelList <bool> gcLayoutInfo = null; if (field.IsThreadStatic) { if (threadStaticLayout == null) { threadStaticLayout = new LowLevelList <bool>(); } gcLayoutInfo = threadStaticLayout; } else if (field.HasGCStaticBase) { if (gcStaticLayout == null) { gcStaticLayout = new LowLevelList <bool>(); } gcLayoutInfo = gcStaticLayout; } else { // Non-GC static no need to record information continue; } TypeBuilder.GCLayout fieldGcLayout = GetFieldGCLayout(field.FieldType); fieldGcLayout.WriteToBitfield(gcLayoutInfo, field.Offset); } if (gcStaticLayout != null && gcStaticLayout.Count > 0) { StaticGCLayout = gcStaticLayout; } if (threadStaticLayout != null && threadStaticLayout.Count > 0) { ThreadStaticGCLayout = threadStaticLayout; } } } }