Chromium Code Reviews| Index: src/runtime/runtime-maths.cc |
| diff --git a/src/runtime/runtime-maths.cc b/src/runtime/runtime-maths.cc |
| index 70c587d7454b401fbfe9f2fc61812b039a6a0531..154961367f6f45cf6f8f5701d36ace547c2374e9 100644 |
| --- a/src/runtime/runtime-maths.cc |
| +++ b/src/runtime/runtime-maths.cc |
| @@ -247,18 +247,48 @@ RUNTIME_FUNCTION(Runtime_IsMinusZero) { |
| } |
| -RUNTIME_FUNCTION(Runtime_InitializeRNG) { |
| +RUNTIME_FUNCTION(Runtime_GenerateRandomNumbers) { |
| HandleScope scope(isolate); |
| - DCHECK(args.length() == 0); |
| - static const int kSize = 4; |
| - Handle<FixedArray> array = isolate->factory()->NewFixedArray(kSize); |
| - uint16_t seeds[kSize]; |
| - do { |
| - isolate->random_number_generator()->NextBytes(seeds, |
| - kSize * sizeof(*seeds)); |
| - } while (!(seeds[0] && seeds[1] && seeds[2] && seeds[3])); |
| - for (int i = 0; i < kSize; i++) array->set(i, Smi::FromInt(seeds[i])); |
| - return *isolate->factory()->NewJSArrayWithElements(array); |
| + DCHECK(args.length() == 1); |
| + static const int kState0Offset = 0; |
| + static const int kState1Offset = 1; |
| + static const int kRandomBatchSize = 64; |
| + CONVERT_ARG_HANDLE_CHECKED(Object, maybe_typed_array, 0); |
| + Handle<JSTypedArray> typed_array; |
| + // Allocate typed array if it does not yet exist. |
| + if (maybe_typed_array->IsJSTypedArray()) { |
| + typed_array = Handle<JSTypedArray>::cast(maybe_typed_array); |
| + } else { |
| + static const int kByteLength = kRandomBatchSize * sizeof(double); |
|
Jakob Kummerow
2015/11/23 14:34:08
"sizeof(double)" used to be a linter violation. Yo
|
| + Handle<JSArrayBuffer> buffer = |
| + isolate->factory()->NewJSArrayBuffer(SharedFlag::kNotShared, TENURED); |
| + JSArrayBuffer::SetupAllocatingData(buffer, isolate, kByteLength, true, |
| + SharedFlag::kNotShared); |
| + typed_array = isolate->factory()->NewJSTypedArray( |
| + kExternalFloat64Array, buffer, 0, kRandomBatchSize); |
| + } |
| + |
| + DisallowHeapAllocation no_gc; |
| + double* array = |
| + reinterpret_cast<double*>(typed_array->GetBuffer()->backing_store()); |
| + // Fetch existing state. |
| + uint64_t state0 = double_to_uint64(array[kState0Offset]); |
| + uint64_t state1 = double_to_uint64(array[kState1Offset]); |
| + // Initialize state if not yet initialized. |
| + while (state0 == 0 || state1 == 0) { |
| + isolate->random_number_generator()->NextBytes(&state0, sizeof(state0)); |
| + isolate->random_number_generator()->NextBytes(&state1, sizeof(state1)); |
| + } |
| + // Create random numbers. |
| + for (int i = kState1Offset + 1; i < kRandomBatchSize; i++) { |
| + // Generate random numbers using xorshift128+. |
| + base::RandomNumberGenerator::XorShift128(&state0, &state1); |
| + array[i] = base::RandomNumberGenerator::ToDouble(state0, state1); |
| + } |
| + // Persist current state. |
| + array[kState0Offset] = uint64_to_double(state0); |
| + array[kState1Offset] = uint64_to_double(state1); |
| + return *typed_array; |
| } |
| } // namespace internal |
| } // namespace v8 |