コード例 #1
0
        /// <summary>
        /// While computing layout, we don't generally compute the full field information. This function is used to
        /// gate how much of field layout to run
        /// </summary>
        /// <param name="fieldStorage">the conceptual location of the field</param>
        /// <param name="loadRequested">what sort of load was requested</param>
        /// <returns></returns>
        internal bool ShouldProcessField(NativeFormat.FieldStorage fieldStorage, FieldLoadState loadRequested)
        {
            if (fieldStorage == (int)NativeFormat.FieldStorage.Instance)
            {
                // Make sure we wanted to load instance fields.
                if ((loadRequested & FieldLoadState.Instance) == FieldLoadState.None)
                {
                    return(false);
                }
            }
            else if ((loadRequested & FieldLoadState.Statics) == FieldLoadState.None)
            {
                // Otherwise the field is a static, and we only want instance fields.
                return(false);
            }

            return(true);
        }
コード例 #2
0
        // The layout algorithm should probably compute results and let the caller set things
        internal unsafe LayoutInt[] ComputeTypeSizeAndAlignment(TypeDesc type, FieldLoadState loadRequested, out LowLevelList <LayoutInt> fieldOffsets)
        {
            fieldOffsets = null;
            TypeLoaderLogger.WriteLine("Laying out type " + type.ToString() + ". IsValueType: " + (type.IsValueType ? "true" : "false") + ". LoadRequested = " + ((int)loadRequested).LowLevelToString());

            Debug.Assert(loadRequested != FieldLoadState.None);
            Debug.Assert(type is ArrayType || (type is DefType && ((DefType)type).HasInstantiation));

            bool isArray = type is ArrayType;

            LayoutInt[] position      = new LayoutInt[5];
            LayoutInt   alignRequired = LayoutInt.One;

            if ((loadRequested & FieldLoadState.Instance) == FieldLoadState.Instance)
            {
                ComputeTypeSizeBeforeFields(type, out position[(int)NativeFormat.FieldStorage.Instance], out alignRequired);
            }

            if (!isArray)
            {
                // Once this is done, the NativeLayoutFields on the type are initialized
                EnsureFieldLayoutLoadedForGenericType((DefType)type);
                Debug.Assert(type.NativeLayoutFields != null);
            }

            int instanceFields = 0;

            if (!isArray && type.NativeLayoutFields.Length > 0)
            {
                fieldOffsets = new LowLevelList <LayoutInt>(type.NativeLayoutFields.Length);
                for (int i = 0; i < type.NativeLayoutFields.Length; i++)
                {
                    TypeDesc fieldType    = type.NativeLayoutFields[i].FieldType;
                    int      fieldStorage = (int)type.NativeLayoutFields[i].FieldStorage;

                    if (!ShouldProcessField((NativeFormat.FieldStorage)fieldStorage, loadRequested))
                    {
                        continue;
                    }

                    // For value types, we will attempt to get the size and alignment from
                    // the runtime if possible, otherwise GetFieldSizeAndAlignment will
                    // recurse to lay out nested struct fields.
                    LayoutInt alignment;
                    LayoutInt size;
                    GetFieldSizeAlignment(fieldType, out size, out alignment);

                    Debug.Assert(alignment.AsInt > 0);

                    if (fieldStorage == (int)NativeFormat.FieldStorage.Instance)
                    {
                        instanceFields++;

                        // Ensure alignment of type is sufficient for this field
                        alignRequired = LayoutInt.Max(alignRequired, alignment);
                    }

                    position[fieldStorage] = LayoutInt.AlignUp(position[fieldStorage], alignment);
                    TypeLoaderLogger.WriteLine(" --> Field type " + fieldType.ToString() +
                                               " storage " + ((uint)(type.NativeLayoutFields[i].FieldStorage)).LowLevelToString() +
                                               " offset " + position[fieldStorage].LowLevelToString() +
                                               " alignment " + alignment.LowLevelToString());

                    fieldOffsets.Add(position[fieldStorage]);
                    position[fieldStorage] += size;
                }
            }

            // Pad the length of structs to be 1 if they are empty so we have no zero-length structures
            if ((position[(int)NativeFormat.FieldStorage.Instance] == LayoutInt.Zero) && type.IsValueType)
            {
                position[(int)NativeFormat.FieldStorage.Instance] = LayoutInt.One;
            }

            Debug.Assert(alignRequired == new LayoutInt(1) ||
                         alignRequired == new LayoutInt(2) ||
                         alignRequired == new LayoutInt(4) ||
                         alignRequired == new LayoutInt(8));

            position[InstanceAlignmentEntry] = alignRequired;

            return(position);
        }
