OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1613 __ add(r0, r0, Operand(Smi::FromInt(argc))); | 1613 __ add(r0, r0, Operand(Smi::FromInt(argc))); |
1614 | 1614 |
1615 // Get the elements' length. | 1615 // Get the elements' length. |
1616 __ ldr(r4, FieldMemOperand(elements, FixedArray::kLengthOffset)); | 1616 __ ldr(r4, FieldMemOperand(elements, FixedArray::kLengthOffset)); |
1617 | 1617 |
1618 // Check if we could survive without allocation. | 1618 // Check if we could survive without allocation. |
1619 __ cmp(r0, r4); | 1619 __ cmp(r0, r4); |
1620 __ b(gt, &call_builtin); | 1620 __ b(gt, &call_builtin); |
1621 | 1621 |
1622 __ ldr(r4, MemOperand(sp, (argc - 1) * kPointerSize)); | 1622 __ ldr(r4, MemOperand(sp, (argc - 1) * kPointerSize)); |
1623 __ StoreNumberToDoubleElements( | 1623 __ StoreNumberToDoubleElements(r4, r0, elements, r5, |
1624 r4, r0, elements, r5, r2, r3, r9, | 1624 &call_builtin, argc * kDoubleSize); |
1625 &call_builtin, argc * kDoubleSize); | |
1626 | 1625 |
1627 // Save new length. | 1626 // Save new length. |
1628 __ str(r0, FieldMemOperand(receiver, JSArray::kLengthOffset)); | 1627 __ str(r0, FieldMemOperand(receiver, JSArray::kLengthOffset)); |
1629 | 1628 |
1630 // Check for a smi. | 1629 // Check for a smi. |
1631 __ Drop(argc + 1); | 1630 __ Drop(argc + 1); |
1632 __ Ret(); | 1631 __ Ret(); |
1633 | 1632 |
1634 __ bind(&with_write_barrier); | 1633 __ bind(&with_write_barrier); |
1635 | 1634 |
(...skipping 1603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3239 case EXTERNAL_INT_ELEMENTS: | 3238 case EXTERNAL_INT_ELEMENTS: |
3240 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 3239 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
3241 __ str(r5, MemOperand(r3, key, LSL, 1)); | 3240 __ str(r5, MemOperand(r3, key, LSL, 1)); |
3242 break; | 3241 break; |
3243 case EXTERNAL_FLOAT_ELEMENTS: | 3242 case EXTERNAL_FLOAT_ELEMENTS: |
3244 // Perform int-to-float conversion and store to memory. | 3243 // Perform int-to-float conversion and store to memory. |
3245 __ SmiUntag(r4, key); | 3244 __ SmiUntag(r4, key); |
3246 StoreIntAsFloat(masm, r3, r4, r5, r7); | 3245 StoreIntAsFloat(masm, r3, r4, r5, r7); |
3247 break; | 3246 break; |
3248 case EXTERNAL_DOUBLE_ELEMENTS: | 3247 case EXTERNAL_DOUBLE_ELEMENTS: |
| 3248 __ vmov(s2, r5); |
| 3249 __ vcvt_f64_s32(d0, s2); |
3249 __ add(r3, r3, Operand(key, LSL, 2)); | 3250 __ add(r3, r3, Operand(key, LSL, 2)); |
3250 // r3: effective address of the double element | 3251 // r3: effective address of the double element |
3251 FloatingPointHelper::Destination destination; | |
3252 destination = FloatingPointHelper::kVFPRegisters; | |
3253 FloatingPointHelper::ConvertIntToDouble( | |
3254 masm, r5, destination, | |
3255 d0, r6, r7, // These are: double_dst, dst_mantissa, dst_exponent. | |
3256 r4, s2); // These are: scratch2, single_scratch. | |
3257 __ vstr(d0, r3, 0); | 3252 __ vstr(d0, r3, 0); |
3258 break; | 3253 break; |
3259 case FAST_ELEMENTS: | 3254 case FAST_ELEMENTS: |
3260 case FAST_SMI_ELEMENTS: | 3255 case FAST_SMI_ELEMENTS: |
3261 case FAST_DOUBLE_ELEMENTS: | 3256 case FAST_DOUBLE_ELEMENTS: |
3262 case FAST_HOLEY_ELEMENTS: | 3257 case FAST_HOLEY_ELEMENTS: |
3263 case FAST_HOLEY_SMI_ELEMENTS: | 3258 case FAST_HOLEY_SMI_ELEMENTS: |
3264 case FAST_HOLEY_DOUBLE_ELEMENTS: | 3259 case FAST_HOLEY_DOUBLE_ELEMENTS: |
3265 case DICTIONARY_ELEMENTS: | 3260 case DICTIONARY_ELEMENTS: |
3266 case NON_STRICT_ARGUMENTS_ELEMENTS: | 3261 case NON_STRICT_ARGUMENTS_ELEMENTS: |
(...skipping 29 matching lines...) Expand all Loading... |
3296 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 3291 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
3297 __ sub(r5, r0, Operand(kHeapObjectTag)); | 3292 __ sub(r5, r0, Operand(kHeapObjectTag)); |
3298 __ vldr(d0, r5, HeapNumber::kValueOffset); | 3293 __ vldr(d0, r5, HeapNumber::kValueOffset); |
3299 __ add(r5, r3, Operand(key, LSL, 2)); | 3294 __ add(r5, r3, Operand(key, LSL, 2)); |
3300 __ vstr(d0, r5, 0); | 3295 __ vstr(d0, r5, 0); |
3301 } else { | 3296 } else { |
3302 // Hoisted load. vldr requires offset to be a multiple of 4 so we can | 3297 // Hoisted load. vldr requires offset to be a multiple of 4 so we can |
3303 // not include -kHeapObjectTag into it. | 3298 // not include -kHeapObjectTag into it. |
3304 __ sub(r5, value, Operand(kHeapObjectTag)); | 3299 __ sub(r5, value, Operand(kHeapObjectTag)); |
3305 __ vldr(d0, r5, HeapNumber::kValueOffset); | 3300 __ vldr(d0, r5, HeapNumber::kValueOffset); |
3306 __ ECMAToInt32(r5, d0, d1, r6, r7, r9); | 3301 __ ECMAToInt32(r5, d0, r6, r7, r9, d1); |
3307 | 3302 |
3308 switch (elements_kind) { | 3303 switch (elements_kind) { |
3309 case EXTERNAL_BYTE_ELEMENTS: | 3304 case EXTERNAL_BYTE_ELEMENTS: |
3310 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 3305 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
3311 __ strb(r5, MemOperand(r3, key, LSR, 1)); | 3306 __ strb(r5, MemOperand(r3, key, LSR, 1)); |
3312 break; | 3307 break; |
3313 case EXTERNAL_SHORT_ELEMENTS: | 3308 case EXTERNAL_SHORT_ELEMENTS: |
3314 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 3309 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
3315 __ strh(r5, MemOperand(r3, key, LSL, 0)); | 3310 __ strh(r5, MemOperand(r3, key, LSL, 0)); |
3316 break; | 3311 break; |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3530 bool is_js_array, | 3525 bool is_js_array, |
3531 KeyedAccessStoreMode store_mode) { | 3526 KeyedAccessStoreMode store_mode) { |
3532 // ----------- S t a t e ------------- | 3527 // ----------- S t a t e ------------- |
3533 // -- r0 : value | 3528 // -- r0 : value |
3534 // -- r1 : key | 3529 // -- r1 : key |
3535 // -- r2 : receiver | 3530 // -- r2 : receiver |
3536 // -- lr : return address | 3531 // -- lr : return address |
3537 // -- r3 : scratch (elements backing store) | 3532 // -- r3 : scratch (elements backing store) |
3538 // -- r4 : scratch | 3533 // -- r4 : scratch |
3539 // -- r5 : scratch | 3534 // -- r5 : scratch |
3540 // -- r6 : scratch | |
3541 // -- r7 : scratch | |
3542 // -- r9 : scratch | |
3543 // ----------------------------------- | 3535 // ----------------------------------- |
3544 Label miss_force_generic, transition_elements_kind, grow, slow; | 3536 Label miss_force_generic, transition_elements_kind, grow, slow; |
3545 Label finish_store, check_capacity; | 3537 Label finish_store, check_capacity; |
3546 | 3538 |
3547 Register value_reg = r0; | 3539 Register value_reg = r0; |
3548 Register key_reg = r1; | 3540 Register key_reg = r1; |
3549 Register receiver_reg = r2; | 3541 Register receiver_reg = r2; |
3550 Register elements_reg = r3; | 3542 Register elements_reg = r3; |
3551 Register scratch1 = r4; | 3543 Register scratch1 = r4; |
3552 Register scratch2 = r5; | 3544 Register scratch2 = r5; |
3553 Register scratch3 = r6; | |
3554 Register scratch4 = r7; | |
3555 Register scratch5 = r9; | |
3556 Register length_reg = r7; | 3545 Register length_reg = r7; |
3557 | 3546 |
3558 // This stub is meant to be tail-jumped to, the receiver must already | 3547 // This stub is meant to be tail-jumped to, the receiver must already |
3559 // have been verified by the caller to not be a smi. | 3548 // have been verified by the caller to not be a smi. |
3560 | 3549 |
3561 // Check that the key is a smi or a heap number convertible to a smi. | 3550 // Check that the key is a smi or a heap number convertible to a smi. |
3562 GenerateSmiKeyCheck(masm, key_reg, r4, r5, d1, d2, &miss_force_generic); | 3551 GenerateSmiKeyCheck(masm, key_reg, r4, r5, d1, d2, &miss_force_generic); |
3563 | 3552 |
3564 __ ldr(elements_reg, | 3553 __ ldr(elements_reg, |
3565 FieldMemOperand(receiver_reg, JSObject::kElementsOffset)); | 3554 FieldMemOperand(receiver_reg, JSObject::kElementsOffset)); |
3566 | 3555 |
3567 // Check that the key is within bounds. | 3556 // Check that the key is within bounds. |
3568 if (is_js_array) { | 3557 if (is_js_array) { |
3569 __ ldr(scratch1, FieldMemOperand(receiver_reg, JSArray::kLengthOffset)); | 3558 __ ldr(scratch1, FieldMemOperand(receiver_reg, JSArray::kLengthOffset)); |
3570 } else { | 3559 } else { |
3571 __ ldr(scratch1, | 3560 __ ldr(scratch1, |
3572 FieldMemOperand(elements_reg, FixedArray::kLengthOffset)); | 3561 FieldMemOperand(elements_reg, FixedArray::kLengthOffset)); |
3573 } | 3562 } |
3574 // Compare smis, unsigned compare catches both negative and out-of-bound | 3563 // Compare smis, unsigned compare catches both negative and out-of-bound |
3575 // indexes. | 3564 // indexes. |
3576 __ cmp(key_reg, scratch1); | 3565 __ cmp(key_reg, scratch1); |
3577 if (IsGrowStoreMode(store_mode)) { | 3566 if (IsGrowStoreMode(store_mode)) { |
3578 __ b(hs, &grow); | 3567 __ b(hs, &grow); |
3579 } else { | 3568 } else { |
3580 __ b(hs, &miss_force_generic); | 3569 __ b(hs, &miss_force_generic); |
3581 } | 3570 } |
3582 | 3571 |
3583 __ bind(&finish_store); | 3572 __ bind(&finish_store); |
3584 __ StoreNumberToDoubleElements(value_reg, | 3573 __ StoreNumberToDoubleElements(value_reg, key_reg, elements_reg, |
3585 key_reg, | 3574 scratch1, &transition_elements_kind); |
3586 // All registers after this are overwritten. | |
3587 elements_reg, | |
3588 scratch1, | |
3589 scratch3, | |
3590 scratch4, | |
3591 scratch2, | |
3592 &transition_elements_kind); | |
3593 __ Ret(); | 3575 __ Ret(); |
3594 | 3576 |
3595 // Handle store cache miss, replacing the ic with the generic stub. | 3577 // Handle store cache miss, replacing the ic with the generic stub. |
3596 __ bind(&miss_force_generic); | 3578 __ bind(&miss_force_generic); |
3597 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_MissForceGeneric); | 3579 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_MissForceGeneric); |
3598 | 3580 |
3599 __ bind(&transition_elements_kind); | 3581 __ bind(&transition_elements_kind); |
3600 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Miss); | 3582 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Miss); |
3601 | 3583 |
3602 if (is_js_array && IsGrowStoreMode(store_mode)) { | 3584 if (is_js_array && IsGrowStoreMode(store_mode)) { |
(...skipping 26 matching lines...) Expand all Loading... |
3629 | 3611 |
3630 // Initialize the new FixedDoubleArray. | 3612 // Initialize the new FixedDoubleArray. |
3631 __ LoadRoot(scratch1, Heap::kFixedDoubleArrayMapRootIndex); | 3613 __ LoadRoot(scratch1, Heap::kFixedDoubleArrayMapRootIndex); |
3632 __ str(scratch1, FieldMemOperand(elements_reg, JSObject::kMapOffset)); | 3614 __ str(scratch1, FieldMemOperand(elements_reg, JSObject::kMapOffset)); |
3633 __ mov(scratch1, | 3615 __ mov(scratch1, |
3634 Operand(Smi::FromInt(JSArray::kPreallocatedArrayElements))); | 3616 Operand(Smi::FromInt(JSArray::kPreallocatedArrayElements))); |
3635 __ str(scratch1, | 3617 __ str(scratch1, |
3636 FieldMemOperand(elements_reg, FixedDoubleArray::kLengthOffset)); | 3618 FieldMemOperand(elements_reg, FixedDoubleArray::kLengthOffset)); |
3637 | 3619 |
3638 __ mov(scratch1, elements_reg); | 3620 __ mov(scratch1, elements_reg); |
3639 __ StoreNumberToDoubleElements(value_reg, | 3621 __ StoreNumberToDoubleElements(value_reg, key_reg, scratch1, |
3640 key_reg, | 3622 scratch2, &transition_elements_kind); |
3641 // All registers after this are overwritten. | |
3642 scratch1, | |
3643 scratch2, | |
3644 scratch3, | |
3645 scratch4, | |
3646 scratch5, | |
3647 &transition_elements_kind); | |
3648 | 3623 |
3649 __ mov(scratch1, Operand(kHoleNanLower32)); | 3624 __ mov(scratch1, Operand(kHoleNanLower32)); |
3650 __ mov(scratch2, Operand(kHoleNanUpper32)); | 3625 __ mov(scratch2, Operand(kHoleNanUpper32)); |
3651 for (int i = 1; i < JSArray::kPreallocatedArrayElements; i++) { | 3626 for (int i = 1; i < JSArray::kPreallocatedArrayElements; i++) { |
3652 int offset = FixedDoubleArray::OffsetOfElementAt(i); | 3627 int offset = FixedDoubleArray::OffsetOfElementAt(i); |
3653 __ str(scratch1, FieldMemOperand(elements_reg, offset)); | 3628 __ str(scratch1, FieldMemOperand(elements_reg, offset)); |
3654 __ str(scratch2, FieldMemOperand(elements_reg, offset + kPointerSize)); | 3629 __ str(scratch2, FieldMemOperand(elements_reg, offset + kPointerSize)); |
3655 } | 3630 } |
3656 | 3631 |
3657 // Install the new backing store in the JSArray. | 3632 // Install the new backing store in the JSArray. |
(...skipping 26 matching lines...) Expand all Loading... |
3684 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); | 3659 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); |
3685 } | 3660 } |
3686 } | 3661 } |
3687 | 3662 |
3688 | 3663 |
3689 #undef __ | 3664 #undef __ |
3690 | 3665 |
3691 } } // namespace v8::internal | 3666 } } // namespace v8::internal |
3692 | 3667 |
3693 #endif // V8_TARGET_ARCH_ARM | 3668 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |