Skip to content

Commit 0d92d27

Browse files
authored
Revert "Use spans in low level lexer char array handling code (#79232)"
This reverts commit fb38d6b.
1 parent 03f9b70 commit 0d92d27

File tree

10 files changed

+52
-33
lines changed

10 files changed

+52
-33
lines changed

src/Compilers/CSharp/Portable/Parser/Lexer.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2337,7 +2337,9 @@ private SyntaxTrivia ScanWhitespace()
23372337
if (width < MaxCachedTokenSize)
23382338
{
23392339
return _cache.LookupTrivia(
2340-
TextWindow.CharacterWindow.AsSpan(TextWindow.LexemeRelativeStart, width),
2340+
TextWindow.CharacterWindow,
2341+
TextWindow.LexemeRelativeStart,
2342+
width,
23412343
hashCode,
23422344
CreateWhitespaceTrivia,
23432345
TextWindow);

src/Compilers/CSharp/Portable/Parser/LexerCache.cs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -182,17 +182,19 @@ internal bool TryGetKeywordKind(string key, out SyntaxKind kind)
182182
}
183183

184184
internal SyntaxTrivia LookupTrivia<TArg>(
185-
ReadOnlySpan<char> textBuffer,
185+
char[] textBuffer,
186+
int keyStart,
187+
int keyLength,
186188
int hashCode,
187189
Func<TArg, SyntaxTrivia> createTriviaFunction,
188190
TArg data)
189191
{
190-
var value = TriviaMap.FindItem(textBuffer, hashCode);
192+
var value = TriviaMap.FindItem(textBuffer, keyStart, keyLength, hashCode);
191193

192194
if (value == null)
193195
{
194196
value = createTriviaFunction(data);
195-
TriviaMap.AddItem(textBuffer, hashCode, value);
197+
TriviaMap.AddItem(textBuffer, keyStart, keyLength, hashCode, value);
196198
}
197199

198200
return value;
@@ -220,20 +222,22 @@ private static void Miss()
220222
#endif
221223

222224
internal SyntaxToken LookupToken<TArg>(
223-
ReadOnlySpan<char> textBuffer,
225+
char[] textBuffer,
226+
int keyStart,
227+
int keyLength,
224228
int hashCode,
225229
Func<TArg, SyntaxToken> createTokenFunction,
226230
TArg data)
227231
{
228-
var value = TokenMap.FindItem(textBuffer, hashCode);
232+
var value = TokenMap.FindItem(textBuffer, keyStart, keyLength, hashCode);
229233

230234
if (value == null)
231235
{
232236
#if COLLECT_STATS
233237
Miss();
234238
#endif
235239
value = createTokenFunction(data);
236-
TokenMap.AddItem(textBuffer, hashCode, value);
240+
TokenMap.AddItem(textBuffer, keyStart, keyLength, hashCode, value);
237241
}
238242
else
239243
{

src/Compilers/CSharp/Portable/Parser/QuickScanner.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,9 @@ private enum CharFlags : byte
235235
{
236236
// this is a good token!
237237
var token = _cache.LookupToken(
238-
TextWindow.CharacterWindow.AsSpan(TextWindow.LexemeRelativeStart, i - TextWindow.LexemeRelativeStart),
238+
TextWindow.CharacterWindow,
239+
TextWindow.LexemeRelativeStart,
240+
i - TextWindow.LexemeRelativeStart,
239241
hashCode,
240242
CreateQuickToken,
241243
this);

src/Compilers/CSharp/Portable/Parser/SlidingTextWindow.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,7 @@ public string Intern(StringBuilder text)
416416

417417
public string Intern(char[] array, int start, int length)
418418
{
419-
return _strings.Add(array.AsSpan(start, length));
419+
return _strings.Add(array, start, length);
420420
}
421421

422422
public string GetInternedText()

src/Compilers/Core/CodeAnalysisTest/StringTableTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public void TestAddSameWithVariousInputsProducesSameStringInstance()
4848
var s3 = st.Add(" ");
4949
Assert.Same(s2, s3);
5050

51-
var s4 = st.Add([' ']);
51+
var s4 = st.Add(new char[1] { ' ' }, 0, 1);
5252
Assert.Same(s3, s4);
5353

5454
var s5 = st.Add("ABC DEF", 3, 1);

src/Compilers/Core/Portable/InternalUtilities/Hash.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,17 @@ internal static int GetFNVHashCode(System.Text.StringBuilder text)
351351
/// <param name="length">The number of characters, beginning with <paramref name="start"/> to hash</param>
352352
/// <returns>The FNV-1a hash code of the substring beginning at <paramref name="start"/> and ending after <paramref name="length"/> characters.</returns>
353353
internal static int GetFNVHashCode(char[] text, int start, int length)
354-
=> GetFNVHashCode(text.AsSpan(start, length));
354+
{
355+
int hashCode = Hash.FnvOffsetBias;
356+
int end = start + length;
357+
358+
for (int i = start; i < end; i++)
359+
{
360+
hashCode = unchecked((hashCode ^ text[i]) * Hash.FnvPrime);
361+
}
362+
363+
return hashCode;
364+
}
355365

356366
/// <summary>
357367
/// Compute the hashcode of a single character using the FNV-1a algorithm

src/Compilers/Core/Portable/InternalUtilities/StringTable.cs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,10 @@ public void Free()
111111

112112
#endregion // Poolable
113113

114-
internal string Add(ReadOnlySpan<char> chars)
114+
internal string Add(char[] chars, int start, int len)
115115
{
116-
var hashCode = Hash.GetFNVHashCode(chars);
116+
var span = chars.AsSpan(start, len);
117+
var hashCode = Hash.GetFNVHashCode(chars, start, len);
117118

118119
// capture array to avoid extra range checks
119120
var arr = _localTable;
@@ -124,13 +125,13 @@ internal string Add(ReadOnlySpan<char> chars)
124125
if (text != null && arr[idx].HashCode == hashCode)
125126
{
126127
var result = arr[idx].Text;
127-
if (TextEquals(result, chars))
128+
if (StringTable.TextEquals(result, span))
128129
{
129130
return result;
130131
}
131132
}
132133

133-
string? shared = FindSharedEntry(chars, hashCode);
134+
string? shared = FindSharedEntry(chars, start, len, hashCode);
134135
if (shared != null)
135136
{
136137
// PERF: the following code does element-wise assignment of a struct
@@ -142,7 +143,7 @@ internal string Add(ReadOnlySpan<char> chars)
142143
return shared;
143144
}
144145

145-
return AddItem(chars, hashCode);
146+
return AddItem(chars, start, len, hashCode);
146147
}
147148

148149
internal string Add(string chars, int start, int len)
@@ -282,7 +283,7 @@ internal string Add(string chars)
282283
return chars;
283284
}
284285

285-
private static string? FindSharedEntry(ReadOnlySpan<char> chars, int hashCode)
286+
private static string? FindSharedEntry(char[] chars, int start, int len, int hashCode)
286287
{
287288
var arr = s_sharedTable;
288289
int idx = SharedIdxFromHash(hashCode);
@@ -297,7 +298,7 @@ internal string Add(string chars)
297298

298299
if (e != null)
299300
{
300-
if (hash == hashCode && TextEquals(e, chars))
301+
if (hash == hashCode && TextEquals(e, chars.AsSpan(start, len)))
301302
{
302303
break;
303304
}
@@ -491,9 +492,9 @@ internal string Add(string chars)
491492
return e;
492493
}
493494

494-
private string AddItem(ReadOnlySpan<char> chars, int hashCode)
495+
private string AddItem(char[] chars, int start, int len, int hashCode)
495496
{
496-
var text = chars.ToString();
497+
var text = new String(chars, start, len);
497498
AddCore(text, hashCode);
498499
return text;
499500
}

src/Compilers/Core/Portable/InternalUtilities/TextKeyedCache.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ public void Free()
105105

106106
#endregion // Poolable
107107

108-
internal T? FindItem(ReadOnlySpan<char> chars, int hashCode)
108+
internal T? FindItem(char[] chars, int start, int len, int hashCode)
109109
{
110110
// get direct element reference to avoid extra range checks
111111
ref var localSlot = ref _localTable[LocalIdxFromHash(hashCode)];
@@ -114,13 +114,13 @@ public void Free()
114114

115115
if (text != null && localSlot.HashCode == hashCode)
116116
{
117-
if (StringTable.TextEquals(text, chars))
117+
if (StringTable.TextEquals(text, chars.AsSpan(start, len)))
118118
{
119119
return localSlot.Item;
120120
}
121121
}
122122

123-
SharedEntryValue? e = FindSharedEntry(chars, hashCode);
123+
SharedEntryValue? e = FindSharedEntry(chars, start, len, hashCode);
124124
if (e != null)
125125
{
126126
localSlot.HashCode = hashCode;
@@ -135,7 +135,7 @@ public void Free()
135135
return null!;
136136
}
137137

138-
private SharedEntryValue? FindSharedEntry(ReadOnlySpan<char> chars, int hashCode)
138+
private SharedEntryValue? FindSharedEntry(char[] chars, int start, int len, int hashCode)
139139
{
140140
var arr = _sharedTableInst;
141141
int idx = SharedIdxFromHash(hashCode);
@@ -151,7 +151,7 @@ public void Free()
151151

152152
if (e != null)
153153
{
154-
if (hash == hashCode && StringTable.TextEquals(e.Text, chars))
154+
if (hash == hashCode && StringTable.TextEquals(e.Text, chars.AsSpan(start, len)))
155155
{
156156
break;
157157
}
@@ -171,9 +171,9 @@ public void Free()
171171
return e;
172172
}
173173

174-
internal void AddItem(ReadOnlySpan<char> chars, int hashCode, T item)
174+
internal void AddItem(char[] chars, int start, int len, int hashCode, T item)
175175
{
176-
var text = _strings.Add(chars);
176+
var text = _strings.Add(chars, start, len);
177177

178178
// add to the shared table first (in case someone looks for same item)
179179
var e = new SharedEntryValue(text, item);

src/Compilers/VisualBasic/Portable/Scanner/Scanner.vb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Syntax.InternalSyntax
166166
Dim quickToken = QuickScanToken(allowLeadingMultilineTrivia)
167167

168168
If quickToken.Succeeded Then
169-
Dim token = _quickTokenTable.FindItem(quickToken.Chars.AsSpan(quickToken.Start, quickToken.Length), quickToken.HashCode)
169+
Dim token = _quickTokenTable.FindItem(quickToken.Chars, quickToken.Start, quickToken.Length, quickToken.HashCode)
170170
If token IsNot Nothing Then
171171
AdvanceChar(quickToken.Length)
172172
If quickToken.TerminatorLength <> 0 Then
@@ -185,7 +185,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Syntax.InternalSyntax
185185
If quickToken.Succeeded Then
186186
Debug.Assert(quickToken.Length = scannedToken.FullWidth)
187187

188-
_quickTokenTable.AddItem(quickToken.Chars.AsSpan(quickToken.Start, quickToken.Length), quickToken.HashCode, scannedToken)
188+
_quickTokenTable.AddItem(quickToken.Chars, quickToken.Start, quickToken.Length, quickToken.HashCode, scannedToken)
189189
End If
190190

191191
Return scannedToken
@@ -399,7 +399,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Syntax.InternalSyntax
399399
Return _stringTable.Add(ch)
400400
End Function
401401
Friend Function Intern(arr As Char()) As String
402-
Return _stringTable.Add(arr.AsSpan())
402+
Return _stringTable.Add(arr)
403403
End Function
404404
#End Region
405405

src/Compilers/VisualBasic/Test/Syntax/QuickTokenTableTests.vb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@ Public Class QuickTokenTableTests
8989
Dim text = New String(qt.Chars, 0, qt.Length)
9090
Dim token = InternalSyntax.SyntaxFactory.Identifier(text)
9191

92-
Assert.Null(table.FindItem(qt.Chars.AsSpan(qt.Start, qt.Length), qt.HashCode))
93-
table.AddItem(qt.Chars.AsSpan(qt.Start, qt.Length), qt.HashCode, DirectCast(token, InternalSyntax.SyntaxToken))
92+
Assert.Null(table.FindItem(qt.Chars, qt.Start, qt.Length, qt.HashCode))
93+
table.AddItem(qt.Chars, qt.Start, qt.Length, qt.HashCode, DirectCast(token, InternalSyntax.SyntaxToken))
9494
Return New Tuple(Of String, InternalSyntax.SyntaxToken)(text, token)
9595
End Using
9696
End Function
@@ -107,7 +107,7 @@ Public Class QuickTokenTableTests
107107
Dim qt = scanner.QuickScanToken(False)
108108
Assert.True(qt.Succeeded)
109109

110-
Dim tokFound = table.FindItem(qt.Chars.AsSpan(qt.Start, qt.Length), qt.HashCode)
110+
Dim tokFound = table.FindItem(qt.Chars, qt.Start, qt.Length, qt.HashCode)
111111
Assert.Same(e.Item2, tokFound)
112112
End Using
113113
End Sub

0 commit comments

Comments
 (0)