Revision: 4354
Author: [email protected]
Date: Wed Apr  7 01:18:51 2010
Log: Change Math.random() to return 32 bits of random goodness, instead of 30 random bits. Math.random now allocates a HeapNumber inline, and calls a C funciton directly to put the random bits into it.
Review URL: http://codereview.chromium.org/1599019
http://code.google.com/p/v8/source/detail?r=4354

Modified:
 /branches/bleeding_edge/src/arm/codegen-arm.cc
 /branches/bleeding_edge/src/arm/codegen-arm.h
 /branches/bleeding_edge/src/assembler.cc
 /branches/bleeding_edge/src/assembler.h
 /branches/bleeding_edge/src/codegen.h
 /branches/bleeding_edge/src/ia32/codegen-ia32.cc
 /branches/bleeding_edge/src/ia32/codegen-ia32.h
 /branches/bleeding_edge/src/math.js
 /branches/bleeding_edge/src/mips/codegen-mips.cc
 /branches/bleeding_edge/src/mips/codegen-mips.h
 /branches/bleeding_edge/src/serialize.cc
 /branches/bleeding_edge/src/v8.cc
 /branches/bleeding_edge/src/v8.h
 /branches/bleeding_edge/src/x64/codegen-x64.cc
 /branches/bleeding_edge/src/x64/codegen-x64.h
 /branches/bleeding_edge/test/cctest/test-log-stack-tracer.cc

=======================================
--- /branches/bleeding_edge/src/arm/codegen-arm.cc      Tue Mar 30 06:55:03 2010
+++ /branches/bleeding_edge/src/arm/codegen-arm.cc      Wed Apr  7 01:18:51 2010
@@ -3624,10 +3624,24 @@
 }


