Title: [192855] trunk/Source
- Revision
- 192855
- Author
- [email protected]
- Date
- 2015-11-30 19:39:59 -0800 (Mon, 30 Nov 2015)
Log Message
Use a better RNG for Math.random()
https://bugs.webkit.org/show_bug.cgi?id=151641
Reviewed by Anders Carlsson.
Source/_javascript_Core:
Updated for interface change.
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::setInputCursor):
Source/WTF:
Use 64 bits in the random number generator instead of 32 bit. (In
the end, _javascript_, which uses doubles, will only see 52 bits.) This
prevents programs that mulitply a random number by a large constant from
seeing non-random "banding" caused by zeroes in the low 20 bits.
I also took the opportunity to upgrade from GameRandom to Xorshift+,
since Xorshift+ passes more benchmarks for randomness, and is not any
slower or more complicated.
Now let us all remember the fateful words of Steve Weibe, who would be
King of Kong: "The randomness went the opposite way that it usually goes."
* wtf/WeakRandom.h:
(WTF::WeakRandom::WeakRandom):
(WTF::WeakRandom::setSeed): Use standard naming.
(WTF::WeakRandom::seed): This function is safe now. "Unsafe" in function
names makes me itch.
(WTF::WeakRandom::get):
(WTF::WeakRandom::getUint32): Update to 64bit.
(WTF::WeakRandom::advance): The Xorshift+ algorithm.
(WTF::WeakRandom::initializeSeed): Deleted.
(WTF::WeakRandom::seedUnsafe): Deleted.
Modified Paths
Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (192854 => 192855)
--- trunk/Source/_javascript_Core/ChangeLog 2015-12-01 02:53:25 UTC (rev 192854)
+++ trunk/Source/_javascript_Core/ChangeLog 2015-12-01 03:39:59 UTC (rev 192855)
@@ -1,3 +1,15 @@
+2015-11-30 Geoffrey Garen <[email protected]>
+
+ Use a better RNG for Math.random()
+ https://bugs.webkit.org/show_bug.cgi?id=151641
+
+ Reviewed by Anders Carlsson.
+
+ Updated for interface change.
+
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::setInputCursor):
+
2015-11-30 Benjamin Poulain <[email protected]>
[JSC] Speed up Air Liveness Analysis on Tmps
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp (192854 => 192855)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2015-12-01 02:53:25 UTC (rev 192854)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2015-12-01 03:39:59 UTC (rev 192855)
@@ -1014,10 +1014,10 @@
// Save or set the random seed. This performed here rather than the constructor
// to avoid threading the input cursor through all the abstraction layers.
if (cursor.isCapturing())
- cursor.appendInput<SetRandomSeed>(m_weakRandom.seedUnsafe());
+ cursor.appendInput<SetRandomSeed>(m_weakRandom.seed());
else if (cursor.isReplaying()) {
if (SetRandomSeed* input = cursor.fetchInput<SetRandomSeed>())
- m_weakRandom.initializeSeed(static_cast<unsigned>(input->randomSeed()));
+ m_weakRandom.setSeed(static_cast<unsigned>(input->randomSeed()));
}
}
#endif
Modified: trunk/Source/WTF/ChangeLog (192854 => 192855)
--- trunk/Source/WTF/ChangeLog 2015-12-01 02:53:25 UTC (rev 192854)
+++ trunk/Source/WTF/ChangeLog 2015-12-01 03:39:59 UTC (rev 192855)
@@ -1,3 +1,37 @@
+2015-11-30 Geoffrey Garen <[email protected]>
+
+ Use a better RNG for Math.random()
+ https://bugs.webkit.org/show_bug.cgi?id=151641
+
+ Reviewed by Anders Carlsson.
+
+ Use 64 bits in the random number generator instead of 32 bit. (In
+ the end, _javascript_, which uses doubles, will only see 52 bits.) This
+ prevents programs that mulitply a random number by a large constant from
+ seeing non-random "banding" caused by zeroes in the low 20 bits.
+
+ I also took the opportunity to upgrade from GameRandom to Xorshift+,
+ since Xorshift+ passes more benchmarks for randomness, and is not any
+ slower or more complicated.
+
+ Now let us all remember the fateful words of Steve Weibe, who would be
+ King of Kong: "The randomness went the opposite way that it usually goes."
+
+ * wtf/WeakRandom.h:
+ (WTF::WeakRandom::WeakRandom):
+ (WTF::WeakRandom::setSeed): Use standard naming.
+
+ (WTF::WeakRandom::seed): This function is safe now. "Unsafe" in function
+ names makes me itch.
+
+ (WTF::WeakRandom::get):
+ (WTF::WeakRandom::getUint32): Update to 64bit.
+
+ (WTF::WeakRandom::advance): The Xorshift+ algorithm.
+
+ (WTF::WeakRandom::initializeSeed): Deleted.
+ (WTF::WeakRandom::seedUnsafe): Deleted.
+
2015-11-30 Benjamin Poulain <[email protected]>
[JSC] Speed up Air Liveness Analysis on Tmps
Modified: trunk/Source/WTF/wtf/WeakRandom.h (192854 => 192855)
--- trunk/Source/WTF/wtf/WeakRandom.h 2015-12-01 02:53:25 UTC (rev 192854)
+++ trunk/Source/WTF/wtf/WeakRandom.h 2015-12-01 03:39:59 UTC (rev 192855)
@@ -22,76 +22,57 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
+ * Vigna, Sebastiano (2014). "Further scramblings of Marsaglia's xorshift
+ * generators". arXiv:1404.0390 (http://arxiv.org/abs/1404.0390)
*
- * Copyright (c) 2009 Ian C. Bullard
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use,
- * copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
+ * See also https://en.wikipedia.org/wiki/Xorshift.
*/
#ifndef WeakRandom_h
#define WeakRandom_h
#include <limits.h>
-#include <wtf/RandomNumber.h>
+#include <wtf/CryptographicallyRandomNumber.h>
#include <wtf/StdLibExtras.h>
namespace WTF {
class WeakRandom {
public:
- WeakRandom()
+ WeakRandom(unsigned seed = cryptographicallyRandomNumber())
{
- initializeSeed(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0));
+ setSeed(seed);
}
-
- WeakRandom(unsigned seed)
+
+ void setSeed(unsigned seed)
{
- initializeSeed(seed);
- }
-
- void initializeSeed(unsigned seed)
- {
- m_low = seed ^ 0x49616E42;
+ m_seed = seed;
+
+ // A zero seed would cause an infinite series of zeroes.
+ if (!seed)
+ seed = 1;
+
+ m_low = seed;
m_high = seed;
}
- // Returns the seed provided that you've never called get() or getUint32().
- unsigned seedUnsafe() const { return m_high; }
+ unsigned seed() const { return m_seed; }
double get()
{
- return advance() / (UINT_MAX + 1.0);
+ return advance() / (std::numeric_limits<uint64_t>::max() + 1.0);
}
unsigned getUint32()
{
- return advance();
+ return static_cast<unsigned>(advance());
}
unsigned getUint32(unsigned limit)
{
if (limit <= 1)
return 0;
- uint64_t cutoff = (static_cast<uint64_t>(UINT_MAX) + 1) / limit * limit;
+ uint64_t cutoff = (static_cast<uint64_t>(std::numeric_limits<unsigned>::max()) + 1) / limit * limit;
for (;;) {
uint64_t value = getUint32();
if (value >= cutoff)
@@ -101,16 +82,21 @@
}
private:
- unsigned advance()
+ uint64_t advance()
{
- m_high = (m_high << 16) + (m_high >> 16);
- m_high += m_low;
- m_low += m_high;
- return m_high;
+ uint64_t x = m_low;
+ uint64_t y = m_high;
+ m_low = y;
+ x ^= x << 23;
+ x ^= x >> 17;
+ x ^= y ^ (y >> 26);
+ m_high = x;
+ return x + y;
}
- unsigned m_low;
- unsigned m_high;
+ unsigned m_seed;
+ uint64_t m_low;
+ uint64_t m_high;
};
} // namespace WTF
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes