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; } }
internal bool TryComputeHasInstantiationDeterminedSize(DefType type, out bool hasInstantiationDeterminedSize) { Debug.Assert(type.HasInstantiation); NativeLayoutInfoLoadContext loadContextUniversal; NativeParser parser = type.GetOrCreateTypeBuilderState().GetParserForUniversalNativeLayoutInfo(out loadContextUniversal); if (parser.IsNull) { hasInstantiationDeterminedSize = false; #if SUPPORTS_NATIVE_METADATA_TYPE_LOADING // TODO, Add logic which uses type loader to identify which types are affected by loading the // universal generic type, and checking its size. At this time, the type loader cannot correctly // compute sizes of generic types that are instantiated over UniversalCanon Environment.FailFast("Unable to determine if a generic has an instantiation determined size."); #endif return false; } int? flags = (int?)parser.GetUnsignedForBagElementKind(BagElementKind.TypeFlags); hasInstantiationDeterminedSize = flags.HasValue ? (((NativeFormat.TypeFlags)flags) & NativeFormat.TypeFlags.HasInstantiationDeterminedSize) != 0 : false; return true; }
private static void EnsureFieldLayoutLoadedForNonUniversalType(DefType type) { Debug.Assert(type.HasInstantiation); Debug.Assert(!type.ComputeTemplate().IsCanonicalSubtype(CanonicalFormKind.Universal)); if (type.NativeLayoutFields != null) return; // Look up the universal template for this type. Only the universal template has field layout // information, so we have to use it to parse the field layout. NativeLayoutInfoLoadContext universalLayoutLoadContext; NativeParser typeInfoParser = type.GetOrCreateTypeBuilderState().GetParserForUniversalNativeLayoutInfo(out universalLayoutLoadContext); if (typeInfoParser.IsNull) throw new TypeBuilder.MissingTemplateException(); // Now parse that layout into the NativeLayoutFields array. NativeParser fieldLayoutParser = typeInfoParser.GetParserForBagElementKind(BagElementKind.FieldLayout); type.NativeLayoutFields = ParseFieldLayout(type, universalLayoutLoadContext, fieldLayoutParser); }
internal static void EnsureFieldLayoutLoadedForGenericType(DefType type) { if (type.NativeLayoutFields != null) return; if (!type.IsTemplateUniversal()) { // We can hit this case where the template of type in question is not a universal canonical type. // Example: // BaseType<T> { ... } // DerivedType<T, U> : BaseType<T> { ... } // and an instantiation like DerivedType<string, int>. In that case, BaseType<string> will have a non-universal // template type, and requires special handling to compute its size and field layout. EnsureFieldLayoutLoadedForNonUniversalType(type); } else { TypeBuilderState state = type.GetOrCreateTypeBuilderState(); NativeParser typeInfoParser = state.GetParserForNativeLayoutInfo(); NativeParser fieldLayoutParser = typeInfoParser.GetParserForBagElementKind(BagElementKind.FieldLayout); EnsureFieldLayoutLoadedForUniversalType(type, state.NativeLayoutInfo.LoadContext, fieldLayoutParser); } }