1958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Copyright 2014 the V8 project authors. All rights reserved. 2958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Use of this source code is governed by a BSD-style license that can be 3958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// found in the LICENSE file. 4958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/runtime/runtime-utils.h" 6958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 7958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/arguments.h" 8958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/assembler.h" 9014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/base/utils/random-number-generator.h" 10014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/bootstrapper.h" 11958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/codegen.h" 1262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/counters.h" 1362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/double.h" 1462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/objects-inl.h" 15958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 16958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace v8 { 17958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace internal { 18958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochRUNTIME_FUNCTION(Runtime_GenerateRandomNumbers) { 20958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HandleScope scope(isolate); 2162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_EQ(0, args.length()); 22c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 23c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<Context> native_context = isolate->native_context(); 24c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch DCHECK_EQ(0, native_context->math_random_index()->value()); 25c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 26c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch static const int kCacheSize = 64; 27c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch static const int kState0Offset = kCacheSize - 1; 28c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch static const int kState1Offset = kState0Offset - 1; 29c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // The index is decremented before used to access the cache. 30c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch static const int kInitialIndex = kState1Offset; 31958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 32c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<FixedDoubleArray> cache; 33c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch uint64_t state0 = 0; 34c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch uint64_t state1 = 0; 35c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (native_context->math_random_cache()->IsFixedDoubleArray()) { 36c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch cache = Handle<FixedDoubleArray>( 37c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch FixedDoubleArray::cast(native_context->math_random_cache()), isolate); 38c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch state0 = double_to_uint64(cache->get_scalar(kState0Offset)); 39c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch state1 = double_to_uint64(cache->get_scalar(kState1Offset)); 40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 41c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch cache = Handle<FixedDoubleArray>::cast( 42c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch isolate->factory()->NewFixedDoubleArray(kCacheSize, TENURED)); 43c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch native_context->set_math_random_cache(*cache); 44c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Initialize state if not yet initialized. 45c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch while (state0 == 0 || state1 == 0) { 46c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch isolate->random_number_generator()->NextBytes(&state0, sizeof(state0)); 47c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch isolate->random_number_generator()->NextBytes(&state1, sizeof(state1)); 48c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 49014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DisallowHeapAllocation no_gc; 52c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch FixedDoubleArray* raw_cache = *cache; 53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Create random numbers. 54c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch for (int i = 0; i < kInitialIndex; i++) { 55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Generate random numbers using xorshift128+. 56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch base::RandomNumberGenerator::XorShift128(&state0, &state1); 57c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch raw_cache->set(i, base::RandomNumberGenerator::ToDouble(state0, state1)); 58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 59c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Persist current state. 61c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch raw_cache->set(kState0Offset, uint64_to_double(state0)); 62c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch raw_cache->set(kState1Offset, uint64_to_double(state1)); 63c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Smi::FromInt(kInitialIndex); 64958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 67