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

Side by Side Diff: src/arm/lithium-codegen-arm.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 2900 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698