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.