Use non-copyleft RNG implementation (#51448)
authorKevin Cathcart <kevincathcart@gmail.com>
Sat, 1 May 2021 20:19:55 +0000 (16:19 -0400)
committerGitHub <noreply@github.com>
Sat, 1 May 2021 20:19:55 +0000 (13:19 -0700)
Using xorshiro128** because it is already used in the project, and licensed under CC0.

THIRD-PARTY-NOTICES.TXT
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/AttributePresenceFilterNode.cs
src/coreclr/zap/zapreadytorun.cpp
src/installer/pkg/THIRD-PARTY-NOTICES.TXT

index b5571e6..54836c8 100644 (file)
@@ -669,22 +669,16 @@ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-License notice for Xorshift RNGs
+License notice for xoshiro RNGs
 --------------------------------
 
-George Marsaglia
-2003-07-04
-Journal of Statistical Software
-License: http://creativecommons.org/licenses/by/3.0/
+Written in 2018 by David Blackman and Sebastiano Vigna (vigna@acm.org)
 
-https://www.jstatsoft.org/article/view/v008i14
-https://www.jstatsoft.org/index.php/jss/article/view/v008i14/xorshift.pdf
+To the extent possible under law, the author has dedicated all copyright
+and related and neighboring rights to this software to the public domain
+worldwide. This software is distributed without any warranty.
 
-License notice for Xorshift (Wikipedia)
----------------------------------------
-
-https://en.wikipedia.org/wiki/Xorshift
-License: https://en.wikipedia.org/wiki/Wikipedia:Text_of_Creative_Commons_Attribution-ShareAlike_3.0_Unported_License
+See <http://creativecommons.org/publicdomain/zero/1.0/>.
 
 License for fastmod (https://github.com/lemire/fastmod)
 --------------------------------------
index ef1fe0e..80cb250 100644 (file)
@@ -5,6 +5,7 @@ using System;
 using System.Collections.Generic;
 using System.Collections.Immutable;
 using System.Diagnostics;
+using System.Numerics;
 using System.Reflection.Metadata;
 using System.Reflection.Metadata.Ecma335;
 
@@ -280,16 +281,20 @@ namespace ILCompiler.DependencyAnalysis.ReadyToRun
             typeName = _module.MetadataReader.GetString(typeNameHandle);
         }
 
-        // Algorithm "xor128" from p. 5 of Marsaglia, "Xorshift RNGs"
-        private uint XorShift128(uint[] state)
+        internal uint Xoshiro128StarStar(uint[] s)
         {
-            uint s, t = state[3];
-            state[3] = state[2];
-            state[2] = state[1];
-            state[1] = s = state[0];
-            t ^= t << 11;
-            t ^= t >> 8;
-            return state[0] = t ^ s ^ (s >> 19);
+            uint result = BitOperations.RotateLeft(s[1] * 5, 7) * 9;
+            uint t = s[1] << 9;
+
+            s[2] ^= s[0];
+            s[3] ^= s[1];
+            s[1] ^= s[2];
+            s[0] ^= s[3];
+
+            s[2] ^= t;
+            s[3] = BitOperations.RotateLeft(s[3], 11);
+
+            return result;
         }
 
         public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
@@ -341,7 +346,7 @@ namespace ILCompiler.DependencyAnalysis.ReadyToRun
                     uint fingerprintHash = (uint)fingerprint;
                     uint bucketBIndex = (bucketAIndex ^ (fingerprintHash % bucketCount));
                     Debug.Assert(bucketAIndex == (bucketBIndex ^ (fingerprintHash % bucketCount)));
-                    if ((XorShift128(state) & 1) != 0) // Randomly choose which bucket to attempt to fill first
+                    if ((Xoshiro128StarStar(state) & 1) != 0) // Randomly choose which bucket to attempt to fill first
                     {
                         uint temp = bucketAIndex;
                         bucketAIndex = bucketBIndex;
@@ -406,7 +411,7 @@ namespace ILCompiler.DependencyAnalysis.ReadyToRun
                     for (int n = 0; !success && n < MaxNumKicks; n++)
                     {
                         // Randomly swap an entry in bucket bucketAIndex with fingerprint
-                        uint entryIndexInBucket = XorShift128(state) & 0x7;
+                        uint entryIndexInBucket = Xoshiro128StarStar(state) & 0x7;
                         ushort temp = fingerprint;
                         fingerprint = pTable[(bucketAIndex * 8) + entryIndexInBucket];
                         pTable[(bucketAIndex * 8) + entryIndexInBucket] = temp;
index d5bb25a..6b7b09c 100644 (file)
@@ -563,16 +563,23 @@ HRESULT EnumerateAllCustomAttributes(IMDInternalImport *pMDImport, Tlambda lambd
     return hr;
 }
 
-uint32_t xorshift128(uint32_t state[4])
-{
-    /* Algorithm "xor128" from p. 5 of Marsaglia, "Xorshift RNGs" */
-    uint32_t s, t = state[3];
-    state[3] = state[2];
-    state[2] = state[1];
-    state[1] = s = state[0];
-    t ^= t << 11;
-    t ^= t >> 8;
-    return state[0] = t ^ s ^ (s >> 19);
+static inline uint32_t RotateLeft(const uint32_t x, int k) {
+       return (x << k) | (x >> (32 - k));
+}
+
+uint32_t Xoshiro128StarStar(uint32_t s[]) {
+    const uint32_t result = RotateLeft(s[1] * 5, 7) * 9;
+    const uint32_t t = s[1] << 9;
+
+    s[2] ^= s[0];
+    s[3] ^= s[1];
+    s[1] ^= s[2];
+    s[0] ^= s[3];
+
+    s[2] ^= t;
+    s[3] = RotateLeft(s[3], 11);
+
+    return result;
 }
 
 HRESULT ZapImage::ComputeAttributePresenceTable(IMDInternalImport * pMDImport, SArray<UINT16> *table)
@@ -639,7 +646,7 @@ HRESULT ZapImage::ComputeAttributePresenceTable(IMDInternalImport * pMDImport, S
 
             _ASSERTE(bucketAIndex == (bucketBIndex ^ (NativeFormat::NativeCuckooFilter::ComputeFingerprintHash(fingerprint) % bucketCount)));
 
-            if (xorshift128(state) & 1) // Randomly choose which bucket to attempt to fill first
+            if (Xoshiro128StarStar(state) & 1) // Randomly choose which bucket to attempt to fill first
             {
                 UINT temp = bucketAIndex;
                 bucketAIndex = bucketBIndex;
@@ -701,7 +708,7 @@ HRESULT ZapImage::ComputeAttributePresenceTable(IMDInternalImport * pMDImport, S
             for (int n = 0; n < MaxNumKicks; n++)
             {
                 // Randomly swap an entry in bucket bucketAIndex with fingerprint
-                UINT entryIndexInBucket = xorshift128(state) & 0x7;
+                UINT entryIndexInBucket = Xoshiro128StarStar(state) & 0x7;
                 UINT16 temp = fingerprint;
                 fingerprint = (*table)[(bucketAIndex * 8) + entryIndexInBucket];
                 (*table)[(bucketAIndex * 8) + entryIndexInBucket] = temp;
index c58f092..445eab6 100644 (file)
@@ -668,22 +668,16 @@ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-License notice for Xorshift RNGs
+License notice for xoshiro RNGs
 --------------------------------
 
-George Marsaglia
-2003-07-04
-Journal of Statistical Software
-License: http://creativecommons.org/licenses/by/3.0/
+Written in 2018 by David Blackman and Sebastiano Vigna (vigna@acm.org)
 
-https://www.jstatsoft.org/article/view/v008i14
-https://www.jstatsoft.org/index.php/jss/article/view/v008i14/xorshift.pdf
+To the extent possible under law, the author has dedicated all copyright
+and related and neighboring rights to this software to the public domain
+worldwide. This software is distributed without any warranty.
 
-License notice for Xorshift (Wikipedia)
----------------------------------------
-
-https://en.wikipedia.org/wiki/Xorshift
-License: https://en.wikipedia.org/wiki/Wikipedia:Text_of_Creative_Commons_Attribution-ShareAlike_3.0_Unported_License
+See <http://creativecommons.org/publicdomain/zero/1.0/>.
 
 License for fastmod (https://github.com/lemire/fastmod)
 --------------------------------------