Welcome to mirror list, hosted at ThFree Co, Russian Federation.

NoMetadataFieldLayoutAlgorithm.cs « TypeLoader « Runtime « Internal « src « System.Private.TypeLoader « src - github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 83c069b89a9d33259f3f86bd43786b0130e1b532 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using Internal.TypeSystem;
using System.Diagnostics;

namespace Internal.Runtime.TypeLoader
{
    /// <summary>
    /// Useable when we have runtime EEType structures. Can represent the field layout necessary 
    /// to represent the size/alignment of the overall type, but must delegate to either NativeLayoutFieldAlgorithm
    /// or MetadataFieldLayoutAlgorithm to get information about individual fields.
    /// </summary>
    internal class NoMetadataFieldLayoutAlgorithm : FieldLayoutAlgorithm
    {
        private MetadataFieldLayoutAlgorithm _metadataFieldLayoutAlgorithm = new MetadataFieldLayoutAlgorithm();
        private static NativeLayoutFieldAlgorithm s_nativeLayoutFieldAlgorithm = new NativeLayoutFieldAlgorithm();

        public unsafe override bool ComputeContainsGCPointers(DefType type)
        {
            return type.RuntimeTypeHandle.ToEETypePtr()->HasGCPointers;
        }

        /// <summary>
        /// Reads the minimal information about type layout encoded in the 
        /// EEType. That doesn't include field information.
        /// </summary>
        public unsafe override ComputedInstanceFieldLayout ComputeInstanceLayout(DefType type, InstanceLayoutKind layoutKind)
        {
            // If we need the field information, delegate to the native layout algorithm or metadata algorithm
            if (layoutKind != InstanceLayoutKind.TypeOnly)
            {
                if (type.HasNativeLayout)
                    return s_nativeLayoutFieldAlgorithm.ComputeInstanceLayout(type, layoutKind);
                else
                    return _metadataFieldLayoutAlgorithm.ComputeInstanceLayout(type, layoutKind);
            }

            type.RetrieveRuntimeTypeHandleIfPossible();
            Debug.Assert(!type.RuntimeTypeHandle.IsNull());
            EEType* eeType = type.RuntimeTypeHandle.ToEETypePtr();

            ComputedInstanceFieldLayout layout = new ComputedInstanceFieldLayout()
            {
                ByteCountAlignment = new LayoutInt(IntPtr.Size),
                ByteCountUnaligned = new LayoutInt(eeType->IsInterface ? IntPtr.Size : checked((int)eeType->FieldByteCountNonGCAligned)),
                FieldAlignment = new LayoutInt(eeType->FieldAlignmentRequirement),
                Offsets = (layoutKind == InstanceLayoutKind.TypeOnly) ? null : Array.Empty<FieldAndOffset>(), // No fields in EETypes
            };

            if (eeType->IsValueType)
            {
                int valueTypeSize = checked((int)eeType->ValueTypeSize);
                layout.FieldSize = new LayoutInt(valueTypeSize);
            }
            else
            {
                layout.FieldSize = new LayoutInt(IntPtr.Size);
            }

            if ((eeType->RareFlags & EETypeRareFlags.RequiresAlign8Flag) == EETypeRareFlags.RequiresAlign8Flag)
            {
                layout.ByteCountAlignment = new LayoutInt(8);
            }

            return layout;
        }

        public override ComputedStaticFieldLayout ComputeStaticFieldLayout(DefType type, StaticLayoutKind layoutKind)
        {
            // We can only reach this for pre-created types where we actually need field information
            // In that case, fall through to one of the other field layout algorithms.
            if (type.HasNativeLayout)
                return s_nativeLayoutFieldAlgorithm.ComputeStaticFieldLayout(type, layoutKind);
            else if (type is MetadataType)
                return _metadataFieldLayoutAlgorithm.ComputeStaticFieldLayout(type, layoutKind);

            // No statics information available
            ComputedStaticFieldLayout staticLayout = new ComputedStaticFieldLayout()
            {
                GcStatics = default(StaticsBlock),
                NonGcStatics = default(StaticsBlock),
                Offsets = Array.Empty<FieldAndOffset>(), // No fields are considered to exist for completely NoMetadataTypes
                ThreadGcStatics = default(StaticsBlock),
                ThreadNonGcStatics = default(StaticsBlock),
            };
            return staticLayout;
        }

        public override DefType ComputeHomogeneousFloatAggregateElementType(DefType type)
        {
            if (type.Context.Target.Architecture == TargetArchitecture.ARM)
            {
                unsafe
                {
                    // On ARM, the HFA type is encoded into the EEType directly
                    type.RetrieveRuntimeTypeHandleIfPossible();
                    Debug.Assert(!type.RuntimeTypeHandle.IsNull());
                    EEType* eeType = type.RuntimeTypeHandle.ToEETypePtr();
                    if (!eeType->IsHFA)
                        return null;

                    if (eeType->RequiresAlign8)
                        return type.Context.GetWellKnownType(WellKnownType.Double);
                    else
                        return type.Context.GetWellKnownType(WellKnownType.Single);
                }
            }
            else
            {
                Debug.Assert(
                    type.Context.Target.Architecture == TargetArchitecture.X86 ||
                    type.Context.Target.Architecture == TargetArchitecture.X64);

                return null;
            }
        }

        public override ValueTypeShapeCharacteristics ComputeValueTypeShapeCharacteristics(DefType type)
        {
            if (type.Context.Target.Architecture == TargetArchitecture.ARM)
            {
                unsafe
                {
                    // On ARM, the HFA type is encoded into the EEType directly
                    type.RetrieveRuntimeTypeHandleIfPossible();
                    Debug.Assert(!type.RuntimeTypeHandle.IsNull());
                    EEType* eeType = type.RuntimeTypeHandle.ToEETypePtr();
                    if (eeType->IsHFA)
                        return ValueTypeShapeCharacteristics.HomogenousFloatAggregate;
                    else
                        return ValueTypeShapeCharacteristics.None;
                }
            }
            else
            {
                Debug.Assert(
                    type.Context.Target.Architecture == TargetArchitecture.X86 ||
                    type.Context.Target.Architecture == TargetArchitecture.X64);

                return ValueTypeShapeCharacteristics.None;
            }
        }
    }
}