Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: src/ia32/lithium-codegen-ia32.cc

Issue 11238016: Consolidated all the key store/load classes in the Hydrogen and Lithium (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fixed the 2 failing mjsunit tests Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 2731 matching lines...) Expand 10 before | Expand all | Expand 10 after
2742 Register length = ToRegister(instr->length()); 2742 Register length = ToRegister(instr->length());
2743 Operand index = ToOperand(instr->index()); 2743 Operand index = ToOperand(instr->index());
2744 Register result = ToRegister(instr->result()); 2744 Register result = ToRegister(instr->result());
2745 // There are two words between the frame pointer and the last argument. 2745 // There are two words between the frame pointer and the last argument.
2746 // Subtracting from length accounts for one of them add one more. 2746 // Subtracting from length accounts for one of them add one more.
2747 __ sub(length, index); 2747 __ sub(length, index);
2748 __ mov(result, Operand(arguments, length, times_4, kPointerSize)); 2748 __ mov(result, Operand(arguments, length, times_4, kPointerSize));
2749 } 2749 }
2750 2750
2751 2751
2752 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { 2752 void LCodeGen::DoLoadKeyedExternal(LLoadKeyed* instr) {
2753 Register result = ToRegister(instr->result());
2754
2755 // Load the result.
2756 __ mov(result,
2757 BuildFastArrayOperand(instr->elements(),
2758 instr->key(),
2759 instr->hydrogen()->key()->representation(),
2760 FAST_ELEMENTS,
2761 FixedArray::kHeaderSize - kHeapObjectTag,
2762 instr->additional_index()));
2763
2764 // Check for the hole value.
2765 if (instr->hydrogen()->RequiresHoleCheck()) {
2766 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) {
2767 __ test(result, Immediate(kSmiTagMask));
2768 DeoptimizeIf(not_equal, instr->environment());
2769 } else {
2770 __ cmp(result, factory()->the_hole_value());
2771 DeoptimizeIf(equal, instr->environment());
2772 }
2773 }
2774 }
2775
2776
2777 void LCodeGen::DoLoadKeyedFastDoubleElement(
2778 LLoadKeyedFastDoubleElement* instr) {
2779 XMMRegister result = ToDoubleRegister(instr->result());
2780
2781 if (instr->hydrogen()->RequiresHoleCheck()) {
2782 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag +
2783 sizeof(kHoleNanLower32);
2784 Operand hole_check_operand = BuildFastArrayOperand(
2785 instr->elements(), instr->key(),
2786 instr->hydrogen()->key()->representation(),
2787 FAST_DOUBLE_ELEMENTS,
2788 offset,
2789 instr->additional_index());
2790 __ cmp(hole_check_operand, Immediate(kHoleNanUpper32));
2791 DeoptimizeIf(equal, instr->environment());
2792 }
2793
2794 Operand double_load_operand = BuildFastArrayOperand(
2795 instr->elements(),
2796 instr->key(),
2797 instr->hydrogen()->key()->representation(),
2798 FAST_DOUBLE_ELEMENTS,
2799 FixedDoubleArray::kHeaderSize - kHeapObjectTag,
2800 instr->additional_index());
2801 __ movdbl(result, double_load_operand);
2802 }
2803
2804
2805 Operand LCodeGen::BuildFastArrayOperand(
2806 LOperand* elements_pointer,
2807 LOperand* key,
2808 Representation key_representation,
2809 ElementsKind elements_kind,
2810 uint32_t offset,
2811 uint32_t additional_index) {
2812 Register elements_pointer_reg = ToRegister(elements_pointer);
2813 int shift_size = ElementsKindToShiftSize(elements_kind);
2814 // Even though the HLoad/StoreKeyedFastElement instructions force the input
2815 // representation for the key to be an integer, the input gets replaced during
2816 // bound check elimination with the index argument to the bounds check, which
2817 // can be tagged, so that case must be handled here, too.
2818 if (key_representation.IsTagged() && (shift_size >= 1)) {
2819 shift_size -= kSmiTagSize;
2820 }
2821 if (key->IsConstantOperand()) {
2822 int constant_value = ToInteger32(LConstantOperand::cast(key));
2823 if (constant_value & 0xF0000000) {
2824 Abort("array index constant value too big");
2825 }
2826 return Operand(elements_pointer_reg,
2827 ((constant_value + additional_index) << shift_size)
2828 + offset);
2829 } else {
2830 ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size);
2831 return Operand(elements_pointer_reg,
2832 ToRegister(key),
2833 scale_factor,
2834 offset + (additional_index << shift_size));
2835 }
2836 }
2837
2838
2839 void LCodeGen::DoLoadKeyedSpecializedArrayElement(
2840 LLoadKeyedSpecializedArrayElement* instr) {
2841 ElementsKind elements_kind = instr->elements_kind(); 2753 ElementsKind elements_kind = instr->elements_kind();
2842 LOperand* key = instr->key(); 2754 LOperand* key = instr->key();
2843 if (!key->IsConstantOperand() && 2755 if (!key->IsConstantOperand() &&
2844 ExternalArrayOpRequiresTemp(instr->hydrogen()->key()->representation(), 2756 ExternalArrayOpRequiresTemp(instr->hydrogen()->key()->representation(),
2845 elements_kind)) { 2757 elements_kind)) {
2846 __ SmiUntag(ToRegister(key)); 2758 __ SmiUntag(ToRegister(key));
2847 } 2759 }
2848 Operand operand(BuildFastArrayOperand( 2760 Operand operand(BuildFastArrayOperand(
2849 instr->external_pointer(), 2761 instr->external_pointer(),
2850 key, 2762 key,
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
2894 case FAST_HOLEY_DOUBLE_ELEMENTS: 2806 case FAST_HOLEY_DOUBLE_ELEMENTS:
2895 case DICTIONARY_ELEMENTS: 2807 case DICTIONARY_ELEMENTS:
2896 case NON_STRICT_ARGUMENTS_ELEMENTS: 2808 case NON_STRICT_ARGUMENTS_ELEMENTS:
2897 UNREACHABLE(); 2809 UNREACHABLE();
2898 break; 2810 break;
2899 } 2811 }
2900 } 2812 }
2901 } 2813 }
2902 2814
2903 2815
2816 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) {
2817 if (instr->is_external()) {
2818 DoLoadKeyedExternal(instr);
2819 } else if (instr->hydrogen()->representation().IsDouble()) {
2820 XMMRegister result = ToDoubleRegister(instr->result());
2821
2822 if (instr->hydrogen()->RequiresHoleCheck()) {
2823 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag +
2824 sizeof(kHoleNanLower32);
2825 Operand hole_check_operand = BuildFastArrayOperand(
2826 instr->elements(), instr->key(),
2827 instr->hydrogen()->key()->representation(),
2828 FAST_DOUBLE_ELEMENTS,
2829 offset,
2830 instr->additional_index());
2831 __ cmp(hole_check_operand, Immediate(kHoleNanUpper32));
2832 DeoptimizeIf(equal, instr->environment());
2833 }
2834
2835 Operand double_load_operand = BuildFastArrayOperand(
2836 instr->elements(),
2837 instr->key(),
2838 instr->hydrogen()->key()->representation(),
2839 FAST_DOUBLE_ELEMENTS,
2840 FixedDoubleArray::kHeaderSize - kHeapObjectTag,
2841 instr->additional_index());
2842 __ movdbl(result, double_load_operand);
2843 } else {
2844 Register result = ToRegister(instr->result());
2845
2846 // Load the result.
2847 __ mov(result,
2848 BuildFastArrayOperand(instr->elements(),
2849 instr->key(),
2850 instr->hydrogen()->key()->representation(),
2851 FAST_ELEMENTS,
2852 FixedArray::kHeaderSize - kHeapObjectTag,
2853 instr->additional_index()));
2854
2855 // Check for the hole value.
2856 if (instr->hydrogen()->RequiresHoleCheck()) {
2857 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) {
2858 __ test(result, Immediate(kSmiTagMask));
2859 DeoptimizeIf(not_equal, instr->environment());
2860 } else {
2861 __ cmp(result, factory()->the_hole_value());
2862 DeoptimizeIf(equal, instr->environment());
2863 }
2864 }
2865 }
2866 }
2867
2868
2869 Operand LCodeGen::BuildFastArrayOperand(
2870 LOperand* elements_pointer,
2871 LOperand* key,
2872 Representation key_representation,
2873 ElementsKind elements_kind,
2874 uint32_t offset,
2875 uint32_t additional_index) {
2876 Register elements_pointer_reg = ToRegister(elements_pointer);
2877 int shift_size = ElementsKindToShiftSize(elements_kind);
2878 // Even though the HLoad/StoreKeyed instructions force the input
2879 // representation for the key to be an integer, the input gets replaced during
2880 // bound check elimination with the index argument to the bounds check, which
2881 // can be tagged, so that case must be handled here, too.
2882 if (key_representation.IsTagged() && (shift_size >= 1)) {
2883 shift_size -= kSmiTagSize;
2884 }
2885 if (key->IsConstantOperand()) {
2886 int constant_value = ToInteger32(LConstantOperand::cast(key));
2887 if (constant_value & 0xF0000000) {
2888 Abort("array index constant value too big");
2889 }
2890 return Operand(elements_pointer_reg,
2891 ((constant_value + additional_index) << shift_size)
2892 + offset);
2893 } else {
2894 ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size);
2895 return Operand(elements_pointer_reg,
2896 ToRegister(key),
2897 scale_factor,
2898 offset + (additional_index << shift_size));
2899 }
2900 }
2901
2902
2904 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { 2903 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
2905 ASSERT(ToRegister(instr->context()).is(esi)); 2904 ASSERT(ToRegister(instr->context()).is(esi));
2906 ASSERT(ToRegister(instr->object()).is(edx)); 2905 ASSERT(ToRegister(instr->object()).is(edx));
2907 ASSERT(ToRegister(instr->key()).is(ecx)); 2906 ASSERT(ToRegister(instr->key()).is(ecx));
2908 2907
2909 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2908 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2910 CallCode(ic, RelocInfo::CODE_TARGET, instr); 2909 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2911 } 2910 }
2912 2911
2913 2912
(...skipping 897 matching lines...) Expand 10 before | Expand all | Expand 10 after
3811 __ cmp(ToOperand(instr->length()), Immediate(constant_index)); 3810 __ cmp(ToOperand(instr->length()), Immediate(constant_index));
3812 } 3811 }
3813 DeoptimizeIf(below_equal, instr->environment()); 3812 DeoptimizeIf(below_equal, instr->environment());
3814 } else { 3813 } else {
3815 __ cmp(ToRegister(instr->index()), ToOperand(instr->length())); 3814 __ cmp(ToRegister(instr->index()), ToOperand(instr->length()));
3816 DeoptimizeIf(above_equal, instr->environment()); 3815 DeoptimizeIf(above_equal, instr->environment());
3817 } 3816 }
3818 } 3817 }
3819 3818
3820 3819
3821 void LCodeGen::DoStoreKeyedSpecializedArrayElement( 3820 void LCodeGen::DoStoreKeyedExternal(LStoreKeyed* instr) {
3822 LStoreKeyedSpecializedArrayElement* instr) {
3823 ElementsKind elements_kind = instr->elements_kind(); 3821 ElementsKind elements_kind = instr->elements_kind();
3824 LOperand* key = instr->key(); 3822 LOperand* key = instr->key();
3825 if (!key->IsConstantOperand() && 3823 if (!key->IsConstantOperand() &&
3826 ExternalArrayOpRequiresTemp(instr->hydrogen()->key()->representation(), 3824 ExternalArrayOpRequiresTemp(instr->hydrogen()->key()->representation(),
3827 elements_kind)) { 3825 elements_kind)) {
3828 __ SmiUntag(ToRegister(key)); 3826 __ SmiUntag(ToRegister(key));
3829 } 3827 }
3830 Operand operand(BuildFastArrayOperand( 3828 Operand operand(BuildFastArrayOperand(
3831 instr->external_pointer(), 3829 instr->external_pointer(),
3832 key, 3830 key,
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
3865 case FAST_HOLEY_DOUBLE_ELEMENTS: 3863 case FAST_HOLEY_DOUBLE_ELEMENTS:
3866 case DICTIONARY_ELEMENTS: 3864 case DICTIONARY_ELEMENTS:
3867 case NON_STRICT_ARGUMENTS_ELEMENTS: 3865 case NON_STRICT_ARGUMENTS_ELEMENTS:
3868 UNREACHABLE(); 3866 UNREACHABLE();
3869 break; 3867 break;
3870 } 3868 }
3871 } 3869 }
3872 } 3870 }
3873 3871
3874 3872
3875 void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) { 3873 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) {
3876 Register value = ToRegister(instr->value()); 3874 // By cases...external, fast-double, fast
3877 Register elements = ToRegister(instr->object()); 3875 if (instr->is_external()) {
3878 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg; 3876 DoStoreKeyedExternal(instr);
3877 } else if (instr->hydrogen()->value()->representation().IsDouble()) {
3878 XMMRegister value = ToDoubleRegister(instr->value());
3879 3879
3880 Operand operand = BuildFastArrayOperand( 3880 if (instr->NeedsCanonicalization()) {
3881 instr->object(), 3881 Label have_value;
3882 instr->key(),
3883 instr->hydrogen()->key()->representation(),
3884 FAST_ELEMENTS,
3885 FixedArray::kHeaderSize - kHeapObjectTag,
3886 instr->additional_index());
3887 __ mov(operand, value);
3888 3882
3889 if (instr->hydrogen()->NeedsWriteBarrier()) { 3883 __ ucomisd(value, value);
3890 ASSERT(!instr->key()->IsConstantOperand()); 3884 __ j(parity_odd, &have_value); // NaN.
3891 HType type = instr->hydrogen()->value()->type(); 3885
3892 SmiCheck check_needed = 3886 ExternalReference canonical_nan_reference =
3893 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 3887 ExternalReference::address_of_canonical_non_hole_nan();
3894 // Compute address of modified element and store it into key register. 3888 __ movdbl(value, Operand::StaticVariable(canonical_nan_reference));
3895 __ lea(key, operand); 3889 __ bind(&have_value);
3896 __ RecordWrite(elements, 3890 }
3897 key, 3891
3898 value, 3892 Operand double_store_operand = BuildFastArrayOperand(
3899 kSaveFPRegs, 3893 instr->object(),
3900 EMIT_REMEMBERED_SET, 3894 instr->key(),
3901 check_needed); 3895 instr->hydrogen()->key()->representation(),
3896 FAST_DOUBLE_ELEMENTS,
3897 FixedDoubleArray::kHeaderSize - kHeapObjectTag,
3898 instr->additional_index());
3899 __ movdbl(double_store_operand, value);
3900 } else {
3901 Register value = ToRegister(instr->value());
3902 Register elements = ToRegister(instr->object());
3903 Register key = instr->key()->IsRegister() ? ToRegister(instr->key())
3904 : no_reg;
3905
3906 Operand operand = BuildFastArrayOperand(
3907 instr->object(),
3908 instr->key(),
3909 instr->hydrogen()->key()->representation(),
3910 FAST_ELEMENTS,
3911 FixedArray::kHeaderSize - kHeapObjectTag,
3912 instr->additional_index());
3913 __ mov(operand, value);
3914
3915 if (instr->hydrogen()->NeedsWriteBarrier()) {
3916 ASSERT(!instr->key()->IsConstantOperand());
3917 HType type = instr->hydrogen()->value()->type();
3918 SmiCheck check_needed =
3919 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
3920 // Compute address of modified element and store it into key register.
3921 __ lea(key, operand);
3922 __ RecordWrite(elements,
3923 key,
3924 value,
3925 kSaveFPRegs,
3926 EMIT_REMEMBERED_SET,
3927 check_needed);
3928 }
3902 } 3929 }
3903 } 3930 }
3904 3931
3905 3932
3906 void LCodeGen::DoStoreKeyedFastDoubleElement(
3907 LStoreKeyedFastDoubleElement* instr) {
3908 XMMRegister value = ToDoubleRegister(instr->value());
3909
3910 if (instr->NeedsCanonicalization()) {
3911 Label have_value;
3912
3913 __ ucomisd(value, value);
3914 __ j(parity_odd, &have_value); // NaN.
3915
3916 ExternalReference canonical_nan_reference =
3917 ExternalReference::address_of_canonical_non_hole_nan();
3918 __ movdbl(value, Operand::StaticVariable(canonical_nan_reference));
3919 __ bind(&have_value);
3920 }
3921
3922 Operand double_store_operand = BuildFastArrayOperand(
3923 instr->elements(),
3924 instr->key(),
3925 instr->hydrogen()->key()->representation(),
3926 FAST_DOUBLE_ELEMENTS,
3927 FixedDoubleArray::kHeaderSize - kHeapObjectTag,
3928 instr->additional_index());
3929 __ movdbl(double_store_operand, value);
3930 }
3931
3932
3933 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { 3933 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
3934 ASSERT(ToRegister(instr->context()).is(esi)); 3934 ASSERT(ToRegister(instr->context()).is(esi));
3935 ASSERT(ToRegister(instr->object()).is(edx)); 3935 ASSERT(ToRegister(instr->object()).is(edx));
3936 ASSERT(ToRegister(instr->key()).is(ecx)); 3936 ASSERT(ToRegister(instr->key()).is(ecx));
3937 ASSERT(ToRegister(instr->value()).is(eax)); 3937 ASSERT(ToRegister(instr->value()).is(eax));
3938 3938
3939 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) 3939 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
3940 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 3940 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
3941 : isolate()->builtins()->KeyedStoreIC_Initialize(); 3941 : isolate()->builtins()->KeyedStoreIC_Initialize();
3942 CallCode(ic, RelocInfo::CODE_TARGET, instr); 3942 CallCode(ic, RelocInfo::CODE_TARGET, instr);
(...skipping 1594 matching lines...) Expand 10 before | Expand all | Expand 10 after
5537 FixedArray::kHeaderSize - kPointerSize)); 5537 FixedArray::kHeaderSize - kPointerSize));
5538 __ bind(&done); 5538 __ bind(&done);
5539 } 5539 }
5540 5540
5541 5541
5542 #undef __ 5542 #undef __
5543 5543
5544 } } // namespace v8::internal 5544 } } // namespace v8::internal
5545 5545
5546 #endif // V8_TARGET_ARCH_IA32 5546 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698