Index: src/mips/stub-cache-mips.cc |
diff --git a/src/mips/stub-cache-mips.cc b/src/mips/stub-cache-mips.cc |
index c4b1ee57a7239ebb9cb73033fd5b1bbcbbe2b916..b84aca74437b424c7b14d6342d391a0665cde8ec 100644 |
--- a/src/mips/stub-cache-mips.cc |
+++ b/src/mips/stub-cache-mips.cc |
@@ -1156,22 +1156,6 @@ static void GenerateCheckPropertyCells(MacroAssembler* masm, |
} |
-// Convert and store int passed in register ival to IEEE 754 single precision |
-// floating point value at memory location (dst + 4 * wordoffset) |
-// If FPU is available use it for conversion. |
-static void StoreIntAsFloat(MacroAssembler* masm, |
- Register dst, |
- Register wordoffset, |
- Register ival, |
- Register scratch1) { |
- __ mtc1(ival, f0); |
- __ cvt_s_w(f0, f0); |
- __ sll(scratch1, wordoffset, 2); |
- __ addu(scratch1, dst, scratch1); |
- __ swc1(f0, MemOperand(scratch1, 0)); |
-} |
- |
- |
void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { |
__ Jump(code, RelocInfo::CODE_TARGET); |
} |
@@ -3229,570 +3213,6 @@ void KeyedLoadStubCompiler::GenerateLoadDictionaryElement( |
} |
-static void GenerateSmiKeyCheck(MacroAssembler* masm, |
- Register key, |
- Register scratch0, |
- Register scratch1, |
- FPURegister double_scratch0, |
- FPURegister double_scratch1, |
- Label* fail) { |
- Label key_ok; |
- // Check for smi or a smi inside a heap number. We convert the heap |
- // number and check if the conversion is exact and fits into the smi |
- // range. |
- __ JumpIfSmi(key, &key_ok); |
- __ CheckMap(key, |
- scratch0, |
- Heap::kHeapNumberMapRootIndex, |
- fail, |
- DONT_DO_SMI_CHECK); |
- __ ldc1(double_scratch0, FieldMemOperand(key, HeapNumber::kValueOffset)); |
- __ EmitFPUTruncate(kRoundToZero, |
- scratch0, |
- double_scratch0, |
- at, |
- double_scratch1, |
- scratch1, |
- kCheckForInexactConversion); |
- |
- __ Branch(fail, ne, scratch1, Operand(zero_reg)); |
- |
- __ SmiTagCheckOverflow(key, scratch0, scratch1); |
- __ BranchOnOverflow(fail, scratch1); |
- __ bind(&key_ok); |
-} |
- |
- |
-void KeyedStoreStubCompiler::GenerateStoreExternalArray( |
- MacroAssembler* masm, |
- ElementsKind elements_kind) { |
- // ---------- S t a t e -------------- |
- // -- a0 : value |
- // -- a1 : key |
- // -- a2 : receiver |
- // -- ra : return address |
- // ----------------------------------- |
- |
- Label slow, check_heap_number, miss_force_generic; |
- |
- // Register usage. |
- Register value = a0; |
- Register key = a1; |
- Register receiver = a2; |
- // a3 mostly holds the elements array or the destination external array. |
- |
- // 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, key, t0, t1, f2, f4, &miss_force_generic); |
- |
- __ lw(a3, FieldMemOperand(receiver, JSObject::kElementsOffset)); |
- |
- // Check that the index is in range. |
- __ lw(t1, FieldMemOperand(a3, ExternalArray::kLengthOffset)); |
- // Unsigned comparison catches both negative and too-large values. |
- __ Branch(&miss_force_generic, Ugreater_equal, key, Operand(t1)); |
- |
- // Handle both smis and HeapNumbers in the fast path. Go to the |
- // runtime for all other kinds of values. |
- // a3: external array. |
- |
- if (elements_kind == EXTERNAL_PIXEL_ELEMENTS) { |
- // Double to pixel conversion is only implemented in the runtime for now. |
- __ JumpIfNotSmi(value, &slow); |
- } else { |
- __ JumpIfNotSmi(value, &check_heap_number); |
- } |
- __ SmiUntag(t1, value); |
- __ lw(a3, FieldMemOperand(a3, ExternalArray::kExternalPointerOffset)); |
- |
- // a3: base pointer of external storage. |
- // t1: value (integer). |
- |
- switch (elements_kind) { |
- case EXTERNAL_PIXEL_ELEMENTS: { |
- // Clamp the value to [0..255]. |
- // v0 is used as a scratch register here. |
- Label done; |
- __ li(v0, Operand(255)); |
- // Normal branch: nop in delay slot. |
- __ Branch(&done, gt, t1, Operand(v0)); |
- // Use delay slot in this branch. |
- __ Branch(USE_DELAY_SLOT, &done, lt, t1, Operand(zero_reg)); |
- __ mov(v0, zero_reg); // In delay slot. |
- __ mov(v0, t1); // Value is in range 0..255. |
- __ bind(&done); |
- __ mov(t1, v0); |
- |
- __ srl(t8, key, 1); |
- __ addu(t8, a3, t8); |
- __ sb(t1, MemOperand(t8, 0)); |
- } |
- break; |
- case EXTERNAL_BYTE_ELEMENTS: |
- case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
- __ srl(t8, key, 1); |
- __ addu(t8, a3, t8); |
- __ sb(t1, MemOperand(t8, 0)); |
- break; |
- case EXTERNAL_SHORT_ELEMENTS: |
- case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
- __ addu(t8, a3, key); |
- __ sh(t1, MemOperand(t8, 0)); |
- break; |
- case EXTERNAL_INT_ELEMENTS: |
- case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
- __ sll(t8, key, 1); |
- __ addu(t8, a3, t8); |
- __ sw(t1, MemOperand(t8, 0)); |
- break; |
- case EXTERNAL_FLOAT_ELEMENTS: |
- // Perform int-to-float conversion and store to memory. |
- __ SmiUntag(t0, key); |
- StoreIntAsFloat(masm, a3, t0, t1, t2); |
- break; |
- case EXTERNAL_DOUBLE_ELEMENTS: |
- __ sll(t8, key, 2); |
- __ addu(a3, a3, t8); |
- // a3: effective address of the double element |
- FloatingPointHelper::Destination destination; |
- destination = FloatingPointHelper::kFPURegisters; |
- FloatingPointHelper::ConvertIntToDouble( |
- masm, t1, destination, |
- f0, t2, t3, // These are: double_dst, dst_mantissa, dst_exponent. |
- t0, f2); // These are: scratch2, single_scratch. |
- __ sdc1(f0, MemOperand(a3, 0)); |
- break; |
- case FAST_ELEMENTS: |
- case FAST_SMI_ELEMENTS: |
- case FAST_DOUBLE_ELEMENTS: |
- case FAST_HOLEY_ELEMENTS: |
- case FAST_HOLEY_SMI_ELEMENTS: |
- case FAST_HOLEY_DOUBLE_ELEMENTS: |
- case DICTIONARY_ELEMENTS: |
- case NON_STRICT_ARGUMENTS_ELEMENTS: |
- UNREACHABLE(); |
- break; |
- } |
- |
- // Entry registers are intact, a0 holds the value which is the return value. |
- __ Ret(USE_DELAY_SLOT); |
- __ mov(v0, a0); |
- |
- if (elements_kind != EXTERNAL_PIXEL_ELEMENTS) { |
- // a3: external array. |
- __ bind(&check_heap_number); |
- __ GetObjectType(value, t1, t2); |
- __ Branch(&slow, ne, t2, Operand(HEAP_NUMBER_TYPE)); |
- |
- __ lw(a3, FieldMemOperand(a3, ExternalArray::kExternalPointerOffset)); |
- |
- // a3: base pointer of external storage. |
- |
- // The WebGL specification leaves the behavior of storing NaN and |
- // +/-Infinity into integer arrays basically undefined. For more |
- // reproducible behavior, convert these to zero. |
- |
- |
- __ ldc1(f0, FieldMemOperand(a0, HeapNumber::kValueOffset)); |
- |
- if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
- __ cvt_s_d(f0, f0); |
- __ sll(t8, key, 1); |
- __ addu(t8, a3, t8); |
- __ swc1(f0, MemOperand(t8, 0)); |
- } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
- __ sll(t8, key, 2); |
- __ addu(t8, a3, t8); |
- __ sdc1(f0, MemOperand(t8, 0)); |
- } else { |
- __ EmitECMATruncate(t3, f0, f2, t2, t1, t5); |
- |
- switch (elements_kind) { |
- case EXTERNAL_BYTE_ELEMENTS: |
- case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
- __ srl(t8, key, 1); |
- __ addu(t8, a3, t8); |
- __ sb(t3, MemOperand(t8, 0)); |
- break; |
- case EXTERNAL_SHORT_ELEMENTS: |
- case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
- __ addu(t8, a3, key); |
- __ sh(t3, MemOperand(t8, 0)); |
- break; |
- case EXTERNAL_INT_ELEMENTS: |
- case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
- __ sll(t8, key, 1); |
- __ addu(t8, a3, t8); |
- __ sw(t3, MemOperand(t8, 0)); |
- break; |
- case EXTERNAL_PIXEL_ELEMENTS: |
- case EXTERNAL_FLOAT_ELEMENTS: |
- case EXTERNAL_DOUBLE_ELEMENTS: |
- case FAST_ELEMENTS: |
- case FAST_SMI_ELEMENTS: |
- case FAST_DOUBLE_ELEMENTS: |
- case FAST_HOLEY_ELEMENTS: |
- case FAST_HOLEY_SMI_ELEMENTS: |
- case FAST_HOLEY_DOUBLE_ELEMENTS: |
- case DICTIONARY_ELEMENTS: |
- case NON_STRICT_ARGUMENTS_ELEMENTS: |
- UNREACHABLE(); |
- break; |
- } |
- } |
- |
- // Entry registers are intact, a0 holds the value |
- // which is the return value. |
- __ Ret(USE_DELAY_SLOT); |
- __ mov(v0, a0); |
- } |
- |
- // Slow case, key and receiver still in a0 and a1. |
- __ bind(&slow); |
- __ IncrementCounter( |
- masm->isolate()->counters()->keyed_load_external_array_slow(), |
- 1, a2, a3); |
- // Entry registers are intact. |
- // ---------- S t a t e -------------- |
- // -- ra : return address |
- // -- a0 : key |
- // -- a1 : receiver |
- // ----------------------------------- |
- TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); |
- |
- // Miss case, call the runtime. |
- __ bind(&miss_force_generic); |
- |
- // ---------- S t a t e -------------- |
- // -- ra : return address |
- // -- a0 : key |
- // -- a1 : receiver |
- // ----------------------------------- |
- TailCallBuiltin(masm, Builtins::kKeyedStoreIC_MissForceGeneric); |
-} |
- |
- |
-void KeyedStoreStubCompiler::GenerateStoreFastElement( |
- MacroAssembler* masm, |
- bool is_js_array, |
- ElementsKind elements_kind, |
- KeyedAccessStoreMode store_mode) { |
- // ----------- S t a t e ------------- |
- // -- a0 : value |
- // -- a1 : key |
- // -- a2 : receiver |
- // -- ra : return address |
- // -- a3 : scratch |
- // -- a4 : scratch (elements) |
- // ----------------------------------- |
- Label miss_force_generic, transition_elements_kind, grow, slow; |
- Label finish_store, check_capacity; |
- |
- Register value_reg = a0; |
- Register key_reg = a1; |
- Register receiver_reg = a2; |
- Register scratch = t0; |
- Register elements_reg = a3; |
- Register length_reg = t1; |
- Register scratch2 = t2; |
- |
- // 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, key_reg, t0, t1, f2, f4, &miss_force_generic); |
- |
- if (IsFastSmiElementsKind(elements_kind)) { |
- __ JumpIfNotSmi(value_reg, &transition_elements_kind); |
- } |
- |
- // Check that the key is within bounds. |
- __ lw(elements_reg, |
- FieldMemOperand(receiver_reg, JSObject::kElementsOffset)); |
- if (is_js_array) { |
- __ lw(scratch, FieldMemOperand(receiver_reg, JSArray::kLengthOffset)); |
- } else { |
- __ lw(scratch, FieldMemOperand(elements_reg, FixedArray::kLengthOffset)); |
- } |
- // Compare smis. |
- if (is_js_array && IsGrowStoreMode(store_mode)) { |
- __ Branch(&grow, hs, key_reg, Operand(scratch)); |
- } else { |
- __ Branch(&miss_force_generic, hs, key_reg, Operand(scratch)); |
- } |
- |
- // Make sure elements is a fast element array, not 'cow'. |
- __ CheckMap(elements_reg, |
- scratch, |
- Heap::kFixedArrayMapRootIndex, |
- &miss_force_generic, |
- DONT_DO_SMI_CHECK); |
- |
- __ bind(&finish_store); |
- |
- if (IsFastSmiElementsKind(elements_kind)) { |
- __ Addu(scratch, |
- elements_reg, |
- Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
- STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2); |
- __ sll(scratch2, key_reg, kPointerSizeLog2 - kSmiTagSize); |
- __ Addu(scratch, scratch, scratch2); |
- __ sw(value_reg, MemOperand(scratch)); |
- } else { |
- ASSERT(IsFastObjectElementsKind(elements_kind)); |
- __ Addu(scratch, |
- elements_reg, |
- Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
- STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2); |
- __ sll(scratch2, key_reg, kPointerSizeLog2 - kSmiTagSize); |
- __ Addu(scratch, scratch, scratch2); |
- __ sw(value_reg, MemOperand(scratch)); |
- __ mov(receiver_reg, value_reg); |
- __ RecordWrite(elements_reg, // Object. |
- scratch, // Address. |
- receiver_reg, // Value. |
- kRAHasNotBeenSaved, |
- kDontSaveFPRegs); |
- } |
- // value_reg (a0) is preserved. |
- // Done. |
- __ Ret(); |
- |
- __ bind(&miss_force_generic); |
- TailCallBuiltin(masm, Builtins::kKeyedStoreIC_MissForceGeneric); |
- |
- __ bind(&transition_elements_kind); |
- TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Miss); |
- |
- if (is_js_array && IsGrowStoreMode(store_mode)) { |
- // Grow the array by a single element if possible. |
- __ bind(&grow); |
- |
- // Make sure the array is only growing by a single element, anything else |
- // must be handled by the runtime. |
- __ Branch(&miss_force_generic, ne, key_reg, Operand(scratch)); |
- |
- // Check for the empty array, and preallocate a small backing store if |
- // possible. |
- __ lw(length_reg, |
- FieldMemOperand(receiver_reg, JSArray::kLengthOffset)); |
- __ lw(elements_reg, |
- FieldMemOperand(receiver_reg, JSObject::kElementsOffset)); |
- __ LoadRoot(at, Heap::kEmptyFixedArrayRootIndex); |
- __ Branch(&check_capacity, ne, elements_reg, Operand(at)); |
- |
- int size = FixedArray::SizeFor(JSArray::kPreallocatedArrayElements); |
- __ Allocate(size, elements_reg, scratch, scratch2, &slow, TAG_OBJECT); |
- |
- __ LoadRoot(scratch, Heap::kFixedArrayMapRootIndex); |
- __ sw(scratch, FieldMemOperand(elements_reg, JSObject::kMapOffset)); |
- __ li(scratch, Operand(Smi::FromInt(JSArray::kPreallocatedArrayElements))); |
- __ sw(scratch, FieldMemOperand(elements_reg, FixedArray::kLengthOffset)); |
- __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); |
- for (int i = 1; i < JSArray::kPreallocatedArrayElements; ++i) { |
- __ sw(scratch, FieldMemOperand(elements_reg, FixedArray::SizeFor(i))); |
- } |
- |
- // Store the element at index zero. |
- __ sw(value_reg, FieldMemOperand(elements_reg, FixedArray::SizeFor(0))); |
- |
- // Install the new backing store in the JSArray. |
- __ sw(elements_reg, |
- FieldMemOperand(receiver_reg, JSObject::kElementsOffset)); |
- __ RecordWriteField(receiver_reg, JSObject::kElementsOffset, elements_reg, |
- scratch, kRAHasNotBeenSaved, kDontSaveFPRegs, |
- EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); |
- |
- // Increment the length of the array. |
- __ li(length_reg, Operand(Smi::FromInt(1))); |
- __ Ret(USE_DELAY_SLOT); |
- __ sw(length_reg, FieldMemOperand(receiver_reg, JSArray::kLengthOffset)); |
- |
- __ bind(&check_capacity); |
- // Check for cow elements, in general they are not handled by this stub |
- __ CheckMap(elements_reg, |
- scratch, |
- Heap::kFixedCOWArrayMapRootIndex, |
- &miss_force_generic, |
- DONT_DO_SMI_CHECK); |
- |
- __ lw(scratch, FieldMemOperand(elements_reg, FixedArray::kLengthOffset)); |
- __ Branch(&slow, hs, length_reg, Operand(scratch)); |
- |
- // Grow the array and finish the store. |
- __ Addu(length_reg, length_reg, Operand(Smi::FromInt(1))); |
- __ sw(length_reg, FieldMemOperand(receiver_reg, JSArray::kLengthOffset)); |
- __ jmp(&finish_store); |
- |
- __ bind(&slow); |
- TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); |
- } |
-} |
- |
- |
-void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement( |
- MacroAssembler* masm, |
- bool is_js_array, |
- KeyedAccessStoreMode store_mode) { |
- // ----------- S t a t e ------------- |
- // -- a0 : value |
- // -- a1 : key |
- // -- a2 : receiver |
- // -- ra : return address |
- // -- a3 : scratch (elements backing store) |
- // -- t0 : scratch (elements_reg) |
- // -- t1 : scratch (mantissa_reg) |
- // -- t2 : scratch (exponent_reg) |
- // -- t3 : scratch4 |
- // -- t4 : scratch |
- // ----------------------------------- |
- Label miss_force_generic, transition_elements_kind, grow, slow; |
- Label finish_store, check_capacity; |
- |
- Register value_reg = a0; |
- Register key_reg = a1; |
- Register receiver_reg = a2; |
- Register elements_reg = a3; |
- Register scratch1 = t0; |
- Register scratch2 = t1; |
- Register scratch3 = t2; |
- Register scratch4 = t3; |
- Register scratch5 = t4; |
- Register length_reg = t3; |
- |
- // 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, key_reg, t0, t1, f2, f4, &miss_force_generic); |
- |
- __ lw(elements_reg, |
- FieldMemOperand(receiver_reg, JSObject::kElementsOffset)); |
- |
- // Check that the key is within bounds. |
- if (is_js_array) { |
- __ lw(scratch1, FieldMemOperand(receiver_reg, JSArray::kLengthOffset)); |
- } else { |
- __ lw(scratch1, |
- FieldMemOperand(elements_reg, FixedArray::kLengthOffset)); |
- } |
- // Compare smis, unsigned compare catches both negative and out-of-bound |
- // indexes. |
- if (IsGrowStoreMode(store_mode)) { |
- __ Branch(&grow, hs, key_reg, Operand(scratch1)); |
- } else { |
- __ Branch(&miss_force_generic, hs, key_reg, Operand(scratch1)); |
- } |
- |
- __ bind(&finish_store); |
- |
- __ StoreNumberToDoubleElements(value_reg, |
- key_reg, |
- // All registers after this are overwritten. |
- elements_reg, |
- scratch1, |
- scratch2, |
- scratch3, |
- scratch4, |
- &transition_elements_kind); |
- |
- __ Ret(USE_DELAY_SLOT); |
- __ mov(v0, value_reg); // In delay slot. |
- |
- // Handle store cache miss, replacing the ic with the generic stub. |
- __ bind(&miss_force_generic); |
- TailCallBuiltin(masm, Builtins::kKeyedStoreIC_MissForceGeneric); |
- |
- __ bind(&transition_elements_kind); |
- TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Miss); |
- |
- if (is_js_array && IsGrowStoreMode(store_mode)) { |
- // Grow the array by a single element if possible. |
- __ bind(&grow); |
- |
- // Make sure the array is only growing by a single element, anything else |
- // must be handled by the runtime. |
- __ Branch(&miss_force_generic, ne, key_reg, Operand(scratch1)); |
- |
- // Transition on values that can't be stored in a FixedDoubleArray. |
- Label value_is_smi; |
- __ JumpIfSmi(value_reg, &value_is_smi); |
- __ lw(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset)); |
- __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); |
- __ Branch(&transition_elements_kind, ne, scratch1, Operand(at)); |
- __ bind(&value_is_smi); |
- |
- // Check for the empty array, and preallocate a small backing store if |
- // possible. |
- __ lw(length_reg, |
- FieldMemOperand(receiver_reg, JSArray::kLengthOffset)); |
- __ lw(elements_reg, |
- FieldMemOperand(receiver_reg, JSObject::kElementsOffset)); |
- __ LoadRoot(at, Heap::kEmptyFixedArrayRootIndex); |
- __ Branch(&check_capacity, ne, elements_reg, Operand(at)); |
- |
- int size = FixedDoubleArray::SizeFor(JSArray::kPreallocatedArrayElements); |
- __ Allocate(size, elements_reg, scratch1, scratch2, &slow, TAG_OBJECT); |
- |
- // Initialize the new FixedDoubleArray. |
- __ LoadRoot(scratch1, Heap::kFixedDoubleArrayMapRootIndex); |
- __ sw(scratch1, FieldMemOperand(elements_reg, JSObject::kMapOffset)); |
- __ li(scratch1, Operand(Smi::FromInt(JSArray::kPreallocatedArrayElements))); |
- __ sw(scratch1, |
- FieldMemOperand(elements_reg, FixedDoubleArray::kLengthOffset)); |
- |
- __ mov(scratch1, elements_reg); |
- __ StoreNumberToDoubleElements(value_reg, |
- key_reg, |
- // All registers after this are overwritten. |
- scratch1, |
- scratch2, |
- scratch3, |
- scratch4, |
- scratch5, |
- &transition_elements_kind); |
- |
- __ li(scratch1, Operand(kHoleNanLower32)); |
- __ li(scratch2, Operand(kHoleNanUpper32)); |
- for (int i = 1; i < JSArray::kPreallocatedArrayElements; i++) { |
- int offset = FixedDoubleArray::OffsetOfElementAt(i); |
- __ sw(scratch1, FieldMemOperand(elements_reg, offset)); |
- __ sw(scratch2, FieldMemOperand(elements_reg, offset + kPointerSize)); |
- } |
- |
- // Install the new backing store in the JSArray. |
- __ sw(elements_reg, |
- FieldMemOperand(receiver_reg, JSObject::kElementsOffset)); |
- __ RecordWriteField(receiver_reg, JSObject::kElementsOffset, elements_reg, |
- scratch1, kRAHasNotBeenSaved, kDontSaveFPRegs, |
- EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); |
- |
- // Increment the length of the array. |
- __ li(length_reg, Operand(Smi::FromInt(1))); |
- __ sw(length_reg, FieldMemOperand(receiver_reg, JSArray::kLengthOffset)); |
- __ Ret(USE_DELAY_SLOT); |
- __ lw(elements_reg, |
- FieldMemOperand(receiver_reg, JSObject::kElementsOffset)); |
- |
- __ bind(&check_capacity); |
- // Make sure that the backing store can hold additional elements. |
- __ lw(scratch1, |
- FieldMemOperand(elements_reg, FixedDoubleArray::kLengthOffset)); |
- __ Branch(&slow, hs, length_reg, Operand(scratch1)); |
- |
- // Grow the array and finish the store. |
- __ Addu(length_reg, length_reg, Operand(Smi::FromInt(1))); |
- __ sw(length_reg, FieldMemOperand(receiver_reg, JSArray::kLengthOffset)); |
- __ jmp(&finish_store); |
- |
- __ bind(&slow); |
- TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); |
- } |
-} |
- |
- |
#undef __ |
} } // namespace v8::internal |