Chromium Code Reviews| 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 2594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2605 // Subtracting from length accounts for one of them add one more. | 2605 // Subtracting from length accounts for one of them add one more. |
| 2606 if (instr->index()->IsRegister()) { | 2606 if (instr->index()->IsRegister()) { |
| 2607 __ subl(length, ToRegister(instr->index())); | 2607 __ subl(length, ToRegister(instr->index())); |
| 2608 } else { | 2608 } else { |
| 2609 __ subl(length, ToOperand(instr->index())); | 2609 __ subl(length, ToOperand(instr->index())); |
| 2610 } | 2610 } |
| 2611 __ movq(result, Operand(arguments, length, times_pointer_size, kPointerSize)); | 2611 __ movq(result, Operand(arguments, length, times_pointer_size, kPointerSize)); |
| 2612 } | 2612 } |
| 2613 | 2613 |
| 2614 | 2614 |
| 2615 template <class T> | |
| 2616 inline void LCodeGen::HandleKeyedAlterations(T* hydrogen_instr, LOperand* key) { | |
|
danno
2012/11/07 22:34:38
How about "PrepareKeyForKeyedOp" or "PrepareKeyFor
mvstanton
2012/11/09 09:43:13
Done.
| |
| 2617 if (ArrayOpClobbersKey<T>(hydrogen_instr)) { | |
| 2618 // Even though the HLoad/StoreKeyed (in this case) instructions force | |
| 2619 // the input representation for the key to be an integer, the input | |
| 2620 // gets replaced during bound check elimination with the index argument | |
| 2621 // to the bounds check, which can be tagged, so that case must be | |
| 2622 // handled here, too. | |
| 2623 Register key_reg = ToRegister(key); | |
| 2624 if (hydrogen_instr->key()->representation().IsTagged()) { | |
| 2625 __ SmiToInteger64(key_reg, key_reg); | |
| 2626 } else if (hydrogen_instr->IsDehoisted()) { | |
| 2627 // Sign extend key because it could be a 32 bit negative value | |
| 2628 // and the dehoisted address computation happens in 64 bits | |
| 2629 __ movsxlq(key_reg, key_reg); | |
| 2630 } | |
| 2631 } | |
| 2632 } | |
| 2633 | |
| 2634 | |
| 2615 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { | 2635 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { |
| 2616 ElementsKind elements_kind = instr->elements_kind(); | 2636 ElementsKind elements_kind = instr->elements_kind(); |
| 2617 LOperand* key = instr->key(); | 2637 LOperand* key = instr->key(); |
| 2618 if (!key->IsConstantOperand()) { | 2638 HandleKeyedAlterations(instr->hydrogen(), key); |
| 2619 Register key_reg = ToRegister(key); | |
| 2620 // Even though the HLoad/StoreKeyed (in this case) instructions force | |
| 2621 // the input representation for the key to be an integer, the input | |
| 2622 // gets replaced during bound check elimination with the index argument | |
| 2623 // to the bounds check, which can be tagged, so that case must be | |
| 2624 // handled here, too. | |
| 2625 if (instr->hydrogen()->key()->representation().IsTagged()) { | |
| 2626 __ SmiToInteger64(key_reg, key_reg); | |
| 2627 } else if (instr->hydrogen()->IsDehoisted()) { | |
| 2628 // Sign extend key because it could be a 32 bit negative value | |
| 2629 // and the dehoisted address computation happens in 64 bits | |
| 2630 __ movsxlq(key_reg, key_reg); | |
| 2631 } | |
| 2632 } | |
| 2633 Operand operand(BuildFastArrayOperand( | 2639 Operand operand(BuildFastArrayOperand( |
| 2634 instr->elements(), | 2640 instr->elements(), |
| 2635 key, | 2641 key, |
| 2636 elements_kind, | 2642 elements_kind, |
| 2637 0, | 2643 0, |
| 2638 instr->additional_index())); | 2644 instr->additional_index())); |
| 2639 | 2645 |
| 2640 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 2646 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
| 2641 XMMRegister result(ToDoubleRegister(instr->result())); | 2647 XMMRegister result(ToDoubleRegister(instr->result())); |
| 2642 __ movss(result, operand); | 2648 __ movss(result, operand); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2682 UNREACHABLE(); | 2688 UNREACHABLE(); |
| 2683 break; | 2689 break; |
| 2684 } | 2690 } |
| 2685 } | 2691 } |
| 2686 } | 2692 } |
| 2687 | 2693 |
| 2688 | 2694 |
| 2689 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { | 2695 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { |
| 2690 XMMRegister result(ToDoubleRegister(instr->result())); | 2696 XMMRegister result(ToDoubleRegister(instr->result())); |
| 2691 LOperand* key = instr->key(); | 2697 LOperand* key = instr->key(); |
| 2692 if (!key->IsConstantOperand()) { | 2698 HandleKeyedAlterations<HLoadKeyed>(instr->hydrogen(), key); |
| 2693 Register key_reg = ToRegister(key); | |
| 2694 // Even though the HLoad/StoreKeyed instructions force the input | |
| 2695 // representation for the key to be an integer, the input gets replaced | |
| 2696 // during bound check elimination with the index argument to the bounds | |
| 2697 // check, which can be tagged, so that case must be handled here, too. | |
| 2698 if (instr->hydrogen()->key()->representation().IsTagged()) { | |
| 2699 __ SmiToInteger64(key_reg, key_reg); | |
| 2700 } else if (instr->hydrogen()->IsDehoisted()) { | |
| 2701 // Sign extend key because it could be a 32 bit negative value | |
| 2702 // and the dehoisted address computation happens in 64 bits | |
| 2703 __ movsxlq(key_reg, key_reg); | |
| 2704 } | |
| 2705 } | |
| 2706 | |
| 2707 if (instr->hydrogen()->RequiresHoleCheck()) { | 2699 if (instr->hydrogen()->RequiresHoleCheck()) { |
| 2708 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag + | 2700 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag + |
| 2709 sizeof(kHoleNanLower32); | 2701 sizeof(kHoleNanLower32); |
| 2710 Operand hole_check_operand = BuildFastArrayOperand( | 2702 Operand hole_check_operand = BuildFastArrayOperand( |
| 2711 instr->elements(), | 2703 instr->elements(), |
| 2712 key, | 2704 key, |
| 2713 FAST_DOUBLE_ELEMENTS, | 2705 FAST_DOUBLE_ELEMENTS, |
| 2714 offset, | 2706 offset, |
| 2715 instr->additional_index()); | 2707 instr->additional_index()); |
| 2716 __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32)); | 2708 __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32)); |
| 2717 DeoptimizeIf(equal, instr->environment()); | 2709 DeoptimizeIf(equal, instr->environment()); |
| 2718 } | 2710 } |
| 2719 | 2711 |
| 2720 Operand double_load_operand = BuildFastArrayOperand( | 2712 Operand double_load_operand = BuildFastArrayOperand( |
| 2721 instr->elements(), | 2713 instr->elements(), |
| 2722 key, | 2714 key, |
| 2723 FAST_DOUBLE_ELEMENTS, | 2715 FAST_DOUBLE_ELEMENTS, |
| 2724 FixedDoubleArray::kHeaderSize - kHeapObjectTag, | 2716 FixedDoubleArray::kHeaderSize - kHeapObjectTag, |
| 2725 instr->additional_index()); | 2717 instr->additional_index()); |
| 2726 __ movsd(result, double_load_operand); | 2718 __ movsd(result, double_load_operand); |
| 2727 } | 2719 } |
| 2728 | 2720 |
| 2729 | 2721 |
| 2730 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { | 2722 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { |
| 2731 Register result = ToRegister(instr->result()); | 2723 Register result = ToRegister(instr->result()); |
| 2732 LOperand* key = instr->key(); | 2724 LOperand* key = instr->key(); |
| 2733 if (!key->IsConstantOperand()) { | 2725 HandleKeyedAlterations<HLoadKeyed>(instr->hydrogen(), key); |
| 2734 Register key_reg = ToRegister(key); | |
| 2735 // Even though the HLoad/StoreKeyedFastElement instructions force | |
| 2736 // the input representation for the key to be an integer, the input | |
| 2737 // gets replaced during bound check elimination with the index | |
| 2738 // argument to the bounds check, which can be tagged, so that | |
| 2739 // case must be handled here, too. | |
| 2740 if (instr->hydrogen()->key()->representation().IsTagged()) { | |
| 2741 __ SmiToInteger64(key_reg, key_reg); | |
| 2742 } else if (instr->hydrogen()->IsDehoisted()) { | |
| 2743 // Sign extend key because it could be a 32 bit negative value | |
| 2744 // and the dehoisted address computation happens in 64 bits | |
| 2745 __ movsxlq(key_reg, key_reg); | |
| 2746 } | |
| 2747 } | |
| 2748 | 2726 |
| 2749 // Load the result. | 2727 // Load the result. |
| 2750 __ movq(result, | 2728 __ movq(result, |
| 2751 BuildFastArrayOperand(instr->elements(), | 2729 BuildFastArrayOperand(instr->elements(), |
| 2752 key, | 2730 key, |
| 2753 FAST_ELEMENTS, | 2731 FAST_ELEMENTS, |
| 2754 FixedArray::kHeaderSize - kHeapObjectTag, | 2732 FixedArray::kHeaderSize - kHeapObjectTag, |
| 2755 instr->additional_index())); | 2733 instr->additional_index())); |
| 2756 | 2734 |
| 2757 // Check for the hole value. | 2735 // Check for the hole value. |
| (...skipping 974 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3732 __ cmpq(length, ToRegister(instr->index())); | 3710 __ cmpq(length, ToRegister(instr->index())); |
| 3733 } | 3711 } |
| 3734 } | 3712 } |
| 3735 DeoptimizeIf(below_equal, instr->environment()); | 3713 DeoptimizeIf(below_equal, instr->environment()); |
| 3736 } | 3714 } |
| 3737 | 3715 |
| 3738 | 3716 |
| 3739 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { | 3717 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { |
| 3740 ElementsKind elements_kind = instr->elements_kind(); | 3718 ElementsKind elements_kind = instr->elements_kind(); |
| 3741 LOperand* key = instr->key(); | 3719 LOperand* key = instr->key(); |
| 3742 if (!key->IsConstantOperand()) { | 3720 HandleKeyedAlterations<HStoreKeyed>(instr->hydrogen(), key); |
| 3743 Register key_reg = ToRegister(key); | |
| 3744 // Even though the HLoad/StoreKeyedFastElement instructions force | |
| 3745 // the input representation for the key to be an integer, the input | |
| 3746 // gets replaced during bound check elimination with the index | |
| 3747 // argument to the bounds check, which can be tagged, so that case | |
| 3748 // must be handled here, too. | |
| 3749 if (instr->hydrogen()->key()->representation().IsTagged()) { | |
| 3750 __ SmiToInteger64(key_reg, key_reg); | |
| 3751 } else if (instr->hydrogen()->IsDehoisted()) { | |
| 3752 // Sign extend key because it could be a 32 bit negative value | |
| 3753 // and the dehoisted address computation happens in 64 bits | |
| 3754 __ movsxlq(key_reg, key_reg); | |
| 3755 } | |
| 3756 } | |
| 3757 Operand operand(BuildFastArrayOperand( | 3721 Operand operand(BuildFastArrayOperand( |
| 3758 instr->elements(), | 3722 instr->elements(), |
| 3759 key, | 3723 key, |
| 3760 elements_kind, | 3724 elements_kind, |
| 3761 0, | 3725 0, |
| 3762 instr->additional_index())); | 3726 instr->additional_index())); |
| 3763 | 3727 |
| 3764 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 3728 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
| 3765 XMMRegister value(ToDoubleRegister(instr->value())); | 3729 XMMRegister value(ToDoubleRegister(instr->value())); |
| 3766 __ cvtsd2ss(value, value); | 3730 __ cvtsd2ss(value, value); |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 3796 UNREACHABLE(); | 3760 UNREACHABLE(); |
| 3797 break; | 3761 break; |
| 3798 } | 3762 } |
| 3799 } | 3763 } |
| 3800 } | 3764 } |
| 3801 | 3765 |
| 3802 | 3766 |
| 3803 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { | 3767 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { |
| 3804 XMMRegister value = ToDoubleRegister(instr->value()); | 3768 XMMRegister value = ToDoubleRegister(instr->value()); |
| 3805 LOperand* key = instr->key(); | 3769 LOperand* key = instr->key(); |
| 3806 if (!key->IsConstantOperand()) { | 3770 HandleKeyedAlterations<HStoreKeyed>(instr->hydrogen(), key); |
| 3807 Register key_reg = ToRegister(key); | |
| 3808 // Even though the HLoad/StoreKeyedFastElement instructions force | |
| 3809 // the input representation for the key to be an integer, the | |
| 3810 // input gets replaced during bound check elimination with the index | |
| 3811 // argument to the bounds check, which can be tagged, so that case | |
| 3812 // must be handled here, too. | |
| 3813 if (instr->hydrogen()->key()->representation().IsTagged()) { | |
| 3814 __ SmiToInteger64(key_reg, key_reg); | |
| 3815 } else if (instr->hydrogen()->IsDehoisted()) { | |
| 3816 // Sign extend key because it could be a 32 bit negative value | |
| 3817 // and the dehoisted address computation happens in 64 bits | |
| 3818 __ movsxlq(key_reg, key_reg); | |
| 3819 } | |
| 3820 } | |
| 3821 | |
| 3822 if (instr->NeedsCanonicalization()) { | 3771 if (instr->NeedsCanonicalization()) { |
| 3823 Label have_value; | 3772 Label have_value; |
| 3824 | 3773 |
| 3825 __ ucomisd(value, value); | 3774 __ ucomisd(value, value); |
| 3826 __ j(parity_odd, &have_value); // NaN. | 3775 __ j(parity_odd, &have_value); // NaN. |
| 3827 | 3776 |
| 3828 __ Set(kScratchRegister, BitCast<uint64_t>( | 3777 __ Set(kScratchRegister, BitCast<uint64_t>( |
| 3829 FixedDoubleArray::canonical_not_the_hole_nan_as_double())); | 3778 FixedDoubleArray::canonical_not_the_hole_nan_as_double())); |
| 3830 __ movq(value, kScratchRegister); | 3779 __ movq(value, kScratchRegister); |
| 3831 | 3780 |
| 3832 __ bind(&have_value); | 3781 __ bind(&have_value); |
| 3833 } | 3782 } |
| 3834 | 3783 |
| 3835 Operand double_store_operand = BuildFastArrayOperand( | 3784 Operand double_store_operand = BuildFastArrayOperand( |
| 3836 instr->elements(), | 3785 instr->elements(), |
| 3837 key, | 3786 key, |
| 3838 FAST_DOUBLE_ELEMENTS, | 3787 FAST_DOUBLE_ELEMENTS, |
| 3839 FixedDoubleArray::kHeaderSize - kHeapObjectTag, | 3788 FixedDoubleArray::kHeaderSize - kHeapObjectTag, |
| 3840 instr->additional_index()); | 3789 instr->additional_index()); |
| 3841 | 3790 |
| 3842 __ movsd(double_store_operand, value); | 3791 __ movsd(double_store_operand, value); |
| 3843 } | 3792 } |
| 3844 | 3793 |
| 3845 | 3794 |
| 3846 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { | 3795 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { |
| 3847 Register value = ToRegister(instr->value()); | 3796 Register value = ToRegister(instr->value()); |
| 3848 Register elements = ToRegister(instr->elements()); | 3797 Register elements = ToRegister(instr->elements()); |
| 3849 LOperand* key = instr->key(); | 3798 LOperand* key = instr->key(); |
| 3850 if (!key->IsConstantOperand()) { | 3799 HandleKeyedAlterations<HStoreKeyed>(instr->hydrogen(), key); |
| 3851 Register key_reg = ToRegister(key); | |
| 3852 // Even though the HLoad/StoreKeyedFastElement instructions force | |
| 3853 // the input representation for the key to be an integer, the | |
| 3854 // input gets replaced during bound check elimination with the index | |
| 3855 // argument to the bounds check, which can be tagged, so that case | |
| 3856 // must be handled here, too. | |
| 3857 if (instr->hydrogen()->key()->representation().IsTagged()) { | |
| 3858 __ SmiToInteger64(key_reg, key_reg); | |
| 3859 } else if (instr->hydrogen()->IsDehoisted()) { | |
| 3860 // Sign extend key because it could be a 32 bit negative value | |
| 3861 // and the dehoisted address computation happens in 64 bits | |
| 3862 __ movsxlq(key_reg, key_reg); | |
| 3863 } | |
| 3864 } | |
| 3865 | 3800 |
| 3866 Operand operand = | 3801 Operand operand = |
| 3867 BuildFastArrayOperand(instr->elements(), | 3802 BuildFastArrayOperand(instr->elements(), |
| 3868 key, | 3803 key, |
| 3869 FAST_ELEMENTS, | 3804 FAST_ELEMENTS, |
| 3870 FixedArray::kHeaderSize - kHeapObjectTag, | 3805 FixedArray::kHeaderSize - kHeapObjectTag, |
| 3871 instr->additional_index()); | 3806 instr->additional_index()); |
| 3872 | 3807 |
| 3873 if (instr->hydrogen()->NeedsWriteBarrier()) { | 3808 if (instr->hydrogen()->NeedsWriteBarrier()) { |
| 3874 ASSERT(!instr->key()->IsConstantOperand()); | 3809 ASSERT(!instr->key()->IsConstantOperand()); |
| (...skipping 1460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5335 FixedArray::kHeaderSize - kPointerSize)); | 5270 FixedArray::kHeaderSize - kPointerSize)); |
| 5336 __ bind(&done); | 5271 __ bind(&done); |
| 5337 } | 5272 } |
| 5338 | 5273 |
| 5339 | 5274 |
| 5340 #undef __ | 5275 #undef __ |
| 5341 | 5276 |
| 5342 } } // namespace v8::internal | 5277 } } // namespace v8::internal |
| 5343 | 5278 |
| 5344 #endif // V8_TARGET_ARCH_X64 | 5279 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |