@@ -81,7 +81,7 @@ internal sealed partial class SymbolicRegexMatcher<TSet> : SymbolicRegexMatcher
81
81
/// <summary>Data and routines for skipping ahead to the next place a match could potentially start.</summary>
82
82
private readonly RegexFindOptimizations ? _findOpts ;
83
83
84
- /// <summary>Dead end state to quickly return NoMatch</summary>
84
+ /// <summary>Dead end state to quickly return NoMatch, this could potentially be a constant </summary>
85
85
private readonly int _deadStateId ;
86
86
87
87
/// <summary>Whether the pattern contains any anchor</summary>
@@ -663,6 +663,7 @@ private bool FindEndPositionDeltasDFANoSkipAscii(ReadOnlySpan<char> input, int l
663
663
/// TODO: this is essentially a stripped down version when there's no good prefix optimizations
664
664
/// i don't trust the compiler to optimize this and it makes a
665
665
/// ~50% difference in performance with removing unnecessary checks alone
666
+ ///
666
667
/// </summary>
667
668
private bool FindEndPositionDeltasDFANoSkip ( ReadOnlySpan < char > input , int lengthMinus1 , RegexRunnerMode mode ,
668
669
ref int posRef , int startStateId , ref int endPosRef , ref int endStateIdRef , ref int initialStatePosRef , ref int initialStatePosCandidateRef )
@@ -674,12 +675,19 @@ private bool FindEndPositionDeltasDFANoSkip(ReadOnlySpan<char> input, int length
674
675
byte [ ] mtlookup = _mintermClassifier . ByteLookup ( ) ! ;
675
676
int endStateId = endStateIdRef ;
676
677
int currStateId = startStateId ;
678
+ // ldfld only once
679
+ int deadStateId = _deadStateId ;
677
680
try
678
681
{
679
682
// Loop through each character in the input, transitioning from state to state for each.
683
+ // The goal is to make this loop as fast as it can possible be,
684
+ // every single piece of overhead should be removed here
685
+ // there should be not a single callvirt instruction in the loop
686
+ // ldfld only if necessary (e.g. a reference changes)
687
+ // no memory writes unless necessary
680
688
while ( true )
681
689
{
682
- if ( currStateId == _deadStateId )
690
+ if ( currStateId == deadStateId )
683
691
{
684
692
return true ;
685
693
}
@@ -709,9 +717,7 @@ private bool FindEndPositionDeltasDFANoSkip(ReadOnlySpan<char> input, int length
709
717
}
710
718
// one off check for the final position
711
719
// this is just to move it out of the hot loop
712
- if ( ( ! _stateFlagsArray [ currStateId ] . IsNullable ( ) &&
713
- ! _stateArray [ currStateId ] ! . IsNullableFor (
714
- GetPositionKind ( - 1 ) ) ) )
720
+ if ( ( ! _stateFlagsArray [ currStateId ] . IsNullable ( ) && IsNullableWithContext ( currStateId , 0 ) ) )
715
721
{
716
722
return false ;
717
723
}
0 commit comments