Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1215)

Unified Diff: src/runtime/runtime-maths.cc

Issue 2402363002: [Math] implement Math.random as TFJ builtin. (Closed)
Patch Set: fix golden file Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/runtime/runtime-maths.cc
diff --git a/src/runtime/runtime-maths.cc b/src/runtime/runtime-maths.cc
index 47e560d022a4189275604c710bfd5bc5a87ad2bc..404305a150592ee07a8684e1bb55f290f7cea2b5 100644
--- a/src/runtime/runtime-maths.cc
+++ b/src/runtime/runtime-maths.cc
@@ -15,58 +15,49 @@ namespace internal {
RUNTIME_FUNCTION(Runtime_GenerateRandomNumbers) {
HandleScope scope(isolate);
- DCHECK(args.length() == 1);
- if (isolate->serializer_enabled()) {
- // Random numbers in the snapshot are not really that random. And we cannot
- // return a typed array as it cannot be serialized. To make calling
- // Math.random possible when creating a custom startup snapshot, we simply
- // return a normal array with a single random number.
- Handle<HeapNumber> random_number = isolate->factory()->NewHeapNumber(
- isolate->random_number_generator()->NextDouble());
- Handle<FixedArray> array_backing = isolate->factory()->NewFixedArray(1);
- array_backing->set(0, *random_number);
- return *isolate->factory()->NewJSArrayWithElements(array_backing);
- }
+ DCHECK(args.length() == 0);
+
+ Handle<Context> native_context = isolate->native_context();
+ DCHECK_EQ(0, native_context->math_random_index()->value());
+
+ static const int kCacheSize = 64;
+ static const int kState0Offset = kCacheSize - 1;
+ static const int kState1Offset = kState0Offset - 1;
+ // The index is decremented before used to access the cache.
+ static const int kInitialIndex = kState1Offset;
- 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);
+ Handle<FixedDoubleArray> cache;
+ uint64_t state0 = 0;
+ uint64_t state1 = 0;
+ if (native_context->math_random_cache()->IsFixedDoubleArray()) {
+ cache = Handle<FixedDoubleArray>(
+ FixedDoubleArray::cast(native_context->math_random_cache()), isolate);
+ state0 = double_to_uint64(cache->get_scalar(kState0Offset));
+ state1 = double_to_uint64(cache->get_scalar(kState1Offset));
} else {
- static const int kByteLength = kRandomBatchSize * kDoubleSize;
- 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);
+ cache = Handle<FixedDoubleArray>::cast(
+ isolate->factory()->NewFixedDoubleArray(kCacheSize, TENURED));
+ native_context->set_math_random_cache(*cache);
+ // 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));
+ }
}
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));
- }
+ FixedDoubleArray* raw_cache = *cache;
// Create random numbers.
- for (int i = kState1Offset + 1; i < kRandomBatchSize; i++) {
+ for (int i = 0; i < kInitialIndex; i++) {
// Generate random numbers using xorshift128+.
base::RandomNumberGenerator::XorShift128(&state0, &state1);
- array[i] = base::RandomNumberGenerator::ToDouble(state0, state1);
+ raw_cache->set(i, base::RandomNumberGenerator::ToDouble(state0, state1));
}
+
// Persist current state.
- array[kState0Offset] = uint64_to_double(state0);
- array[kState1Offset] = uint64_to_double(state1);
- return *typed_array;
+ raw_cache->set(kState0Offset, uint64_to_double(state0));
+ raw_cache->set(kState1Offset, uint64_to_double(state1));
+ return Smi::FromInt(kInitialIndex);
}
} // namespace internal
} // namespace v8

Powered by Google App Engine
This is Rietveld 408576698