1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2013 the V8 project authors. All rights reserved. 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met: 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions of source code must retain the above copyright 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer. 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions in binary form must reproduce the above 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// copyright notice, this list of conditions and the following 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// disclaimer in the documentation and/or other materials provided 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// with the distribution. 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Neither the name of Google Inc. nor the names of its 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// contributors may be used to endorse or promote products derived 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// from this software without specific prior written permission. 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/v8.h" 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "test/cctest/cctest.h" 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/utils/random-number-generator.h" 32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochusing namespace v8::internal; 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const int64_t kRandomSeeds[] = {-1, 1, 42, 100, 1234567890, 987654321}; 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(RandomSeedFlagIsUsed) { 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (unsigned n = 0; n < arraysize(kRandomSeeds); ++n) { 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FLAG_random_seed = static_cast<int>(kRandomSeeds[n]); 42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch v8::Isolate::CreateParams create_params; 43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch create_params.array_buffer_allocator = CcTest::array_buffer_allocator(); 44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch v8::Isolate* i = v8::Isolate::New(create_params); 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::base::RandomNumberGenerator& rng = 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *reinterpret_cast<Isolate*>(i)->random_number_generator(); 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(kRandomSeeds[n], rng.initial_seed()); 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i->Dispose(); 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 52014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Chi squared for getting m 0s out of n bits. 54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochdouble ChiSquared(int m, int n) { 55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch double ys_minus_np1 = (m - n / 2.0); 56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch double chi_squared_1 = ys_minus_np1 * ys_minus_np1 * 2.0 / n; 57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch double ys_minus_np2 = ((n - m) - n / 2.0); 58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch double chi_squared_2 = ys_minus_np2 * ys_minus_np2 * 2.0 / n; 59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return chi_squared_1 + chi_squared_2; 60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Test for correlations between recent bits from the PRNG, or bits that are 64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// biased. 65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid RandomBitCorrelation(int random_bit) { 66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FLAG_random_seed = 31415926; 67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch v8::Isolate::CreateParams create_params; 68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch create_params.array_buffer_allocator = CcTest::array_buffer_allocator(); 69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch v8::Isolate* isolate = v8::Isolate::New(create_params); 70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* i_isolate = reinterpret_cast<Isolate*>(isolate); 71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch v8::base::RandomNumberGenerator* rng = i_isolate->random_number_generator(); 72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifdef DEBUG 73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const int kHistory = 2; 74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const int kRepeats = 1000; 75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#else 76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const int kHistory = 8; 77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const int kRepeats = 10000; 78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t history[kHistory]; 80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // The predictor bit is either constant 0 or 1, or one of the bits from the 81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // history. 82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int predictor_bit = -2; predictor_bit < 32; predictor_bit++) { 83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // The predicted bit is one of the bits from the PRNG. 84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int ago = 0; ago < kHistory; ago++) { 85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // We don't want to check whether each bit predicts itself. 86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (ago == 0 && predictor_bit == random_bit) continue; 87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Enter the new random value into the history 89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = ago; i >= 0; i--) { 90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch history[i] = bit_cast<uint32_t>(rng->NextInt()); 91014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 92014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 93014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Find out how many of the bits are the same as the prediction bit. 94014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int m = 0; 95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < kRepeats; i++) { 96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch v8::HandleScope scope(isolate); 97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t random = bit_cast<uint32_t>(rng->NextInt()); 98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int j = ago - 1; j >= 0; j--) history[j + 1] = history[j]; 99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch history[0] = random; 100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int predicted; 102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (predictor_bit >= 0) { 103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch predicted = (history[ago] >> predictor_bit) & 1; 104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch predicted = predictor_bit == -2 ? 0 : 1; 106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int bit = (random >> random_bit) & 1; 108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (bit == predicted) m++; 109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Chi squared analysis for k = 2 (2, states: same/not-same) and one 112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // degree of freedom (k - 1). 113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch double chi_squared = ChiSquared(m, kRepeats); 114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (chi_squared > 24) { 115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int percent = static_cast<int>(m * 100.0 / kRepeats); 116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (predictor_bit < 0) { 117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PrintF("Bit %d is %d %d%% of the time\n", random_bit, 118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch predictor_bit == -2 ? 0 : 1, percent); 119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PrintF("Bit %d is the same as bit %d %d ago %d%% of the time\n", 121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch random_bit, predictor_bit, ago, percent); 122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // For 1 degree of freedom this corresponds to 1 in a million. We are 126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // running ~8000 tests, so that would be surprising. 127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK(chi_squared <= 24); 128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // If the predictor bit is a fixed 0 or 1 then it makes no sense to 130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // repeat the test with a different age. 131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (predictor_bit < 0) break; 132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate->Dispose(); 135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define TEST_RANDOM_BIT(BIT) \ 139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch TEST(RandomBitCorrelations##BIT) { RandomBitCorrelation(BIT); } 140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_RANDOM_BIT(0) 142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_RANDOM_BIT(1) 143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_RANDOM_BIT(2) 144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_RANDOM_BIT(3) 145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_RANDOM_BIT(4) 146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_RANDOM_BIT(5) 147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_RANDOM_BIT(6) 148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_RANDOM_BIT(7) 149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_RANDOM_BIT(8) 150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_RANDOM_BIT(9) 151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_RANDOM_BIT(10) 152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_RANDOM_BIT(11) 153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_RANDOM_BIT(12) 154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_RANDOM_BIT(13) 155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_RANDOM_BIT(14) 156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_RANDOM_BIT(15) 157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_RANDOM_BIT(16) 158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_RANDOM_BIT(17) 159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_RANDOM_BIT(18) 160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_RANDOM_BIT(19) 161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_RANDOM_BIT(20) 162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_RANDOM_BIT(21) 163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_RANDOM_BIT(22) 164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_RANDOM_BIT(23) 165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_RANDOM_BIT(24) 166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_RANDOM_BIT(25) 167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_RANDOM_BIT(26) 168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_RANDOM_BIT(27) 169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_RANDOM_BIT(28) 170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_RANDOM_BIT(29) 171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_RANDOM_BIT(30) 172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_RANDOM_BIT(31) 173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef TEST_RANDOM_BIT 175