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 2900 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2911 Register index = ToRegister(instr->index()); | 2911 Register index = ToRegister(instr->index()); |
2912 Register result = ToRegister(instr->result()); | 2912 Register result = ToRegister(instr->result()); |
2913 // There are two words between the frame pointer and the last argument. | 2913 // There are two words between the frame pointer and the last argument. |
2914 // Subtracting from length accounts for one of them add one more. | 2914 // Subtracting from length accounts for one of them add one more. |
2915 __ sub(length, length, index); | 2915 __ sub(length, length, index); |
2916 __ add(length, length, Operand(1)); | 2916 __ add(length, length, Operand(1)); |
2917 __ ldr(result, MemOperand(arguments, length, LSL, kPointerSizeLog2)); | 2917 __ ldr(result, MemOperand(arguments, length, LSL, kPointerSizeLog2)); |
2918 } | 2918 } |
2919 | 2919 |
2920 | 2920 |
2921 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { | 2921 void LCodeGen::DoLoadKeyedExternal(LLoadKeyed* instr) { |
2922 Register elements = ToRegister(instr->elements()); | |
2923 Register result = ToRegister(instr->result()); | |
2924 Register scratch = scratch0(); | |
2925 Register store_base = scratch; | |
2926 int offset = 0; | |
2927 | |
2928 if (instr->key()->IsConstantOperand()) { | |
2929 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); | |
2930 offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) + | |
2931 instr->additional_index()); | |
2932 store_base = elements; | |
2933 } else { | |
2934 Register key = EmitLoadRegister(instr->key(), scratch0()); | |
2935 // Even though the HLoadKeyedFastElement instruction forces the input | |
2936 // representation for the key to be an integer, the input gets replaced | |
2937 // during bound check elimination with the index argument to the bounds | |
2938 // check, which can be tagged, so that case must be handled here, too. | |
2939 if (instr->hydrogen()->key()->representation().IsTagged()) { | |
2940 __ add(scratch, elements, | |
2941 Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize)); | |
2942 } else { | |
2943 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); | |
2944 } | |
2945 offset = FixedArray::OffsetOfElementAt(instr->additional_index()); | |
2946 } | |
2947 __ ldr(result, FieldMemOperand(store_base, offset)); | |
2948 | |
2949 // Check for the hole value. | |
2950 if (instr->hydrogen()->RequiresHoleCheck()) { | |
2951 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { | |
2952 __ tst(result, Operand(kSmiTagMask)); | |
2953 DeoptimizeIf(ne, instr->environment()); | |
2954 } else { | |
2955 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); | |
2956 __ cmp(result, scratch); | |
2957 DeoptimizeIf(eq, instr->environment()); | |
2958 } | |
2959 } | |
2960 } | |
2961 | |
2962 | |
2963 void LCodeGen::DoLoadKeyedFastDoubleElement( | |
2964 LLoadKeyedFastDoubleElement* instr) { | |
2965 Register elements = ToRegister(instr->elements()); | |
2966 bool key_is_constant = instr->key()->IsConstantOperand(); | |
2967 Register key = no_reg; | |
2968 DwVfpRegister result = ToDoubleRegister(instr->result()); | |
2969 Register scratch = scratch0(); | |
2970 | |
2971 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); | |
2972 int shift_size = (instr->hydrogen()->key()->representation().IsTagged()) | |
2973 ? (element_size_shift - kSmiTagSize) : element_size_shift; | |
2974 int constant_key = 0; | |
2975 if (key_is_constant) { | |
2976 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | |
2977 if (constant_key & 0xF0000000) { | |
2978 Abort("array index constant value too big."); | |
2979 } | |
2980 } else { | |
2981 key = ToRegister(instr->key()); | |
2982 } | |
2983 | |
2984 Operand operand = key_is_constant | |
2985 ? Operand(((constant_key + instr->additional_index()) << | |
2986 element_size_shift) + | |
2987 FixedDoubleArray::kHeaderSize - kHeapObjectTag) | |
2988 : Operand(key, LSL, shift_size); | |
2989 __ add(elements, elements, operand); | |
2990 if (!key_is_constant) { | |
2991 __ add(elements, elements, | |
2992 Operand((FixedDoubleArray::kHeaderSize - kHeapObjectTag) + | |
2993 (instr->additional_index() << element_size_shift))); | |
2994 } | |
2995 | |
2996 if (instr->hydrogen()->RequiresHoleCheck()) { | |
2997 __ ldr(scratch, MemOperand(elements, sizeof(kHoleNanLower32))); | |
2998 __ cmp(scratch, Operand(kHoleNanUpper32)); | |
2999 DeoptimizeIf(eq, instr->environment()); | |
3000 } | |
3001 | |
3002 __ vldr(result, elements, 0); | |
3003 } | |
3004 | |
3005 | |
3006 MemOperand LCodeGen::PrepareKeyedOperand(Register key, | |
3007 Register base, | |
3008 bool key_is_constant, | |
3009 int constant_key, | |
3010 int element_size, | |
3011 int shift_size, | |
3012 int additional_index, | |
3013 int additional_offset) { | |
3014 if (additional_index != 0 && !key_is_constant) { | |
3015 additional_index *= 1 << (element_size - shift_size); | |
3016 __ add(scratch0(), key, Operand(additional_index)); | |
3017 } | |
3018 | |
3019 if (key_is_constant) { | |
3020 return MemOperand(base, | |
3021 (constant_key << element_size) + additional_offset); | |
3022 } | |
3023 | |
3024 if (additional_index == 0) { | |
3025 if (shift_size >= 0) { | |
3026 return MemOperand(base, key, LSL, shift_size); | |
3027 } else { | |
3028 ASSERT_EQ(-1, shift_size); | |
3029 return MemOperand(base, key, LSR, 1); | |
3030 } | |
3031 } | |
3032 | |
3033 if (shift_size >= 0) { | |
3034 return MemOperand(base, scratch0(), LSL, shift_size); | |
3035 } else { | |
3036 ASSERT_EQ(-1, shift_size); | |
3037 return MemOperand(base, scratch0(), LSR, 1); | |
3038 } | |
3039 } | |
3040 | |
3041 | |
3042 void LCodeGen::DoLoadKeyedSpecializedArrayElement( | |
3043 LLoadKeyedSpecializedArrayElement* instr) { | |
3044 Register external_pointer = ToRegister(instr->external_pointer()); | 2922 Register external_pointer = ToRegister(instr->external_pointer()); |
3045 Register key = no_reg; | 2923 Register key = no_reg; |
3046 ElementsKind elements_kind = instr->elements_kind(); | 2924 ElementsKind elements_kind = instr->elements_kind(); |
3047 bool key_is_constant = instr->key()->IsConstantOperand(); | 2925 bool key_is_constant = instr->key()->IsConstantOperand(); |
3048 int constant_key = 0; | 2926 int constant_key = 0; |
3049 if (key_is_constant) { | 2927 if (key_is_constant) { |
3050 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 2928 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
3051 if (constant_key & 0xF0000000) { | 2929 if (constant_key & 0xF0000000) { |
3052 Abort("array index constant value too big."); | 2930 Abort("array index constant value too big."); |
3053 } | 2931 } |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3111 case FAST_DOUBLE_ELEMENTS: | 2989 case FAST_DOUBLE_ELEMENTS: |
3112 case FAST_ELEMENTS: | 2990 case FAST_ELEMENTS: |
3113 case FAST_SMI_ELEMENTS: | 2991 case FAST_SMI_ELEMENTS: |
3114 case DICTIONARY_ELEMENTS: | 2992 case DICTIONARY_ELEMENTS: |
3115 case NON_STRICT_ARGUMENTS_ELEMENTS: | 2993 case NON_STRICT_ARGUMENTS_ELEMENTS: |
3116 UNREACHABLE(); | 2994 UNREACHABLE(); |
3117 break; | 2995 break; |
3118 } | 2996 } |
3119 } | 2997 } |
3120 } | 2998 } |
3121 | 2999 |
danno
2012/10/21 20:44:41
nit: two line returns between functions
mvstanton
2012/10/23 23:44:20
Done.
| |
3000 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) { | |
3001 Register elements = ToRegister(instr->elements()); | |
3002 | |
3003 if (instr->is_external()) { | |
3004 DoLoadKeyedExternal(instr); | |
3005 } else if (instr->hydrogen()->representation().IsDouble()) { | |
3006 bool key_is_constant = instr->key()->IsConstantOperand(); | |
danno
2012/10/21 20:44:41
Just for clarity and readability, perhaps it makes
mvstanton
2012/10/23 23:44:20
Done.
| |
3007 Register key = no_reg; | |
3008 DwVfpRegister result = ToDoubleRegister(instr->result()); | |
3009 Register scratch = scratch0(); | |
3010 | |
3011 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); | |
3012 int shift_size = (instr->hydrogen()->key()->representation().IsTagged()) | |
3013 ? (element_size_shift - kSmiTagSize) : element_size_shift; | |
3014 int constant_key = 0; | |
3015 if (key_is_constant) { | |
3016 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | |
3017 if (constant_key & 0xF0000000) { | |
3018 Abort("array index constant value too big."); | |
3019 } | |
3020 } else { | |
3021 key = ToRegister(instr->key()); | |
3022 } | |
3023 | |
3024 Operand operand = key_is_constant | |
3025 ? Operand(((constant_key + instr->additional_index()) << | |
3026 element_size_shift) + | |
3027 FixedDoubleArray::kHeaderSize - kHeapObjectTag) | |
3028 : Operand(key, LSL, shift_size); | |
3029 __ add(elements, elements, operand); | |
3030 if (!key_is_constant) { | |
3031 __ add(elements, elements, | |
3032 Operand((FixedDoubleArray::kHeaderSize - kHeapObjectTag) + | |
3033 (instr->additional_index() << element_size_shift))); | |
3034 } | |
3035 | |
3036 if (instr->hydrogen()->RequiresHoleCheck()) { | |
3037 __ ldr(scratch, MemOperand(elements, sizeof(kHoleNanLower32))); | |
3038 __ cmp(scratch, Operand(kHoleNanUpper32)); | |
3039 DeoptimizeIf(eq, instr->environment()); | |
3040 } | |
3041 | |
3042 __ vldr(result, elements, 0); | |
3043 } else { | |
3044 Register result = ToRegister(instr->result()); | |
danno
2012/10/21 20:44:41
Perhaps here too with DoLoadKeyedFixedArray?
| |
3045 Register scratch = scratch0(); | |
3046 Register store_base = scratch; | |
3047 int offset = 0; | |
3048 | |
3049 if (instr->key()->IsConstantOperand()) { | |
3050 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); | |
3051 offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) + | |
3052 instr->additional_index()); | |
3053 store_base = elements; | |
3054 } else { | |
3055 Register key = EmitLoadRegister(instr->key(), scratch0()); | |
3056 // Even though the HLoadKeyed instruction forces the input | |
3057 // representation for the key to be an integer, the input gets replaced | |
3058 // during bound check elimination with the index argument to the bounds | |
3059 // check, which can be tagged, so that case must be handled here, too. | |
3060 if (instr->hydrogen()->key()->representation().IsTagged()) { | |
3061 __ add(scratch, elements, | |
3062 Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize)); | |
3063 } else { | |
3064 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); | |
3065 } | |
3066 offset = FixedArray::OffsetOfElementAt(instr->additional_index()); | |
3067 } | |
3068 __ ldr(result, FieldMemOperand(store_base, offset)); | |
3069 | |
3070 // Check for the hole value. | |
3071 if (instr->hydrogen()->RequiresHoleCheck()) { | |
3072 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { | |
3073 __ tst(result, Operand(kSmiTagMask)); | |
3074 DeoptimizeIf(ne, instr->environment()); | |
3075 } else { | |
3076 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); | |
3077 __ cmp(result, scratch); | |
3078 DeoptimizeIf(eq, instr->environment()); | |
3079 } | |
3080 } | |
3081 } | |
3082 } | |
3083 | |
3084 | |
3085 MemOperand LCodeGen::PrepareKeyedOperand(Register key, | |
3086 Register base, | |
3087 bool key_is_constant, | |
3088 int constant_key, | |
3089 int element_size, | |
3090 int shift_size, | |
3091 int additional_index, | |
3092 int additional_offset) { | |
3093 if (additional_index != 0 && !key_is_constant) { | |
3094 additional_index *= 1 << (element_size - shift_size); | |
3095 __ add(scratch0(), key, Operand(additional_index)); | |
3096 } | |
3097 | |
3098 if (key_is_constant) { | |
3099 return MemOperand(base, | |
3100 (constant_key << element_size) + additional_offset); | |
3101 } | |
3102 | |
3103 if (additional_index == 0) { | |
3104 if (shift_size >= 0) { | |
3105 return MemOperand(base, key, LSL, shift_size); | |
3106 } else { | |
3107 ASSERT_EQ(-1, shift_size); | |
3108 return MemOperand(base, key, LSR, 1); | |
3109 } | |
3110 } | |
3111 | |
3112 if (shift_size >= 0) { | |
3113 return MemOperand(base, scratch0(), LSL, shift_size); | |
3114 } else { | |
3115 ASSERT_EQ(-1, shift_size); | |
3116 return MemOperand(base, scratch0(), LSR, 1); | |
3117 } | |
3118 } | |
3119 | |
3122 | 3120 |
3123 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { | 3121 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { |
3124 ASSERT(ToRegister(instr->object()).is(r1)); | 3122 ASSERT(ToRegister(instr->object()).is(r1)); |
3125 ASSERT(ToRegister(instr->key()).is(r0)); | 3123 ASSERT(ToRegister(instr->key()).is(r0)); |
3126 | 3124 |
3127 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 3125 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
3128 CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS); | 3126 CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS); |
3129 } | 3127 } |
3130 | 3128 |
3131 | 3129 |
(...skipping 860 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3992 } else { | 3990 } else { |
3993 __ mov(ip, Operand(constant_index)); | 3991 __ mov(ip, Operand(constant_index)); |
3994 } | 3992 } |
3995 __ cmp(ip, ToRegister(instr->length())); | 3993 __ cmp(ip, ToRegister(instr->length())); |
3996 } else { | 3994 } else { |
3997 __ cmp(ToRegister(instr->index()), ToRegister(instr->length())); | 3995 __ cmp(ToRegister(instr->index()), ToRegister(instr->length())); |
3998 } | 3996 } |
3999 DeoptimizeIf(hs, instr->environment()); | 3997 DeoptimizeIf(hs, instr->environment()); |
4000 } | 3998 } |
4001 | 3999 |
4002 | 4000 void LCodeGen::DoStoreKeyedExternal(LStoreKeyed* instr) { |
4003 void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) { | |
4004 Register value = ToRegister(instr->value()); | |
4005 Register elements = ToRegister(instr->object()); | |
4006 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg; | |
4007 Register scratch = scratch0(); | |
4008 Register store_base = scratch; | |
4009 int offset = 0; | |
4010 | |
4011 // Do the store. | |
4012 if (instr->key()->IsConstantOperand()) { | |
4013 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); | |
4014 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); | |
4015 offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) + | |
4016 instr->additional_index()); | |
4017 store_base = elements; | |
4018 } else { | |
4019 // Even though the HLoadKeyedFastElement instruction forces the input | |
4020 // representation for the key to be an integer, the input gets replaced | |
4021 // during bound check elimination with the index argument to the bounds | |
4022 // check, which can be tagged, so that case must be handled here, too. | |
4023 if (instr->hydrogen()->key()->representation().IsTagged()) { | |
4024 __ add(scratch, elements, | |
4025 Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize)); | |
4026 } else { | |
4027 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); | |
4028 } | |
4029 offset = FixedArray::OffsetOfElementAt(instr->additional_index()); | |
4030 } | |
4031 __ str(value, FieldMemOperand(store_base, offset)); | |
4032 | |
4033 if (instr->hydrogen()->NeedsWriteBarrier()) { | |
4034 HType type = instr->hydrogen()->value()->type(); | |
4035 SmiCheck check_needed = | |
4036 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | |
4037 // Compute address of modified element and store it into key register. | |
4038 __ add(key, store_base, Operand(offset - kHeapObjectTag)); | |
4039 __ RecordWrite(elements, | |
4040 key, | |
4041 value, | |
4042 kLRHasBeenSaved, | |
4043 kSaveFPRegs, | |
4044 EMIT_REMEMBERED_SET, | |
4045 check_needed); | |
4046 } | |
4047 } | |
4048 | |
4049 | |
4050 void LCodeGen::DoStoreKeyedFastDoubleElement( | |
4051 LStoreKeyedFastDoubleElement* instr) { | |
4052 DwVfpRegister value = ToDoubleRegister(instr->value()); | |
4053 Register elements = ToRegister(instr->elements()); | |
4054 Register key = no_reg; | |
4055 Register scratch = scratch0(); | |
4056 bool key_is_constant = instr->key()->IsConstantOperand(); | |
4057 int constant_key = 0; | |
4058 | |
4059 // Calculate the effective address of the slot in the array to store the | |
4060 // double value. | |
4061 if (key_is_constant) { | |
4062 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | |
4063 if (constant_key & 0xF0000000) { | |
4064 Abort("array index constant value too big."); | |
4065 } | |
4066 } else { | |
4067 key = ToRegister(instr->key()); | |
4068 } | |
4069 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); | |
4070 int shift_size = (instr->hydrogen()->key()->representation().IsTagged()) | |
4071 ? (element_size_shift - kSmiTagSize) : element_size_shift; | |
4072 Operand operand = key_is_constant | |
4073 ? Operand((constant_key << element_size_shift) + | |
4074 FixedDoubleArray::kHeaderSize - kHeapObjectTag) | |
4075 : Operand(key, LSL, shift_size); | |
4076 __ add(scratch, elements, operand); | |
4077 if (!key_is_constant) { | |
4078 __ add(scratch, scratch, | |
4079 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag)); | |
4080 } | |
4081 | |
4082 if (instr->NeedsCanonicalization()) { | |
4083 // Check for NaN. All NaNs must be canonicalized. | |
4084 __ VFPCompareAndSetFlags(value, value); | |
4085 // Only load canonical NaN if the comparison above set the overflow. | |
4086 __ Vmov(value, | |
4087 FixedDoubleArray::canonical_not_the_hole_nan_as_double(), | |
4088 no_reg, vs); | |
4089 } | |
4090 | |
4091 __ vstr(value, scratch, instr->additional_index() << element_size_shift); | |
4092 } | |
4093 | |
4094 | |
4095 void LCodeGen::DoStoreKeyedSpecializedArrayElement( | |
4096 LStoreKeyedSpecializedArrayElement* instr) { | |
4097 | |
4098 Register external_pointer = ToRegister(instr->external_pointer()); | 4001 Register external_pointer = ToRegister(instr->external_pointer()); |
4099 Register key = no_reg; | 4002 Register key = no_reg; |
4100 ElementsKind elements_kind = instr->elements_kind(); | 4003 ElementsKind elements_kind = instr->elements_kind(); |
4101 bool key_is_constant = instr->key()->IsConstantOperand(); | 4004 bool key_is_constant = instr->key()->IsConstantOperand(); |
4102 int constant_key = 0; | 4005 int constant_key = 0; |
4103 if (key_is_constant) { | 4006 if (key_is_constant) { |
4104 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 4007 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
4105 if (constant_key & 0xF0000000) { | 4008 if (constant_key & 0xF0000000) { |
4106 Abort("array index constant value too big."); | 4009 Abort("array index constant value too big."); |
4107 } | 4010 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4155 case FAST_HOLEY_DOUBLE_ELEMENTS: | 4058 case FAST_HOLEY_DOUBLE_ELEMENTS: |
4156 case FAST_HOLEY_ELEMENTS: | 4059 case FAST_HOLEY_ELEMENTS: |
4157 case FAST_HOLEY_SMI_ELEMENTS: | 4060 case FAST_HOLEY_SMI_ELEMENTS: |
4158 case DICTIONARY_ELEMENTS: | 4061 case DICTIONARY_ELEMENTS: |
4159 case NON_STRICT_ARGUMENTS_ELEMENTS: | 4062 case NON_STRICT_ARGUMENTS_ELEMENTS: |
4160 UNREACHABLE(); | 4063 UNREACHABLE(); |
4161 break; | 4064 break; |
4162 } | 4065 } |
4163 } | 4066 } |
4164 } | 4067 } |
4165 | 4068 |
danno
2012/10/21 20:44:41
nit: two spaces between functions
mvstanton
2012/10/23 23:44:20
Done.
| |
4069 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) { | |
4070 // By cases: external, fast double | |
4071 if (instr->is_external()) { | |
4072 DoStoreKeyedExternal(instr); | |
4073 } else if (instr->hydrogen()->value()->representation().IsDouble()) { | |
4074 DwVfpRegister value = ToDoubleRegister(instr->value()); | |
danno
2012/10/21 20:44:41
Same here as above, how about DoStoreKeyedFixedDou
mvstanton
2012/10/23 23:44:20
Done.
| |
4075 Register elements = ToRegister(instr->object()); | |
4076 Register key = no_reg; | |
4077 Register scratch = scratch0(); | |
4078 bool key_is_constant = instr->key()->IsConstantOperand(); | |
4079 int constant_key = 0; | |
4080 | |
4081 // Calculate the effective address of the slot in the array to store the | |
4082 // double value. | |
4083 if (key_is_constant) { | |
4084 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | |
4085 if (constant_key & 0xF0000000) { | |
4086 Abort("array index constant value too big."); | |
4087 } | |
4088 } else { | |
4089 key = ToRegister(instr->key()); | |
4090 } | |
4091 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); | |
4092 int shift_size = (instr->hydrogen()->key()->representation().IsTagged()) | |
4093 ? (element_size_shift - kSmiTagSize) : element_size_shift; | |
4094 Operand operand = key_is_constant | |
4095 ? Operand((constant_key << element_size_shift) + | |
4096 FixedDoubleArray::kHeaderSize - kHeapObjectTag) | |
4097 : Operand(key, LSL, shift_size); | |
4098 __ add(scratch, elements, operand); | |
4099 if (!key_is_constant) { | |
4100 __ add(scratch, scratch, | |
4101 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag)); | |
4102 } | |
4103 | |
4104 if (instr->NeedsCanonicalization()) { | |
4105 // Check for NaN. All NaNs must be canonicalized. | |
4106 __ VFPCompareAndSetFlags(value, value); | |
4107 // Only load canonical NaN if the comparison above set the overflow. | |
4108 __ Vmov(value, | |
4109 FixedDoubleArray::canonical_not_the_hole_nan_as_double(), | |
4110 no_reg, vs); | |
4111 } | |
4112 | |
4113 __ vstr(value, scratch, instr->additional_index() << element_size_shift); | |
4114 } else { | |
4115 Register value = ToRegister(instr->value()); | |
4116 Register elements = ToRegister(instr->object()); | |
4117 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) | |
4118 : no_reg; | |
4119 Register scratch = scratch0(); | |
4120 Register store_base = scratch; | |
4121 int offset = 0; | |
4122 | |
4123 // Do the store. | |
4124 if (instr->key()->IsConstantOperand()) { | |
4125 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); | |
4126 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); | |
4127 offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) + | |
4128 instr->additional_index()); | |
4129 store_base = elements; | |
4130 } else { | |
4131 // Even though the HLoadKeyed instruction forces the input | |
4132 // representation for the key to be an integer, the input gets replaced | |
4133 // during bound check elimination with the index argument to the bounds | |
4134 // check, which can be tagged, so that case must be handled here, too. | |
4135 if (instr->hydrogen()->key()->representation().IsTagged()) { | |
4136 __ add(scratch, elements, | |
4137 Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize)); | |
4138 } else { | |
4139 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); | |
4140 } | |
4141 offset = FixedArray::OffsetOfElementAt(instr->additional_index()); | |
4142 } | |
4143 __ str(value, FieldMemOperand(store_base, offset)); | |
4144 | |
4145 if (instr->hydrogen()->NeedsWriteBarrier()) { | |
4146 HType type = instr->hydrogen()->value()->type(); | |
4147 SmiCheck check_needed = | |
4148 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | |
4149 // Compute address of modified element and store it into key register. | |
4150 __ add(key, store_base, Operand(offset - kHeapObjectTag)); | |
4151 __ RecordWrite(elements, | |
4152 key, | |
4153 value, | |
4154 kLRHasBeenSaved, | |
4155 kSaveFPRegs, | |
4156 EMIT_REMEMBERED_SET, | |
4157 check_needed); | |
4158 } | |
4159 } | |
4160 } | |
4161 | |
4166 | 4162 |
4167 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { | 4163 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { |
4168 ASSERT(ToRegister(instr->object()).is(r2)); | 4164 ASSERT(ToRegister(instr->object()).is(r2)); |
4169 ASSERT(ToRegister(instr->key()).is(r1)); | 4165 ASSERT(ToRegister(instr->key()).is(r1)); |
4170 ASSERT(ToRegister(instr->value()).is(r0)); | 4166 ASSERT(ToRegister(instr->value()).is(r0)); |
4171 | 4167 |
4172 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) | 4168 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) |
4173 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() | 4169 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() |
4174 : isolate()->builtins()->KeyedStoreIC_Initialize(); | 4170 : isolate()->builtins()->KeyedStoreIC_Initialize(); |
4175 CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS); | 4171 CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS); |
(...skipping 1503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5679 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); | 5675 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); |
5680 __ ldr(result, FieldMemOperand(scratch, | 5676 __ ldr(result, FieldMemOperand(scratch, |
5681 FixedArray::kHeaderSize - kPointerSize)); | 5677 FixedArray::kHeaderSize - kPointerSize)); |
5682 __ bind(&done); | 5678 __ bind(&done); |
5683 } | 5679 } |
5684 | 5680 |
5685 | 5681 |
5686 #undef __ | 5682 #undef __ |
5687 | 5683 |
5688 } } // namespace v8::internal | 5684 } } // namespace v8::internal |
OLD | NEW |