diff --git a/src/api.cc b/src/api.cc index 0fa6294699..8540dfdec7 100644 --- a/src/api.cc +++ b/src/api.cc @@ -4105,8 +4105,9 @@ Persistent v8::Context::New( } // Leave V8. - if (env.is_null()) + if (env.is_null()) { return Persistent(); + } return Persistent(Utils::ToLocal(env)); } diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc index 7ac6ce9d1e..4ab158fea6 100644 --- a/src/arm/full-codegen-arm.cc +++ b/src/arm/full-codegen-arm.cc @@ -2828,7 +2828,8 @@ void FullCodeGenerator::EmitRandomHeapNumber(ZoneList* args) { // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)). if (CpuFeatures::IsSupported(VFP3)) { __ 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); CpuFeatures::Scope scope(VFP3); @@ -2848,8 +2849,9 @@ void FullCodeGenerator::EmitRandomHeapNumber(ZoneList* args) { __ mov(r0, r4); } else { __ PrepareCallCFunction(2, r0); + __ ldr(r1, ContextOperand(context_register(), Context::GLOBAL_INDEX)); __ mov(r0, Operand(r4)); - __ mov(r1, Operand(ExternalReference::isolate_address())); + __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalContextOffset)); __ CallCFunction( ExternalReference::fill_heap_number_with_random_function(isolate()), 2); } diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc index ffefdc6d93..921c1b6e22 100644 --- a/src/bootstrapper.cc +++ b/src/bootstrapper.cc @@ -1227,6 +1227,14 @@ void Genesis::InitializeGlobal(Handle inner_global, // Initialize the data slot. global_context()->set_data(heap->undefined_value()); + + { + // Initialize the random seed slot. + Handle zeroed_byte_array( + factory->NewByteArray(kRandomStateSize)); + global_context()->set_random_seed(*zeroed_byte_array); + memset(zeroed_byte_array->GetDataStartAddress(), 0, kRandomStateSize); + } } diff --git a/src/contexts.h b/src/contexts.h index fe0e22ef57..db725c36d9 100644 --- a/src/contexts.h +++ b/src/contexts.h @@ -138,7 +138,8 @@ enum BindingFlags { to_complete_property_descriptor) \ V(DERIVED_HAS_TRAP_INDEX, JSFunction, derived_has_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 // closures. A Context object is used to represent function contexts and @@ -259,6 +260,7 @@ class Context: public FixedArray { DERIVED_HAS_TRAP_INDEX, DERIVED_GET_TRAP_INDEX, DERIVED_SET_TRAP_INDEX, + RANDOM_SEED_INDEX, // Properties from here are treated as weak references by the full GC. // Scavenge treats them as strong references. diff --git a/src/globals.h b/src/globals.h index d0c78d6e22..cbe7abdf66 100644 --- a/src/globals.h +++ b/src/globals.h @@ -230,6 +230,9 @@ const int kPointerSize = sizeof(void*); // NOLINT 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 const int kPointerSizeLog2 = 3; const intptr_t kIntptrSignBit = V8_INT64_C(0x8000000000000000); diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc index 8362cbf013..5f92f75fb8 100644 --- a/src/ia32/full-codegen-ia32.cc +++ b/src/ia32/full-codegen-ia32.cc @@ -2832,9 +2832,10 @@ void FullCodeGenerator::EmitRandomHeapNumber(ZoneList* args) { __ bind(&heapnumber_allocated); __ PrepareCallCFunction(1, ebx); - __ mov(Operand(esp, 0), Immediate(ExternalReference::isolate_address())); - __ CallCFunction(ExternalReference::random_uint32_function(isolate()), - 1); + __ mov(eax, ContextOperand(context_register(), Context::GLOBAL_INDEX)); + __ mov(eax, FieldOperand(eax, GlobalObject::kGlobalContextOffset)); + __ 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 // by computing: diff --git a/src/isolate.h b/src/isolate.h index 72b8abf6c6..5453bf249a 100644 --- a/src/isolate.h +++ b/src/isolate.h @@ -314,7 +314,6 @@ class HashMap; V(int, bad_char_shift_table, kUC16AlphabetSize) \ V(int, good_suffix_shift_table, (kBMMaxShift + 1)) \ V(int, suffix_table, (kBMMaxShift + 1)) \ - V(uint32_t, random_seed, 2) \ V(uint32_t, private_random_seed, 2) \ ISOLATE_INIT_DEBUG_ARRAY_LIST(V) diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc index cf54beae83..e39911e951 100644 --- a/src/mips/full-codegen-mips.cc +++ b/src/mips/full-codegen-mips.cc @@ -2850,7 +2850,8 @@ void FullCodeGenerator::EmitRandomHeapNumber(ZoneList* args) { // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)). if (CpuFeatures::IsSupported(FPU)) { __ 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); @@ -2868,7 +2869,8 @@ void FullCodeGenerator::EmitRandomHeapNumber(ZoneList* args) { } else { __ PrepareCallCFunction(2, a0); __ mov(a0, s0); - __ li(a1, Operand(ExternalReference::isolate_address())); + __ lw(a1, ContextOperand(cp, Context::GLOBAL_INDEX)); + __ lw(a1, FieldOperand(a1, GlobalObject::kGlobalContextOffset)); __ CallCFunction( ExternalReference::fill_heap_number_with_random_function(isolate()), 2); } diff --git a/src/objects.cc b/src/objects.cc index 8478f7423a..f007f38729 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -3517,7 +3517,7 @@ Smi* JSReceiver::GenerateIdentityHash() { do { // Generate a random 32-bit hash value but limit range to fit // within a smi. - hash_value = V8::Random(isolate) & Smi::kMaxValue; + hash_value = V8::RandomPrivate(isolate) & Smi::kMaxValue; attempts++; } while (hash_value == 0 && attempts < 30); hash_value = hash_value != 0 ? hash_value : 1; // never return 0 diff --git a/src/v8.cc b/src/v8.cc index a04114e701..f055a8ab07 100644 --- a/src/v8.cc +++ b/src/v8.cc @@ -150,9 +150,10 @@ void V8::SetEntropySource(EntropySource source) { // Used by JavaScript APIs -uint32_t V8::Random(Isolate* isolate) { - ASSERT(isolate == Isolate::Current()); - return random_base(isolate->random_seed()); +uint32_t V8::Random(Context* context) { + ASSERT(context->IsGlobalContext()); + ByteArray* seed = context->random_seed(); + return random_base(reinterpret_cast(seed->GetDataStartAddress())); } @@ -182,8 +183,9 @@ typedef union { } double_int_union; -Object* V8::FillHeapNumberWithRandom(Object* heap_number, Isolate* isolate) { - uint64_t random_bits = Random(isolate); +Object* V8::FillHeapNumberWithRandom(Object* heap_number, + Context* context) { + uint64_t random_bits = Random(context); // Make a double* from address (heap_number + sizeof(double)). double_int_union* r = reinterpret_cast( reinterpret_cast(heap_number) + diff --git a/src/v8.h b/src/v8.h index 2e039d429f..01feefce6f 100644 --- a/src/v8.h +++ b/src/v8.h @@ -96,14 +96,14 @@ class V8 : public AllStatic { // generation. static void SetEntropySource(EntropySource source); // 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 // compilers for security. In order to prevent information leaks we // use a separate random state for internal random number // generation. static uint32_t RandomPrivate(Isolate* isolate); static Object* FillHeapNumberWithRandom(Object* heap_number, - Isolate* isolate); + Context* context); // Idle notification directly from the API. static bool IdleNotification(); diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc index 7ddb8b8c16..8e8962c9f5 100644 --- a/src/x64/full-codegen-x64.cc +++ b/src/x64/full-codegen-x64.cc @@ -2706,9 +2706,12 @@ void FullCodeGenerator::EmitRandomHeapNumber(ZoneList* args) { // The fresh HeapNumber is in rbx, which is callee-save on both x64 ABIs. __ PrepareCallCFunction(1); #ifdef _WIN64 - __ LoadAddress(rcx, ExternalReference::isolate_address()); + __ movq(rcx, ContextOperand(context_register(), Context::GLOBAL_INDEX)); + __ movq(rcx, FieldOperand(rcx, GlobalObject::kGlobalContextOffset)); + #else - __ LoadAddress(rdi, ExternalReference::isolate_address()); + __ movq(rdi, ContextOperand(context_register(), Context::GLOBAL_INDEX)); + __ movq(rdi, FieldOperand(rdi, GlobalObject::kGlobalContextOffset)); #endif __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1);