Exemple #1
0
        private ComputedStaticFieldLayout ParseStaticRegionSizesFromNativeLayout(TypeDesc type)
        {
            LayoutInt nonGcDataSize  = LayoutInt.Zero;
            LayoutInt gcDataSize     = LayoutInt.Zero;
            LayoutInt threadDataSize = LayoutInt.Zero;

            TypeBuilderState state          = type.GetOrCreateTypeBuilderState();
            NativeParser     typeInfoParser = state.GetParserForNativeLayoutInfo();

            BagElementKind kind;

            while ((kind = typeInfoParser.GetBagElementKind()) != BagElementKind.End)
            {
                switch (kind)
                {
                case BagElementKind.NonGcStaticDataSize:
                    TypeLoaderLogger.WriteLine("Found BagElementKind.NonGcStaticDataSize");
                    // Use checked typecast to int to ensure there aren't any overflows/truncations (size value used in allocation of memory later)
                    nonGcDataSize = new LayoutInt(checked ((int)typeInfoParser.GetUnsigned()));
                    break;

                case BagElementKind.GcStaticDataSize:
                    TypeLoaderLogger.WriteLine("Found BagElementKind.GcStaticDataSize");
                    // Use checked typecast to int to ensure there aren't any overflows/truncations (size value used in allocation of memory later)
                    gcDataSize = new LayoutInt(checked ((int)typeInfoParser.GetUnsigned()));
                    break;

                case BagElementKind.ThreadStaticDataSize:
                    TypeLoaderLogger.WriteLine("Found BagElementKind.ThreadStaticDataSize");
                    // Use checked typecast to int to ensure there aren't any overflows/truncations (size value used in allocation of memory later)
                    threadDataSize = new LayoutInt(checked ((int)typeInfoParser.GetUnsigned()));
                    break;

                default:
                    typeInfoParser.SkipInteger();
                    break;
                }
            }

            ComputedStaticFieldLayout staticLayout = new ComputedStaticFieldLayout()
            {
                GcStatics = new StaticsBlock()
                {
                    Size = gcDataSize, LargestAlignment = DefType.MaximumAlignmentPossible
                },
                NonGcStatics = new StaticsBlock()
                {
                    Size = nonGcDataSize, LargestAlignment = DefType.MaximumAlignmentPossible
                },
                Offsets       = null, // We're not computing field offsets here, so return null
                ThreadStatics = new StaticsBlock()
                {
                    Size = threadDataSize, LargestAlignment = DefType.MaximumAlignmentPossible
                },
            };

            return(staticLayout);
        }
Exemple #2
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;
                    }
                }
            }
        }