| Index: src/ia32/stub-cache-ia32.cc
|
| diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc
|
| index 127d16aab475c3e61bb89b5f14720f3d49d5ba33..2da0f43f7236bc60aabd5e4cb035141898a78e6f 100644
|
| --- a/src/ia32/stub-cache-ia32.cc
|
| +++ b/src/ia32/stub-cache-ia32.cc
|
| @@ -3366,9 +3366,17 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadElement(
|
| // -----------------------------------
|
|
|
| ElementsKind elements_kind = receiver_map->elements_kind();
|
| - Handle<Code> stub = KeyedLoadElementStub(elements_kind).GetCode();
|
| -
|
| - __ DispatchMap(edx, receiver_map, stub, DO_SMI_CHECK);
|
| + if (receiver_map->has_fast_elements() ||
|
| + receiver_map->has_external_array_elements()) {
|
| + Handle<Code> stub = KeyedLoadFastElementStub(
|
| + receiver_map->instance_type() == JS_ARRAY_TYPE,
|
| + elements_kind).GetCode();
|
| + __ DispatchMap(edx, receiver_map, stub, DO_SMI_CHECK);
|
| + } else {
|
| + Handle<Code> stub =
|
| + KeyedLoadDictionaryElementStub().GetCode();
|
| + __ DispatchMap(edx, receiver_map, stub, DO_SMI_CHECK);
|
| + }
|
|
|
| GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
|
|
|
| @@ -3629,157 +3637,6 @@ static void GenerateSmiKeyCheck(MacroAssembler* masm,
|
| }
|
|
|
|
|
| -void KeyedLoadStubCompiler::GenerateLoadExternalArray(
|
| - MacroAssembler* masm,
|
| - ElementsKind elements_kind) {
|
| - // ----------- S t a t e -------------
|
| - // -- ecx : key
|
| - // -- edx : receiver
|
| - // -- esp[0] : return address
|
| - // -----------------------------------
|
| - Label miss_force_generic, failed_allocation, slow;
|
| -
|
| - // 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 or a heap number convertible to a smi.
|
| - GenerateSmiKeyCheck(masm, ecx, eax, xmm0, xmm1, &miss_force_generic);
|
| -
|
| - // Check that the index is in range.
|
| - __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
|
| - __ cmp(ecx, FieldOperand(ebx, ExternalArray::kLengthOffset));
|
| - // Unsigned comparison catches both negative and too-large values.
|
| - __ j(above_equal, &miss_force_generic);
|
| - __ mov(ebx, FieldOperand(ebx, ExternalArray::kExternalPointerOffset));
|
| - // ebx: base pointer of external storage
|
| - switch (elements_kind) {
|
| - case EXTERNAL_BYTE_ELEMENTS:
|
| - __ SmiUntag(ecx); // Untag the index.
|
| - __ movsx_b(eax, Operand(ebx, ecx, times_1, 0));
|
| - break;
|
| - case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
|
| - case EXTERNAL_PIXEL_ELEMENTS:
|
| - __ SmiUntag(ecx); // Untag the index.
|
| - __ movzx_b(eax, Operand(ebx, ecx, times_1, 0));
|
| - break;
|
| - case EXTERNAL_SHORT_ELEMENTS:
|
| - __ movsx_w(eax, Operand(ebx, ecx, times_1, 0));
|
| - break;
|
| - case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
|
| - __ movzx_w(eax, Operand(ebx, ecx, times_1, 0));
|
| - break;
|
| - case EXTERNAL_UNSIGNED_INT_ELEMENTS:
|
| - case EXTERNAL_INT_ELEMENTS:
|
| - __ mov(eax, Operand(ebx, ecx, times_2, 0));
|
| - break;
|
| - case EXTERNAL_FLOAT_ELEMENTS:
|
| - __ fld_s(Operand(ebx, ecx, times_2, 0));
|
| - break;
|
| - case EXTERNAL_DOUBLE_ELEMENTS:
|
| - __ fld_d(Operand(ebx, ecx, times_4, 0));
|
| - break;
|
| - default:
|
| - UNREACHABLE();
|
| - break;
|
| - }
|
| -
|
| - // For integer array types:
|
| - // eax: value
|
| - // For floating-point array type:
|
| - // FP(0): value
|
| -
|
| - if (elements_kind == EXTERNAL_INT_ELEMENTS ||
|
| - elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) {
|
| - // For the Int and UnsignedInt array types, we need to see whether
|
| - // the value can be represented in a Smi. If not, we need to convert
|
| - // it to a HeapNumber.
|
| - Label box_int;
|
| - if (elements_kind == EXTERNAL_INT_ELEMENTS) {
|
| - __ cmp(eax, 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(eax, Immediate(0xc0000000));
|
| - __ j(not_zero, &box_int);
|
| - }
|
| -
|
| - __ SmiTag(eax);
|
| - __ ret(0);
|
| -
|
| - __ bind(&box_int);
|
| -
|
| - // Allocate a HeapNumber for the int and perform int-to-double
|
| - // conversion.
|
| - if (elements_kind == EXTERNAL_INT_ELEMENTS) {
|
| - __ push(eax);
|
| - __ fild_s(Operand(esp, 0));
|
| - __ pop(eax);
|
| - } else {
|
| - ASSERT_EQ(EXTERNAL_UNSIGNED_INT_ELEMENTS, elements_kind);
|
| - // Need to zero-extend the value.
|
| - // There's no fild variant for unsigned values, so zero-extend
|
| - // to a 64-bit int manually.
|
| - __ push(Immediate(0));
|
| - __ push(eax);
|
| - __ fild_d(Operand(esp, 0));
|
| - __ pop(eax);
|
| - __ pop(eax);
|
| - }
|
| - // FP(0): value
|
| - __ AllocateHeapNumber(eax, ebx, edi, &failed_allocation);
|
| - // Set the value.
|
| - __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
|
| - __ ret(0);
|
| - } else if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
|
| - elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
|
| - // For the floating-point array type, we need to always allocate a
|
| - // HeapNumber.
|
| - __ AllocateHeapNumber(eax, ebx, edi, &failed_allocation);
|
| - // Set the value.
|
| - __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
|
| - __ ret(0);
|
| - } else {
|
| - __ SmiTag(eax);
|
| - __ ret(0);
|
| - }
|
| -
|
| - // If we fail allocation of the HeapNumber, we still have a value on
|
| - // top of the FPU stack. Remove it.
|
| - __ bind(&failed_allocation);
|
| - __ fstp(0);
|
| - // Fall through to slow case.
|
| -
|
| - // Slow case: Jump to runtime.
|
| - __ bind(&slow);
|
| - Counters* counters = masm->isolate()->counters();
|
| - __ IncrementCounter(counters->keyed_load_external_array_slow(), 1);
|
| -
|
| - // ----------- S t a t e -------------
|
| - // -- ecx : key
|
| - // -- edx : receiver
|
| - // -- esp[0] : return address
|
| - // -----------------------------------
|
| -
|
| - Handle<Code> ic = masm->isolate()->builtins()->KeyedLoadIC_Slow();
|
| - __ jmp(ic, RelocInfo::CODE_TARGET);
|
| -
|
| - // ----------- S t a t e -------------
|
| - // -- ecx : key
|
| - // -- edx : receiver
|
| - // -- esp[0] : return address
|
| - // -----------------------------------
|
| -
|
| - // Miss case: Jump to runtime.
|
| - __ bind(&miss_force_generic);
|
| - Handle<Code> miss_ic =
|
| - masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
|
| - __ jmp(miss_ic, RelocInfo::CODE_TARGET);
|
| -}
|
| -
|
| -
|
| void KeyedStoreStubCompiler::GenerateStoreExternalArray(
|
| MacroAssembler* masm,
|
| ElementsKind elements_kind) {
|
| @@ -3979,106 +3836,6 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray(
|
| }
|
|
|
|
|
| -void KeyedLoadStubCompiler::GenerateLoadFastElement(MacroAssembler* masm) {
|
| - // ----------- S t a t e -------------
|
| - // -- ecx : key
|
| - // -- edx : receiver
|
| - // -- esp[0] : return address
|
| - // -----------------------------------
|
| - Label miss_force_generic;
|
| -
|
| - // 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 or a heap number convertible to a smi.
|
| - GenerateSmiKeyCheck(masm, ecx, eax, xmm0, xmm1, &miss_force_generic);
|
| -
|
| - // Get the elements array.
|
| - __ mov(eax, FieldOperand(edx, JSObject::kElementsOffset));
|
| - __ AssertFastElements(eax);
|
| -
|
| - // Check that the key is within bounds.
|
| - __ cmp(ecx, FieldOperand(eax, FixedArray::kLengthOffset));
|
| - __ j(above_equal, &miss_force_generic);
|
| -
|
| - // Load the result and make sure it's not the hole.
|
| - __ mov(ebx, Operand(eax, ecx, times_2,
|
| - FixedArray::kHeaderSize - kHeapObjectTag));
|
| - __ cmp(ebx, masm->isolate()->factory()->the_hole_value());
|
| - __ j(equal, &miss_force_generic);
|
| - __ mov(eax, ebx);
|
| - __ ret(0);
|
| -
|
| - __ bind(&miss_force_generic);
|
| - Handle<Code> miss_ic =
|
| - masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
|
| - __ jmp(miss_ic, RelocInfo::CODE_TARGET);
|
| -}
|
| -
|
| -
|
| -void KeyedLoadStubCompiler::GenerateLoadFastDoubleElement(
|
| - MacroAssembler* masm) {
|
| - // ----------- S t a t e -------------
|
| - // -- ecx : key
|
| - // -- edx : receiver
|
| - // -- esp[0] : return address
|
| - // -----------------------------------
|
| - Label miss_force_generic, slow_allocate_heapnumber;
|
| -
|
| - // 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 or a heap number convertible to a smi.
|
| - GenerateSmiKeyCheck(masm, ecx, eax, xmm0, xmm1, &miss_force_generic);
|
| -
|
| - // Get the elements array.
|
| - __ mov(eax, FieldOperand(edx, JSObject::kElementsOffset));
|
| - __ AssertFastElements(eax);
|
| -
|
| - // Check that the key is within bounds.
|
| - __ cmp(ecx, FieldOperand(eax, FixedDoubleArray::kLengthOffset));
|
| - __ j(above_equal, &miss_force_generic);
|
| -
|
| - // Check for the hole
|
| - uint32_t offset = FixedDoubleArray::kHeaderSize + sizeof(kHoleNanLower32);
|
| - __ cmp(FieldOperand(eax, ecx, times_4, offset), Immediate(kHoleNanUpper32));
|
| - __ j(equal, &miss_force_generic);
|
| -
|
| - // Always allocate a heap number for the result.
|
| - if (CpuFeatures::IsSupported(SSE2)) {
|
| - CpuFeatures::Scope use_sse2(SSE2);
|
| - __ movdbl(xmm0, FieldOperand(eax, ecx, times_4,
|
| - FixedDoubleArray::kHeaderSize));
|
| - } else {
|
| - __ fld_d(FieldOperand(eax, ecx, times_4, FixedDoubleArray::kHeaderSize));
|
| - }
|
| - __ AllocateHeapNumber(eax, ebx, edi, &slow_allocate_heapnumber);
|
| - // Set the value.
|
| - if (CpuFeatures::IsSupported(SSE2)) {
|
| - CpuFeatures::Scope use_sse2(SSE2);
|
| - __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0);
|
| - } else {
|
| - __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
|
| - }
|
| - __ ret(0);
|
| -
|
| - __ bind(&slow_allocate_heapnumber);
|
| - // A value was pushed on the floating point stack before the allocation, if
|
| - // the allocation fails it needs to be removed.
|
| - if (!CpuFeatures::IsSupported(SSE2)) {
|
| - __ fstp(0);
|
| - }
|
| - Handle<Code> slow_ic =
|
| - masm->isolate()->builtins()->KeyedLoadIC_Slow();
|
| - __ jmp(slow_ic, RelocInfo::CODE_TARGET);
|
| -
|
| - __ bind(&miss_force_generic);
|
| - Handle<Code> miss_ic =
|
| - masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
|
| - __ jmp(miss_ic, RelocInfo::CODE_TARGET);
|
| -}
|
| -
|
| -
|
| void KeyedStoreStubCompiler::GenerateStoreFastElement(
|
| MacroAssembler* masm,
|
| bool is_js_array,
|
|
|