From: Jan Kotas Date: Mon, 19 Mar 2018 19:51:33 +0000 (-0700) Subject: Switch over to managed Marvin implementation for string hashing (#17029) X-Git-Tag: accepted/tizen/unified/20190422.045933~2589 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d3b818787748f09e63106b9b08d7bd6f5cd171bb;p=platform%2Fupstream%2Fcoreclr.git Switch over to managed Marvin implementation for string hashing (#17029) --- diff --git a/src/classlibnative/bcltype/stringnative.cpp b/src/classlibnative/bcltype/stringnative.cpp index 63eed73..8b040dc 100644 --- a/src/classlibnative/bcltype/stringnative.cpp +++ b/src/classlibnative/bcltype/stringnative.cpp @@ -31,31 +31,6 @@ #pragma optimize("tgy", on) #endif -inline COMNlsHashProvider * GetCurrentNlsHashProvider() -{ - LIMITED_METHOD_CONTRACT; - return &COMNlsHashProvider::s_NlsHashProvider; -} - -FCIMPL1(INT32, COMString::Marvin32HashString, StringObject* thisRefUNSAFE) { - FCALL_CONTRACT; - - int iReturnHash = 0; - - if (thisRefUNSAFE == NULL) { - FCThrow(kNullReferenceException); - } - - BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException)); - iReturnHash = GetCurrentNlsHashProvider()->HashString(thisRefUNSAFE->GetBuffer(), thisRefUNSAFE->GetStringLength()); - END_SO_INTOLERANT_CODE; - - FC_GC_POLL_RET(); - - return iReturnHash; -} -FCIMPLEND - /*===============================IsFastSort=============================== **Action: Call the helper to walk the string and see if we have any high chars. **Returns: void. The appropriate bits are set on the String. diff --git a/src/classlibnative/bcltype/stringnative.h b/src/classlibnative/bcltype/stringnative.h index f0df050..1f3970b 100644 --- a/src/classlibnative/bcltype/stringnative.h +++ b/src/classlibnative/bcltype/stringnative.h @@ -61,9 +61,6 @@ public: static FCDECL2(FC_BOOL_RET, FCTryGetTrailByte, StringObject* thisRefUNSAFE, UINT8 *pbData); static FCDECL2(VOID, FCSetTrailByte, StringObject* thisRefUNSAFE, UINT8 bData); #endif // FEATURE_COMINTEROP - - static FCDECL1(INT32, Marvin32HashString, StringObject* thisRefUNSAFE); - }; // Revert to command line compilation flags diff --git a/src/classlibnative/nls/nlsinfo.cpp b/src/classlibnative/nls/nlsinfo.cpp index e12e41b..7699b4a 100644 --- a/src/classlibnative/nls/nlsinfo.cpp +++ b/src/classlibnative/nls/nlsinfo.cpp @@ -34,72 +34,6 @@ #include "nls.h" #include "nlsinfo.h" -// -// Constant Declarations. -// - -#define MAX_STRING_VALUE 512 - -//////////////////////////////////////////////////////////////////////////// -// -// InternalGetGlobalizedHashCode -// -//////////////////////////////////////////////////////////////////////////// -INT32 QCALLTYPE COMNlsInfo::InternalGetGlobalizedHashCode(INT_PTR handle, LPCWSTR localeName, LPCWSTR string, INT32 length, INT32 dwFlagsIn) -{ - CONTRACTL - { - QCALL_CHECK; - PRECONDITION(CheckPointer(localeName)); - PRECONDITION(CheckPointer(string, NULL_OK)); - } CONTRACTL_END; - - INT32 iReturnHash = 0; - BEGIN_QCALL; - - int byteCount = 0; - - // - // Make sure there is a string. - // - if (!string) { - COMPlusThrowArgumentNull(W("string"),W("ArgumentNull_String")); - } - - DWORD dwFlags = (LCMAP_SORTKEY | dwFlagsIn); - - // - // Caller has already verified that the string is not of zero length - // - // Assert if we might hit an AV in LCMapStringEx for the invariant culture. - _ASSERTE(length > 0 || (dwFlags & LCMAP_LINGUISTIC_CASING) == 0); - { - byteCount=::LCMapStringEx(handle != NULL ? NULL : localeName, dwFlags, string, length, NULL, 0, NULL, NULL, (LPARAM) handle); - } - - //A count of 0 indicates that we either had an error or had a zero length string originally. - if (byteCount==0) - { - COMPlusThrow(kArgumentException, W("Arg_MustBeString")); - } - - // We used to use a NewArrayHolder here, but it turns out that hurts our large # process - // scalability in ASP.Net hosting scenarios, using the quick bytes instead mostly stack - // allocates and ups throughput by 8% in 100 process case, 5% in 1000 process case - { - CQuickBytesSpecifySize qbBuffer; - BYTE* pByte = (BYTE*)qbBuffer.AllocThrows(byteCount); - - { - ::LCMapStringEx(handle != NULL ? NULL : localeName, dwFlags, string, length, (LPWSTR)pByte, byteCount, NULL,NULL, (LPARAM) handle); - } - - iReturnHash = COMNlsHashProvider::s_NlsHashProvider.HashSortKey(pByte, byteCount); - } - END_QCALL; - return(iReturnHash); -} - /** * This function returns a pointer to this table that we use in System.Globalization.EncodingTable. * No error checking of any sort is performed. Range checking is entirely the responsibility of the managed diff --git a/src/inc/marvin32.h b/src/inc/marvin32.h deleted file mode 100644 index 85b9e95..0000000 --- a/src/inc/marvin32.h +++ /dev/null @@ -1,85 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -#ifndef MARVIN32_INCLUDED -#define MARVIN32_INCLUDED - - -#include "common.h" -#include "windows.h" - -// -// Pointer-const typedefs: -// -// These definitions are missing from the standard Windows declarations. -// Should probably be moved to a central typedef file. -// -typedef const BYTE * PCBYTE; -typedef const USHORT * PCUSHORT; -typedef const ULONG * PCULONG; -typedef const ULONGLONG * PCULONGLONG; -typedef const VOID * PCVOID; - - - -// -// MARVIN32 -// - -#define SYMCRYPT_MARVIN32_RESULT_SIZE (8) -#define SYMCRYPT_MARVIN32_SEED_SIZE (8) -#define SYMCRYPT_MARVIN32_INPUT_BLOCK_SIZE (4) - -// These macros only support little-endian machines with unaligned access -#define LOAD_LSBFIRST16( p ) ( *(USHORT *)(p)) -#define LOAD_LSBFIRST32( p ) ( *(ULONG *)(p)) -#define STORE_LSBFIRST32( p, x ) ( *(ULONG *)(p) = (x) ) - -// Disable the warning about padding the struct on amd64 -#pragma warning(push) -#pragma warning(disable:4324) - -typedef struct _SYMCRYPT_MARVIN32_EXPANDED_SEED -{ - ULONG s[2]; -} SYMCRYPT_MARVIN32_EXPANDED_SEED, *PSYMCRYPT_MARVIN32_EXPANDED_SEED; - -typedef SYMCRYPT_MARVIN32_EXPANDED_SEED SYMCRYPT_MARVIN32_CHAINING_STATE, *PSYMCRYPT_MARVIN32_CHAINING_STATE; -typedef const SYMCRYPT_MARVIN32_EXPANDED_SEED * PCSYMCRYPT_MARVIN32_EXPANDED_SEED; - -typedef struct _SYMCRYPT_MARVIN32_STATE -{ - BYTE buffer[8]; // 4 bytes of data, 4 more bytes for final padding - SYMCRYPT_MARVIN32_CHAINING_STATE chain; // chaining state - PCSYMCRYPT_MARVIN32_EXPANDED_SEED pSeed; // - ULONG dataLength; // length of the data processed so far, mod 2^32 -} SYMCRYPT_MARVIN32_STATE, *PSYMCRYPT_MARVIN32_STATE; -typedef const SYMCRYPT_MARVIN32_STATE *PCSYMCRYPT_MARVIN32_STATE; -#pragma warning(pop) - -// -// Function declarations -// -HRESULT SymCryptMarvin32ExpandSeed( - __out PSYMCRYPT_MARVIN32_EXPANDED_SEED pExpandedSeed, - __in_ecount(cbSeed) PCBYTE pbSeed, - SIZE_T cbSeed); - -VOID SymCryptMarvin32Init(_Out_ PSYMCRYPT_MARVIN32_STATE pState, - _In_ PCSYMCRYPT_MARVIN32_EXPANDED_SEED pExpandedSeed); - -VOID SymCryptMarvin32Result( - _Inout_ PSYMCRYPT_MARVIN32_STATE pState, - _Out_ PBYTE pbResult); - -VOID SymCryptMarvin32Append(_Inout_ SYMCRYPT_MARVIN32_STATE * state, - _In_reads_bytes_(cbData) PCBYTE pbData, - SIZE_T cbData); - -VOID SymCryptMarvin32( - __in PCSYMCRYPT_MARVIN32_EXPANDED_SEED pExpandedSeed, - __in_ecount(cbData) PCBYTE pbData, - SIZE_T cbData, - __out_ecount(SYMCRYPT_MARVIN32_RESULT_SIZE) PBYTE pbResult); -#endif // MARVIN32_INCLUDED diff --git a/src/mscorlib/src/System/Globalization/CompareInfo.Unix.cs b/src/mscorlib/src/System/Globalization/CompareInfo.Unix.cs index e9fdf01..fe4c55c 100644 --- a/src/mscorlib/src/System/Globalization/CompareInfo.Unix.cs +++ b/src/mscorlib/src/System/Globalization/CompareInfo.Unix.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Buffers; using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -732,7 +733,10 @@ namespace System.Globalization fixed (byte* pSortKey = keyData) { - Interop.Globalization.GetSortKey(_sortHandle, source, source.Length, pSortKey, sortKeyLength, options); + if (Interop.Globalization.GetSortKey(_sortHandle, source, source.Length, pSortKey, sortKeyLength, options) != sortKeyLength) + { + throw new ArgumentException(SR.Arg_ExternalException); + } } } @@ -796,25 +800,29 @@ namespace System.Globalization int sortKeyLength = Interop.Globalization.GetSortKey(_sortHandle, source, source.Length, null, 0, options); - // As an optimization, for small sort keys we allocate the buffer on the stack. - if (sortKeyLength <= 256) + byte[] borrowedArr = null; + Span span = sortKeyLength <= 512 ? + stackalloc byte[512] : + (borrowedArr = ArrayPool.Shared.Rent(sortKeyLength)); + + fixed (byte* pSortKey = &MemoryMarshal.GetReference(span)) { - byte* pSortKey = stackalloc byte[sortKeyLength]; - Interop.Globalization.GetSortKey(_sortHandle, source, source.Length, pSortKey, sortKeyLength, options); - return InternalHashSortKey(pSortKey, sortKeyLength); + if (Interop.Globalization.GetSortKey(_sortHandle, source, source.Length, pSortKey, sortKeyLength, options) != sortKeyLength) + { + throw new ArgumentException(SR.Arg_ExternalException); + } } - byte[] sortKey = new byte[sortKeyLength]; + int hash = Marvin.ComputeHash32(span.Slice(0, sortKeyLength), Marvin.DefaultSeed); - fixed (byte* pSortKey = sortKey) + // Return the borrowed array if necessary. + if (borrowedArr != null) { - Interop.Globalization.GetSortKey(_sortHandle, source, source.Length, pSortKey, sortKeyLength, options); - return InternalHashSortKey(pSortKey, sortKeyLength); + ArrayPool.Shared.Return(borrowedArr); } - } - [DllImport(JitHelpers.QCall)] - private static extern unsafe int InternalHashSortKey(byte* sortKey, int sortKeyLength); + return hash; + } private static CompareOptions GetOrdinalCompareOptions(CompareOptions options) { diff --git a/src/mscorlib/src/System/Globalization/CompareInfo.Windows.cs b/src/mscorlib/src/System/Globalization/CompareInfo.Windows.cs index 1188c21..dafcdd1 100644 --- a/src/mscorlib/src/System/Globalization/CompareInfo.Windows.cs +++ b/src/mscorlib/src/System/Globalization/CompareInfo.Windows.cs @@ -2,10 +2,11 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Security; +using System.Buffers; using System.Diagnostics; -using System.Runtime.InteropServices; +using System.Security; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace System.Globalization { @@ -120,24 +121,47 @@ namespace System.Globalization return 0; } - int flags = GetNativeCompareFlags(options); - int tmpHash = 0; -#if CORECLR - tmpHash = InternalGetGlobalizedHashCode(_sortHandle, _sortName, source, source.Length, flags); -#else + uint flags = LCMAP_SORTKEY | (uint)GetNativeCompareFlags(options); + fixed (char* pSource = source) { - if (Interop.Kernel32.LCMapStringEx(_sortHandle != IntPtr.Zero ? null : _sortName, - LCMAP_HASH | (uint)flags, + int sortKeyLength = Interop.Kernel32.LCMapStringEx(_sortHandle != IntPtr.Zero ? null : _sortName, + flags, pSource, source.Length, - &tmpHash, sizeof(int), - null, null, _sortHandle) == 0) + null, 0, + null, null, _sortHandle); + if (sortKeyLength == 0) { - Environment.FailFast("LCMapStringEx failed!"); + throw new ArgumentException(SR.Arg_ExternalException); + } + + byte[] borrowedArr = null; + Span span = sortKeyLength <= 512 ? + stackalloc byte[512] : + (borrowedArr = ArrayPool.Shared.Rent(sortKeyLength)); + + fixed (byte* pSortKey = &MemoryMarshal.GetReference(span)) + { + if (Interop.Kernel32.LCMapStringEx(_sortHandle != IntPtr.Zero ? null : _sortName, + flags, + pSource, source.Length, + null, 0, + null, null, _sortHandle) != sortKeyLength) + { + throw new ArgumentException(SR.Arg_ExternalException); + } } + + int hash = Marvin.ComputeHash32(span.Slice(0, sortKeyLength), Marvin.DefaultSeed); + + // Return the borrowed array if necessary. + if (borrowedArr != null) + { + ArrayPool.Shared.Return(borrowedArr); + } + + return hash; } -#endif - return tmpHash; } private static unsafe int CompareStringOrdinalIgnoreCase(char* string1, int count1, char* string2, int count2) @@ -516,27 +540,32 @@ namespace System.Globalization } else { + uint flags = LCMAP_SORTKEY | (uint)GetNativeCompareFlags(options); + fixed (char *pSource = source) { - int result = Interop.Kernel32.LCMapStringEx(_sortHandle != IntPtr.Zero ? null : _sortName, - LCMAP_SORTKEY | (uint) GetNativeCompareFlags(options), + int sortKeyLength = Interop.Kernel32.LCMapStringEx(_sortHandle != IntPtr.Zero ? null : _sortName, + flags, pSource, source.Length, null, 0, null, null, _sortHandle); - if (result == 0) + if (sortKeyLength == 0) { - throw new ArgumentException(SR.Argument_InvalidFlag, "source"); + throw new ArgumentException(SR.Arg_ExternalException); } - keyData = new byte[result]; + keyData = new byte[sortKeyLength]; fixed (byte* pBytes = keyData) { - result = Interop.Kernel32.LCMapStringEx(_sortHandle != IntPtr.Zero ? null : _sortName, - LCMAP_SORTKEY | (uint) GetNativeCompareFlags(options), + if (Interop.Kernel32.LCMapStringEx(_sortHandle != IntPtr.Zero ? null : _sortName, + flags, pSource, source.Length, pBytes, keyData.Length, - null, null, _sortHandle); + null, null, _sortHandle) != sortKeyLength) + { + throw new ArgumentException(SR.Arg_ExternalException); + } } } } @@ -601,11 +630,5 @@ namespace System.Globalization nlsVersion.dwEffectiveId == 0 ? LCID : nlsVersion.dwEffectiveId, nlsVersion.guidCustomVersion); } - -#if CORECLR - // Get a locale sensitive sort hash code from native code -- COMNlsInfo::InternalGetGlobalizedHashCode - [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] - private static extern int InternalGetGlobalizedHashCode(IntPtr handle, string localeName, string source, int length, int dwFlags); -#endif } } diff --git a/src/mscorlib/src/System/String.Comparison.cs b/src/mscorlib/src/System/String.Comparison.cs index 6f12a65..b85af82 100644 --- a/src/mscorlib/src/System/String.Comparison.cs +++ b/src/mscorlib/src/System/String.Comparison.cs @@ -895,17 +895,14 @@ namespace System return !String.Equals(a, b); } - [MethodImplAttribute(MethodImplOptions.InternalCall)] - private static extern int InternalMarvin32HashString(string s); - // Gets a hash code for this string. If strings A and B are such that A.Equals(B), then // they will return the same hash code. public override int GetHashCode() { - return InternalMarvin32HashString(this); + return Marvin.ComputeHash32(ref Unsafe.As(ref _firstChar), _stringLength * 2, Marvin.DefaultSeed); } - // Gets a hash code for this string and this comparison. If strings A and B and comparition C are such + // Gets a hash code for this string and this comparison. If strings A and B and comparison C are such // that String.Equals(A, B, C), then they will return the same hash code with this comparison C. public int GetHashCode(StringComparison comparisonType) => StringComparer.FromComparison(comparisonType).GetHashCode(this); diff --git a/src/vm/CMakeLists.txt b/src/vm/CMakeLists.txt index b7b9d22..dec64f7 100644 --- a/src/vm/CMakeLists.txt +++ b/src/vm/CMakeLists.txt @@ -213,7 +213,6 @@ set(VM_SOURCES_WKS jithelpers.cpp managedmdimport.cpp marshalnative.cpp - marvin32.cpp mdaassistants.cpp methodtablebuilder.cpp mlinfo.cpp diff --git a/src/vm/appdomain.cpp b/src/vm/appdomain.cpp index 8bb747b..67b79ec 100644 --- a/src/vm/appdomain.cpp +++ b/src/vm/appdomain.cpp @@ -74,12 +74,6 @@ #include "clrprivtypecachewinrt.h" - -#pragma warning(push) -#pragma warning(disable:4324) -#include "marvin32.h" -#pragma warning(pop) - // this file handles string conversion errors for itself #undef MAKE_TRANSLATIONFAILED diff --git a/src/vm/comutilnative.cpp b/src/vm/comutilnative.cpp index 8fc326e..48efc11 100644 --- a/src/vm/comutilnative.cpp +++ b/src/vm/comutilnative.cpp @@ -2240,137 +2240,6 @@ FCIMPL1(INT32, ValueTypeHelper::GetHashCodeOfPtr, LPVOID ptr) } FCIMPLEND - -COMNlsHashProvider COMNlsHashProvider::s_NlsHashProvider; - - -COMNlsHashProvider::COMNlsHashProvider() -{ - LIMITED_METHOD_CONTRACT; - - pEntropy = NULL; - pDefaultSeed = NULL; -} - -INT32 COMNlsHashProvider::HashString(LPCWSTR szStr, SIZE_T strLen) -{ - CONTRACTL { - THROWS; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - - int marvinResult[SYMCRYPT_MARVIN32_RESULT_SIZE / sizeof(int)]; - - SymCryptMarvin32(GetDefaultSeed(), (PCBYTE) szStr, strLen * sizeof(WCHAR), (PBYTE) &marvinResult); - - return marvinResult[0] ^ marvinResult[1]; -} - - -INT32 COMNlsHashProvider::HashSortKey(PCBYTE pSrc, SIZE_T cbSrc) -{ - CONTRACTL { - THROWS; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - - int marvinResult[SYMCRYPT_MARVIN32_RESULT_SIZE / sizeof(int)]; - - // Sort Keys are terminated with a null byte which we didn't hash using the old algorithm, - // so we don't have it with Marvin32 either. - SymCryptMarvin32(GetDefaultSeed(), pSrc, cbSrc - 1, (PBYTE) &marvinResult); - - return marvinResult[0] ^ marvinResult[1]; -} - -void COMNlsHashProvider::InitializeDefaultSeed() -{ - CONTRACTL { - THROWS; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - - PCBYTE pEntropy = GetEntropy(); - AllocMemHolder pSeed(GetAppDomain()->GetLowFrequencyHeap()->AllocMem(S_SIZE_T(sizeof(SYMCRYPT_MARVIN32_EXPANDED_SEED)))); - SymCryptMarvin32ExpandSeed(pSeed, pEntropy, SYMCRYPT_MARVIN32_SEED_SIZE); - - if(InterlockedCompareExchangeT(&pDefaultSeed, (PCSYMCRYPT_MARVIN32_EXPANDED_SEED) pSeed, NULL) == NULL) - { - pSeed.SuppressRelease(); - } -} - -PCSYMCRYPT_MARVIN32_EXPANDED_SEED COMNlsHashProvider::GetDefaultSeed() -{ - CONTRACTL { - THROWS; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - - if(pDefaultSeed == NULL) - { - InitializeDefaultSeed(); - } - - return pDefaultSeed; -} - -PCBYTE COMNlsHashProvider::GetEntropy() -{ - CONTRACTL { - THROWS; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - - if(pEntropy == NULL) - { - AllocMemHolder pNewEntropy(GetAppDomain()->GetLowFrequencyHeap()->AllocMem(S_SIZE_T(sizeof(SYMCRYPT_MARVIN32_SEED_SIZE)))); - -#ifdef FEATURE_PAL - PAL_Random(pNewEntropy, SYMCRYPT_MARVIN32_SEED_SIZE); -#else - HCRYPTPROV hCryptProv; - WszCryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); - CryptGenRandom(hCryptProv, SYMCRYPT_MARVIN32_SEED_SIZE, pNewEntropy); - CryptReleaseContext(hCryptProv, 0); -#endif - - if(InterlockedCompareExchangeT(&pEntropy, (PBYTE) pNewEntropy, NULL) == NULL) - { - pNewEntropy.SuppressRelease(); - } - } - - return (PCBYTE) pEntropy; -} - -#ifdef FEATURE_COREFX_GLOBALIZATION -INT32 QCALLTYPE CoreFxGlobalization::HashSortKey(PCBYTE pSortKey, INT32 cbSortKey) -{ - QCALL_CONTRACT; - - INT32 retVal = 0; - - BEGIN_QCALL; - - retVal = COMNlsHashProvider::s_NlsHashProvider.HashSortKey(pSortKey, cbSortKey); - - END_QCALL; - - return retVal; -} -#endif //FEATURE_COREFX_GLOBALIZATION - static MethodTable * g_pStreamMT; static WORD g_slotBeginRead, g_slotEndRead; static WORD g_slotBeginWrite, g_slotEndWrite; diff --git a/src/vm/comutilnative.h b/src/vm/comutilnative.h index 617785d..3e63a04 100644 --- a/src/vm/comutilnative.h +++ b/src/vm/comutilnative.h @@ -26,15 +26,6 @@ #include "windows.h" #undef GetCurrentTime - -#pragma warning(push) -#pragma warning(disable:4324) -#if !defined(CROSS_COMPILE) && defined(_TARGET_ARM_) && !defined(PLATFORM_UNIX) -#include "arm_neon.h" -#endif -#include "marvin32.h" -#pragma warning(pop) - // // // EXCEPTION NATIVE @@ -206,34 +197,6 @@ public: static FCDECL1(INT32, GetHashCodeOfPtr, LPVOID ptr); }; - -typedef const BYTE * PCBYTE; - -class COMNlsHashProvider { -public: - COMNlsHashProvider(); - - INT32 HashString(LPCWSTR szStr, SIZE_T strLen); - INT32 HashSortKey(PCBYTE pSrc, SIZE_T cbSrc); - - static COMNlsHashProvider s_NlsHashProvider; - -private: - PBYTE pEntropy; - PCSYMCRYPT_MARVIN32_EXPANDED_SEED pDefaultSeed; - - PCBYTE GetEntropy(); - PCSYMCRYPT_MARVIN32_EXPANDED_SEED GetDefaultSeed(); - void InitializeDefaultSeed(); -}; - -#ifdef FEATURE_COREFX_GLOBALIZATION -class CoreFxGlobalization { -public: - static INT32 QCALLTYPE HashSortKey(PCBYTE pSortKey, INT32 cbSortKey); -}; -#endif // FEATURE_COREFX_GLOBALIZATION - class StreamNative { public: static FCDECL1(FC_BOOL_RET, HasOverriddenBeginEndRead, Object *stream); diff --git a/src/vm/ecalllist.h b/src/vm/ecalllist.h index 5877f31..f14a5a2 100644 --- a/src/vm/ecalllist.h +++ b/src/vm/ecalllist.h @@ -116,7 +116,6 @@ FCFuncStart(gStringFuncs) FCFuncElement("SetTrailByte", COMString::FCSetTrailByte) FCFuncElement("TryGetTrailByte", COMString::FCTryGetTrailByte) #endif // FEATURE_COMINTEROP - FCFuncElement("InternalMarvin32HashString", COMString::Marvin32HashString) FCFuncEnd() FCFuncStart(gStringBufferFuncs) @@ -795,10 +794,6 @@ FCFuncStart(gClrConfig) FCFuncEnd() #if !defined(FEATURE_COREFX_GLOBALIZATION) -FCFuncStart(gCompareInfoFuncs) - QCFuncElement("InternalGetGlobalizedHashCode", COMNlsInfo::InternalGetGlobalizedHashCode) -FCFuncEnd() - FCFuncStart(gEncodingTableFuncs) FCFuncElement("GetNumEncodingItems", COMNlsInfo::nativeGetNumEncodingItems) FCFuncElement("GetEncodingData", COMNlsInfo::nativeGetEncodingTableDataPointer) @@ -806,12 +801,6 @@ FCFuncStart(gEncodingTableFuncs) FCFuncEnd() #endif // !defined(FEATURE_COREFX_GLOBALIZATION) -#ifdef FEATURE_COREFX_GLOBALIZATION -FCFuncStart(gCompareInfoFuncs) - QCFuncElement("InternalHashSortKey", CoreFxGlobalization::HashSortKey) -FCFuncEnd() -#endif - FCFuncStart(gArrayFuncs) FCFuncElement("get_Rank", ArrayNative::GetRank) FCFuncElement("GetLowerBound", ArrayNative::GetLowerBound) @@ -1288,7 +1277,6 @@ FCClassElement("AssemblyLoadContext", "System.Runtime.Loader", gAssemblyLoadCont FCClassElement("AssemblyName", "System.Reflection", gAssemblyNameFuncs) FCClassElement("Buffer", "System", gBufferFuncs) FCClassElement("CLRConfig", "System", gClrConfig) -FCClassElement("CompareInfo", "System.Globalization", gCompareInfoFuncs) FCClassElement("CompatibilitySwitch", "System.Runtime.Versioning", gCompatibilitySwitchFuncs) FCClassElement("CriticalHandle", "System.Runtime.InteropServices", gCriticalHandleFuncs) FCClassElement("Currency", "System", gCurrencyFuncs) diff --git a/src/vm/marvin32.cpp b/src/vm/marvin32.cpp deleted file mode 100644 index 4fadee4..0000000 --- a/src/vm/marvin32.cpp +++ /dev/null @@ -1,266 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// -// This module contains the routines to implement the Marvin32 checksum function -// -// - -#include "common.h" -#include "marvin32.h" - -// -// See the symcrypt.h file for documentation on what the various functions do. -// - -// -// Round rotation amounts. This array is optimized away by the compiler -// as we inline all our rotations. -// -static const int rotate[4] = { - 20, 9, 27, 19, -}; - - -#define ROL32( x, n ) _rotl( (x), (n) ) -#define ROR32( x, n ) _rotr( (x), (n) ) - -#define BLOCK( a, b ) \ -{\ - b ^= a; a = ROL32( a, rotate[0] );\ - a += b; b = ROL32( b, rotate[1] );\ - b ^= a; a = ROL32( a, rotate[2] );\ - a += b; b = ROL32( b, rotate[3] );\ -} - - - -HRESULT -SymCryptMarvin32ExpandSeed( - __out PSYMCRYPT_MARVIN32_EXPANDED_SEED pExpandedSeed, - __in_ecount(cbSeed) PCBYTE pbSeed, - SIZE_T cbSeed ) -{ - HRESULT retVal = S_OK; - - if( cbSeed != SYMCRYPT_MARVIN32_SEED_SIZE ) - { - retVal =E_INVALIDARG; - goto cleanup; - } - pExpandedSeed->s[0] = LOAD_LSBFIRST32( pbSeed ); - pExpandedSeed->s[1] = LOAD_LSBFIRST32( pbSeed + 4 ); - -cleanup: - return retVal; -} - - -VOID -SymCryptMarvin32Init( _Out_ PSYMCRYPT_MARVIN32_STATE pState, - _In_ PCSYMCRYPT_MARVIN32_EXPANDED_SEED pExpandedSeed) -{ - pState->chain = *pExpandedSeed; - pState->dataLength = 0; - pState->pSeed = pExpandedSeed; - - *(ULONG *) &pState->buffer[4] = 0; // wipe the last 4 bytes of the buffer. -} - -VOID -SymCryptMarvin32AppendBlocks( - _Inout_ PSYMCRYPT_MARVIN32_CHAINING_STATE pChain, - _In_reads_( cbData ) PCBYTE pbData, - SIZE_T cbData ) -{ - ULONG s0 = pChain->s[0]; - ULONG s1 = pChain->s[1]; - - SIZE_T bytesInFirstBlock = cbData & 0xc; // 0, 4, 8, or 12 - - pbData += bytesInFirstBlock; - cbData -= bytesInFirstBlock; - - switch( bytesInFirstBlock ) - { - case 0: // This handles the cbData == 0 case too - while( cbData > 0 ) - { - pbData += 16; - cbData -= 16; - - s0 += LOAD_LSBFIRST32( pbData - 16 ); - BLOCK( s0, s1 ); - case 12: - s0 += LOAD_LSBFIRST32( pbData - 12 ); - BLOCK( s0, s1 ); - case 8: - s0 += LOAD_LSBFIRST32( pbData - 8 ); - BLOCK( s0, s1 ); - case 4: - s0 += LOAD_LSBFIRST32( pbData - 4 ); - BLOCK( s0, s1 ); - } - } - - pChain->s[0] = s0; - pChain->s[1] = s1; -} - -VOID -SymCryptMarvin32Append(_Inout_ SYMCRYPT_MARVIN32_STATE * state, -_In_reads_bytes_(cbData) PCBYTE pbData, -SIZE_T cbData) -{ - ULONG bytesInBuffer = state->dataLength; - - state->dataLength += (ULONG)cbData; // We only keep track of the last 2 bits... - - // - // Truncate bytesInBuffer so that we never have an integer overflow. - // - bytesInBuffer &= SYMCRYPT_MARVIN32_INPUT_BLOCK_SIZE - 1; - - // - // If previous data in buffer, buffer new input and transform if possible. - // - if (bytesInBuffer > 0) - { - SIZE_T freeInBuffer = SYMCRYPT_MARVIN32_INPUT_BLOCK_SIZE - bytesInBuffer; - if (cbData < freeInBuffer) - { - // - // All the data will fit in the buffer. - // We don't do anything here. - // As cbData < INPUT_BLOCK_SIZE the bulk data processing is skipped, - // and the data will be copied to the buffer at the end - // of this code. - } - else { - // - // Enough data to fill the whole buffer & process it - // - memcpy(&state->buffer[bytesInBuffer], pbData, freeInBuffer); - pbData += freeInBuffer; - cbData -= freeInBuffer; - SymCryptMarvin32AppendBlocks(&state->chain, state->buffer, SYMCRYPT_MARVIN32_INPUT_BLOCK_SIZE); - - // - // Set bytesInBuffer to zero to ensure that the trailing data in the - // buffer will be copied to the right location of the buffer below. - // - bytesInBuffer = 0; - } - } - - // - // Internal buffer is empty; process all remaining whole blocks in the input - // - if (cbData >= SYMCRYPT_MARVIN32_INPUT_BLOCK_SIZE) - { - SIZE_T cbDataRoundedDown = cbData & ~(SIZE_T)(SYMCRYPT_MARVIN32_INPUT_BLOCK_SIZE - 1); - SymCryptMarvin32AppendBlocks(&state->chain, pbData, cbDataRoundedDown); - pbData += cbDataRoundedDown; - cbData -= cbDataRoundedDown; - } - - // - // buffer remaining input if necessary. - // - if (cbData > 0) - { - memcpy(&state->buffer[bytesInBuffer], pbData, cbData); - } - -} - -VOID -SymCryptMarvin32Result( - _Inout_ PSYMCRYPT_MARVIN32_STATE pState, - _Out_writes_( SYMCRYPT_MARVIN32_RESULT_SIZE ) PBYTE pbResult ) -{ - SIZE_T bytesInBuffer = ( pState->dataLength) & 0x3; - - // - // Wipe four bytes in the buffer. - // Doing this first ensures that this write is aligned when the input was of - // length 0 mod 4. - // The buffer is 8 bytes long, so we never overwrite anything else. - // - *(ULONG *) &pState->buffer[bytesInBuffer] = 0; - - // - // The buffer is never completely full, so we can always put the first - // padding byte in. - // - pState->buffer[bytesInBuffer++] = 0x80; - - // - // Process the final block - // - SymCryptMarvin32AppendBlocks( &pState->chain, pState->buffer, 8 ); - - STORE_LSBFIRST32( pbResult , pState->chain.s[0] ); - STORE_LSBFIRST32( pbResult + 4, pState->chain.s[1] ); - - // - // Wipe only those things that we need to wipe. - // - - *(ULONG *) &pState->buffer[0] = 0; - pState->dataLength = 0; - - pState->chain = *pState->pSeed; -} - - -VOID -SymCryptMarvin32( - __in PCSYMCRYPT_MARVIN32_EXPANDED_SEED pExpandedSeed, - __in_ecount(cbData) PCBYTE pbData, - SIZE_T cbData, - __out_ecount(SYMCRYPT_MARVIN32_RESULT_SIZE) PBYTE pbResult) -// -// To reduce the per-computation overhead, we have a dedicated code here instead of the whole Init/Append/Result stuff. -// -{ - ULONG tmp; - - ULONG s0 = pExpandedSeed->s[0]; - ULONG s1 = pExpandedSeed->s[1]; - - while( cbData > 7 ) - { - s0 += LOAD_LSBFIRST32( pbData ); - BLOCK( s0, s1 ); - s0 += LOAD_LSBFIRST32( pbData + 4 ); - BLOCK( s0, s1 ); - pbData += 8; - cbData -= 8; - } - - switch( cbData ) - { - default: - case 4: s0 += LOAD_LSBFIRST32( pbData ); BLOCK( s0, s1 ); pbData += 4; - case 0: tmp = 0x80; break; - - case 5: s0 += LOAD_LSBFIRST32( pbData ); BLOCK( s0, s1 ); pbData += 4; - case 1: tmp = 0x8000 | pbData[0]; break; - - case 6: s0 += LOAD_LSBFIRST32( pbData ); BLOCK( s0, s1 ); pbData += 4; - case 2: tmp = 0x800000 | LOAD_LSBFIRST16( pbData ); break; - - case 7: s0 += LOAD_LSBFIRST32( pbData ); BLOCK( s0, s1 ); pbData += 4; - case 3: tmp = LOAD_LSBFIRST16( pbData ) | (pbData[2] << 16) | 0x80000000; break; - } - s0 += tmp; - - - BLOCK( s0, s1 ); - BLOCK( s0, s1 ); - - STORE_LSBFIRST32( pbResult , s0 ); - STORE_LSBFIRST32( pbResult + 4, s1 ); -}