Revert "Do not use FixedDoubleArray to store RNG state"

This reverts commit 33fa357b6f.

Reason for revert: Breaking the V8 Linux - arm64 - sim - MSAN bot. Please see here:
https://ci.chromium.org/p/v8/builders/luci.v8.ci/V8%20Linux%20-%20arm64%20-%20sim%20-%20MSAN/23001

Original change's description:
> Do not use FixedDoubleArray to store RNG state
> 
> Also:
>  - replace runtime call with cheaper C call
>  - use xor instead of addition to remove bias
> 
> R=​mvstanton@chromium.org
> 
> Bug: v8:8212
> Cq-Include-Trybots: luci.chromium.try:linux_chromium_rel_ng
> Change-Id: If4bfe0f5fb1864c89f4acd871cb8b74c7cd7ab09
> Reviewed-on: https://chromium-review.googlesource.com/1240116
> Commit-Queue: Yang Guo <yangguo@chromium.org>
> Reviewed-by: Michael Stanton <mvstanton@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#56165}

TBR=yangguo@chromium.org,mvstanton@chromium.org

Change-Id: I05f23f0b52a706233bbc1a1877cc15691ed9f40a
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: v8:8212
Cq-Include-Trybots: luci.chromium.try:linux_chromium_rel_ng
Reviewed-on: https://chromium-review.googlesource.com/1238549
Reviewed-by: Maya Lekova <mslekova@chromium.org>
Commit-Queue: Maya Lekova <mslekova@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56167}
This commit is contained in:
Maya Lekova 2018-09-24 13:09:48 +00:00 committed by Commit Bot
parent ee1335adef
commit 601d8896b3
14 changed files with 85 additions and 130 deletions

View File

