| Index: src/ia32/stub-cache-ia32.cc
|
| ===================================================================
|
| --- src/ia32/stub-cache-ia32.cc (revision 11183)
|
| +++ src/ia32/stub-cache-ia32.cc (working copy)
|
| @@ -3301,6 +3301,39 @@
|
| }
|
|
|
|
|
| +static void GenerateSmiKeyCheck(MacroAssembler* masm,
|
| + Register key,
|
| + Register scratch,
|
| + XMMRegister xmm_scratch0,
|
| + XMMRegister xmm_scratch1,
|
| + Label* fail) {
|
| + // Check that key is a smi and if SSE2 is available a heap number
|
| + // 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(key, fail);
|
| + }
|
| +}
|
| +
|
| +
|
| void KeyedLoadStubCompiler::GenerateLoadExternalArray(
|
| MacroAssembler* masm,
|
| ElementsKind elements_kind) {
|
| @@ -3314,8 +3347,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.
|
| + GenerateSmiKeyCheck(masm, eax, ecx, xmm0, xmm1, &miss_force_generic);
|
|
|
| // Check that the index is in range.
|
| __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
|
| @@ -3367,14 +3400,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);
|
| }
|
|
|
| @@ -3459,7 +3492,8 @@
|
| MacroAssembler* masm,
|
| ElementsKind elements_kind) {
|
| // ----------- S t a t e -------------
|
| - // -- eax : key
|
| + // -- eax : value
|
| + // -- ecx : key
|
| // -- edx : receiver
|
| // -- esp[0] : return address
|
| // -----------------------------------
|
| @@ -3468,8 +3502,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.
|
| + GenerateSmiKeyCheck(masm, ecx, ebx, xmm0, xmm1, &miss_force_generic);
|
|
|
| // Check that the index is in range.
|
| __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
|
| @@ -3664,8 +3698,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.
|
| + GenerateSmiKeyCheck(masm, eax, ecx, xmm0, xmm1, &miss_force_generic);
|
|
|
| // Get the elements array.
|
| __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset));
|
| @@ -3702,8 +3736,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.
|
| + GenerateSmiKeyCheck(masm, eax, ecx, xmm0, xmm1, &miss_force_generic);
|
|
|
| // Get the elements array.
|
| __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset));
|
| @@ -3771,8 +3805,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.
|
| + GenerateSmiKeyCheck(masm, ecx, ebx, xmm0, xmm1, &miss_force_generic);
|
|
|
| if (elements_kind == FAST_SMI_ONLY_ELEMENTS) {
|
| __ JumpIfNotSmi(eax, &transition_elements_kind);
|
| @@ -3926,8 +3960,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.
|
| + GenerateSmiKeyCheck(masm, ecx, ebx, xmm0, xmm1, &miss_force_generic);
|
|
|
| // Get the elements array.
|
| __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
|
|
|