Index: src/ia32/stub-cache-ia32.cc |
=================================================================== |
--- src/ia32/stub-cache-ia32.cc (revision 11183) |
+++ src/ia32/stub-cache-ia32.cc (working copy) |
@@ -3367,14 +3367,14 @@ |
// it to a HeapNumber. |
Label box_int; |
if (elements_kind == EXTERNAL_INT_ELEMENTS) { |
- __ cmp(ecx, 0xC0000000); |
+ __ cmp(ecx, 0xc0000000); |
__ j(sign, &box_int); |
} else { |
ASSERT_EQ(EXTERNAL_UNSIGNED_INT_ELEMENTS, elements_kind); |
// The test is different for unsigned int values. Since we need |
// the value to be in the range of a positive smi, we can't |
// handle either of the top two bits being set in the value. |
- __ test(ecx, Immediate(0xC0000000)); |
+ __ test(ecx, Immediate(0xc0000000)); |
__ j(not_zero, &box_int); |
} |
@@ -3653,6 +3653,39 @@ |
} |
+static void GenerateSmiAsHeapNumberCheck(MacroAssembler* masm, |
Jakob Kummerow
2012/03/29 11:38:45
"Smi as HeapNumber" sounds like a Smi->HeapNumber
|
+ Register key, |
+ Register scratch, |
+ XMMRegister xmm_scratch0, |
+ XMMRegister xmm_scratch1, |
+ Label* fail) { |
+ // Check that key is a smi or if SSE2 in available a heap number |
Jakob Kummerow
2012/03/29 11:38:45
nit: s/in/is/
|
+ // containing a smi and branch if the check fails. |
+ if (CpuFeatures::IsSupported(SSE2)) { |
+ CpuFeatures::Scope use_sse2(SSE2); |
+ Label key_ok; |
+ __ JumpIfSmi(key, &key_ok); |
+ __ cmp(FieldOperand(key, HeapObject::kMapOffset), |
+ Immediate(Handle<Map>(masm->isolate()->heap()->heap_number_map()))); |
+ __ j(not_equal, fail); |
+ __ movdbl(xmm_scratch0, FieldOperand(key, HeapNumber::kValueOffset)); |
+ __ cvttsd2si(scratch, Operand(xmm_scratch0)); |
+ __ cvtsi2sd(xmm_scratch1, scratch); |
+ __ ucomisd(xmm_scratch1, xmm_scratch0); |
+ __ j(not_equal, fail); |
+ __ j(parity_even, fail); // NaN. |
+ // Check if the key fits in the smi range. |
+ __ cmp(scratch, 0xc0000000); |
+ __ j(sign, fail); |
+ __ SmiTag(scratch); |
+ __ mov(key, scratch); |
+ __ bind(&key_ok); |
+ } else { |
+ __ JumpIfNotSmi(eax, fail); |
+ } |
+} |
+ |
+ |
void KeyedLoadStubCompiler::GenerateLoadFastElement(MacroAssembler* masm) { |
// ----------- S t a t e ------------- |
// -- eax : key |
@@ -3664,8 +3697,8 @@ |
// This stub is meant to be tail-jumped to, the receiver must already |
// have been verified by the caller to not be a smi. |
- // Check that the key is a smi. |
- __ JumpIfNotSmi(eax, &miss_force_generic); |
+ // Check that the key is a smi or a heap number convertible to a smi. |
+ GenerateSmiAsHeapNumberCheck(masm, eax, ecx, xmm0, xmm1, &miss_force_generic); |
// Get the elements array. |
__ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset)); |
@@ -3771,8 +3804,8 @@ |
// This stub is meant to be tail-jumped to, the receiver must already |
// have been verified by the caller to not be a smi. |
- // Check that the key is a smi. |
- __ JumpIfNotSmi(ecx, &miss_force_generic); |
+ // Check that the key is a smi or a heap number convertible to a smi. |
+ GenerateSmiAsHeapNumberCheck(masm, ecx, ebx, xmm0, xmm1, &miss_force_generic); |
if (elements_kind == FAST_SMI_ONLY_ELEMENTS) { |
__ JumpIfNotSmi(eax, &transition_elements_kind); |