summaryrefslogtreecommitdiff
path: root/deps/v8/src/math-random.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/math-random.cc')
-rw-r--r--deps/v8/src/math-random.cc70
1 files changed, 70 insertions, 0 deletions
diff --git a/deps/v8/src/math-random.cc b/deps/v8/src/math-random.cc
new file mode 100644
index 0000000000..932d4b9d2a
--- /dev/null
+++ b/deps/v8/src/math-random.cc
@@ -0,0 +1,70 @@
+// Copyright 2018 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/math-random.h"
+
+#include "src/assert-scope.h"
+#include "src/base/utils/random-number-generator.h"
+#include "src/contexts-inl.h"
+#include "src/isolate.h"
+#include "src/objects/fixed-array.h"
+
+namespace v8 {
+namespace internal {
+
+void MathRandom::InitializeContext(Isolate* isolate,
+ Handle<Context> native_context) {
+ Handle<FixedDoubleArray> cache = Handle<FixedDoubleArray>::cast(
+ isolate->factory()->NewFixedDoubleArray(kCacheSize, TENURED));
+ for (int i = 0; i < kCacheSize; i++) cache->set(i, 0);
+ native_context->set_math_random_cache(*cache);
+ Handle<PodArray<State>> pod = PodArray<State>::New(isolate, 1, TENURED);
+ native_context->set_math_random_state(*pod);
+ ResetContext(*native_context);
+}
+
+void MathRandom::ResetContext(Context* native_context) {
+ native_context->set_math_random_index(Smi::kZero);
+ State state = {0, 0};
+ PodArray<State>::cast(native_context->math_random_state())->set(0, state);
+}
+
+Smi* MathRandom::RefillCache(Isolate* isolate, Context* native_context) {
+ DisallowHeapAllocation no_gc;
+ PodArray<State>* pod =
+ PodArray<State>::cast(native_context->math_random_state());
+ State state = pod->get(0);
+ // Initialize state if not yet initialized. If a fixed random seed was
+ // requested, use it to reset our state the first time a script asks for
+ // random numbers in this context. This ensures the script sees a consistent
+ // sequence.
+ if (state.s0 == 0 && state.s1 == 0) {
+ uint64_t seed;
+ if (FLAG_random_seed != 0) {
+ seed = FLAG_random_seed;
+ } else {
+ isolate->random_number_generator()->NextBytes(&seed, sizeof(seed));
+ }
+ state.s0 = base::RandomNumberGenerator::MurmurHash3(seed);
+ state.s1 = base::RandomNumberGenerator::MurmurHash3(~seed);
+ CHECK(state.s0 != 0 || state.s1 != 0);
+ }
+
+ FixedDoubleArray* cache =
+ FixedDoubleArray::cast(native_context->math_random_cache());
+ // Create random numbers.
+ for (int i = 0; i < kCacheSize; i++) {
+ // Generate random numbers using xorshift128+.
+ base::RandomNumberGenerator::XorShift128(&state.s0, &state.s1);
+ cache->set(i, base::RandomNumberGenerator::ToDouble(state.s0));
+ }
+ pod->set(0, state);
+
+ Smi* new_index = Smi::FromInt(kCacheSize);
+ native_context->set_math_random_index(new_index);
+ return new_index;
+}
+
+} // namespace internal
+} // namespace v8