-void CodeGenerator::GenerateRandomPositiveSmi(ZoneList<Expression*>* args) {
+void CodeGenerator::GenerateRandomHeapNumber(
+    ZoneList<Expression*>* args) {
   VirtualFrame::SpilledScope spilled_scope;
   ASSERT(args->length() == 0);
-  __ Call(ExternalReference::random_positive_smi_function().address(),
+
+  Label slow_allocate_heapnumber;
+  Label heapnumber_allocated;
+
+  __ AllocateHeapNumber(r0, r1, r2, &slow_allocate_heapnumber);
+  __ jmp(&heapnumber_allocated);
+
+  __ bind(&slow_allocate_heapnumber);
+  __ mov(r0, Operand(Smi::FromInt(0)));
+  __ push(r0);
+  __ CallRuntime(Runtime::kNumberUnaryMinus, 1);
+
+  __ bind(&heapnumber_allocated);
+ __ Call(ExternalReference::fill_heap_number_with_random_function().address(),
           RelocInfo::RUNTIME_ENTRY);
   frame_->EmitPush(r0);
 }
=======================================
--- /branches/bleeding_edge/src/arm/codegen-arm.h       Fri Mar 26 00:55:38 2010
+++ /branches/bleeding_edge/src/arm/codegen-arm.h       Wed Apr  7 01:18:51 2010
@@ -387,7 +387,7 @@
   void GenerateLog(ZoneList<Expression*>* args);

   // Fast support for Math.random().
-  void GenerateRandomPositiveSmi(ZoneList<Expression*>* args);
+  void GenerateRandomHeapNumber(ZoneList<Expression*>* args);

   // Fast support for StringAdd.
   void GenerateStringAdd(ZoneList<Expression*>* args);
=======================================
--- /branches/bleeding_edge/src/assembler.cc    Tue Mar 23 07:33:42 2010
+++ /branches/bleeding_edge/src/assembler.cc    Wed Apr  7 01:18:51 2010
@@ -574,8 +574,9 @@
 }


-ExternalReference ExternalReference::random_positive_smi_function() {
-  return ExternalReference(Redirect(FUNCTION_ADDR(V8::RandomPositiveSmi)));
+ExternalReference ExternalReference::fill_heap_number_with_random_function() {
+  return
+ ExternalReference(Redirect(FUNCTION_ADDR(V8::FillHeapNumberWithRandom)));
 }


=======================================
--- /branches/bleeding_edge/src/assembler.h     Tue Mar 23 07:33:42 2010
+++ /branches/bleeding_edge/src/assembler.h     Wed Apr  7 01:18:51 2010
@@ -398,7 +398,7 @@
   // ExternalReferenceTable in serialize.cc manually.

   static ExternalReference perform_gc_function();
-  static ExternalReference random_positive_smi_function();
+  static ExternalReference fill_heap_number_with_random_function();
   static ExternalReference transcendental_cache_array_address();

   // Static data in the keyed lookup cache.
=======================================
--- /branches/bleeding_edge/src/codegen.h       Tue Mar 30 06:55:03 2010
+++ /branches/bleeding_edge/src/codegen.h       Wed Apr  7 01:18:51 2010
@@ -114,7 +114,7 @@
F(CharFromCode, 1, 1) \ F(ObjectEquals, 2, 1) \ F(Log, 3, 1) \ - F(RandomPositiveSmi, 0, 1) \
+  F(RandomHeapNumber, 0, 1)                                          \
F(IsObject, 1, 1) \ F(IsFunction, 1, 1) \ F(IsUndetectableObject, 1, 1) \
=======================================
--- /branches/bleeding_edge/src/ia32/codegen-ia32.cc Tue Apr 6 02:27:09 2010 +++ /branches/bleeding_edge/src/ia32/codegen-ia32.cc Wed Apr 7 01:18:51 2010
@@ -6430,16 +6430,30 @@
 }


-void CodeGenerator::GenerateRandomPositiveSmi(ZoneList<Expression*>* args) {
+void CodeGenerator::GenerateRandomHeapNumber(
+    ZoneList<Expression*>* args) {
   ASSERT(args->length() == 0);
   frame_->SpillAll();

-  static const int num_arguments = 0;
-  __ PrepareCallCFunction(num_arguments, eax);
-
-  // Call V8::RandomPositiveSmi().
-  __ CallCFunction(ExternalReference::random_positive_smi_function(),
-                   num_arguments);
+  Label slow_allocate_heapnumber;
+  Label heapnumber_allocated;
+
+  __ AllocateHeapNumber(eax, ebx, ecx, &slow_allocate_heapnumber);
+  __ jmp(&heapnumber_allocated);
+
+  __ bind(&slow_allocate_heapnumber);
+  // To allocate a heap number, and ensure that it is not a smi, we
+  // call the runtime function FUnaryMinus on 0, returning the double
+  // -0.0.  A new, distinct heap number is returned each time.
+  __ push(Immediate(Smi::FromInt(0)));
+  __ CallRuntime(Runtime::kNumberUnaryMinus, 1);
+
+  __ bind(&heapnumber_allocated);
+
+  __ PrepareCallCFunction(1, ebx);
+  __ mov(Operand(esp, 0), eax);
+ __ CallCFunction(ExternalReference::fill_heap_number_with_random_function(),
+                   1);

   Result result = allocator_->Allocate(eax);
   frame_->Push(&result);
=======================================
--- /branches/bleeding_edge/src/ia32/codegen-ia32.h     Tue Mar 30 05:12:31 2010
+++ /branches/bleeding_edge/src/ia32/codegen-ia32.h     Wed Apr  7 01:18:51 2010
@@ -614,7 +614,7 @@
   void GenerateGetFramePointer(ZoneList<Expression*>* args);

   // Fast support for Math.random().
-  void GenerateRandomPositiveSmi(ZoneList<Expression*>* args);
+  void GenerateRandomHeapNumber(ZoneList<Expression*>* args);

   // Fast support for StringAdd.
   void GenerateStringAdd(ZoneList<Expression*>* args);
=======================================
--- /branches/bleeding_edge/src/math.js Thu Mar 18 06:00:57 2010
+++ /branches/bleeding_edge/src/math.js Wed Apr  7 01:18:51 2010
@@ -165,7 +165,7 @@

 // ECMA 262 - 15.8.2.14
 function MathRandom() {
-  return %_RandomPositiveSmi() / 0x40000000;
+  return %_RandomHeapNumber();
 }

 // ECMA 262 - 15.8.2.15
=======================================
--- /branches/bleeding_edge/src/mips/codegen-mips.cc Tue Mar 23 08:04:45 2010 +++ /branches/bleeding_edge/src/mips/codegen-mips.cc Wed Apr 7 01:18:51 2010
@@ -890,7 +890,7 @@
 }


-void CodeGenerator::GenerateRandomPositiveSmi(ZoneList<Expression*>* args) {
+void CodeGenerator::GenerateRandomHeapNumber(ZoneList<Expression*>* args) {
   UNIMPLEMENTED_MIPS();
 }

=======================================
--- /branches/bleeding_edge/src/mips/codegen-mips.h     Tue Mar 23 08:04:45 2010
+++ /branches/bleeding_edge/src/mips/codegen-mips.h     Wed Apr  7 01:18:51 2010
@@ -352,7 +352,7 @@
   void GenerateLog(ZoneList<Expression*>* args);

   // Fast support for Math.random().
-  void GenerateRandomPositiveSmi(ZoneList<Expression*>* args);
+  void GenerateRandomHeapNumber(ZoneList<Expression*>* args);

   void GenerateIsObject(ZoneList<Expression*>* args);
   void GenerateIsFunction(ZoneList<Expression*>* args);
=======================================
--- /branches/bleeding_edge/src/serialize.cc    Tue Mar 23 07:33:42 2010
+++ /branches/bleeding_edge/src/serialize.cc    Wed Apr  7 01:18:51 2010
@@ -329,10 +329,10 @@
       RUNTIME_ENTRY,
       1,
       "Runtime::PerformGC");
-  Add(ExternalReference::random_positive_smi_function().address(),
+  Add(ExternalReference::fill_heap_number_with_random_function().address(),
       RUNTIME_ENTRY,
       2,
-      "V8::RandomPositiveSmi");
+      "V8::FillHeapNumberWithRandom");

   // Miscellaneous
   Add(ExternalReference::the_hole_value_location().address(),
=======================================
--- /branches/bleeding_edge/src/v8.cc   Tue Apr  6 03:36:38 2010
+++ /branches/bleeding_edge/src/v8.cc   Wed Apr  7 01:18:51 2010
@@ -208,14 +208,27 @@
   return Heap::IdleNotification();
 }

-static const uint32_t kRandomPositiveSmiMax = 0x3fffffff;
-
-Smi* V8::RandomPositiveSmi() {
-  uint32_t random = Random();
-  ASSERT(static_cast<uint32_t>(Smi::kMaxValue) >= kRandomPositiveSmiMax);
-  // kRandomPositiveSmiMax must match the value being divided
-  // by in math.js.
-  return Smi::FromInt(random & kRandomPositiveSmiMax);
+
+// Use a union type to avoid type-aliasing optimizations in GCC.
+typedef union {
+  double double_value;
+  uint64_t uint64_t_value;
+} double_int_union;
+
+
+Object* V8::FillHeapNumberWithRandom(Object* heap_number) {
+  uint64_t random_bits = Random();
+  // Make a double* from address (heap_number + sizeof(double)).
+  double_int_union* r = reinterpret_cast<double_int_union*>(
+      reinterpret_cast<char*>(heap_number) +
+      HeapNumber::kValueOffset - kHeapObjectTag);
+  // Create a random number between 0.0 and 1.0 by putting random bits into
+  // the mantissa of 1.0 and subtracting 1.0.
+  r->double_value = 1.0;
+  r->uint64_t_value |= (random_bits << 20);
+  r->double_value -= 1.0;  // Force into the range [0.0, 1.0).
+
+  return heap_number;
 }

 } }  // namespace v8::internal
=======================================
--- /branches/bleeding_edge/src/v8.h    Tue Apr  6 03:36:38 2010
+++ /branches/bleeding_edge/src/v8.h    Wed Apr  7 01:18:51 2010
@@ -95,7 +95,7 @@

   // Random number generation support. Not cryptographically safe.
   static uint32_t Random();
-  static Smi* RandomPositiveSmi();
+  static Object* FillHeapNumberWithRandom(Object* heap_number);

   // Idle notification directly from the API.
   static bool IdleNotification();
=======================================
--- /branches/bleeding_edge/src/x64/codegen-x64.cc      Tue Mar 30 06:55:03 2010
+++ /branches/bleeding_edge/src/x64/codegen-x64.cc      Wed Apr  7 01:18:51 2010
@@ -4074,19 +4074,41 @@
 }


