| Index: src/ia32/stub-cache-ia32.cc
|
| diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc
|
| index d0b7881496ef0f3c80b78be9f7e41dab1b97163a..6ab8e5e364b68192b825a004a0907fdba244ccff 100644
|
| --- a/src/ia32/stub-cache-ia32.cc
|
| +++ b/src/ia32/stub-cache-ia32.cc
|
| @@ -2879,13 +2879,20 @@ Handle<Code> KeyedStoreStubCompiler::CompileStoreElement(
|
| // -- esp[0] : return address
|
| // -----------------------------------
|
| ElementsKind elements_kind = receiver_map->elements_kind();
|
| - bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE;
|
| - Handle<Code> stub =
|
| - KeyedStoreElementStub(is_jsarray,
|
| - elements_kind,
|
| - store_mode_).GetCode(isolate());
|
| -
|
| - __ DispatchMap(edx, receiver_map, stub, DO_SMI_CHECK);
|
| + bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
|
| + if ((receiver_map->has_fast_elements() ||
|
| + receiver_map->has_external_array_elements())) {
|
| + Handle<Code> stub = KeyedStoreFastElementStub(
|
| + is_js_array,
|
| + elements_kind,
|
| + store_mode_).GetCode(isolate());
|
| + __ DispatchMap(edx, receiver_map, stub, DO_SMI_CHECK);
|
| + } else {
|
| + Handle<Code> stub =
|
| + KeyedStoreElementStub(is_js_array, elements_kind,
|
| + store_mode_).GetCode(isolate());
|
| + __ DispatchMap(edx, receiver_map, stub, DO_SMI_CHECK);
|
| + }
|
|
|
| Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
|
| __ jmp(ic, RelocInfo::CODE_TARGET);
|
| @@ -3335,205 +3342,6 @@ static void GenerateSmiKeyCheck(MacroAssembler* masm,
|
| }
|
|
|
|
|
| -void KeyedStoreStubCompiler::GenerateStoreExternalArray(
|
| - MacroAssembler* masm,
|
| - ElementsKind elements_kind) {
|
| - // ----------- S t a t e -------------
|
| - // -- eax : value
|
| - // -- ecx : key
|
| - // -- edx : receiver
|
| - // -- esp[0] : return address
|
| - // -----------------------------------
|
| - Label miss_force_generic, slow, check_heap_number;
|
| -
|
| - // 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, ebx, xmm0, xmm1, &miss_force_generic);
|
| -
|
| - // Check that the index is in range.
|
| - __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
|
| - __ cmp(ecx, FieldOperand(edi, ExternalArray::kLengthOffset));
|
| - // Unsigned comparison catches both negative and too-large values.
|
| - __ j(above_equal, &slow);
|
| -
|
| - // Handle both smis and HeapNumbers in the fast path. Go to the
|
| - // runtime for all other kinds of values.
|
| - // eax: value
|
| - // edx: receiver
|
| - // ecx: key
|
| - // edi: elements array
|
| - if (elements_kind == EXTERNAL_PIXEL_ELEMENTS) {
|
| - __ JumpIfNotSmi(eax, &slow);
|
| - } else {
|
| - __ JumpIfNotSmi(eax, &check_heap_number);
|
| - }
|
| -
|
| - // smi case
|
| - __ mov(ebx, eax); // Preserve the value in eax as the return value.
|
| - __ SmiUntag(ebx);
|
| - __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset));
|
| - // edi: base pointer of external storage
|
| - switch (elements_kind) {
|
| - case EXTERNAL_PIXEL_ELEMENTS:
|
| - __ ClampUint8(ebx);
|
| - __ SmiUntag(ecx);
|
| - __ mov_b(Operand(edi, ecx, times_1, 0), ebx);
|
| - break;
|
| - case EXTERNAL_BYTE_ELEMENTS:
|
| - case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
|
| - __ SmiUntag(ecx);
|
| - __ mov_b(Operand(edi, ecx, times_1, 0), ebx);
|
| - break;
|
| - case EXTERNAL_SHORT_ELEMENTS:
|
| - case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
|
| - __ mov_w(Operand(edi, ecx, times_1, 0), ebx);
|
| - break;
|
| - case EXTERNAL_INT_ELEMENTS:
|
| - case EXTERNAL_UNSIGNED_INT_ELEMENTS:
|
| - __ mov(Operand(edi, ecx, times_2, 0), ebx);
|
| - break;
|
| - case EXTERNAL_FLOAT_ELEMENTS:
|
| - case EXTERNAL_DOUBLE_ELEMENTS:
|
| - // Need to perform int-to-float conversion.
|
| - __ push(ebx);
|
| - __ fild_s(Operand(esp, 0));
|
| - __ pop(ebx);
|
| - if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
|
| - __ fstp_s(Operand(edi, ecx, times_2, 0));
|
| - } else { // elements_kind == EXTERNAL_DOUBLE_ELEMENTS.
|
| - __ fstp_d(Operand(edi, ecx, times_4, 0));
|
| - }
|
| - break;
|
| - default:
|
| - UNREACHABLE();
|
| - break;
|
| - }
|
| - __ ret(0); // Return the original value.
|
| -
|
| - // TODO(danno): handle heap number -> pixel array conversion
|
| - if (elements_kind != EXTERNAL_PIXEL_ELEMENTS) {
|
| - __ bind(&check_heap_number);
|
| - // eax: value
|
| - // edx: receiver
|
| - // ecx: key
|
| - // edi: elements array
|
| - __ cmp(FieldOperand(eax, HeapObject::kMapOffset),
|
| - Immediate(masm->isolate()->factory()->heap_number_map()));
|
| - __ j(not_equal, &slow);
|
| -
|
| - // The WebGL specification leaves the behavior of storing NaN and
|
| - // +/-Infinity into integer arrays basically undefined. For more
|
| - // reproducible behavior, convert these to zero.
|
| - __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset));
|
| - // edi: base pointer of external storage
|
| - if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
|
| - __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
|
| - __ fstp_s(Operand(edi, ecx, times_2, 0));
|
| - __ ret(0);
|
| - } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
|
| - __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
|
| - __ fstp_d(Operand(edi, ecx, times_4, 0));
|
| - __ ret(0);
|
| - } else {
|
| - // Perform float-to-int conversion with truncation (round-to-zero)
|
| - // behavior.
|
| -
|
| - // For the moment we make the slow call to the runtime on
|
| - // processors that don't support SSE2. The code in IntegerConvert
|
| - // (code-stubs-ia32.cc) is roughly what is needed here though the
|
| - // conversion failure case does not need to be handled.
|
| - if (CpuFeatures::IsSupported(SSE2)) {
|
| - if ((elements_kind == EXTERNAL_INT_ELEMENTS ||
|
| - elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) &&
|
| - CpuFeatures::IsSupported(SSE3)) {
|
| - CpuFeatureScope scope(masm, SSE3);
|
| - // fisttp stores values as signed integers. To represent the
|
| - // entire range of int and unsigned int arrays, store as a
|
| - // 64-bit int and discard the high 32 bits.
|
| - __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
|
| - __ sub(esp, Immediate(2 * kPointerSize));
|
| - __ fisttp_d(Operand(esp, 0));
|
| -
|
| - // If conversion failed (NaN, infinity, or a number outside
|
| - // signed int64 range), the result is 0x8000000000000000, and
|
| - // we must handle this case in the runtime.
|
| - Label ok;
|
| - __ cmp(Operand(esp, kPointerSize), Immediate(0x80000000u));
|
| - __ j(not_equal, &ok);
|
| - __ cmp(Operand(esp, 0), Immediate(0));
|
| - __ j(not_equal, &ok);
|
| - __ add(esp, Immediate(2 * kPointerSize)); // Restore the stack.
|
| - __ jmp(&slow);
|
| -
|
| - __ bind(&ok);
|
| - __ pop(ebx);
|
| - __ add(esp, Immediate(kPointerSize));
|
| - __ mov(Operand(edi, ecx, times_2, 0), ebx);
|
| - } else {
|
| - ASSERT(CpuFeatures::IsSupported(SSE2));
|
| - CpuFeatureScope scope(masm, SSE2);
|
| - __ cvttsd2si(ebx, FieldOperand(eax, HeapNumber::kValueOffset));
|
| - __ cmp(ebx, 0x80000000u);
|
| - __ j(equal, &slow);
|
| - // ebx: untagged integer value
|
| - switch (elements_kind) {
|
| - case EXTERNAL_PIXEL_ELEMENTS:
|
| - __ ClampUint8(ebx);
|
| - // Fall through.
|
| - case EXTERNAL_BYTE_ELEMENTS:
|
| - case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
|
| - __ SmiUntag(ecx);
|
| - __ mov_b(Operand(edi, ecx, times_1, 0), ebx);
|
| - break;
|
| - case EXTERNAL_SHORT_ELEMENTS:
|
| - case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
|
| - __ mov_w(Operand(edi, ecx, times_1, 0), ebx);
|
| - break;
|
| - case EXTERNAL_INT_ELEMENTS:
|
| - case EXTERNAL_UNSIGNED_INT_ELEMENTS:
|
| - __ mov(Operand(edi, ecx, times_2, 0), ebx);
|
| - break;
|
| - default:
|
| - UNREACHABLE();
|
| - break;
|
| - }
|
| - }
|
| - __ ret(0); // Return original value.
|
| - }
|
| - }
|
| - }
|
| -
|
| - // Slow case: call runtime.
|
| - __ bind(&slow);
|
| - Counters* counters = masm->isolate()->counters();
|
| - __ IncrementCounter(counters->keyed_store_external_array_slow(), 1);
|
| -
|
| - // ----------- S t a t e -------------
|
| - // -- eax : value
|
| - // -- ecx : key
|
| - // -- edx : receiver
|
| - // -- esp[0] : return address
|
| - // -----------------------------------
|
| -
|
| - Handle<Code> ic = masm->isolate()->builtins()->KeyedStoreIC_Slow();
|
| - __ jmp(ic, RelocInfo::CODE_TARGET);
|
| -
|
| - // ----------- S t a t e -------------
|
| - // -- eax : value
|
| - // -- ecx : key
|
| - // -- edx : receiver
|
| - // -- esp[0] : return address
|
| - // -----------------------------------
|
| -
|
| - __ bind(&miss_force_generic);
|
| - Handle<Code> miss_ic =
|
| - masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
|
| - __ jmp(miss_ic, RelocInfo::CODE_TARGET);
|
| -}
|
| -
|
| -
|
| void KeyedStoreStubCompiler::GenerateStoreFastElement(
|
| MacroAssembler* masm,
|
| bool is_js_array,
|
|
|