Index: src/arm/codegen-arm.cc |
=================================================================== |
--- src/arm/codegen-arm.cc (revision 4476) |
+++ src/arm/codegen-arm.cc (working copy) |
@@ -4232,19 +4232,49 @@ |
Label slow_allocate_heapnumber; |
Label heapnumber_allocated; |
- __ AllocateHeapNumber(r0, r1, r2, &slow_allocate_heapnumber); |
+ __ AllocateHeapNumber(r4, r1, r2, &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. |
__ mov(r0, Operand(Smi::FromInt(0))); |
__ push(r0); |
__ CallRuntime(Runtime::kNumberUnaryMinus, 1); |
Lasse Reichstein
2010/04/23 12:12:50
It seems fragile to use a function meant for somet
|
+ __ mov(r4, Operand(r0)); |
__ bind(&heapnumber_allocated); |
- __ PrepareCallCFunction(1, r1); |
- __ CallCFunction( |
- ExternalReference::fill_heap_number_with_random_function(), 1); |
- frame_->EmitPush(r0); |
+ |
+ // Convert 32 random bits in r0 to 0.(32 random bits) in a double |
+ // by computing: |
+ // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)). |
+ if (CpuFeatures::IsSupported(VFP3)) { |
+ __ PrepareCallCFunction(0, r1); |
+ __ CallCFunction(ExternalReference::random_uint32_function(), 0); |
+ |
+ CpuFeatures::Scope scope(VFP3); |
+ // 0x41300000 is the top half of 1.0 x 2^20 as a double. |
+ // Create this constant using mov/orr to avoid PC relative load. |
+ __ mov(r1, Operand(0x41000000)); |
+ __ orr(r1, r1, Operand(0x300000)); |
+ // Move 0x41300000xxxxxxxx (x = random bits) to VFP. |
+ __ vmov(d7, r0, r1); |
+ // Move 0x4130000000000000 to VFP. |
+ __ mov(r0, Operand(0)); |
+ __ vmov(d8, r0, r1); |
+ // Subtract and store the result in the heap number. |
+ __ vsub(d7, d7, d8); |
+ __ sub(r0, r4, Operand(kHeapObjectTag)); |
+ __ vstr(d7, r0, HeapNumber::kValueOffset); |
+ frame_->EmitPush(r4); |
+ } else { |
+ __ mov(r0, Operand(r4)); |
+ __ PrepareCallCFunction(1, r1); |
+ __ CallCFunction( |
+ ExternalReference::fill_heap_number_with_random_function(), 1); |
+ frame_->EmitPush(r0); |
+ } |
} |