@@ -146,31 +146,6 @@ private unsafe struct RelatedTypeUnion
146146 public MethodTable * _pRelatedParameterType ;
147147 }
148148
149- private static unsafe class OptionalFieldsReader
150- {
151- internal static uint GetInlineField ( byte * pFields , EETypeOptionalFieldTag eTag , uint uiDefaultValue )
152- {
153- if ( pFields == null )
154- return uiDefaultValue ;
155-
156- bool isLastField = false ;
157- while ( ! isLastField )
158- {
159- byte fieldHeader = NativePrimitiveDecoder . ReadUInt8 ( ref pFields ) ;
160- isLastField = ( fieldHeader & 0x80 ) != 0 ;
161- EETypeOptionalFieldTag eCurrentTag = ( EETypeOptionalFieldTag ) ( fieldHeader & 0x7f ) ;
162- uint uiCurrentValue = NativePrimitiveDecoder . DecodeUnsigned ( ref pFields ) ;
163-
164- // If we found a tag match return the current value.
165- if ( eCurrentTag == eTag )
166- return uiCurrentValue ;
167- }
168-
169- // Reached end of stream without getting a match. Field is not present so return default value.
170- return uiDefaultValue ;
171- }
172- }
173-
174149 /// <summary>
175150 /// Gets a value indicating whether the statically generated data structures use relative pointers.
176151 /// </summary>
@@ -200,17 +175,6 @@ internal static bool SupportsRelativePointers
200175
201176 // vtable follows
202177
203- // These masks and paddings have been chosen so that the ValueTypePadding field can always fit in a byte of data.
204- // if the alignment is 8 bytes or less. If the alignment is higher then there may be a need for more bits to hold
205- // the rest of the padding data.
206- // If paddings of greater than 7 bytes are necessary, then the high bits of the field represent that padding
207- private const uint ValueTypePaddingLowMask = 0x7 ;
208- private const uint ValueTypePaddingHighMask = 0xFFFFFF00 ;
209- private const uint ValueTypePaddingMax = 0x07FFFFFF ;
210- private const int ValueTypePaddingHighShift = 8 ;
211- private const uint ValueTypePaddingAlignmentMask = 0xF8 ;
212- private const int ValueTypePaddingAlignmentShift = 3 ;
213-
214178 internal bool HasComponentSize
215179 {
216180 get
@@ -255,13 +219,13 @@ internal ushort GenericParameterCount
255219 get
256220 {
257221 Debug . Assert ( IsGenericTypeDefinition ) ;
258- return ComponentSize ;
222+ return ( ushort ) _uBaseSize ;
259223 }
260224#if TYPE_LOADER_IMPLEMENTATION
261225 set
262226 {
263227 Debug . Assert ( IsGenericTypeDefinition ) ;
264- ComponentSize = value ;
228+ _uBaseSize = value ;
265229 }
266230#endif
267231 }
@@ -376,14 +340,6 @@ private EETypeKind Kind
376340 }
377341 }
378342
379- internal bool HasOptionalFields
380- {
381- get
382- {
383- return ( _uFlags & ( uint ) EETypeFlags . OptionalFieldsFlag ) != 0 ;
384- }
385- }
386-
387343 // Mark or determine that a type is generic and one or more of it's type parameters is co- or
388344 // contra-variant. This only applies to interface and delegate types.
389345 internal bool HasGenericVariance
@@ -618,7 +574,7 @@ internal bool IsByRefLike
618574 {
619575 get
620576 {
621- return ( RareFlags & EETypeRareFlags . IsByRefLikeFlag ) != 0 ;
577+ return IsValueType && ( _uFlags & ( uint ) EETypeFlagsEx . IsByRefLikeFlag ) != 0 ;
622578 }
623579 }
624580
@@ -809,19 +765,8 @@ internal uint ValueTypeFieldPadding
809765 {
810766 get
811767 {
812- byte * optionalFields = OptionalFieldsPtr ;
813-
814- // If there are no optional fields then the padding must have been the default, 0.
815- if ( optionalFields == null )
816- return 0 ;
817-
818- // Get the value from the optional fields. The default is zero if that particular field was not included.
819- // The low bits of this field is the ValueType field padding, the rest of the byte is the alignment if present
820- uint ValueTypeFieldPaddingData = OptionalFieldsReader . GetInlineField ( optionalFields , EETypeOptionalFieldTag . ValueTypeFieldPadding , 0 ) ;
821- uint padding = ValueTypeFieldPaddingData & ValueTypePaddingLowMask ;
822- // If there is additional padding, the other bits have that data
823- padding |= ( ValueTypeFieldPaddingData & ValueTypePaddingHighMask ) >> ( ValueTypePaddingHighShift - ValueTypePaddingAlignmentShift ) ;
824- return padding ;
768+ Debug . Assert ( IsValueType ) ;
769+ return ( _uFlags & ( uint ) EETypeFlagsEx . ValueTypeFieldPaddingMask ) >> ValueTypeFieldPaddingConsts . Shift ;
825770 }
826771 }
827772
@@ -956,17 +901,8 @@ internal byte NullableValueOffset
956901 get
957902 {
958903 Debug . Assert ( IsNullable ) ;
959-
960- // Grab optional fields. If there aren't any then the offset was the default of 1 (immediately after the
961- // Nullable's boolean flag).
962- byte * optionalFields = OptionalFieldsPtr ;
963- if ( optionalFields == null )
964- return 1 ;
965-
966- // The offset is never zero (Nullable has a boolean there indicating whether the value is valid). So the
967- // offset is encoded - 1 to save space. The zero below is the default value if the field wasn't encoded at
968- // all.
969- return ( byte ) ( OptionalFieldsReader . GetInlineField ( optionalFields , EETypeOptionalFieldTag . NullableValueOffset , 0 ) + 1 ) ;
904+ int log2valueoffset = ( int ) ( _uFlags & ( ushort ) EETypeFlagsEx . NullableValueOffsetMask ) >> NullableValueOffsetConsts . Shift ;
905+ return ( byte ) ( 1 << log2valueoffset ) ;
970906 }
971907 }
972908
@@ -1033,32 +969,6 @@ internal IntPtr GetSealedVirtualSlot(ushort slotNumber)
1033969 }
1034970 }
1035971
1036- internal byte * OptionalFieldsPtr
1037- {
1038- get
1039- {
1040- if ( ! HasOptionalFields )
1041- return null ;
1042-
1043- uint offset = GetFieldOffset ( EETypeField . ETF_OptionalFieldsPtr ) ;
1044-
1045- if ( IsDynamicType || ! SupportsRelativePointers )
1046- return GetField < Pointer < byte > > ( offset ) . Value ;
1047-
1048- return GetField < RelativePointer < byte > > ( offset ) . Value ;
1049- }
1050- #if TYPE_LOADER_IMPLEMENTATION
1051- set
1052- {
1053- Debug . Assert ( IsDynamicType ) ;
1054-
1055- _uFlags |= ( uint ) EETypeFlags . OptionalFieldsFlag ;
1056-
1057- GetField < IntPtr > ( EETypeField . ETF_OptionalFieldsPtr ) = ( IntPtr ) value ;
1058- }
1059- #endif
1060- }
1061-
1062972 internal MethodTable * DynamicTemplateType
1063973 {
1064974 get
@@ -1079,21 +989,21 @@ internal bool IsDynamicTypeWithCctor
1079989 {
1080990 get
1081991 {
1082- return ( RareFlags & EETypeRareFlags . IsDynamicTypeWithLazyCctor ) != 0 ;
992+ return ( DynamicTypeFlags & DynamicTypeFlags . HasLazyCctor ) != 0 ;
1083993 }
1084994 }
1085995
1086996 internal IntPtr DynamicGcStaticsData
1087997 {
1088998 get
1089999 {
1090- Debug . Assert ( ( RareFlags & EETypeRareFlags . IsDynamicTypeWithGcStatics ) != 0 ) ;
1000+ Debug . Assert ( ( DynamicTypeFlags & DynamicTypeFlags . HasGCStatics ) != 0 ) ;
10911001 return GetField< IntPtr > ( EETypeField . ETF_DynamicGcStatics ) ;
10921002 }
10931003#if TYPE_LOADER_IMPLEMENTATION
10941004 set
10951005 {
1096- Debug . Assert ( ( RareFlags & EETypeRareFlags . IsDynamicTypeWithGcStatics ) != 0 ) ;
1006+ Debug . Assert ( ( DynamicTypeFlags & DynamicTypeFlags . HasGCStatics ) != 0 ) ;
10971007 GetField< IntPtr > ( EETypeField . ETF_DynamicGcStatics ) = value ;
10981008 }
10991009#endif
@@ -1103,13 +1013,13 @@ internal IntPtr DynamicNonGcStaticsData
11031013 {
11041014 get
11051015 {
1106- Debug. Assert ( ( RareFlags & EETypeRareFlags . IsDynamicTypeWithNonGcStatics ) != 0 ) ;
1016+ Debug. Assert ( ( DynamicTypeFlags & DynamicTypeFlags . HasNonGCStatics ) != 0 ) ;
11071017 return GetField< IntPtr > ( EETypeField . ETF_DynamicNonGcStatics ) ;
11081018 }
11091019#if TYPE_LOADER_IMPLEMENTATION
11101020 set
11111021 {
1112- Debug . Assert ( ( RareFlags & EETypeRareFlags . IsDynamicTypeWithNonGcStatics ) != 0 ) ;
1022+ Debug . Assert ( ( DynamicTypeFlags & DynamicTypeFlags . HasNonGCStatics ) != 0 ) ;
11131023 GetField< IntPtr > ( EETypeField . ETF_DynamicNonGcStatics ) = value ;
11141024 }
11151025#endif
@@ -1119,13 +1029,13 @@ internal IntPtr DynamicThreadStaticsIndex
11191029 {
11201030 get
11211031 {
1122- Debug . Assert ( ( RareFlags & EETypeRareFlags . IsDynamicTypeWithThreadStatics ) != 0 ) ;
1032+ Debug . Assert ( ( DynamicTypeFlags & DynamicTypeFlags . HasThreadStatics ) != 0 ) ;
11231033 return GetField< IntPtr > ( EETypeField . ETF_DynamicThreadStaticOffset ) ;
11241034 }
11251035#if TYPE_LOADER_IMPLEMENTATION
11261036 set
11271037 {
1128- Debug . Assert ( ( RareFlags & EETypeRareFlags . IsDynamicTypeWithThreadStatics ) != 0 ) ;
1038+ Debug . Assert ( ( DynamicTypeFlags & DynamicTypeFlags . HasThreadStatics ) != 0 ) ;
11291039 GetField< IntPtr > ( EETypeField . ETF_DynamicThreadStaticOffset ) = value ;
11301040 }
11311041#endif
@@ -1191,37 +1101,20 @@ internal void* WritableData
11911101#endif
11921102 }
11931103
1194- internal unsafe EETypeRareFlags RareFlags
1104+ internal DynamicTypeFlags DynamicTypeFlags
11951105 {
11961106 get
11971107 {
1198- // If there are no optional fields then none of the rare flags have been set.
1199- // Get the flags from the optional fields. The default is zero if that particular field was not included.
1200- return HasOptionalFields ? ( EETypeRareFlags ) OptionalFieldsReader . GetInlineField ( OptionalFieldsPtr , EETypeOptionalFieldTag . RareFlags , 0 ) : 0 ;
1108+ Debug. Assert ( IsDynamicType ) ;
1109+ return ( DynamicTypeFlags ) GetField< nint > ( EETypeField . ETF_DynamicTypeFlags ) ;
12011110 }
1202- }
1203-
1204- internal int FieldAlignmentRequirement
1205- {
1206- get
1111+ #if TYPE_LOADER_IMPLEMENTATION
1112+ set
12071113 {
1208- byte * optionalFields = OptionalFieldsPtr;
1209-
1210- // If there are no optional fields then the alignment must have been the default, IntPtr.Size.
1211- // (This happens for all reference types, and for valuetypes with default alignment and no padding)
1212- if ( optionalFields = = null )
1213- return IntPtr . Size ;
1214-
1215- // Get the value from the optional fields. The default is zero if that particular field was not included.
1216- // The low bits of this field is the ValueType field padding, the rest of the value is the alignment if present
1217- uint alignmentValue = ( OptionalFieldsReader . GetInlineField ( optionalFields , EETypeOptionalFieldTag . ValueTypeFieldPadding , 0 ) & ValueTypePaddingAlignmentMask ) > > ValueTypePaddingAlignmentShift ;
1218-
1219- // Alignment is stored as 1 + the log base 2 of the alignment, except a 0 indicates standard pointer alignment.
1220- if ( alignmentValue = = 0 )
1221- return IntPtr . Size ;
1222- else
1223- return 1 << ( ( int ) alignmentValue - 1 ) ;
1114+ Debug . Assert ( IsDynamicType ) ;
1115+ GetField < nint > ( EETypeField . ETF_DynamicTypeFlags ) = ( nint ) value ;
12241116 }
1117+ #endif
12251118 }
12261119
12271120 internal EETypeElementType ElementType
@@ -1283,15 +1176,6 @@ public uint GetFieldOffset(EETypeField eField)
12831176 if ( IsFinalizable )
12841177 cbOffset += relativeOrFullPointerOffset;
12851178
1286- // Followed by the pointer to the optional fields.
1287- if ( eField == EETypeField . ETF_OptionalFieldsPtr )
1288- {
1289- Debug . Assert ( HasOptionalFields ) ;
1290- return cbOffset;
1291- }
1292- if ( HasOptionalFields )
1293- cbOffset += relativeOrFullPointerOffset;
1294-
12951179 // Followed by the pointer to the sealed virtual slots
12961180 if ( eField == EETypeField . ETF_SealedVirtualSlots )
12971181 return cbOffset;
@@ -1338,26 +1222,37 @@ public uint GetFieldOffset(EETypeField eField)
13381222 if ( IsDynamicType )
13391223 cbOffset += ( uint ) IntPtr . Size ;
13401224
1341- EETypeRareFlags rareFlags = RareFlags ;
1225+ DynamicTypeFlags dynamicTypeFlags = 0 ;
1226+ if ( eField = = EETypeField . ETF_DynamicTypeFlags )
1227+ {
1228+ Debug . Assert ( IsDynamicType ) ;
1229+ return cbOffset;
1230+ }
1231+ if ( IsDynamicType )
1232+ {
1233+ dynamicTypeFlags = ( DynamicTypeFlags ) GetField < nint > ( cbOffset ) ;
1234+ cbOffset += ( uint ) IntPtr . Size ;
1235+ }
1236+
13421237 if ( eField == EETypeField . ETF_DynamicGcStatics )
13431238 {
1344- Debug . Assert ( ( rareFlags & EETypeRareFlags . IsDynamicTypeWithGcStatics ) != 0 ) ;
1239+ Debug . Assert ( ( dynamicTypeFlags & DynamicTypeFlags . HasGCStatics ) != 0 ) ;
13451240 return cbOffset;
13461241 }
1347- if ( ( rareFlags & EETypeRareFlags . IsDynamicTypeWithGcStatics ) != 0 )
1242+ if ( ( dynamicTypeFlags & DynamicTypeFlags . HasGCStatics ) != 0 )
13481243 cbOffset += ( uint ) IntPtr . Size ;
13491244
13501245 if ( eField == EETypeField . ETF_DynamicNonGcStatics )
13511246 {
1352- Debug . Assert ( ( rareFlags & EETypeRareFlags . IsDynamicTypeWithNonGcStatics ) != 0 ) ;
1247+ Debug. Assert ( ( dynamicTypeFlags & DynamicTypeFlags . HasNonGCStatics ) != 0 ) ;
13531248 return cbOffset;
13541249 }
1355- if ( ( rareFlags & EETypeRareFlags . IsDynamicTypeWithNonGcStatics ) != 0 )
1250+ if ( ( dynamicTypeFlags & DynamicTypeFlags . HasNonGCStatics ) != 0 )
13561251 cbOffset += ( uint ) IntPtr . Size ;
13571252
13581253 if ( eField = = EETypeField . ETF_DynamicThreadStaticOffset )
13591254 {
1360- Debug . Assert ( ( rareFlags & EETypeRareFlags . IsDynamicTypeWithThreadStatics ) != 0 ) ;
1255+ Debug . Assert ( ( dynamicTypeFlags & DynamicTypeFlags . HasThreadStatics ) != 0 ) ;
13611256 return cbOffset;
13621257 }
13631258
@@ -1383,7 +1278,6 @@ internal static uint GetSizeofEEType(
13831278 ushort cInterfaces ,
13841279 bool fHasDispatchMap ,
13851280 bool fHasFinalizer ,
1386- bool fRequiresOptionalFields ,
13871281 bool fHasSealedVirtuals ,
13881282 bool fHasGenericInfo ,
13891283 int cFunctionPointerTypeParameters ,
@@ -1398,10 +1292,10 @@ internal static uint GetSizeofEEType(
13981292 sizeof ( IntPtr ) + // WritableData
13991293 ( fHasDispatchMap ? sizeof ( UIntPtr) : 0 ) +
14001294 ( fHasFinalizer ? sizeof ( UIntPtr) : 0 ) +
1401- ( fRequiresOptionalFields ? sizeof ( IntPtr) : 0 ) +
14021295 ( fHasSealedVirtuals ? sizeof ( IntPtr) : 0 ) +
14031296 cFunctionPointerTypeParameters * sizeof ( IntPtr ) +
14041297 ( fHasGenericInfo ? sizeof ( IntPtr ) * 2 : 0 ) + // pointers to GenericDefinition and GenericComposition
1298+ sizeof ( IntPtr ) + // dynamic type flags
14051299 ( fHasNonGcStatics ? sizeof ( IntPtr) : 0 ) + // pointer to data
14061300 ( fHasGcStatics ? sizeof ( IntPtr) : 0 ) + // pointer to data
14071301 ( fHasThreadStatics ? sizeof ( IntPtr) : 0 ) ) ; // threadstatic index cell
0 commit comments