Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions src/Compilers/CSharp/Portable/Parser/Lexer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2337,9 +2337,7 @@ private SyntaxTrivia ScanWhitespace()
if (width < MaxCachedTokenSize)
{
return _cache.LookupTrivia(
TextWindow.CharacterWindow,
TextWindow.LexemeRelativeStart,
width,
TextWindow.CharacterWindow.AsSpan(TextWindow.LexemeRelativeStart, width),
hashCode,
CreateWhitespaceTrivia,
TextWindow);
Expand Down
16 changes: 6 additions & 10 deletions src/Compilers/CSharp/Portable/Parser/LexerCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -182,19 +182,17 @@ internal bool TryGetKeywordKind(string key, out SyntaxKind kind)
}

internal SyntaxTrivia LookupTrivia<TArg>(
char[] textBuffer,
int keyStart,
int keyLength,
ReadOnlySpan<char> textBuffer,
int hashCode,
Func<TArg, SyntaxTrivia> createTriviaFunction,
TArg data)
{
var value = TriviaMap.FindItem(textBuffer, keyStart, keyLength, hashCode);
var value = TriviaMap.FindItem(textBuffer, hashCode);

if (value == null)
{
value = createTriviaFunction(data);
TriviaMap.AddItem(textBuffer, keyStart, keyLength, hashCode, value);
TriviaMap.AddItem(textBuffer, hashCode, value);
}

return value;
Expand Down Expand Up @@ -222,22 +220,20 @@ private static void Miss()
#endif

internal SyntaxToken LookupToken<TArg>(
char[] textBuffer,
int keyStart,
int keyLength,
ReadOnlySpan<char> textBuffer,
int hashCode,
Func<TArg, SyntaxToken> createTokenFunction,
TArg data)
{
var value = TokenMap.FindItem(textBuffer, keyStart, keyLength, hashCode);
var value = TokenMap.FindItem(textBuffer, hashCode);

if (value == null)
{
#if COLLECT_STATS
Miss();
#endif
value = createTokenFunction(data);
TokenMap.AddItem(textBuffer, keyStart, keyLength, hashCode, value);
TokenMap.AddItem(textBuffer, hashCode, value);
}
else
{
Expand Down
4 changes: 1 addition & 3 deletions src/Compilers/CSharp/Portable/Parser/QuickScanner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -235,9 +235,7 @@ private enum CharFlags : byte
{
// this is a good token!
var token = _cache.LookupToken(
TextWindow.CharacterWindow,
TextWindow.LexemeRelativeStart,
i - TextWindow.LexemeRelativeStart,
TextWindow.CharacterWindow.AsSpan(TextWindow.LexemeRelativeStart, i - TextWindow.LexemeRelativeStart),
hashCode,
CreateQuickToken,
this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ public string Intern(StringBuilder text)

public string Intern(char[] array, int start, int length)
{
return _strings.Add(array, start, length);
return _strings.Add(array.AsSpan(start, length));
}

public string GetInternedText()
Expand Down
2 changes: 1 addition & 1 deletion src/Compilers/Core/CodeAnalysisTest/StringTableTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public void TestAddSameWithVariousInputsProducesSameStringInstance()
var s3 = st.Add(" ");
Assert.Same(s2, s3);

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

var s5 = st.Add("ABC DEF", 3, 1);
Expand Down
12 changes: 1 addition & 11 deletions src/Compilers/Core/Portable/InternalUtilities/Hash.cs
Original file line number Diff line number Diff line change
Expand Up @@ -351,17 +351,7 @@ internal static int GetFNVHashCode(System.Text.StringBuilder text)
/// <param name="length">The number of characters, beginning with <paramref name="start"/> to hash</param>
/// <returns>The FNV-1a hash code of the substring beginning at <paramref name="start"/> and ending after <paramref name="length"/> characters.</returns>
internal static int GetFNVHashCode(char[] text, int start, int length)
{
int hashCode = Hash.FnvOffsetBias;
int end = start + length;

for (int i = start; i < end; i++)
{
hashCode = unchecked((hashCode ^ text[i]) * Hash.FnvPrime);
}

return hashCode;
}
=> GetFNVHashCode(text.AsSpan(start, length));

/// <summary>
/// Compute the hashcode of a single character using the FNV-1a algorithm
Expand Down
29 changes: 20 additions & 9 deletions src/Compilers/Core/Portable/InternalUtilities/StringTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,21 @@ public void Free()

#endregion // Poolable

/// <summary>
/// Legacy entrypoint for VB.
/// </summary>
internal string Add(char[] chars)
=> Add(chars.AsSpan());

/// <summary>
/// Legacy entrypoint for VB.
/// </summary>
internal string Add(char[] chars, int start, int len)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these are now kept around for VB.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

have confirmed that Scanner.GetText/Scanner.Intern calls into this entrypoint still.

=> Add(chars.AsSpan(start, len));

internal string Add(ReadOnlySpan<char> chars)
{
var span = chars.AsSpan(start, len);
var hashCode = Hash.GetFNVHashCode(chars, start, len);
var hashCode = Hash.GetFNVHashCode(chars);

// capture array to avoid extra range checks
var arr = _localTable;
Expand All @@ -125,13 +136,13 @@ internal string Add(char[] chars, int start, int len)
if (text != null && arr[idx].HashCode == hashCode)
{
var result = arr[idx].Text;
if (StringTable.TextEquals(result, span))
if (TextEquals(result, chars))
{
return result;
}
}

string? shared = FindSharedEntry(chars, start, len, hashCode);
string? shared = FindSharedEntry(chars, hashCode);
if (shared != null)
{
// PERF: the following code does element-wise assignment of a struct
Expand All @@ -143,7 +154,7 @@ internal string Add(char[] chars, int start, int len)
return shared;
}

return AddItem(chars, start, len, hashCode);
return AddItem(chars, hashCode);
}

internal string Add(string chars, int start, int len)
Expand Down Expand Up @@ -283,7 +294,7 @@ internal string Add(string chars)
return chars;
}

private static string? FindSharedEntry(char[] chars, int start, int len, int hashCode)
private static string? FindSharedEntry(ReadOnlySpan<char> chars, int hashCode)
{
var arr = s_sharedTable;
int idx = SharedIdxFromHash(hashCode);
Expand All @@ -298,7 +309,7 @@ internal string Add(string chars)

if (e != null)
{
if (hash == hashCode && TextEquals(e, chars.AsSpan(start, len)))
if (hash == hashCode && TextEquals(e, chars))
{
break;
}
Expand Down Expand Up @@ -492,9 +503,9 @@ internal string Add(string chars)
return e;
}

private string AddItem(char[] chars, int start, int len, int hashCode)
private string AddItem(ReadOnlySpan<char> chars, int hashCode)
{
var text = new String(chars, start, len);
var text = chars.ToString();
AddCore(text, hashCode);
return text;
}
Expand Down
22 changes: 17 additions & 5 deletions src/Compilers/Core/Portable/InternalUtilities/TextKeyedCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,13 @@ public void Free()

#endregion // Poolable

/// <summary>
/// Legacy entrypoint for VB.
/// </summary>
internal T? FindItem(char[] chars, int start, int len, int hashCode)
=> FindItem(chars.AsSpan(start, len), hashCode);

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

if (text != null && localSlot.HashCode == hashCode)
{
if (StringTable.TextEquals(text, chars.AsSpan(start, len)))
if (StringTable.TextEquals(text, chars))
{
return localSlot.Item;
}
}

SharedEntryValue? e = FindSharedEntry(chars, start, len, hashCode);
SharedEntryValue? e = FindSharedEntry(chars, hashCode);
if (e != null)
{
localSlot.HashCode = hashCode;
Expand All @@ -135,7 +141,7 @@ public void Free()
return null!;
}

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

if (e != null)
{
if (hash == hashCode && StringTable.TextEquals(e.Text, chars.AsSpan(start, len)))
if (hash == hashCode && StringTable.TextEquals(e.Text, chars))
{
break;
}
Expand All @@ -171,9 +177,15 @@ public void Free()
return e;
}

/// <summary>
/// Legacy entrypoint for VB.
/// </summary>
internal void AddItem(char[] chars, int start, int len, int hashCode, T item)
=> AddItem(chars.AsSpan(start, len), hashCode, item);

internal void AddItem(ReadOnlySpan<char> chars, int hashCode, T item)
{
var text = _strings.Add(chars, start, len);
var text = _strings.Add(chars);

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