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( |
Jakob Kummerow
2013/03/11 16:36:07
Love this change! :-)
|
- 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, |