Commit 5f4611bc authored by yangguo's avatar yangguo Committed by Commit bot

Store RNG state on function context.

R=bmeurer@chromium.org

Review URL: https://codereview.chromium.org/1425693006

Cr-Commit-Position: refs/heads/master@{#31712}
parent 395bd6d7
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
#include "src/accessors.h" #include "src/accessors.h"
#include "src/api-natives.h" #include "src/api-natives.h"
#include "src/base/utils/random-number-generator.h"
#include "src/code-stubs.h" #include "src/code-stubs.h"
#include "src/extensions/externalize-string-extension.h" #include "src/extensions/externalize-string-extension.h"
#include "src/extensions/free-buffer-extension.h" #include "src/extensions/free-buffer-extension.h"
...@@ -1792,28 +1791,11 @@ Handle<JSTypedArray> CreateTypedArray(Isolate* isolate, ExternalArrayType type, ...@@ -1792,28 +1791,11 @@ Handle<JSTypedArray> CreateTypedArray(Isolate* isolate, ExternalArrayType type,
bool Genesis::InitializeBuiltinTypedArrays() { bool Genesis::InitializeBuiltinTypedArrays() {
HandleScope scope(isolate()); HandleScope scope(isolate());
Handle<JSTypedArray> rng_state; const size_t num_elements = 2;
Handle<JSTypedArray> rempio2result; double* data = NULL;
Handle<JSTypedArray> rempio2result =
{ CreateTypedArray(isolate(), kExternalFloat64Array, num_elements, &data);
// Seed the per-context RNG using the per-isolate RNG. for (size_t i = 0; i < num_elements; i++) data[i] = 0;
const size_t num_elements = 2;
const size_t num_bytes = num_elements * sizeof(uint32_t);
uint32_t* state = NULL;
rng_state =
CreateTypedArray(isolate(), kExternalUint32Array, num_elements, &state);
do {
isolate()->random_number_generator()->NextBytes(state, num_bytes);
} while (state[0] == 0 || state[1] == 0);
}
{ // Initialize a result array for rempio2 calculation
const size_t num_elements = 2;
double* data = NULL;
rempio2result =
CreateTypedArray(isolate(), kExternalFloat64Array, num_elements, &data);
for (size_t i = 0; i < num_elements; i++) data[i] = 0;
}
Handle<JSObject> utils = Handle<JSObject> utils =
Handle<JSObject>::cast(isolate()->natives_utils_object()); Handle<JSObject>::cast(isolate()->natives_utils_object());
...@@ -1821,7 +1803,7 @@ bool Genesis::InitializeBuiltinTypedArrays() { ...@@ -1821,7 +1803,7 @@ bool Genesis::InitializeBuiltinTypedArrays() {
"InitializeBuiltinTypedArrays"); "InitializeBuiltinTypedArrays");
Handle<Object> fun = JSObject::GetDataProperty(utils, name_string); Handle<Object> fun = JSObject::GetDataProperty(utils, name_string);
Handle<Object> receiver = isolate()->factory()->undefined_value(); Handle<Object> receiver = isolate()->factory()->undefined_value();
Handle<Object> args[] = {utils, rng_state, rempio2result}; Handle<Object> args[] = {utils, rempio2result};
return !Execution::Call(isolate(), fun, receiver, arraysize(args), args) return !Execution::Call(isolate(), fun, receiver, arraysize(args), args)
.is_null(); .is_null();
} }
......
...@@ -14,12 +14,19 @@ var GlobalMath = global.Math; ...@@ -14,12 +14,19 @@ var GlobalMath = global.Math;
var GlobalObject = global.Object; var GlobalObject = global.Object;
var InternalArray = utils.InternalArray; var InternalArray = utils.InternalArray;
var NaN = %GetRootNaN(); var NaN = %GetRootNaN();
var rngstate; var rngstate_0;
var rngstate_1;
var rngstate_2;
var rngstate_3;
var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol"); var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
utils.SetupTypedArray(function(arg1, arg2, arg3) { utils.InitializeRNG = function() {
rngstate = arg1; var rngstate = %InitializeRNG();
}); rngstate_0 = rngstate[0];
rngstate_1 = rngstate[1];
rngstate_2 = rngstate[2];
rngstate_3 = rngstate[3];
};
//------------------------------------------------------------------- //-------------------------------------------------------------------
...@@ -134,22 +141,25 @@ function MathPowJS(x, y) { ...@@ -134,22 +141,25 @@ function MathPowJS(x, y) {
// ECMA 262 - 15.8.2.14 // ECMA 262 - 15.8.2.14
function MathRandom() { function MathRandom() {
var r0 = (MathImul(18030, rngstate[0] & 0xFFFF) + (rngstate[0] >>> 16)) | 0; var r0 = (MathImul(18030, rngstate_0) + rngstate_1) | 0;
rngstate[0] = r0; var r1 = (MathImul(36969, rngstate_2) + rngstate_3) | 0;
var r1 = (MathImul(36969, rngstate[1] & 0xFFFF) + (rngstate[1] >>> 16)) | 0; rngstate_0 = r0 & 0xFFFF;
rngstate[1] = r1; rngstate_1 = r0 >>> 16;
var x = ((r0 << 16) + (r1 & 0xFFFF)) | 0; rngstate_2 = r1 & 0xFFFF;
// Division by 0x100000000 through multiplication by reciprocal. rngstate_3 = r1 >>> 16;
return (x < 0 ? (x + 0x100000000) : x) * 2.3283064365386962890625e-10; // Construct a double number 1.<32-bits of randomness> and subtract 1.
return %_ConstructDouble(0x3FF00000 | (r0 & 0x000FFFFF), r1 & 0xFFF00000) - 1;
} }
function MathRandomRaw() { function MathRandomRaw() {
var r0 = (MathImul(18030, rngstate[0] & 0xFFFF) + (rngstate[0] >>> 16)) | 0; var r0 = (MathImul(18030, rngstate_0) + rngstate_1) | 0;
rngstate[0] = r0; var r1 = (MathImul(36969, rngstate_2) + rngstate_3) | 0;
var r1 = (MathImul(36969, rngstate[1] & 0xFFFF) + (rngstate[1] >>> 16)) | 0; rngstate_0 = r0 & 0xFFFF;
rngstate[1] = r1; rngstate_1 = r0 >>> 16;
rngstate_2 = r1 & 0xFFFF;
rngstate_3 = r1 >>> 16;
var x = ((r0 << 16) + (r1 & 0xFFFF)) | 0; var x = ((r0 << 16) + (r1 & 0xFFFF)) | 0;
return x & 0x3fffffff; return x & 0x3FFFFFFF;
} }
// ECMA 262 - 15.8.2.15 // ECMA 262 - 15.8.2.15
......
...@@ -245,6 +245,9 @@ function PostExperimentals(utils) { ...@@ -245,6 +245,9 @@ function PostExperimentals(utils) {
imports_from_experimental(exports_container); imports_from_experimental(exports_container);
} }
utils.InitializeRNG();
utils.InitializeRNG = UNDEFINED;
utils.Export = UNDEFINED; utils.Export = UNDEFINED;
utils.PostDebug = UNDEFINED; utils.PostDebug = UNDEFINED;
utils.PostExperimentals = UNDEFINED; utils.PostExperimentals = UNDEFINED;
...@@ -259,6 +262,9 @@ function PostDebug(utils) { ...@@ -259,6 +262,9 @@ function PostDebug(utils) {
imports(exports_container); imports(exports_container);
} }
utils.InitializeRNG();
utils.InitializeRNG = UNDEFINED;
exports_container = UNDEFINED; exports_container = UNDEFINED;
utils.Export = UNDEFINED; utils.Export = UNDEFINED;
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "src/arguments.h" #include "src/arguments.h"
#include "src/assembler.h" #include "src/assembler.h"
#include "src/base/utils/random-number-generator.h"
#include "src/codegen.h" #include "src/codegen.h"
#include "src/third_party/fdlibm/fdlibm.h" #include "src/third_party/fdlibm/fdlibm.h"
...@@ -244,5 +245,20 @@ RUNTIME_FUNCTION(Runtime_IsMinusZero) { ...@@ -244,5 +245,20 @@ RUNTIME_FUNCTION(Runtime_IsMinusZero) {
HeapNumber* number = HeapNumber::cast(obj); HeapNumber* number = HeapNumber::cast(obj);
return isolate->heap()->ToBoolean(IsMinusZero(number->value())); return isolate->heap()->ToBoolean(IsMinusZero(number->value()));
} }
RUNTIME_FUNCTION(Runtime_InitializeRNG) {
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);
}
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -404,7 +404,8 @@ namespace internal { ...@@ -404,7 +404,8 @@ namespace internal {
F(RoundNumber, 1, 1) \ F(RoundNumber, 1, 1) \
F(MathSqrt, 1, 1) \ F(MathSqrt, 1, 1) \
F(MathFround, 1, 1) \ F(MathFround, 1, 1) \
F(IsMinusZero, 1, 1) F(IsMinusZero, 1, 1) \
F(InitializeRNG, 0, 1)
#define FOR_EACH_INTRINSIC_NUMBERS(F) \ #define FOR_EACH_INTRINSIC_NUMBERS(F) \
......
...@@ -39,8 +39,8 @@ utils.Import(function(from) { ...@@ -39,8 +39,8 @@ utils.Import(function(from) {
MathExp = from.MathExp; MathExp = from.MathExp;
}); });
utils.SetupTypedArray(function(arg1, arg2) { utils.SetupTypedArray(function(arg) {
rempio2result = arg2; rempio2result = arg;
}); });
// ------------------------------------------------------------------- // -------------------------------------------------------------------
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment