Switch over to managed Marvin implementation for string hashing (#17029)
authorJan Kotas <jkotas@microsoft.com>
Mon, 19 Mar 2018 19:51:33 +0000 (12:51 -0700)
committerGitHub <noreply@github.com>
Mon, 19 Mar 2018 19:51:33 +0000 (12:51 -0700)
13 files changed:
src/classlibnative/bcltype/stringnative.cpp
src/classlibnative/bcltype/stringnative.h
src/classlibnative/nls/nlsinfo.cpp
src/inc/marvin32.h [deleted file]
src/mscorlib/src/System/Globalization/CompareInfo.Unix.cs
src/mscorlib/src/System/Globalization/CompareInfo.Windows.cs
src/mscorlib/src/System/String.Comparison.cs
src/vm/CMakeLists.txt
src/vm/appdomain.cpp
src/vm/comutilnative.cpp
src/vm/comutilnative.h
src/vm/ecalllist.h
src/vm/marvin32.cpp [deleted file]

index 63eed73..8b040dc 100644 (file)
 #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.
index f0df050..1f3970b 100644 (file)
@@ -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
index e12e41b..7699b4a 100644 (file)
 #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<MAX_STRING_VALUE * sizeof(WCHAR)> 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 (file)
index 85b9e95..0000000
+++ /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
index e9fdf01..fe4c55c 100644 (file)
@@ -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<byte> span = sortKeyLength <= 512 ?
+                stackalloc byte[512] :
+                (borrowedArr = ArrayPool<byte>.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<byte>.Shared.Return(borrowedArr);
             }
-        }
 
-        [DllImport(JitHelpers.QCall)]
-        private static extern unsafe int InternalHashSortKey(byte* sortKey, int sortKeyLength);
+            return hash;
+        }
 
         private static CompareOptions GetOrdinalCompareOptions(CompareOptions options)
         {
index 1188c21..dafcdd1 100644 (file)
@@ -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<byte> span = sortKeyLength <= 512 ?
+                    stackalloc byte[512] :
+                    (borrowedArr = ArrayPool<byte>.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<byte>.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
     }
 }
index 6f12a65..b85af82 100644 (file)
@@ -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<char, byte>(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);
 
index b7b9d22..dec64f7 100644 (file)
@@ -213,7 +213,6 @@ set(VM_SOURCES_WKS
     jithelpers.cpp
     managedmdimport.cpp
     marshalnative.cpp
-    marvin32.cpp
     mdaassistants.cpp
     methodtablebuilder.cpp
     mlinfo.cpp
index 8bb747b..67b79ec 100644 (file)
 
 #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
 
index 8fc326e..48efc11 100644 (file)
@@ -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<SYMCRYPT_MARVIN32_EXPANDED_SEED> 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<BYTE> 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;
index 617785d..3e63a04 100644 (file)
 #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);
index 5877f31..f14a5a2 100644 (file)
@@ -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 (file)
index 4fadee4..0000000
+++ /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 );
-}