@ -2164,8 +2164,6 @@ v8_source_set("v8_base") {
"src/macro-assembler.h",
"src/map-updater.cc",
"src/map-updater.h",
"src/math-random.cc",
"src/math-random.h",
"src/maybe-handles-inl.h",
"src/maybe-handles.h",
"src/messages.cc",
@ -2406,6 +2404,7 @@ v8_source_set("v8_base") {
"src/runtime/runtime-interpreter.cc",
"src/runtime/runtime-intl.cc",
"src/runtime/runtime-literals.cc",
"src/runtime/runtime-maths.cc",
"src/runtime/runtime-module.cc",
"src/runtime/runtime-numbers.cc",
"src/runtime/runtime-object.cc",

View File

@ -99,7 +99,7 @@ int RandomNumberGenerator::NextInt(int max) {
double RandomNumberGenerator::NextDouble() {
XorShift128(&state0_, &state1_);
return ToDouble(state0_);
return ToDouble(state0_, state1_);
}

View File

@ -108,10 +108,11 @@ class V8_BASE_EXPORT RandomNumberGenerator final {
int64_t initial_seed() const { return initial_seed_; }
// Static and exposed for external use.
static inline double ToDouble(uint64_t state0) {
static inline double ToDouble(uint64_t state0, uint64_t state1) {
// Exponent for double values for [1.0 .. 2.0)
static const uint64_t kExponentBits = uint64_t{0x3FF0000000000000};
uint64_t random = (state0 >> 12) | kExponentBits;
static const uint64_t kMantissaMask = uint64_t{0x000FFFFFFFFFFFFF};
uint64_t random = ((state0 + state1) & kMantissaMask) | kExponentBits;
return bit_cast<double>(random) - 1;
}

View File

@ -19,7 +19,6 @@
#include "src/extensions/trigger-failure-extension.h"
#include "src/heap/heap.h"
#include "src/isolate-inl.h"
#include "src/math-random.h"
#include "src/objects/api-callbacks.h"
#include "src/objects/arguments.h"
#include "src/objects/hash-table-inl.h"
@ -5770,7 +5769,6 @@ Genesis::Genesis(
DCHECK_EQ(0u, context_snapshot_index);
// We get here if there was no context snapshot.
CreateRoots();
MathRandom::InitializeContext(isolate, native_context());
Handle<JSFunction> empty_function = CreateEmptyFunction();
CreateSloppyModeFunctionMaps(empty_function);
CreateStrictModeFunctionMaps(empty_function);

View File

@ -413,16 +413,7 @@ TF_BUILTIN(MathRandom, CodeStubAssembler) {
GotoIf(SmiAbove(smi_index.value(), SmiConstant(0)), &if_cached);
// Cache exhausted, populate the cache. Return value is the new index.
Node* const refill_math_random =
ExternalConstant(ExternalReference::refill_math_random());
Node* const isolate_ptr =
ExternalConstant(ExternalReference::isolate_address(isolate()));
MachineType type_tagged = MachineType::AnyTagged();
MachineType type_ptr = MachineType::Pointer();
smi_index =
CAST(CallCFunction2(type_tagged, type_ptr, type_tagged,
refill_math_random, isolate_ptr, native_context));
smi_index = CAST(CallRuntime(Runtime::kGenerateRandomNumbers, context));
Goto(&if_cached);
// Compute next index by decrement.

View File

@ -233,8 +233,7 @@ enum ContextLookupFlags {
V(MAP_KEY_VALUE_ITERATOR_MAP_INDEX, Map, map_key_value_iterator_map) \
V(MAP_VALUE_ITERATOR_MAP_INDEX, Map, map_value_iterator_map) \
V(MATH_RANDOM_INDEX_INDEX, Smi, math_random_index) \
V(MATH_RANDOM_STATE_INDEX, ByteArray, math_random_state) \
V(MATH_RANDOM_CACHE_INDEX, FixedDoubleArray, math_random_cache) \
V(MATH_RANDOM_CACHE_INDEX, Object, math_random_cache) \
V(MESSAGE_LISTENERS_INDEX, TemplateList, message_listeners) \
V(NATIVES_UTILS_OBJECT_INDEX, Object, natives_utils_object) \
V(NORMALIZED_MAP_CACHE_INDEX, Object, normalized_map_cache) \

View File

@ -308,6 +308,7 @@ bool IntrinsicHasNoSideEffect(Runtime::FunctionId id) {
V(ArrayIndexOf) \
V(ArrayIsArray) \
V(ClassOf) \
V(GenerateRandomNumbers) \
V(GetFunctionName) \
V(GetOwnPropertyDescriptor) \
V(GlobalPrint) \

View File

@ -16,7 +16,6 @@
#include "src/ic/stub-cache.h"
#include "src/interpreter/interpreter.h"
#include "src/isolate.h"
#include "src/math-random.h"
#include "src/objects-inl.h"
#include "src/regexp/regexp-stack.h"
#include "src/simulator-base.h"
@ -720,10 +719,6 @@ ExternalReference ExternalReference::printf_function() {
return ExternalReference(Redirect(FUNCTION_ADDR(std::printf)));
}
ExternalReference ExternalReference::refill_math_random() {
return ExternalReference(Redirect(FUNCTION_ADDR(MathRandom::RefillCache)));
}
template <typename SubjectChar, typename PatternChar>
ExternalReference ExternalReference::search_string_raw() {
auto f = SearchStringRaw<SubjectChar, PatternChar>;

View File

@ -133,7 +133,6 @@ class StatsCounter;
V(orderedhashmap_gethash_raw, "orderedhashmap_gethash_raw") \
V(power_double_double_function, "power_double_double_function") \
V(printf_function, "printf") \
V(refill_math_random, "MathRandom::RefillCache") \
V(store_buffer_overflow_function, "StoreBuffer::StoreBufferOverflow") \
V(search_string_raw_one_one, "search_string_raw_one_one") \
V(search_string_raw_one_two, "search_string_raw_one_two") \

View File

@ -1,70 +0,0 @@
// 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));
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) {
if (FLAG_random_seed != 0) {
state.s0 = FLAG_random_seed;
state.s1 = FLAG_random_seed;
} else {
base::RandomNumberGenerator* rng = isolate->random_number_generator();
while (state.s0 == 0 || state.s1 == 0) {
rng->NextBytes(&state.s0, sizeof(state.s0));
rng->NextBytes(&state.s1, sizeof(state.s1));
}
}
}
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

View File

@ -1,33 +0,0 @@
// 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.
#ifndef V8_MATH_RANDOM_H_
#define V8_MATH_RANDOM_H_
#include "src/contexts.h"
#include "src/globals.h"
namespace v8 {
namespace internal {
class MathRandom : public AllStatic {
public:
static void InitializeContext(Isolate* isolate,
Handle<Context> native_context);
static void ResetContext(Context* native_context);
static Smi* RefillCache(Isolate* isolate, Context* native_context);
static const int kCacheSize = 64;
static const int kStateSize = 2 * kInt64Size;
struct State {
uint64_t s0;
uint64_t s1;
};
};
} // namespace internal
} // namespace v8
#endif // V8_MATH_RANDOM_H_

View File

@ -0,0 +1,72 @@
// Copyright 2014 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/runtime/runtime-utils.h"
#include "src/arguments.h"
#include "src/base/utils/random-number-generator.h"
#include "src/bootstrapper.h"
#include "src/counters.h"
#include "src/double.h"
#include "src/objects-inl.h"
namespace v8 {
namespace internal {
RUNTIME_FUNCTION(Runtime_GenerateRandomNumbers) {
HandleScope scope(isolate);
DCHECK_EQ(0, args.length());
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;
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 {
cache = Handle<FixedDoubleArray>::cast(
isolate->factory()->NewFixedDoubleArray(kCacheSize, TENURED));
native_context->set_math_random_cache(*cache);
// 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 (FLAG_random_seed != 0) {
state0 = FLAG_random_seed;
state1 = FLAG_random_seed;
} else {
while (state0 == 0 || state1 == 0) {
isolate->random_number_generator()->NextBytes(&state0, sizeof(state0));
isolate->random_number_generator()->NextBytes(&state1, sizeof(state1));
}
}
}
DisallowHeapAllocation no_gc;
FixedDoubleArray* raw_cache = *cache;
// Create random numbers.
for (int i = 0; i < kInitialIndex; i++) {
// Generate random numbers using xorshift128+.
base::RandomNumberGenerator::XorShift128(&state0, &state1);
raw_cache->set(i, base::RandomNumberGenerator::ToDouble(state0, state1));
}
// Persist current state.
raw_cache->set(kState0Offset, uint64_to_double(state0));
raw_cache->set(kState1Offset, uint64_to_double(state1));
return Smi::FromInt(kInitialIndex);
}
} // namespace internal
} // namespace v8

View File

@ -256,6 +256,8 @@ namespace internal {
F(CreateObjectLiteralWithoutAllocationSite, 2, 1) \
F(CreateRegExpLiteral, 4, 1)
#define FOR_EACH_INTRINSIC_MATHS(F) F(GenerateRandomNumbers, 0, 1)
#define FOR_EACH_INTRINSIC_MODULE(F) \
F(DynamicImportCall, 2, 1) \
F(GetImportMetaObject, 0, 1) \
@ -579,6 +581,7 @@ namespace internal {
FOR_EACH_INTRINSIC_INTERPRETER(F) \
FOR_EACH_INTRINSIC_INTL(F) \
FOR_EACH_INTRINSIC_LITERALS(F) \
FOR_EACH_INTRINSIC_MATHS(F) \
FOR_EACH_INTRINSIC_MODULE(F) \
FOR_EACH_INTRINSIC_NUMBERS(F) \
FOR_EACH_INTRINSIC_OBJECT(F) \

View File

@ -6,7 +6,6 @@
#include "src/snapshot/startup-serializer.h"
#include "src/api-inl.h"
#include "src/math-random.h"
#include "src/objects-inl.h"
namespace v8 {
@ -41,7 +40,8 @@ void PartialSerializer::Serialize(Context** o, bool include_global_proxy) {
ReadOnlyRoots(isolate()).undefined_value());
DCHECK(!context_->global_object()->IsUndefined());
// Reset math random cache to get fresh random numbers.
MathRandom::ResetContext(context_);
context_->set_math_random_index(Smi::kZero);
context_->set_math_random_cache(ReadOnlyRoots(isolate()).undefined_value());
VisitRootPointer(Root::kPartialSnapshotCache, nullptr,
reinterpret_cast<Object**>(o));