@@ -1252,20 +1252,30 @@ private RuntimePropertyInfo[] PopulateProperties(Filter filter)
12521252 Dictionary < string , List < RuntimePropertyInfo > > ? csPropertyInfos = filter . CaseSensitive ( ) ? null :
12531253 new Dictionary < string , List < RuntimePropertyInfo > > ( ) ;
12541254
1255- // All elements automatically initialized to false.
1256- bool [ ] usedSlots = new bool [ RuntimeTypeHandle . GetNumVirtuals ( declaringType ) ] ;
1255+ // All elements initialized to false.
1256+ int numVirtuals = RuntimeTypeHandle . GetNumVirtuals ( declaringType ) ;
1257+ Span < bool > usedSlots = stackalloc bool [ 0 ] ;
1258+ if ( numVirtuals <= 128 ) // arbitrary stack limit
1259+ {
1260+ usedSlots = stackalloc bool [ numVirtuals ] ;
1261+ usedSlots . Clear ( ) ;
1262+ }
1263+ else
1264+ {
1265+ usedSlots = new bool [ numVirtuals ] ;
1266+ }
12571267
12581268 // Populate associates off of the class hierarchy
12591269 do
12601270 {
1261- PopulateProperties ( filter , declaringType , csPropertyInfos , usedSlots , ref list ) ;
1271+ PopulateProperties ( filter , declaringType , csPropertyInfos , usedSlots , isInterface : false , ref list ) ;
12621272 declaringType = RuntimeTypeHandle . GetBaseType ( declaringType ) ;
12631273 } while ( declaringType != null ) ;
12641274 }
12651275 else
12661276 {
12671277 // Populate associates for this interface
1268- PopulateProperties ( filter , declaringType , null , null , ref list ) ;
1278+ PopulateProperties ( filter , declaringType , null , default , isInterface : true , ref list ) ;
12691279 }
12701280
12711281 return list . ToArray ( ) ;
@@ -1275,7 +1285,8 @@ private void PopulateProperties(
12751285 Filter filter ,
12761286 RuntimeType declaringType ,
12771287 Dictionary < string , List < RuntimePropertyInfo > > ? csPropertyInfos ,
1278- bool [ ] ? usedSlots ,
1288+ Span < bool > usedSlots ,
1289+ bool isInterface ,
12791290 ref ListBuilder < RuntimePropertyInfo > list )
12801291 {
12811292 int tkDeclaringType = RuntimeTypeHandle . GetToken ( declaringType ) ;
@@ -1290,8 +1301,8 @@ private void PopulateProperties(
12901301
12911302 int numVirtuals = RuntimeTypeHandle . GetNumVirtuals ( declaringType ) ;
12921303
1293- Debug . Assert ( ( declaringType . IsInterface && usedSlots == null && csPropertyInfos == null ) ||
1294- ( ! declaringType . IsInterface && usedSlots != null && usedSlots . Length >= numVirtuals ) ) ;
1304+ Debug . Assert ( ( declaringType . IsInterface && isInterface && csPropertyInfos == null ) ||
1305+ ( ! declaringType . IsInterface && ! isInterface && usedSlots . Length >= numVirtuals ) ) ;
12951306
12961307 for ( int i = 0 ; i < tkProperties . Length ; i ++ )
12971308 {
@@ -1313,7 +1324,7 @@ private void PopulateProperties(
13131324 tkProperty , declaringType , m_runtimeTypeCache , out bool isPrivate ) ;
13141325
13151326 // If this is a class, not an interface
1316- if ( usedSlots != null )
1327+ if ( ! isInterface )
13171328 {
13181329 #region Remove Privates
13191330 if ( declaringType != ReflectedType && isPrivate )
0 commit comments