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 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 |