Commit 7ab6e55f authored by lrn@chromium.org's avatar lrn@chromium.org

Moved random generator state to global context.

Change Random to take global context, not isolate.

BUG=v8:864

Review URL: http://codereview.chromium.org/8162014

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9753 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 6898ff27
...@@ -4105,8 +4105,9 @@ Persistent<Context> v8::Context::New( ...@@ -4105,8 +4105,9 @@ Persistent<Context> v8::Context::New(
} }
// Leave V8. // Leave V8.
if (env.is_null()) if (env.is_null()) {
return Persistent<Context>(); return Persistent<Context>();
}
return Persistent<Context>(Utils::ToLocal(env)); return Persistent<Context>(Utils::ToLocal(env));
} }
......
...@@ -2828,7 +2828,8 @@ void FullCodeGenerator::EmitRandomHeapNumber(ZoneList<Expression*>* args) { ...@@ -2828,7 +2828,8 @@ void FullCodeGenerator::EmitRandomHeapNumber(ZoneList<Expression*>* args) {
// ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)). // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)).
if (CpuFeatures::IsSupported(VFP3)) { if (CpuFeatures::IsSupported(VFP3)) {
__ PrepareCallCFunction(1, r0); __ PrepareCallCFunction(1, r0);
__ mov(r0, Operand(ExternalReference::isolate_address())); __ ldr(r0, ContextOperand(context_register(), Context::GLOBAL_INDEX));
__ ldr(r0, FieldMemOperand(r0, GlobalObject::kGlobalContextOffset));
__ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1); __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1);
CpuFeatures::Scope scope(VFP3); CpuFeatures::Scope scope(VFP3);
...@@ -2848,8 +2849,9 @@ void FullCodeGenerator::EmitRandomHeapNumber(ZoneList<Expression*>* args) { ...@@ -2848,8 +2849,9 @@ void FullCodeGenerator::EmitRandomHeapNumber(ZoneList<Expression*>* args) {
__ mov(r0, r4); __ mov(r0, r4);
} else { } else {
__ PrepareCallCFunction(2, r0); __ PrepareCallCFunction(2, r0);
__ ldr(r1, ContextOperand(context_register(), Context::GLOBAL_INDEX));
__ mov(r0, Operand(r4)); __ mov(r0, Operand(r4));
__ mov(r1, Operand(ExternalReference::isolate_address())); __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalContextOffset));
__ CallCFunction( __ CallCFunction(
ExternalReference::fill_heap_number_with_random_function(isolate()), 2); ExternalReference::fill_heap_number_with_random_function(isolate()), 2);
} }
......
...@@ -1227,6 +1227,14 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global, ...@@ -1227,6 +1227,14 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
// Initialize the data slot. // Initialize the data slot.
global_context()->set_data(heap->undefined_value()); global_context()->set_data(heap->undefined_value());
{
// Initialize the random seed slot.
Handle<ByteArray> zeroed_byte_array(
factory->NewByteArray(kRandomStateSize));
global_context()->set_random_seed(*zeroed_byte_array);
memset(zeroed_byte_array->GetDataStartAddress(), 0, kRandomStateSize);
}
} }
......
...@@ -138,7 +138,8 @@ enum BindingFlags { ...@@ -138,7 +138,8 @@ enum BindingFlags {
to_complete_property_descriptor) \ to_complete_property_descriptor) \
V(DERIVED_HAS_TRAP_INDEX, JSFunction, derived_has_trap) \ V(DERIVED_HAS_TRAP_INDEX, JSFunction, derived_has_trap) \
V(DERIVED_GET_TRAP_INDEX, JSFunction, derived_get_trap) \ V(DERIVED_GET_TRAP_INDEX, JSFunction, derived_get_trap) \
V(DERIVED_SET_TRAP_INDEX, JSFunction, derived_set_trap) V(DERIVED_SET_TRAP_INDEX, JSFunction, derived_set_trap) \
V(RANDOM_SEED_INDEX, ByteArray, random_seed)
// JSFunctions are pairs (context, function code), sometimes also called // JSFunctions are pairs (context, function code), sometimes also called
// closures. A Context object is used to represent function contexts and // closures. A Context object is used to represent function contexts and
...@@ -259,6 +260,7 @@ class Context: public FixedArray { ...@@ -259,6 +260,7 @@ class Context: public FixedArray {
DERIVED_HAS_TRAP_INDEX, DERIVED_HAS_TRAP_INDEX,
DERIVED_GET_TRAP_INDEX, DERIVED_GET_TRAP_INDEX,
DERIVED_SET_TRAP_INDEX, DERIVED_SET_TRAP_INDEX,
RANDOM_SEED_INDEX,
// Properties from here are treated as weak references by the full GC. // Properties from here are treated as weak references by the full GC.
// Scavenge treats them as strong references. // Scavenge treats them as strong references.
......
...@@ -230,6 +230,9 @@ const int kPointerSize = sizeof(void*); // NOLINT ...@@ -230,6 +230,9 @@ const int kPointerSize = sizeof(void*); // NOLINT
const int kDoubleSizeLog2 = 3; const int kDoubleSizeLog2 = 3;
// Size of the state of a the random number generator.
const int kRandomStateSize = 2 * kIntSize;
#if V8_HOST_ARCH_64_BIT #if V8_HOST_ARCH_64_BIT
const int kPointerSizeLog2 = 3; const int kPointerSizeLog2 = 3;
const intptr_t kIntptrSignBit = V8_INT64_C(0x8000000000000000); const intptr_t kIntptrSignBit = V8_INT64_C(0x8000000000000000);
......
...@@ -2832,9 +2832,10 @@ void FullCodeGenerator::EmitRandomHeapNumber(ZoneList<Expression*>* args) { ...@@ -2832,9 +2832,10 @@ void FullCodeGenerator::EmitRandomHeapNumber(ZoneList<Expression*>* args) {
__ bind(&heapnumber_allocated); __ bind(&heapnumber_allocated);
__ PrepareCallCFunction(1, ebx); __ PrepareCallCFunction(1, ebx);
__ mov(Operand(esp, 0), Immediate(ExternalReference::isolate_address())); __ mov(eax, ContextOperand(context_register(), Context::GLOBAL_INDEX));
__ CallCFunction(ExternalReference::random_uint32_function(isolate()), __ mov(eax, FieldOperand(eax, GlobalObject::kGlobalContextOffset));
1); __ mov(Operand(esp, 0), eax);
__ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1);
// Convert 32 random bits in eax to 0.(32 random bits) in a double // Convert 32 random bits in eax to 0.(32 random bits) in a double
// by computing: // by computing:
......
...@@ -314,7 +314,6 @@ class HashMap; ...@@ -314,7 +314,6 @@ class HashMap;
V(int, bad_char_shift_table, kUC16AlphabetSize) \ V(int, bad_char_shift_table, kUC16AlphabetSize) \
V(int, good_suffix_shift_table, (kBMMaxShift + 1)) \ V(int, good_suffix_shift_table, (kBMMaxShift + 1)) \
V(int, suffix_table, (kBMMaxShift + 1)) \ V(int, suffix_table, (kBMMaxShift + 1)) \
V(uint32_t, random_seed, 2) \
V(uint32_t, private_random_seed, 2) \ V(uint32_t, private_random_seed, 2) \
ISOLATE_INIT_DEBUG_ARRAY_LIST(V) ISOLATE_INIT_DEBUG_ARRAY_LIST(V)
......
...@@ -2850,7 +2850,8 @@ void FullCodeGenerator::EmitRandomHeapNumber(ZoneList<Expression*>* args) { ...@@ -2850,7 +2850,8 @@ void FullCodeGenerator::EmitRandomHeapNumber(ZoneList<Expression*>* args) {
// ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)). // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)).
if (CpuFeatures::IsSupported(FPU)) { if (CpuFeatures::IsSupported(FPU)) {
__ PrepareCallCFunction(1, a0); __ PrepareCallCFunction(1, a0);
__ li(a0, Operand(ExternalReference::isolate_address())); __ lw(a0, ContextOperand(cp, Context::GLOBAL_INDEX));
__ lw(a0, FieldOperand(a0, GlobalObject::kGlobalContextOffset));
__ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1); __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1);
...@@ -2868,7 +2869,8 @@ void FullCodeGenerator::EmitRandomHeapNumber(ZoneList<Expression*>* args) { ...@@ -2868,7 +2869,8 @@ void FullCodeGenerator::EmitRandomHeapNumber(ZoneList<Expression*>* args) {
} else { } else {
__ PrepareCallCFunction(2, a0); __ PrepareCallCFunction(2, a0);
__ mov(a0, s0); __ mov(a0, s0);
__ li(a1, Operand(ExternalReference::isolate_address())); __ lw(a1, ContextOperand(cp, Context::GLOBAL_INDEX));
__ lw(a1, FieldOperand(a1, GlobalObject::kGlobalContextOffset));
__ CallCFunction( __ CallCFunction(
ExternalReference::fill_heap_number_with_random_function(isolate()), 2); ExternalReference::fill_heap_number_with_random_function(isolate()), 2);
} }
......
...@@ -3517,7 +3517,7 @@ Smi* JSReceiver::GenerateIdentityHash() { ...@@ -3517,7 +3517,7 @@ Smi* JSReceiver::GenerateIdentityHash() {
do { do {
// Generate a random 32-bit hash value but limit range to fit // Generate a random 32-bit hash value but limit range to fit
// within a smi. // within a smi.
hash_value = V8::Random(isolate) & Smi::kMaxValue; hash_value = V8::RandomPrivate(isolate) & Smi::kMaxValue;
attempts++; attempts++;
} while (hash_value == 0 && attempts < 30); } while (hash_value == 0 && attempts < 30);
hash_value = hash_value != 0 ? hash_value : 1; // never return 0 hash_value = hash_value != 0 ? hash_value : 1; // never return 0
......
...@@ -150,9 +150,10 @@ void V8::SetEntropySource(EntropySource source) { ...@@ -150,9 +150,10 @@ void V8::SetEntropySource(EntropySource source) {
// Used by JavaScript APIs // Used by JavaScript APIs
uint32_t V8::Random(Isolate* isolate) { uint32_t V8::Random(Context* context) {
ASSERT(isolate == Isolate::Current()); ASSERT(context->IsGlobalContext());
return random_base(isolate->random_seed()); ByteArray* seed = context->random_seed();
return random_base(reinterpret_cast<uint32_t*>(seed->GetDataStartAddress()));
} }
...@@ -182,8 +183,9 @@ typedef union { ...@@ -182,8 +183,9 @@ typedef union {
} double_int_union; } double_int_union;
Object* V8::FillHeapNumberWithRandom(Object* heap_number, Isolate* isolate) { Object* V8::FillHeapNumberWithRandom(Object* heap_number,
uint64_t random_bits = Random(isolate); Context* context) {
uint64_t random_bits = Random(context);
// Make a double* from address (heap_number + sizeof(double)). // Make a double* from address (heap_number + sizeof(double)).
double_int_union* r = reinterpret_cast<double_int_union*>( double_int_union* r = reinterpret_cast<double_int_union*>(
reinterpret_cast<char*>(heap_number) + reinterpret_cast<char*>(heap_number) +
......
...@@ -96,14 +96,14 @@ class V8 : public AllStatic { ...@@ -96,14 +96,14 @@ class V8 : public AllStatic {
// generation. // generation.
static void SetEntropySource(EntropySource source); static void SetEntropySource(EntropySource source);
// Random number generation support. Not cryptographically safe. // Random number generation support. Not cryptographically safe.
static uint32_t Random(Isolate* isolate); static uint32_t Random(Context* context);
// We use random numbers internally in memory allocation and in the // We use random numbers internally in memory allocation and in the
// compilers for security. In order to prevent information leaks we // compilers for security. In order to prevent information leaks we
// use a separate random state for internal random number // use a separate random state for internal random number
// generation. // generation.
static uint32_t RandomPrivate(Isolate* isolate); static uint32_t RandomPrivate(Isolate* isolate);
static Object* FillHeapNumberWithRandom(Object* heap_number, static Object* FillHeapNumberWithRandom(Object* heap_number,
Isolate* isolate); Context* context);
// Idle notification directly from the API. // Idle notification directly from the API.
static bool IdleNotification(); static bool IdleNotification();
......
...@@ -2706,9 +2706,12 @@ void FullCodeGenerator::EmitRandomHeapNumber(ZoneList<Expression*>* args) { ...@@ -2706,9 +2706,12 @@ void FullCodeGenerator::EmitRandomHeapNumber(ZoneList<Expression*>* args) {
// The fresh HeapNumber is in rbx, which is callee-save on both x64 ABIs. // The fresh HeapNumber is in rbx, which is callee-save on both x64 ABIs.
__ PrepareCallCFunction(1); __ PrepareCallCFunction(1);
#ifdef _WIN64 #ifdef _WIN64
__ LoadAddress(rcx, ExternalReference::isolate_address()); __ movq(rcx, ContextOperand(context_register(), Context::GLOBAL_INDEX));
__ movq(rcx, FieldOperand(rcx, GlobalObject::kGlobalContextOffset));
#else #else
__ LoadAddress(rdi, ExternalReference::isolate_address()); __ movq(rdi, ContextOperand(context_register(), Context::GLOBAL_INDEX));
__ movq(rdi, FieldOperand(rdi, GlobalObject::kGlobalContextOffset));
#endif #endif
__ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1); __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1);
......
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