@@ -100,6 +100,7 @@ internal abstract class RegexCompiler
100
100
private static readonly MethodInfo s_arrayResize = typeof ( Array ) . GetMethod ( "Resize" ) ! . MakeGenericMethod ( typeof ( int ) ) ;
101
101
private static readonly MethodInfo s_mathMinIntInt = typeof ( Math ) . GetMethod ( "Min" , new Type [ ] { typeof ( int ) , typeof ( int ) } ) ! ;
102
102
private static readonly MethodInfo s_memoryMarshalGetArrayDataReferenceSearchValues = typeof ( MemoryMarshal ) . GetMethod ( "GetArrayDataReference" , new Type [ ] { Type . MakeGenericMethodParameter ( 0 ) . MakeArrayType ( ) } ) ! . MakeGenericMethod ( typeof ( SearchValues < char > ) ) ! ;
103
+ private static readonly MethodInfo s_unsafeAs = typeof ( Unsafe ) . GetMethod ( "As" , new Type [ ] { typeof ( object ) } ) ! ;
103
104
// Note:
104
105
// Single-range helpers like IsAsciiLetterLower, IsAsciiLetterUpper, IsAsciiDigit, and IsBetween aren't used here, as the IL generated for those
105
106
// single-range checks is as cheap as the method call, and there's no readability issue as with the source generator.
@@ -6117,16 +6118,21 @@ private void LoadSearchValues(ReadOnlySpan<char> chars)
6117
6118
// Logically do _searchValues[index], but avoid the bounds check on accessing the array,
6118
6119
// and cast to the known derived sealed type to enable devirtualization.
6119
6120
6120
- // DerivedSearchValues d = Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(this._searchValues), index);
6121
+ // DerivedSearchValues d = Unsafe.As<DerivedSearchValues>(Unsafe. Add(ref MemoryMarshal.GetArrayDataReference(this._searchValues), index) );
6121
6122
// ... = d;
6122
6123
Ldthisfld ( s_searchValuesArrayField ) ;
6123
6124
Call ( s_memoryMarshalGetArrayDataReferenceSearchValues ) ;
6124
6125
Ldc ( index * IntPtr . Size ) ;
6125
6126
Add ( ) ;
6126
6127
_ilg ! . Emit ( OpCodes . Ldind_Ref ) ;
6127
- LocalBuilder ioavLocal = _ilg ! . DeclareLocal ( list [ index ] . GetType ( ) ) ;
6128
- Stloc ( ioavLocal ) ;
6129
- Ldloc ( ioavLocal ) ;
6128
+ Call ( MakeUnsafeAs ( list [ index ] . GetType ( ) ) ) ; // provide JIT with details necessary to devirtualize calls on this instance
6129
+
6130
+ [ UnconditionalSuppressMessage ( "ReflectionAnalysis" , "IL2060:MakeGenericMethod" , Justification =
6131
+ "Calling Unsafe.As<T> is safe since the T doesn't have trimming annotations." ) ]
6132
+ static MethodInfo MakeUnsafeAs ( Type type )
6133
+ {
6134
+ return s_unsafeAs . MakeGenericMethod ( type ) ;
6135
+ }
6130
6136
}
6131
6137
}
6132
6138
}
0 commit comments