From e52aaee4fd770bfe728d35e10e51cafb257dec92 Mon Sep 17 00:00:00 2001 From: Ben Adams Date: Mon, 31 Dec 2018 16:16:54 +0100 Subject: Improve MdUtf8String (#21720) * Move MdUtf8String::EqualsCaseSensitive to managed code * Move MdUtf8String.ToString to safe code * Use Encoding.UTF8.GetString --- src/System.Private.CoreLib/src/System/RtType.cs | 73 ++++++------------------- src/vm/ecalllist.h | 1 - src/vm/runtimehandles.cpp | 19 ------- src/vm/runtimehandles.h | 2 - 4 files changed, 16 insertions(+), 79 deletions(-) diff --git a/src/System.Private.CoreLib/src/System/RtType.cs b/src/System.Private.CoreLib/src/System/RtType.cs index e500a7081e..259c8a6948 100644 --- a/src/System.Private.CoreLib/src/System/RtType.cs +++ b/src/System.Private.CoreLib/src/System/RtType.cs @@ -164,7 +164,7 @@ namespace System public unsafe Filter(byte* pUtf8Name, int cUtf8Name, MemberListType listType) { - m_name = new MdUtf8String((void*)pUtf8Name, cUtf8Name); + m_name = new MdUtf8String(pUtf8Name, cUtf8Name); m_listType = listType; m_nameHash = 0; @@ -4808,42 +4808,21 @@ namespace System #region Library internal readonly unsafe struct MdUtf8String { - [MethodImpl(MethodImplOptions.InternalCall)] - private static extern unsafe bool EqualsCaseSensitive(void* szLhs, void* szRhs, int cSz); - [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] private static extern unsafe bool EqualsCaseInsensitive(void* szLhs, void* szRhs, int cSz); [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] private static extern unsafe uint HashCaseInsensitive(void* sz, int cSz); - private static int GetUtf8StringByteLength(void* pUtf8String) - { - int len = 0; - - unsafe - { - byte* pItr = (byte*)pUtf8String; - - while (*pItr != 0) - { - len++; - pItr++; - } - } - - return len; - } - - private readonly void* m_pStringHeap; // This is the raw UTF8 string. + private readonly byte* m_pStringHeap; // This is the raw UTF8 string. private readonly int m_StringHeapByteLength; internal MdUtf8String(void* pStringHeap) { - m_pStringHeap = pStringHeap; + m_pStringHeap = (byte*)pStringHeap; if (pStringHeap != null) { - m_StringHeapByteLength = GetUtf8StringByteLength(pStringHeap); + m_StringHeapByteLength = StubHelpers.StubHelpers.strlen((sbyte*)pStringHeap); } else { @@ -4851,36 +4830,36 @@ namespace System } } - internal unsafe MdUtf8String(void* pUtf8String, int cUtf8String) + internal unsafe MdUtf8String(byte* pUtf8String, int cUtf8String) { m_pStringHeap = pUtf8String; m_StringHeapByteLength = cUtf8String; } + // Very common called version of the Equals pair + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal unsafe bool Equals(MdUtf8String s) { - if (m_pStringHeap == null) + if (s.m_StringHeapByteLength != m_StringHeapByteLength) { - return s.m_StringHeapByteLength == 0; + return false; } - if ((s.m_StringHeapByteLength == m_StringHeapByteLength) && (m_StringHeapByteLength != 0)) + else { - return EqualsCaseSensitive(s.m_pStringHeap, m_pStringHeap, m_StringHeapByteLength); + return SpanHelpers.SequenceEqual(ref *s.m_pStringHeap, ref *m_pStringHeap, m_StringHeapByteLength); } - return false; } internal unsafe bool EqualsCaseInsensitive(MdUtf8String s) { - if (m_pStringHeap == null) + if (s.m_StringHeapByteLength != m_StringHeapByteLength) { - return s.m_StringHeapByteLength == 0; + return false; } - if ((s.m_StringHeapByteLength == m_StringHeapByteLength) && (m_StringHeapByteLength != 0)) + else { - return EqualsCaseInsensitive(s.m_pStringHeap, m_pStringHeap, m_StringHeapByteLength); + return (m_StringHeapByteLength == 0) || EqualsCaseInsensitive(s.m_pStringHeap, m_pStringHeap, m_StringHeapByteLength); } - return false; } internal unsafe uint HashCaseInsensitive() @@ -4889,27 +4868,7 @@ namespace System } public override string ToString() - { - unsafe - { - byte* buf = stackalloc byte[m_StringHeapByteLength]; - byte* pItr = (byte*)m_pStringHeap; - - for (int currentPos = 0; currentPos < m_StringHeapByteLength; currentPos++) - { - buf[currentPos] = *pItr; - pItr++; - } - - if (m_StringHeapByteLength == 0) - return ""; - - int cResult = Encoding.UTF8.GetCharCount(buf, m_StringHeapByteLength); - char* result = stackalloc char[cResult]; - Encoding.UTF8.GetChars(buf, m_StringHeapByteLength, result, cResult); - return new string(result, 0, cResult); - } - } + => Encoding.UTF8.GetString(new ReadOnlySpan(m_pStringHeap, m_StringHeapByteLength)); } #endregion } diff --git a/src/vm/ecalllist.h b/src/vm/ecalllist.h index 2d07ac39aa..82e7e978ac 100644 --- a/src/vm/ecalllist.h +++ b/src/vm/ecalllist.h @@ -449,7 +449,6 @@ FCFuncEnd() #endif FCFuncStart(gMdUtf8String) - FCFuncElement("EqualsCaseSensitive", MdUtf8String::EqualsCaseSensitive) QCFuncElement("EqualsCaseInsensitive", MdUtf8String::EqualsCaseInsensitive) QCFuncElement("HashCaseInsensitive", MdUtf8String::HashCaseInsensitive) FCFuncEnd() diff --git a/src/vm/runtimehandles.cpp b/src/vm/runtimehandles.cpp index 8f2d8effad..e25a1a3ddb 100644 --- a/src/vm/runtimehandles.cpp +++ b/src/vm/runtimehandles.cpp @@ -31,25 +31,6 @@ #include "eventtrace.h" #include "invokeutil.h" - -FCIMPL3(FC_BOOL_RET, MdUtf8String::EqualsCaseSensitive, LPCUTF8 szLhs, LPCUTF8 szRhs, INT32 stringNumBytes) -{ - CONTRACTL { - FCALL_CHECK; - PRECONDITION(CheckPointer(szLhs)); - PRECONDITION(CheckPointer(szRhs)); - } - CONTRACTL_END; - - // Important: the string in pSsz isn't null terminated so the length must be used - // when performing operations on the string. - - // At this point, both the left and right strings are guaranteed to have the - // same length. - FC_RETURN_BOOL(strncmp(szLhs, szRhs, stringNumBytes) == 0); -} -FCIMPLEND - BOOL QCALLTYPE MdUtf8String::EqualsCaseInsensitive(LPCUTF8 szLhs, LPCUTF8 szRhs, INT32 stringNumBytes) { QCALL_CONTRACT; diff --git a/src/vm/runtimehandles.h b/src/vm/runtimehandles.h index 739eb245f0..6edf61ec99 100644 --- a/src/vm/runtimehandles.h +++ b/src/vm/runtimehandles.h @@ -106,8 +106,6 @@ public: class MdUtf8String { public: - static FCDECL3(FC_BOOL_RET, EqualsCaseSensitive, LPCUTF8 szLhs, LPCUTF8 szRhs, INT32 stringNumBytes); - static BOOL QCALLTYPE EqualsCaseInsensitive(LPCUTF8 szLhs, LPCUTF8 szRhs, INT32 stringNumBytes); -- cgit v1.2.3