diff --git a/3rdparty/tinymt/LICENSE.txt b/3rdparty/tinymt/LICENSE.txt deleted file mode 100644 index 2ba0bf4ab3..0000000000 --- a/3rdparty/tinymt/LICENSE.txt +++ /dev/null @@ -1,30 +0,0 @@ -Copyright (c) 2011, 2013 Mutsuo Saito, Makoto Matsumoto, -Hiroshima University and The University of Tokyo. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - * Neither the name of the Hiroshima University nor the names of - its contributors may be used to endorse or promote products - derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 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. diff --git a/3rdparty/tinymt/README.txt b/3rdparty/tinymt/README.txt deleted file mode 100644 index 58d557f710..0000000000 --- a/3rdparty/tinymt/README.txt +++ /dev/null @@ -1,11 +0,0 @@ -64-bit version of TinyMT[1] as used by MoarVM[2] - -Original code published by - - Mutsuo Saito, (saito@math.sci.hiroshima-u.ac.jp) Hiroshima University - Makoto Matsumoto, The University of Tokyo - -under the 3-clause BSD license. - -[1] http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/TINYMT/ -[2] https://github.com/MoarVM/MoarVM/ diff --git a/3rdparty/tinymt/tinymt64.c b/3rdparty/tinymt/tinymt64.c deleted file mode 100644 index 8cefd9e979..0000000000 --- a/3rdparty/tinymt/tinymt64.c +++ /dev/null @@ -1,133 +0,0 @@ -/** - * @file tinymt64.h - * - * @brief Tiny Mersenne Twister only 127 bit internal state - * - * @author Mutsuo Saito (Hiroshima University) - * @author Makoto Matsumoto (The University of Tokyo) - * - * Copyright (C) 2011 Mutsuo Saito, Makoto Matsumoto, - * Hiroshima University and The University of Tokyo. - * All rights reserved. - * - * The 3-clause BSD License is applied to this software, see - * LICENSE.txt - * - * @file tinymt64.c - * - * @brief 64-bit Tiny Mersenne Twister only 127 bit internal state - * - * @author Mutsuo Saito (Hiroshima University) - * @author Makoto Matsumoto (The University of Tokyo) - * - * Copyright (C) 2011 Mutsuo Saito, Makoto Matsumoto, - * Hiroshima University and The University of Tokyo. - * All rights reserved. - * - * The 3-clause BSD License is applied to this software, see - * LICENSE.txt - */ - - -#include -#include "tinymt64.h" - -#define TINYMT64_SH0 12 -#define TINYMT64_SH1 11 -#define TINYMT64_SH8 8 -#define TINYMT64_MASK UINT64_C(0x7fffffffffffffff) -#define TINYMT64_MUL (1.0 / 9007199254740992.0) - -/* - * tinymt64 default parameters - */ -#ifndef TINYMT64_MAT1 -# define TINYMT64_MAT1 0x7a840f50 -#endif -#ifndef TINYMT64_MAT2 -# define TINYMT64_MAT2 0xf3d8fcf6 -#endif -#ifndef TINYMT64_TMAT -# define TINYMT64_TMAT 0x9746beffffbffffe -#endif - -/* - * Initialization loop - */ -#define MIN_LOOP 8 - -static const uint32_t mat1 = TINYMT64_MAT1; -static const uint32_t mat2 = TINYMT64_MAT2; -static const uint64_t tmat = TINYMT64_TMAT; - -/** - * This function changes internal state of tinymt64. - * Users should not call this function directly. - * @param random tinymt internal status - */ -static void tinymt64_next_state(uint64_t * random) { - uint64_t x; - - random[0] &= TINYMT64_MASK; - x = random[0] ^ random[1]; - x ^= x << TINYMT64_SH0; - x ^= x >> 32; - x ^= x << 32; - x ^= x << TINYMT64_SH1; - random[0] = random[1]; - random[1] = x; - random[0] ^= -((int64_t)(x & 1)) & mat1; - random[1] ^= -((int64_t)(x & 1)) & (((uint64_t)mat2) << 32); -} - -/** - * This function outputs 64-bit unsigned integer from internal state. - * Users should not call this function directly. - * @param random tinymt internal status - * @return 64-bit unsigned pseudorandom number - */ -static uint64_t uint64_temper(uint64_t * random) { - uint64_t x; - x = random[0] + random[1]; - x ^= random[0] >> TINYMT64_SH8; - x ^= -((int64_t)(x & 1)) & tmat; - return x; -} - -/** - * This function outputs 64-bit unsigned integer from internal state. - * @param random tinymt internal status - * @return 64-bit unsigned integer r (0 <= r < 2^64) - */ -uint64_t tinymt64_generate_uint64(uint64_t * random) { - tinymt64_next_state(random); - return uint64_temper(random); -} - -/** - * This function outputs floating point number from internal state. - * This function is implemented using multiplying by 1 / 2^64. - * @param random tinymt internal status - * @return floating point number r (0.0 <= r < 1.0) - */ -double tinymt64_generate_double(uint64_t * random) { - tinymt64_next_state(random); - return (uint64_temper(random) >> 11) * TINYMT64_MUL; -} - -/** - * This function initializes the internal state array with a 64-bit - * unsigned integer seed. - * @param random tinymt state vector. - * @param seed a 64-bit unsigned integer used as a seed. - */ -void tinymt64_init(uint64_t * random, uint64_t seed) { - int i; - random[0] = seed ^ ((uint64_t)mat1 << 32); - random[1] = mat2 ^ tmat; - for (i = 1; i < MIN_LOOP; i++) { - random[i & 1] ^= i + UINT64_C(6364136223846793005) - * (random[(i - 1) & 1] - ^ (random[(i - 1) & 1] >> 62)); - } -} diff --git a/3rdparty/tinymt/tinymt64.h b/3rdparty/tinymt/tinymt64.h deleted file mode 100644 index 3aa5422ceb..0000000000 --- a/3rdparty/tinymt/tinymt64.h +++ /dev/null @@ -1,3 +0,0 @@ -void tinymt64_init(uint64_t *state, uint64_t seed); -uint64_t tinymt64_generate_uint64(uint64_t *state); -double tinymt64_generate_double(uint64_t *state); diff --git a/LICENSE b/LICENSE index 1fbcd2ad97..c7e4cfbdb4 100644 --- a/LICENSE +++ b/LICENSE @@ -28,6 +28,5 @@ Unofficial summary of the intended application of the Artistic License 2.0: - libuv MIT,BSD,ISC - msinttypes MIT - sha1 Public Domain -- tinymt MIT - freebsd MIT - mimalloc MIT diff --git a/build/Makefile.in b/build/Makefile.in index 4d327b6ac9..510294e4dd 100644 --- a/build/Makefile.in +++ b/build/Makefile.in @@ -41,7 +41,6 @@ CFLAGS = @cflags@ @ccdef@MVM_TRACING=$(TRACING) @ccdef@MVM_CGOTO=$(CGOTO) CINCLUDES = @moar_cincludes@ \ @ccinc@@shaincludedir@ \ @mimalloc_include@ \ - @ccincsystem@3rdparty/tinymt \ @ccincsystem@3rdparty/ryu \ @ccincsystem@3rdparty/dynasm \ @ccincsystem@3rdparty/cmp \ @@ -302,6 +301,7 @@ HEADERS = src/moar.h \ src/core/intcache.h \ src/core/fixedsizealloc.h \ src/core/regionalloc.h \ + src/core/jfs64.h \ src/debug/debugserver.h \ src/io/io.h \ src/io/eventloop.h \ @@ -721,10 +721,6 @@ tools/repr_size_table@exe@: tools/repr_size_table@obj@ @moarlib@ $(DLL_LIBS) $(MSG) linking $@ $(CMD)@sharule@ $(NOOUT) -@mtlib@: @mtobjects@ - $(MSG) linking $@ - $(CMD)@mtrule@ $(NOOUT) - @cmplib@: @cmpobjects@ $(MSG) linking $@ $(CMD)@cmprule@ $(NOOUT) @@ -754,7 +750,6 @@ realclean: clean -$(RM) @laolib@ $(NOOUT) $(NOERR) -$(CMD)@tomclean@ $(NOOUT) $(NOERR) -$(CMD)@shaclean@ $(NOOUT) $(NOERR) - -$(CMD)@mtclean@ $(NOOUT) $(NOERR) -$(CMD)@dcclean@ $(NOOUT) $(NOERR) -$(CMD)@cmpclean@ $(NOOUT) $(NOERR) -$(RM) $(MINILUA) $(NOOUT) $(NOERR) diff --git a/build/setup.pm b/build/setup.pm index 6ba96534ff..9a43cd2c3e 100644 --- a/build/setup.pm +++ b/build/setup.pm @@ -26,12 +26,6 @@ my %TP_TOM = ( src => [ '3rdparty/libtommath' ], ); -my %TP_MT = ( - name => 'tinymt', - path => '3rdparty/tinymt', - src => [ '3rdparty/tinymt' ], -); - my %TP_DC = ( name => 'dyncall_s', path => '3rdparty/dyncall/dyncall', @@ -77,7 +71,6 @@ our %THIRDPARTY = ( lao => { %TP_LAO }, tom => { %TP_TOM }, sha => { %TP_SHA }, - mt => { %TP_MT }, dc => { %TP_DC }, dcb => { %TP_DCB }, dl => { %TP_DL }, diff --git a/src/core/jfs64.h b/src/core/jfs64.h new file mode 100644 index 0000000000..81f226baf7 --- /dev/null +++ b/src/core/jfs64.h @@ -0,0 +1,34 @@ +/* This is the "A small noncryptographic PRNG" by Bob Jenkins, later given the name JFS64. + http://burtleburtle.net/bob/rand/smallprng.html + "I wrote this PRNG. I place it in the public domain." + It's small, and good enough: + https://www.pcg-random.org/posts/bob-jenkins-small-prng-passes-practrand.html +*/ +/* Adapted from https://github.com/nwc10/perl5/commit/16ff20f28225d92d24c7b0d7a7196c035640b27f */ + +/* Find best way to ROTL64 */ +/* Copied from https://github.com/Perl/perl5/blob/d6b487cec2690eccc59f18bd6c3803ea06b3c9d6/hv_macro.h */ +#if defined(_MSC_VER) + #include /* Microsoft put _rotl declaration in here */ + #define ROTL64(x,r) _rotl64(x,r) +#else + /* gcc recognises this code and generates a rotate instruction for CPUs with one */ + #define ROTL64(x,r) ( ( (MVMuint64)(x) << (r) ) | ( (MVMuint64)(x) >> ( 64 - (r) ) ) ) +#endif + +MVM_STATIC_INLINE MVMuint64 jfs64_generate_uint64(MVMuint64 *rand_state) { + MVMuint64 e = rand_state[0] - ROTL64(rand_state[1], 7); + rand_state[0] = rand_state[1] ^ ROTL64(rand_state[2], 13); + rand_state[1] = rand_state[2] + ROTL64(rand_state[3], 37); + rand_state[2] = rand_state[3] + e; + rand_state[3] = e + rand_state[0]; + return rand_state[3]; +} + +MVM_STATIC_INLINE void jfs64_init(MVMuint64 *rand_state, MVMuint64 seed) { + rand_state[0] = 0xf1ea5eed; + rand_state[1] = rand_state[2] = rand_state[3] = seed; + for (int i = 0; i < 20; ++i) { + (void)jfs64_generate_uint64(rand_state); + } +} diff --git a/src/core/threadcontext.h b/src/core/threadcontext.h index 2c183b6e28..9307102546 100644 --- a/src/core/threadcontext.h +++ b/src/core/threadcontext.h @@ -278,7 +278,7 @@ struct MVMThreadContext { MVMStrHashTable native_callback_cache; /* Random number generator state. */ - MVMuint64 rand_state[2]; + MVMuint64 rand_state[4]; /* Temporary big integers for when we need to upgrade operands in order * to perform an operation. */ diff --git a/src/io/procops.c b/src/io/procops.c index b3e803a856..5180c1465b 100644 --- a/src/io/procops.c +++ b/src/io/procops.c @@ -1,7 +1,7 @@ #include "moar.h" #include "platform/time.h" #include "platform/fork.h" -#include "tinymt64.h" +#include "core/jfs64.h" #include "bithacks.h" /* concatenating with "" ensures that only literal strings are accepted as argument. */ @@ -1094,22 +1094,21 @@ MVMint64 MVM_proc_getppid(MVMThreadContext *tc) { /* generates a random int64 */ MVMint64 MVM_proc_rand_i(MVMThreadContext *tc) { - MVMuint64 result = tinymt64_generate_uint64(tc->rand_state); - return *(MVMint64 *)&result; + return (MVMint64)jfs64_generate_uint64(tc->rand_state); } /* generates a number between 0 and 1 */ MVMnum64 MVM_proc_rand_n(MVMThreadContext *tc) { - return tinymt64_generate_double(tc->rand_state); + return ((jfs64_generate_uint64(tc->rand_state) >> 11) / (double)(1L << 53)); } MVMnum64 MVM_proc_randscale_n(MVMThreadContext *tc, MVMnum64 scale) { - return tinymt64_generate_double(tc->rand_state) * scale; + return ((jfs64_generate_uint64(tc->rand_state) >> 11) / (double)(1L << 53)) * scale; } /* seed random number generator */ void MVM_proc_seed(MVMThreadContext *tc, MVMint64 seed) { - tinymt64_init(tc->rand_state, (MVMuint64)seed); + jfs64_init(tc->rand_state, (MVMuint64)seed); } /* gets the system time since the epoch in nanoseconds */ diff --git a/src/math/bigintops.c b/src/math/bigintops.c index e12caf8034..9bc3abcaa0 100644 --- a/src/math/bigintops.c +++ b/src/math/bigintops.c @@ -1,6 +1,6 @@ #include "moar.h" #include "platform/random.h" -#include "tinymt64.h" +#include "core/jfs64.h" #define MANTISSA_BITS_IN_DOUBLE 53 #define EXPONENT_SHIFT 52 @@ -1397,7 +1397,7 @@ MVMnum64 MVM_bigint_div_num(MVMThreadContext *tc, MVMObject *a, MVMObject *b) { } /* The below function is copied from libtommath and modified to use - * tinymt64 as the source of randomness. As of LTM v1.1.0, mp_rand() + * jfs64 as the source of randomness. As of LTM v1.1.0, mp_rand() * uses sources of randomness that can't be seeded. Since we want to * be able to do that, for now just copy and modify. */ @@ -1421,12 +1421,12 @@ mp_err MVM_mp_rand(MVMThreadContext *tc, mp_int *a, int digits) /* TODO: We ensure that the highest digit is nonzero. Should this be removed? */ while ((a->dp[digits - 1] & MP_MASK) == 0u) { - a->dp[digits - 1] = tinymt64_generate_uint64(tc->rand_state); + a->dp[digits - 1] = jfs64_generate_uint64(tc->rand_state); } a->used = digits; for (i = 0; i < digits; ++i) { - a->dp[i] = tinymt64_generate_uint64(tc->rand_state); + a->dp[i] = jfs64_generate_uint64(tc->rand_state); a->dp[i] &= MP_MASK; } @@ -1465,7 +1465,7 @@ MVMObject * MVM_bigint_rand(MVMThreadContext *tc, MVMObject *type, MVMObject *b) if (use_small_arithmetic) { if (MP_GEN_RANDOM_MAX >= (unsigned long)abs(smallint_max)) { - mp_digit result_int = tinymt64_generate_uint64(tc->rand_state); + mp_digit result_int = jfs64_generate_uint64(tc->rand_state); result_int = result_int % smallint_max; if (have_to_negate) result_int *= -1;