@@ -68,6 +68,7 @@ private static (int utfAdjust, int scalarAdjust) GetFinalScalarUtfAdjustments(by
68
68
// We scan the input from buf to len, possibly going back howFarBack bytes, to find the end of
69
69
// a valid UTF-8 sequence. We return buf + len if the buffer is valid, otherwise we return the
70
70
// pointer to the first invalid byte.
71
+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
71
72
private unsafe static byte * SimpleRewindAndValidateWithErrors ( int howFarBack , byte * buf , int len )
72
73
{
73
74
int extraLen = 0 ;
@@ -90,7 +91,6 @@ private static (int utfAdjust, int scalarAdjust) GetFinalScalarUtfAdjustments(by
90
91
{
91
92
return buf - howFarBack ;
92
93
}
93
-
94
94
int pos = 0 ;
95
95
int nextPos ;
96
96
uint codePoint = 0 ;
@@ -598,7 +598,7 @@ private unsafe static (int utfadjust, int scalaradjust) calculateErrorPathadjust
598
598
}
599
599
else
600
600
{
601
- invalidBytePointer = SimdUnicode . UTF8 . SimpleRewindAndValidateWithErrors ( processedLength - 3 , pInputBuffer + processedLength - 3 , inputLength - processedLength + 3 ) ;
601
+ invalidBytePointer = SimdUnicode . UTF8 . SimpleRewindAndValidateWithErrors ( 3 , pInputBuffer + processedLength - 3 , inputLength - processedLength + 3 ) ;
602
602
}
603
603
if ( invalidBytePointer < pInputBuffer + processedLength )
604
604
{
@@ -624,16 +624,17 @@ private unsafe static (int utfadjust, int scalaradjust) calculateErrorPathadjust
624
624
625
625
626
626
// We may still have an error.
627
- if ( processedLength < inputLength || ! Sse42 . TestZ ( prevIncomplete , prevIncomplete ) )
627
+ bool hasIncompete = ! Sse42 . TestZ ( prevIncomplete , prevIncomplete ) ;
628
+ if ( processedLength < inputLength || hasIncompete )
628
629
{
629
630
byte * invalidBytePointer ;
630
- if ( processedLength == 0 )
631
+ if ( processedLength == 0 || ! hasIncompete )
631
632
{
632
633
invalidBytePointer = SimdUnicode . UTF8 . SimpleRewindAndValidateWithErrors ( 0 , pInputBuffer + processedLength , inputLength - processedLength ) ;
633
634
}
634
635
else
635
636
{
636
- invalidBytePointer = SimdUnicode . UTF8 . SimpleRewindAndValidateWithErrors ( processedLength - 3 , pInputBuffer + processedLength - 3 , inputLength - processedLength + 3 ) ;
637
+ invalidBytePointer = SimdUnicode . UTF8 . SimpleRewindAndValidateWithErrors ( 3 , pInputBuffer + processedLength - 3 , inputLength - processedLength + 3 ) ;
637
638
638
639
}
639
640
if ( invalidBytePointer != pInputBuffer + inputLength )
@@ -813,7 +814,7 @@ private unsafe static (int utfadjust, int scalaradjust) calculateErrorPathadjust
813
814
if ( ! Avx2 . TestZ ( prevIncomplete , prevIncomplete ) )
814
815
{
815
816
int off = processedLength >= 3 ? processedLength - 3 : processedLength ;
816
- byte * invalidBytePointer = SimdUnicode . UTF8 . SimpleRewindAndValidateWithErrors ( 16 - 3 , pInputBuffer + processedLength - 3 , inputLength - processedLength + 3 ) ;
817
+ byte * invalidBytePointer = SimdUnicode . UTF8 . SimpleRewindAndValidateWithErrors ( 32 - 3 , pInputBuffer + processedLength - 3 , inputLength - processedLength + 3 ) ;
817
818
// So the code is correct up to invalidBytePointer
818
819
if ( invalidBytePointer < pInputBuffer + processedLength )
819
820
{
@@ -877,7 +878,7 @@ private unsafe static (int utfadjust, int scalaradjust) calculateErrorPathadjust
877
878
}
878
879
else
879
880
{
880
- invalidBytePointer = SimdUnicode . UTF8 . SimpleRewindAndValidateWithErrors ( processedLength - 3 , pInputBuffer + processedLength - 3 , inputLength - processedLength + 3 ) ;
881
+ invalidBytePointer = SimdUnicode . UTF8 . SimpleRewindAndValidateWithErrors ( 3 , pInputBuffer + processedLength - 3 , inputLength - processedLength + 3 ) ;
881
882
}
882
883
if ( invalidBytePointer < pInputBuffer + processedLength )
883
884
{
@@ -899,17 +900,17 @@ private unsafe static (int utfadjust, int scalaradjust) calculateErrorPathadjust
899
900
}
900
901
}
901
902
// We may still have an error.
902
- if ( processedLength < inputLength || ! Avx2 . TestZ ( prevIncomplete , prevIncomplete ) )
903
+ bool hasIncompete = ! Avx2 . TestZ ( prevIncomplete , prevIncomplete ) ;
904
+ if ( processedLength < inputLength || hasIncompete )
903
905
{
904
906
byte * invalidBytePointer ;
905
- if ( processedLength == 0 )
907
+ if ( processedLength == 0 || ! hasIncompete )
906
908
{
907
909
invalidBytePointer = SimdUnicode . UTF8 . SimpleRewindAndValidateWithErrors ( 0 , pInputBuffer + processedLength , inputLength - processedLength ) ;
908
910
}
909
911
else
910
912
{
911
- invalidBytePointer = SimdUnicode . UTF8 . SimpleRewindAndValidateWithErrors ( processedLength - 3 , pInputBuffer + processedLength - 3 , inputLength - processedLength + 3 ) ;
912
-
913
+ invalidBytePointer = SimdUnicode . UTF8 . SimpleRewindAndValidateWithErrors ( 3 , pInputBuffer + processedLength - 3 , inputLength - processedLength + 3 ) ;
913
914
}
914
915
if ( invalidBytePointer != pInputBuffer + inputLength )
915
916
{
@@ -1215,7 +1216,7 @@ private unsafe static (int utfadjust, int scalaradjust) calculateErrorPathadjust
1215
1216
}
1216
1217
else
1217
1218
{
1218
- invalidBytePointer = SimdUnicode . UTF8 . SimpleRewindAndValidateWithErrors ( processedLength - 3 , pInputBuffer + processedLength - 3 , inputLength - processedLength + 3 ) ;
1219
+ invalidBytePointer = SimdUnicode . UTF8 . SimpleRewindAndValidateWithErrors ( 3 , pInputBuffer + processedLength - 3 , inputLength - processedLength + 3 ) ;
1219
1220
}
1220
1221
if ( invalidBytePointer < pInputBuffer + processedLength )
1221
1222
{
@@ -1237,16 +1238,17 @@ private unsafe static (int utfadjust, int scalaradjust) calculateErrorPathadjust
1237
1238
}
1238
1239
}
1239
1240
// We may still have an error.
1240
- if ( processedLength < inputLength || Avx512BW . CompareGreaterThan ( prevIncomplete , Vector512 < byte > . Zero ) . ExtractMostSignificantBits ( ) != 0 )
1241
+ bool hasIncompete = Avx512BW . CompareGreaterThan ( prevIncomplete , Vector512 < byte > . Zero ) . ExtractMostSignificantBits ( ) != 0 ;
1242
+ if ( processedLength < inputLength || hasIncompete )
1241
1243
{
1242
1244
byte * invalidBytePointer ;
1243
- if ( processedLength == 0 )
1245
+ if ( processedLength == 0 || ! hasIncompete )
1244
1246
{
1245
1247
invalidBytePointer = SimdUnicode . UTF8 . SimpleRewindAndValidateWithErrors ( 0 , pInputBuffer + processedLength , inputLength - processedLength ) ;
1246
1248
}
1247
1249
else
1248
1250
{
1249
- invalidBytePointer = SimdUnicode . UTF8 . SimpleRewindAndValidateWithErrors ( processedLength - 3 , pInputBuffer + processedLength - 3 , inputLength - processedLength + 3 ) ;
1251
+ invalidBytePointer = SimdUnicode . UTF8 . SimpleRewindAndValidateWithErrors ( 3 , pInputBuffer + processedLength - 3 , inputLength - processedLength + 3 ) ;
1250
1252
1251
1253
}
1252
1254
if ( invalidBytePointer != pInputBuffer + inputLength )
@@ -1360,8 +1362,9 @@ private unsafe static (int utfadjust, int scalaradjust) calculateErrorPathadjust
1360
1362
{
1361
1363
1362
1364
Vector128 < byte > currentBlock = AdvSimd . LoadVector128 ( pInputBuffer + processedLength ) ;
1363
-
1364
- if ( AdvSimd . Arm64 . MaxAcross ( currentBlock ) . ToScalar ( ) <= 127 )
1365
+ if ( AdvSimd . Arm64 . MaxAcross ( Vector128 . AsUInt32 ( AdvSimd . And ( currentBlock , v80 ) ) ) . ToScalar ( ) == 0 )
1366
+ // We could it with (AdvSimd.Arm64.MaxAcross(currentBlock).ToScalar() <= 127) but it is slower on some
1367
+ // hardware.
1365
1368
{
1366
1369
// We have an ASCII block, no need to process it, but
1367
1370
// we need to check if the previous block was incomplete.
@@ -1431,7 +1434,7 @@ private unsafe static (int utfadjust, int scalaradjust) calculateErrorPathadjust
1431
1434
}
1432
1435
else
1433
1436
{
1434
- invalidBytePointer = SimdUnicode . UTF8 . SimpleRewindAndValidateWithErrors ( processedLength - 3 , pInputBuffer + processedLength - 3 , inputLength - processedLength + 3 ) ;
1437
+ invalidBytePointer = SimdUnicode . UTF8 . SimpleRewindAndValidateWithErrors ( 3 , pInputBuffer + processedLength - 3 , inputLength - processedLength + 3 ) ;
1435
1438
}
1436
1439
if ( invalidBytePointer < pInputBuffer + processedLength )
1437
1440
{
@@ -1457,18 +1460,17 @@ private unsafe static (int utfadjust, int scalaradjust) calculateErrorPathadjust
1457
1460
n4 += negn4add ;
1458
1461
}
1459
1462
}
1460
-
1461
- // We may still have an error.
1462
- if ( processedLength < inputLength || AdvSimd . Arm64 . MaxAcross ( prevIncomplete ) . ToScalar ( ) != 0 )
1463
+ bool hasIncompete = AdvSimd . Arm64 . MaxAcross ( Vector128 . AsUInt32 ( prevIncomplete ) ) . ToScalar ( ) != 0 ;
1464
+ if ( processedLength < inputLength || hasIncompete )
1463
1465
{
1464
1466
byte * invalidBytePointer ;
1465
- if ( processedLength == 0 )
1467
+ if ( processedLength == 0 || ! hasIncompete )
1466
1468
{
1467
1469
invalidBytePointer = SimdUnicode . UTF8 . SimpleRewindAndValidateWithErrors ( 0 , pInputBuffer + processedLength , inputLength - processedLength ) ;
1468
1470
}
1469
1471
else
1470
1472
{
1471
- invalidBytePointer = SimdUnicode . UTF8 . SimpleRewindAndValidateWithErrors ( processedLength - 3 , pInputBuffer + processedLength - 3 , inputLength - processedLength + 3 ) ;
1473
+ invalidBytePointer = SimdUnicode . UTF8 . SimpleRewindAndValidateWithErrors ( 3 , pInputBuffer + processedLength - 3 , inputLength - processedLength + 3 ) ;
1472
1474
}
1473
1475
if ( invalidBytePointer != pInputBuffer + inputLength )
1474
1476
{
@@ -1497,6 +1499,7 @@ private unsafe static (int utfadjust, int scalaradjust) calculateErrorPathadjust
1497
1499
return GetPointerToFirstInvalidByteScalar ( pInputBuffer + processedLength , inputLength - processedLength , out utf16CodeUnitCountAdjustment , out scalarCountAdjustment ) ;
1498
1500
}
1499
1501
1502
+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
1500
1503
private static unsafe void removeCounters ( byte * start , byte * end , ref int n4 , ref int contbytes )
1501
1504
{
1502
1505
for ( byte * p = start ; p < end ; p ++ )
@@ -1512,6 +1515,7 @@ private static unsafe void removeCounters(byte* start, byte* end, ref int n4, re
1512
1515
}
1513
1516
}
1514
1517
1518
+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
1515
1519
private static unsafe void addCounters ( byte * start , byte * end , ref int n4 , ref int contbytes )
1516
1520
{
1517
1521
for ( byte * p = start ; p < end ; p ++ )
0 commit comments