| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 950 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 961 case CodeStub::SubString: { | 961 case CodeStub::SubString: { |
| 962 SubStringStub stub; | 962 SubStringStub stub; |
| 963 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 963 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| 964 break; | 964 break; |
| 965 } | 965 } |
| 966 case CodeStub::StringCompare: { | 966 case CodeStub::StringCompare: { |
| 967 StringCompareStub stub; | 967 StringCompareStub stub; |
| 968 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 968 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| 969 break; | 969 break; |
| 970 } | 970 } |
| 971 case CodeStub::TranscendentalCache: { | |
| 972 TranscendentalCacheStub stub(instr->transcendental_type(), | |
| 973 TranscendentalCacheStub::TAGGED); | |
| 974 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | |
| 975 break; | |
| 976 } | |
| 977 default: | 971 default: |
| 978 UNREACHABLE(); | 972 UNREACHABLE(); |
| 979 } | 973 } |
| 980 } | 974 } |
| 981 | 975 |
| 982 | 976 |
| 983 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { | 977 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { |
| 984 GenerateOsrPrologue(); | 978 GenerateOsrPrologue(); |
| 985 } | 979 } |
| 986 | 980 |
| (...skipping 910 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1897 // Don't delete this mov. It may improve performance on some CPUs, | 1891 // Don't delete this mov. It may improve performance on some CPUs, |
| 1898 // when there is a mulsd depending on the result | 1892 // when there is a mulsd depending on the result |
| 1899 __ movaps(left, left); | 1893 __ movaps(left, left); |
| 1900 break; | 1894 break; |
| 1901 case Token::MOD: { | 1895 case Token::MOD: { |
| 1902 XMMRegister xmm_scratch = double_scratch0(); | 1896 XMMRegister xmm_scratch = double_scratch0(); |
| 1903 __ PrepareCallCFunction(2); | 1897 __ PrepareCallCFunction(2); |
| 1904 __ movaps(xmm_scratch, left); | 1898 __ movaps(xmm_scratch, left); |
| 1905 ASSERT(right.is(xmm1)); | 1899 ASSERT(right.is(xmm1)); |
| 1906 __ CallCFunction( | 1900 __ CallCFunction( |
| 1907 ExternalReference::double_fp_operation(Token::MOD, isolate()), 2); | 1901 ExternalReference::mod_two_doubles_operation(isolate()), 2); |
| 1908 __ movaps(result, xmm_scratch); | 1902 __ movaps(result, xmm_scratch); |
| 1909 break; | 1903 break; |
| 1910 } | 1904 } |
| 1911 default: | 1905 default: |
| 1912 UNREACHABLE(); | 1906 UNREACHABLE(); |
| 1913 break; | 1907 break; |
| 1914 } | 1908 } |
| 1915 } | 1909 } |
| 1916 | 1910 |
| 1917 | 1911 |
| (...skipping 918 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2836 XMMRegister result = ToDoubleRegister(instr->result()); | 2830 XMMRegister result = ToDoubleRegister(instr->result()); |
| 2837 __ movsd(result, FieldOperand(object, offset)); | 2831 __ movsd(result, FieldOperand(object, offset)); |
| 2838 return; | 2832 return; |
| 2839 } | 2833 } |
| 2840 | 2834 |
| 2841 Register result = ToRegister(instr->result()); | 2835 Register result = ToRegister(instr->result()); |
| 2842 if (!access.IsInobject()) { | 2836 if (!access.IsInobject()) { |
| 2843 __ movq(result, FieldOperand(object, JSObject::kPropertiesOffset)); | 2837 __ movq(result, FieldOperand(object, JSObject::kPropertiesOffset)); |
| 2844 object = result; | 2838 object = result; |
| 2845 } | 2839 } |
| 2846 __ Load(result, FieldOperand(object, offset), access.representation()); | 2840 |
| 2841 Representation representation = access.representation(); |
| 2842 if (representation.IsSmi() && |
| 2843 instr->hydrogen()->representation().IsInteger32()) { |
| 2844 // Read int value directly from upper half of the smi. |
| 2845 STATIC_ASSERT(kSmiTag == 0); |
| 2846 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32); |
| 2847 offset += kPointerSize / 2; |
| 2848 representation = Representation::Integer32(); |
| 2849 } |
| 2850 __ Load(result, FieldOperand(object, offset), representation); |
| 2847 } | 2851 } |
| 2848 | 2852 |
| 2849 | 2853 |
| 2850 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { | 2854 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { |
| 2851 ASSERT(ToRegister(instr->context()).is(rsi)); | 2855 ASSERT(ToRegister(instr->context()).is(rsi)); |
| 2852 ASSERT(ToRegister(instr->object()).is(rax)); | 2856 ASSERT(ToRegister(instr->object()).is(rax)); |
| 2853 ASSERT(ToRegister(instr->result()).is(rax)); | 2857 ASSERT(ToRegister(instr->result()).is(rax)); |
| 2854 | 2858 |
| 2855 __ Move(rcx, instr->name()); | 2859 __ Move(rcx, instr->name()); |
| 2856 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 2860 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3046 instr->elements(), | 3050 instr->elements(), |
| 3047 key, | 3051 key, |
| 3048 FAST_DOUBLE_ELEMENTS, | 3052 FAST_DOUBLE_ELEMENTS, |
| 3049 FixedDoubleArray::kHeaderSize - kHeapObjectTag, | 3053 FixedDoubleArray::kHeaderSize - kHeapObjectTag, |
| 3050 instr->additional_index()); | 3054 instr->additional_index()); |
| 3051 __ movsd(result, double_load_operand); | 3055 __ movsd(result, double_load_operand); |
| 3052 } | 3056 } |
| 3053 | 3057 |
| 3054 | 3058 |
| 3055 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { | 3059 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { |
| 3060 HLoadKeyed* hinstr = instr->hydrogen(); |
| 3056 Register result = ToRegister(instr->result()); | 3061 Register result = ToRegister(instr->result()); |
| 3057 LOperand* key = instr->key(); | 3062 LOperand* key = instr->key(); |
| 3058 if (!key->IsConstantOperand()) { | 3063 if (!key->IsConstantOperand()) { |
| 3059 Register key_reg = ToRegister(key); | 3064 Register key_reg = ToRegister(key); |
| 3060 // Even though the HLoad/StoreKeyedFastElement instructions force | 3065 // Even though the HLoad/StoreKeyedFastElement instructions force |
| 3061 // the input representation for the key to be an integer, the input | 3066 // the input representation for the key to be an integer, the input |
| 3062 // gets replaced during bound check elimination with the index | 3067 // gets replaced during bound check elimination with the index |
| 3063 // argument to the bounds check, which can be tagged, so that | 3068 // argument to the bounds check, which can be tagged, so that |
| 3064 // case must be handled here, too. | 3069 // case must be handled here, too. |
| 3065 if (instr->hydrogen()->IsDehoisted()) { | 3070 if (hinstr->IsDehoisted()) { |
| 3066 // Sign extend key because it could be a 32 bit negative value | 3071 // Sign extend key because it could be a 32 bit negative value |
| 3067 // and the dehoisted address computation happens in 64 bits | 3072 // and the dehoisted address computation happens in 64 bits |
| 3068 __ movsxlq(key_reg, key_reg); | 3073 __ movsxlq(key_reg, key_reg); |
| 3069 } | 3074 } |
| 3070 } | 3075 } |
| 3071 | 3076 |
| 3072 // Load the result. | 3077 bool requires_hole_check = hinstr->RequiresHoleCheck(); |
| 3073 __ movq(result, | 3078 int offset = FixedArray::kHeaderSize - kHeapObjectTag; |
| 3079 Representation representation = hinstr->representation(); |
| 3080 |
| 3081 if (representation.IsInteger32() && |
| 3082 hinstr->elements_kind() == FAST_SMI_ELEMENTS) { |
| 3083 ASSERT(!requires_hole_check); |
| 3084 // Read int value directly from upper half of the smi. |
| 3085 STATIC_ASSERT(kSmiTag == 0); |
| 3086 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32); |
| 3087 offset += kPointerSize / 2; |
| 3088 } |
| 3089 |
| 3090 __ Load(result, |
| 3074 BuildFastArrayOperand(instr->elements(), | 3091 BuildFastArrayOperand(instr->elements(), |
| 3075 key, | 3092 key, |
| 3076 FAST_ELEMENTS, | 3093 FAST_ELEMENTS, |
| 3077 FixedArray::kHeaderSize - kHeapObjectTag, | 3094 offset, |
| 3078 instr->additional_index())); | 3095 instr->additional_index()), |
| 3096 representation); |
| 3079 | 3097 |
| 3080 // Check for the hole value. | 3098 // Check for the hole value. |
| 3081 if (instr->hydrogen()->RequiresHoleCheck()) { | 3099 if (requires_hole_check) { |
| 3082 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { | 3100 if (IsFastSmiElementsKind(hinstr->elements_kind())) { |
| 3083 Condition smi = __ CheckSmi(result); | 3101 Condition smi = __ CheckSmi(result); |
| 3084 DeoptimizeIf(NegateCondition(smi), instr->environment()); | 3102 DeoptimizeIf(NegateCondition(smi), instr->environment()); |
| 3085 } else { | 3103 } else { |
| 3086 __ CompareRoot(result, Heap::kTheHoleValueRootIndex); | 3104 __ CompareRoot(result, Heap::kTheHoleValueRootIndex); |
| 3087 DeoptimizeIf(equal, instr->environment()); | 3105 DeoptimizeIf(equal, instr->environment()); |
| 3088 } | 3106 } |
| 3089 } | 3107 } |
| 3090 } | 3108 } |
| 3091 | 3109 |
| 3092 | 3110 |
| (...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3715 | 3733 |
| 3716 | 3734 |
| 3717 void LCodeGen::DoMathLog(LMathLog* instr) { | 3735 void LCodeGen::DoMathLog(LMathLog* instr) { |
| 3718 ASSERT(instr->value()->Equals(instr->result())); | 3736 ASSERT(instr->value()->Equals(instr->result())); |
| 3719 XMMRegister input_reg = ToDoubleRegister(instr->value()); | 3737 XMMRegister input_reg = ToDoubleRegister(instr->value()); |
| 3720 XMMRegister xmm_scratch = double_scratch0(); | 3738 XMMRegister xmm_scratch = double_scratch0(); |
| 3721 Label positive, done, zero; | 3739 Label positive, done, zero; |
| 3722 __ xorps(xmm_scratch, xmm_scratch); | 3740 __ xorps(xmm_scratch, xmm_scratch); |
| 3723 __ ucomisd(input_reg, xmm_scratch); | 3741 __ ucomisd(input_reg, xmm_scratch); |
| 3724 __ j(above, &positive, Label::kNear); | 3742 __ j(above, &positive, Label::kNear); |
| 3725 __ j(equal, &zero, Label::kNear); | 3743 __ j(not_carry, &zero, Label::kNear); |
| 3726 ExternalReference nan = | 3744 ExternalReference nan = |
| 3727 ExternalReference::address_of_canonical_non_hole_nan(); | 3745 ExternalReference::address_of_canonical_non_hole_nan(); |
| 3728 Operand nan_operand = masm()->ExternalOperand(nan); | 3746 Operand nan_operand = masm()->ExternalOperand(nan); |
| 3729 __ movsd(input_reg, nan_operand); | 3747 __ movsd(input_reg, nan_operand); |
| 3730 __ jmp(&done, Label::kNear); | 3748 __ jmp(&done, Label::kNear); |
| 3731 __ bind(&zero); | 3749 __ bind(&zero); |
| 3732 ExternalReference ninf = | 3750 ExternalReference ninf = |
| 3733 ExternalReference::address_of_negative_infinity(); | 3751 ExternalReference::address_of_negative_infinity(); |
| 3734 Operand ninf_operand = masm()->ExternalOperand(ninf); | 3752 Operand ninf_operand = masm()->ExternalOperand(ninf); |
| 3735 __ movsd(input_reg, ninf_operand); | 3753 __ movsd(input_reg, ninf_operand); |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3913 LConstantOperand* offset = LConstantOperand::cast(instr->offset()); | 3931 LConstantOperand* offset = LConstantOperand::cast(instr->offset()); |
| 3914 __ lea(result, Operand(base, ToInteger32(offset))); | 3932 __ lea(result, Operand(base, ToInteger32(offset))); |
| 3915 } else { | 3933 } else { |
| 3916 Register offset = ToRegister(instr->offset()); | 3934 Register offset = ToRegister(instr->offset()); |
| 3917 __ lea(result, Operand(base, offset, times_1, 0)); | 3935 __ lea(result, Operand(base, offset, times_1, 0)); |
| 3918 } | 3936 } |
| 3919 } | 3937 } |
| 3920 | 3938 |
| 3921 | 3939 |
| 3922 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { | 3940 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { |
| 3941 HStoreNamedField* hinstr = instr->hydrogen(); |
| 3923 Representation representation = instr->representation(); | 3942 Representation representation = instr->representation(); |
| 3924 | 3943 |
| 3925 HObjectAccess access = instr->hydrogen()->access(); | 3944 HObjectAccess access = hinstr->access(); |
| 3926 int offset = access.offset(); | 3945 int offset = access.offset(); |
| 3927 | 3946 |
| 3928 if (access.IsExternalMemory()) { | 3947 if (access.IsExternalMemory()) { |
| 3929 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); | 3948 ASSERT(!hinstr->NeedsWriteBarrier()); |
| 3930 Register value = ToRegister(instr->value()); | 3949 Register value = ToRegister(instr->value()); |
| 3931 if (instr->object()->IsConstantOperand()) { | 3950 if (instr->object()->IsConstantOperand()) { |
| 3932 ASSERT(value.is(rax)); | 3951 ASSERT(value.is(rax)); |
| 3933 ASSERT(!access.representation().IsSpecialization()); | 3952 ASSERT(!access.representation().IsSpecialization()); |
| 3934 LConstantOperand* object = LConstantOperand::cast(instr->object()); | 3953 LConstantOperand* object = LConstantOperand::cast(instr->object()); |
| 3935 __ store_rax(ToExternalReference(object)); | 3954 __ store_rax(ToExternalReference(object)); |
| 3936 } else { | 3955 } else { |
| 3937 Register object = ToRegister(instr->object()); | 3956 Register object = ToRegister(instr->object()); |
| 3938 __ Store(MemOperand(object, offset), value, representation); | 3957 __ Store(MemOperand(object, offset), value, representation); |
| 3939 } | 3958 } |
| 3940 return; | 3959 return; |
| 3941 } | 3960 } |
| 3942 | 3961 |
| 3943 Register object = ToRegister(instr->object()); | 3962 Register object = ToRegister(instr->object()); |
| 3944 Handle<Map> transition = instr->transition(); | 3963 Handle<Map> transition = instr->transition(); |
| 3945 | 3964 |
| 3946 if (FLAG_track_fields && representation.IsSmi()) { | 3965 if (FLAG_track_fields && representation.IsSmi()) { |
| 3947 if (instr->value()->IsConstantOperand()) { | 3966 if (instr->value()->IsConstantOperand()) { |
| 3948 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); | 3967 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); |
| 3949 if (!IsSmiConstant(operand_value)) { | 3968 if (!IsInteger32Constant(operand_value) && |
| 3969 !IsSmiConstant(operand_value)) { |
| 3950 DeoptimizeIf(no_condition, instr->environment()); | 3970 DeoptimizeIf(no_condition, instr->environment()); |
| 3951 } | 3971 } |
| 3952 } | 3972 } |
| 3953 } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { | 3973 } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { |
| 3954 if (instr->value()->IsConstantOperand()) { | 3974 if (instr->value()->IsConstantOperand()) { |
| 3955 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); | 3975 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); |
| 3956 if (IsInteger32Constant(operand_value)) { | 3976 if (IsInteger32Constant(operand_value)) { |
| 3957 DeoptimizeIf(no_condition, instr->environment()); | 3977 DeoptimizeIf(no_condition, instr->environment()); |
| 3958 } | 3978 } |
| 3959 } else { | 3979 } else { |
| 3960 if (!instr->hydrogen()->value()->type().IsHeapObject()) { | 3980 if (!hinstr->value()->type().IsHeapObject()) { |
| 3961 Register value = ToRegister(instr->value()); | 3981 Register value = ToRegister(instr->value()); |
| 3962 Condition cc = masm()->CheckSmi(value); | 3982 Condition cc = masm()->CheckSmi(value); |
| 3963 DeoptimizeIf(cc, instr->environment()); | 3983 DeoptimizeIf(cc, instr->environment()); |
| 3964 } | 3984 } |
| 3965 } | 3985 } |
| 3966 } else if (FLAG_track_double_fields && representation.IsDouble()) { | 3986 } else if (FLAG_track_double_fields && representation.IsDouble()) { |
| 3967 ASSERT(transition.is_null()); | 3987 ASSERT(transition.is_null()); |
| 3968 ASSERT(access.IsInobject()); | 3988 ASSERT(access.IsInobject()); |
| 3969 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); | 3989 ASSERT(!hinstr->NeedsWriteBarrier()); |
| 3970 XMMRegister value = ToDoubleRegister(instr->value()); | 3990 XMMRegister value = ToDoubleRegister(instr->value()); |
| 3971 __ movsd(FieldOperand(object, offset), value); | 3991 __ movsd(FieldOperand(object, offset), value); |
| 3972 return; | 3992 return; |
| 3973 } | 3993 } |
| 3974 | 3994 |
| 3975 if (!transition.is_null()) { | 3995 if (!transition.is_null()) { |
| 3976 if (!instr->hydrogen()->NeedsWriteBarrierForMap()) { | 3996 if (!hinstr->NeedsWriteBarrierForMap()) { |
| 3977 __ Move(FieldOperand(object, HeapObject::kMapOffset), transition); | 3997 __ Move(FieldOperand(object, HeapObject::kMapOffset), transition); |
| 3978 } else { | 3998 } else { |
| 3979 Register temp = ToRegister(instr->temp()); | 3999 Register temp = ToRegister(instr->temp()); |
| 3980 __ Move(kScratchRegister, transition); | 4000 __ Move(kScratchRegister, transition); |
| 3981 __ movq(FieldOperand(object, HeapObject::kMapOffset), kScratchRegister); | 4001 __ movq(FieldOperand(object, HeapObject::kMapOffset), kScratchRegister); |
| 3982 // Update the write barrier for the map field. | 4002 // Update the write barrier for the map field. |
| 3983 __ RecordWriteField(object, | 4003 __ RecordWriteField(object, |
| 3984 HeapObject::kMapOffset, | 4004 HeapObject::kMapOffset, |
| 3985 kScratchRegister, | 4005 kScratchRegister, |
| 3986 temp, | 4006 temp, |
| 3987 kSaveFPRegs, | 4007 kSaveFPRegs, |
| 3988 OMIT_REMEMBERED_SET, | 4008 OMIT_REMEMBERED_SET, |
| 3989 OMIT_SMI_CHECK); | 4009 OMIT_SMI_CHECK); |
| 3990 } | 4010 } |
| 3991 } | 4011 } |
| 3992 | 4012 |
| 3993 // Do the store. | 4013 // Do the store. |
| 3994 SmiCheck check_needed = | 4014 SmiCheck check_needed = hinstr->value()->IsHeapObject() |
| 3995 instr->hydrogen()->value()->IsHeapObject() | 4015 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
| 3996 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | |
| 3997 | 4016 |
| 3998 Register write_register = object; | 4017 Register write_register = object; |
| 3999 if (!access.IsInobject()) { | 4018 if (!access.IsInobject()) { |
| 4000 write_register = ToRegister(instr->temp()); | 4019 write_register = ToRegister(instr->temp()); |
| 4001 __ movq(write_register, FieldOperand(object, JSObject::kPropertiesOffset)); | 4020 __ movq(write_register, FieldOperand(object, JSObject::kPropertiesOffset)); |
| 4002 } | 4021 } |
| 4003 | 4022 |
| 4004 if (instr->value()->IsConstantOperand()) { | 4023 if (representation.IsSmi() && |
| 4024 hinstr->value()->representation().IsInteger32()) { |
| 4025 ASSERT(hinstr->store_mode() == STORE_TO_INITIALIZED_ENTRY); |
| 4026 // Store int value directly to upper half of the smi. |
| 4027 STATIC_ASSERT(kSmiTag == 0); |
| 4028 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32); |
| 4029 offset += kPointerSize / 2; |
| 4030 representation = Representation::Integer32(); |
| 4031 } |
| 4032 |
| 4033 Operand operand = FieldOperand(write_register, offset); |
| 4034 |
| 4035 if (instr->value()->IsRegister()) { |
| 4036 Register value = ToRegister(instr->value()); |
| 4037 __ Store(operand, value, representation); |
| 4038 } else { |
| 4005 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); | 4039 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); |
| 4006 if (operand_value->IsRegister()) { | 4040 if (IsInteger32Constant(operand_value)) { |
| 4007 Register value = ToRegister(operand_value); | 4041 ASSERT(!hinstr->NeedsWriteBarrier()); |
| 4008 __ Store(FieldOperand(write_register, offset), value, representation); | |
| 4009 } else if (representation.IsInteger32()) { | |
| 4010 int32_t value = ToInteger32(operand_value); | 4042 int32_t value = ToInteger32(operand_value); |
| 4011 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); | 4043 if (representation.IsSmi()) { |
| 4012 __ movl(FieldOperand(write_register, offset), Immediate(value)); | 4044 __ Move(operand, Smi::FromInt(value)); |
| 4045 |
| 4046 } else { |
| 4047 __ movl(operand, Immediate(value)); |
| 4048 } |
| 4049 |
| 4013 } else { | 4050 } else { |
| 4014 Handle<Object> handle_value = ToHandle(operand_value); | 4051 Handle<Object> handle_value = ToHandle(operand_value); |
| 4015 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); | 4052 ASSERT(!hinstr->NeedsWriteBarrier()); |
| 4016 __ Move(FieldOperand(write_register, offset), handle_value); | 4053 __ Move(operand, handle_value); |
| 4017 } | 4054 } |
| 4018 } else { | |
| 4019 Register value = ToRegister(instr->value()); | |
| 4020 __ Store(FieldOperand(write_register, offset), value, representation); | |
| 4021 } | 4055 } |
| 4022 | 4056 |
| 4023 if (instr->hydrogen()->NeedsWriteBarrier()) { | 4057 if (hinstr->NeedsWriteBarrier()) { |
| 4024 Register value = ToRegister(instr->value()); | 4058 Register value = ToRegister(instr->value()); |
| 4025 Register temp = access.IsInobject() ? ToRegister(instr->temp()) : object; | 4059 Register temp = access.IsInobject() ? ToRegister(instr->temp()) : object; |
| 4026 // Update the write barrier for the object for in-object properties. | 4060 // Update the write barrier for the object for in-object properties. |
| 4027 __ RecordWriteField(write_register, | 4061 __ RecordWriteField(write_register, |
| 4028 offset, | 4062 offset, |
| 4029 value, | 4063 value, |
| 4030 temp, | 4064 temp, |
| 4031 kSaveFPRegs, | 4065 kSaveFPRegs, |
| 4032 EMIT_REMEMBERED_SET, | 4066 EMIT_REMEMBERED_SET, |
| 4033 check_needed); | 4067 check_needed); |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4200 key, | 4234 key, |
| 4201 FAST_DOUBLE_ELEMENTS, | 4235 FAST_DOUBLE_ELEMENTS, |
| 4202 FixedDoubleArray::kHeaderSize - kHeapObjectTag, | 4236 FixedDoubleArray::kHeaderSize - kHeapObjectTag, |
| 4203 instr->additional_index()); | 4237 instr->additional_index()); |
| 4204 | 4238 |
| 4205 __ movsd(double_store_operand, value); | 4239 __ movsd(double_store_operand, value); |
| 4206 } | 4240 } |
| 4207 | 4241 |
| 4208 | 4242 |
| 4209 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { | 4243 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { |
| 4210 Register elements = ToRegister(instr->elements()); | 4244 HStoreKeyed* hinstr = instr->hydrogen(); |
| 4211 LOperand* key = instr->key(); | 4245 LOperand* key = instr->key(); |
| 4212 if (!key->IsConstantOperand()) { | 4246 if (!key->IsConstantOperand()) { |
| 4213 Register key_reg = ToRegister(key); | 4247 Register key_reg = ToRegister(key); |
| 4214 // Even though the HLoad/StoreKeyedFastElement instructions force | 4248 // Even though the HLoad/StoreKeyedFastElement instructions force |
| 4215 // the input representation for the key to be an integer, the | 4249 // the input representation for the key to be an integer, the |
| 4216 // input gets replaced during bound check elimination with the index | 4250 // input gets replaced during bound check elimination with the index |
| 4217 // argument to the bounds check, which can be tagged, so that case | 4251 // argument to the bounds check, which can be tagged, so that case |
| 4218 // must be handled here, too. | 4252 // must be handled here, too. |
| 4219 if (instr->hydrogen()->IsDehoisted()) { | 4253 if (hinstr->IsDehoisted()) { |
| 4220 // Sign extend key because it could be a 32 bit negative value | 4254 // Sign extend key because it could be a 32 bit negative value |
| 4221 // and the dehoisted address computation happens in 64 bits | 4255 // and the dehoisted address computation happens in 64 bits |
| 4222 __ movsxlq(key_reg, key_reg); | 4256 __ movsxlq(key_reg, key_reg); |
| 4223 } | 4257 } |
| 4224 } | 4258 } |
| 4225 | 4259 |
| 4260 int offset = FixedArray::kHeaderSize - kHeapObjectTag; |
| 4261 Representation representation = hinstr->value()->representation(); |
| 4262 |
| 4263 if (representation.IsInteger32()) { |
| 4264 ASSERT(hinstr->store_mode() == STORE_TO_INITIALIZED_ENTRY); |
| 4265 ASSERT(hinstr->elements_kind() == FAST_SMI_ELEMENTS); |
| 4266 // Store int value directly to upper half of the smi. |
| 4267 STATIC_ASSERT(kSmiTag == 0); |
| 4268 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32); |
| 4269 offset += kPointerSize / 2; |
| 4270 } |
| 4271 |
| 4226 Operand operand = | 4272 Operand operand = |
| 4227 BuildFastArrayOperand(instr->elements(), | 4273 BuildFastArrayOperand(instr->elements(), |
| 4228 key, | 4274 key, |
| 4229 FAST_ELEMENTS, | 4275 FAST_ELEMENTS, |
| 4230 FixedArray::kHeaderSize - kHeapObjectTag, | 4276 offset, |
| 4231 instr->additional_index()); | 4277 instr->additional_index()); |
| 4278 |
| 4232 if (instr->value()->IsRegister()) { | 4279 if (instr->value()->IsRegister()) { |
| 4233 __ movq(operand, ToRegister(instr->value())); | 4280 __ Store(operand, ToRegister(instr->value()), representation); |
| 4234 } else { | 4281 } else { |
| 4235 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); | 4282 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); |
| 4236 if (IsInteger32Constant(operand_value)) { | 4283 if (IsInteger32Constant(operand_value)) { |
| 4237 Smi* smi_value = Smi::FromInt(ToInteger32(operand_value)); | 4284 int32_t value = ToInteger32(operand_value); |
| 4238 __ Move(operand, smi_value); | 4285 if (representation.IsSmi()) { |
| 4286 __ Move(operand, Smi::FromInt(value)); |
| 4287 |
| 4288 } else { |
| 4289 __ movl(operand, Immediate(value)); |
| 4290 } |
| 4239 } else { | 4291 } else { |
| 4240 Handle<Object> handle_value = ToHandle(operand_value); | 4292 Handle<Object> handle_value = ToHandle(operand_value); |
| 4241 __ Move(operand, handle_value); | 4293 __ Move(operand, handle_value); |
| 4242 } | 4294 } |
| 4243 } | 4295 } |
| 4244 | 4296 |
| 4245 if (instr->hydrogen()->NeedsWriteBarrier()) { | 4297 if (hinstr->NeedsWriteBarrier()) { |
| 4298 Register elements = ToRegister(instr->elements()); |
| 4246 ASSERT(instr->value()->IsRegister()); | 4299 ASSERT(instr->value()->IsRegister()); |
| 4247 Register value = ToRegister(instr->value()); | 4300 Register value = ToRegister(instr->value()); |
| 4248 ASSERT(!instr->key()->IsConstantOperand()); | 4301 ASSERT(!key->IsConstantOperand()); |
| 4249 SmiCheck check_needed = | 4302 SmiCheck check_needed = hinstr->value()->IsHeapObject() |
| 4250 instr->hydrogen()->value()->IsHeapObject() | |
| 4251 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | 4303 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
| 4252 // Compute address of modified element and store it into key register. | 4304 // Compute address of modified element and store it into key register. |
| 4253 Register key_reg(ToRegister(key)); | 4305 Register key_reg(ToRegister(key)); |
| 4254 __ lea(key_reg, operand); | 4306 __ lea(key_reg, operand); |
| 4255 __ RecordWrite(elements, | 4307 __ RecordWrite(elements, |
| 4256 key_reg, | 4308 key_reg, |
| 4257 value, | 4309 value, |
| 4258 kSaveFPRegs, | 4310 kSaveFPRegs, |
| 4259 EMIT_REMEMBERED_SET, | 4311 EMIT_REMEMBERED_SET, |
| 4260 check_needed); | 4312 check_needed); |
| (...skipping 1321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5582 FixedArray::kHeaderSize - kPointerSize)); | 5634 FixedArray::kHeaderSize - kPointerSize)); |
| 5583 __ bind(&done); | 5635 __ bind(&done); |
| 5584 } | 5636 } |
| 5585 | 5637 |
| 5586 | 5638 |
| 5587 #undef __ | 5639 #undef __ |
| 5588 | 5640 |
| 5589 } } // namespace v8::internal | 5641 } } // namespace v8::internal |
| 5590 | 5642 |
| 5591 #endif // V8_TARGET_ARCH_X64 | 5643 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |