Ejemplo n.º 1
0
        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);
            }
        }
Ejemplo n.º 2
0
        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();
            }
        }
Ejemplo n.º 3
0
        /// <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;
                    }
                }
            }
        }