コード例 #3
0
        // The layout algorithm should probably compute results and let the caller set things
        internal unsafe int[] ComputeTypeSizeAndAlignment(TypeDesc type, FieldLoadState loadRequested, out LowLevelList<int> fieldOffsets)
        {
            fieldOffsets = null;
            TypeLoaderLogger.WriteLine("Laying out type " + type.ToString() + ". IsValueType: " + (type.IsValueType ? "true" : "false") + ". LoadRequested = " + ((int)loadRequested).LowLevelToString());

            Debug.Assert(loadRequested != FieldLoadState.None);
            Debug.Assert(type is ArrayType || (type is DefType && ((DefType)type).HasInstantiation));

            bool isArray = type is ArrayType;

            int[] position = new int[5];
            int alignRequired = 1;

            if ((loadRequested & FieldLoadState.Instance) == FieldLoadState.Instance)
            {
                ComputeTypeSizeBeforeFields(type, out position[(int)NativeFormat.FieldStorage.Instance], out alignRequired);
            }

            if (!isArray)
            {
                // Once this is done, the NativeLayoutFields on the type are initialized
                EnsureFieldLayoutLoadedForGenericType((DefType)type);
                Debug.Assert(type.NativeLayoutFields != null);
            }

            int instanceFields = 0;

            if (!isArray && type.NativeLayoutFields.Length > 0)
            {
                fieldOffsets = new LowLevelList<int>(type.NativeLayoutFields.Length);
                for (int i = 0; i < type.NativeLayoutFields.Length; i++)
                {
                    TypeDesc fieldType = type.NativeLayoutFields[i].FieldType;
                    int fieldStorage = (int)type.NativeLayoutFields[i].FieldStorage;

                    if (!ShouldProcessField((NativeFormat.FieldStorage)fieldStorage, loadRequested))
                        continue;

                    // For value types, we will attempt to get the size and alignment from
                    // the runtime if possible, otherwise GetFieldSizeAndAlignment will
                    // recurse to lay out nested struct fields.
                    int alignment;
                    int size;
                    GetFieldSizeAlignment(fieldType, out size, out alignment);

                    Debug.Assert(alignment > 0);

                    if (fieldStorage == (int)NativeFormat.FieldStorage.Instance)
                    {
                        instanceFields++;

                        // Ensure alignment of type is sufficient for this field
                        if (alignRequired < alignment)
                            alignRequired = alignment;
                    }

                    position[fieldStorage] = MemoryHelpers.AlignUp(position[fieldStorage], alignment);
                    TypeLoaderLogger.WriteLine(" --> Field type " + fieldType.ToString() +
                        " storage " + ((uint)(type.NativeLayoutFields[i].FieldStorage)).LowLevelToString() +
                        " offset " + position[fieldStorage].LowLevelToString() +
                        " alignment " + alignment.LowLevelToString());

                    fieldOffsets.Add(position[fieldStorage]);
                    position[fieldStorage] += size;
                }
            }

            // Pad the length of structs to be 1 if they are empty so we have no zero-length structures
            if ((position[(int)NativeFormat.FieldStorage.Instance] == 0) && type.IsValueType)
                position[(int)NativeFormat.FieldStorage.Instance] = 1;

            Debug.Assert(alignRequired == 1 || alignRequired == 2 || alignRequired == 4 || alignRequired == 8);

            position[InstanceAlignmentEntry] = alignRequired;

            return position;
        }
コード例 #4
0
        /// <summary>
        /// While computing layout, we don't generally compute the full field information. This function is used to 
        /// gate how much of field layout to run
        /// </summary>
        /// <param name="fieldStorage">the conceptual location of the field</param>
        /// <param name="loadRequested">what sort of load was requested</param>
        /// <returns></returns>
        internal bool ShouldProcessField(NativeFormat.FieldStorage fieldStorage, FieldLoadState loadRequested)
        {
            if (fieldStorage == (int)NativeFormat.FieldStorage.Instance)
            {
                // Make sure we wanted to load instance fields.
                if ((loadRequested & FieldLoadState.Instance) == FieldLoadState.None)
                    return false;
            }
            else if ((loadRequested & FieldLoadState.Statics) == FieldLoadState.None)
            {
                // Otherwise the field is a static, and we only want instance fields.
                return false;
            }

            return true;
        }