-void CodeGenerator::GenerateRandomPositiveSmi(ZoneList<Expression*>* args) {
+void CodeGenerator::GenerateRandomHeapNumber(
+    ZoneList<Expression*>* args) {
   ASSERT(args->length() == 0);
   frame_->SpillAll();
-  __ push(rsi);
-
-  static const int num_arguments = 0;
-  __ PrepareCallCFunction(num_arguments);
-
-  // Call V8::RandomPositiveSmi().
-  __ CallCFunction(ExternalReference::random_positive_smi_function(),
-                   num_arguments);
-
+
+  Label slow_allocate_heapnumber;
+  Label heapnumber_allocated;
+  __ AllocateHeapNumber(rdi, rbx, &slow_allocate_heapnumber);
+  __ jmp(&heapnumber_allocated);
+
+  __ bind(&slow_allocate_heapnumber);
+  // To allocate a heap number, and ensure that it is not a smi, we
+  // call the runtime function FUnaryMinus on 0, returning the double
+  // -0.0.  A new, distinct heap number is returned each time.
+  __ Push(Smi::FromInt(0));
+  __ CallRuntime(Runtime::kNumberUnaryMinus, 1);
+  __ movq(rdi, rax);
+
+  __ bind(&heapnumber_allocated);
+
+  // Put a random number into the heap number rdi using a C++ function.
+  // Return the heap number in rax.
+#ifdef _WIN64
+  __ movq(rcx, rdi);
+#else
+  // Callee-save in Microsoft 64-bit ABI, but not in AMD64 ABI.
+  __ push(rsi);
+#endif
+  __ PrepareCallCFunction(1);
+ __ CallCFunction(ExternalReference::fill_heap_number_with_random_function(),
+                   1);
+#ifndef _WIN64
+  // Callee-save in Microsoft 64-bit ABI, but not in AMD64 ABI.
   __ pop(rsi);
+#endif
   Result result = allocator_->Allocate(rax);
   frame_->Push(&result);
 }
=======================================
--- /branches/bleeding_edge/src/x64/codegen-x64.h       Fri Mar 26 00:55:38 2010
+++ /branches/bleeding_edge/src/x64/codegen-x64.h       Wed Apr  7 01:18:51 2010
@@ -568,7 +568,7 @@
   void GenerateGetFramePointer(ZoneList<Expression*>* args);

   // Fast support for Math.random().
-  void GenerateRandomPositiveSmi(ZoneList<Expression*>* args);
+  void GenerateRandomHeapNumber(ZoneList<Expression*>* args);

   // Fast support for StringAdd.
   void GenerateStringAdd(ZoneList<Expression*>* args);
=======================================
--- /branches/bleeding_edge/test/cctest/test-log-stack-tracer.cc Wed Mar 24 01:46:17 2010 +++ /branches/bleeding_edge/test/cctest/test-log-stack-tracer.cc Wed Apr 7 01:18:51 2010
@@ -235,11 +235,11 @@
   CodeGeneratorPatcher() {
     CodeGenerator::InlineRuntimeLUT genGetFramePointer =
         {&CodeGenerator::GenerateGetFramePointer, "_GetFramePointer", 0};
- // _RandomPositiveSmi is not used in our tests. The one we replace need to - // have the same number of arguments as the one we put in, which is zero in
-    // this case.
+    // _RandomHeapNumber is just used as a dummy function that has zero
+ // arguments, the same as the _GetFramePointer function we actually patch
+    // in.
     bool result = CodeGenerator::PatchInlineRuntimeEntry(
-        NewString("_RandomPositiveSmi"),
+        NewString("_RandomHeapNumber"),
         genGetFramePointer, &oldInlineEntry);
     CHECK(result);
   }

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

To unsubscribe, reply using "remove me" as the subject.

Reply via email to