OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 3130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3141 public: | 3141 public: |
3142 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) | 3142 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) |
3143 : LDeferredCode(codegen), instr_(instr) { } | 3143 : LDeferredCode(codegen), instr_(instr) { } |
3144 virtual void Generate() { codegen()->DoDeferredStringCharCodeAt(instr_); } | 3144 virtual void Generate() { codegen()->DoDeferredStringCharCodeAt(instr_); } |
3145 private: | 3145 private: |
3146 LStringCharCodeAt* instr_; | 3146 LStringCharCodeAt* instr_; |
3147 }; | 3147 }; |
3148 | 3148 |
3149 Register string = ToRegister(instr->string()); | 3149 Register string = ToRegister(instr->string()); |
3150 Register index = no_reg; | 3150 Register index = no_reg; |
| 3151 Register offset = ToRegister(instr->TempAt(0)); |
3151 int const_index = -1; | 3152 int const_index = -1; |
3152 if (instr->index()->IsConstantOperand()) { | 3153 if (instr->index()->IsConstantOperand()) { |
3153 const_index = ToInteger32(LConstantOperand::cast(instr->index())); | 3154 const_index = ToInteger32(LConstantOperand::cast(instr->index())); |
3154 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue); | 3155 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue); |
3155 if (!Smi::IsValid(const_index)) { | 3156 if (!Smi::IsValid(const_index)) { |
3156 // Guaranteed to be out of bounds because of the assert above. | 3157 // Guaranteed to be out of bounds because of the assert above. |
3157 // So the bounds check that must dominate this instruction must | 3158 // So the bounds check that must dominate this instruction must |
3158 // have deoptimized already. | 3159 // have deoptimized already. |
3159 if (FLAG_debug_code) { | 3160 if (FLAG_debug_code) { |
3160 __ Abort("StringCharCodeAt: out of bounds index."); | 3161 __ Abort("StringCharCodeAt: out of bounds index."); |
3161 } | 3162 } |
3162 // No code needs to be generated. | 3163 // No code needs to be generated. |
3163 return; | 3164 return; |
3164 } | 3165 } |
3165 } else { | 3166 } else { |
3166 index = ToRegister(instr->index()); | 3167 index = ToRegister(instr->index()); |
3167 } | 3168 } |
3168 Register result = ToRegister(instr->result()); | 3169 Register result = ToRegister(instr->result()); |
3169 | 3170 |
3170 DeferredStringCharCodeAt* deferred = | 3171 DeferredStringCharCodeAt* deferred = |
3171 new DeferredStringCharCodeAt(this, instr); | 3172 new DeferredStringCharCodeAt(this, instr); |
3172 | 3173 |
3173 Label flat_string, ascii_string, done; | 3174 Label flat_string, ascii_string, cons_string, sliced_ascii_string, done; |
3174 | 3175 |
3175 // Fetch the instance type of the receiver into result register. | 3176 // Fetch the instance type of the receiver into result register. |
3176 __ movq(result, FieldOperand(string, HeapObject::kMapOffset)); | 3177 __ movq(result, FieldOperand(string, HeapObject::kMapOffset)); |
3177 __ movzxbl(result, FieldOperand(result, Map::kInstanceTypeOffset)); | 3178 __ movzxbl(result, FieldOperand(result, Map::kInstanceTypeOffset)); |
3178 | 3179 |
3179 // We need special handling for non-sequential strings. | 3180 // We need special handling for non-sequential strings. |
3180 STATIC_ASSERT(kSeqStringTag == 0); | 3181 STATIC_ASSERT(kSeqStringTag == 0); |
3181 __ testb(result, Immediate(kStringRepresentationMask)); | 3182 __ testb(result, Immediate(kStringRepresentationMask)); |
3182 __ j(zero, &flat_string, Label::kNear); | 3183 __ j(zero, &flat_string, Label::kNear); |
3183 | 3184 |
3184 // Handle cons strings and go to deferred code for the rest. | 3185 // Handle non-flat strings. |
3185 __ testb(result, Immediate(kIsConsStringMask)); | 3186 __ and_(result, Immediate(kStringRepresentationMask)); |
3186 __ j(zero, deferred->entry()); | 3187 __ cmpb(result, Immediate(kConsStringTag)); |
| 3188 __ j(equal, &cons_string, Label::kNear); |
| 3189 __ cmpb(result, Immediate(kExternalStringTag)); |
| 3190 __ j(equal, deferred->entry()); |
| 3191 |
| 3192 // SlicedString. |
| 3193 // Unpack slice, add offset and retrieve the result char. |
| 3194 __ movq(offset, FieldOperand(string, SlicedString::kOffsetOffset)); |
| 3195 __ SmiToInteger32(offset, offset); |
| 3196 if (instr->index()->IsConstantOperand()) { |
| 3197 __ addq(offset, Immediate(const_index)); |
| 3198 } else { |
| 3199 __ addq(offset, index); |
| 3200 } |
| 3201 __ movq(string, FieldOperand(string, SlicedString::kParentOffset)); |
| 3202 __ movq(result, FieldOperand(string, HeapObject::kMapOffset)); |
| 3203 __ movzxbl(result, FieldOperand(result, Map::kInstanceTypeOffset)); |
| 3204 // Check for ASCII or two-byte string. |
| 3205 STATIC_ASSERT(kAsciiStringTag != 0); |
| 3206 __ testb(result, Immediate(kStringEncodingMask)); |
| 3207 __ j(not_zero, &sliced_ascii_string, Label::kNear); |
| 3208 __ movzxwl(result, FieldOperand(string, |
| 3209 offset, |
| 3210 times_2, |
| 3211 SeqTwoByteString::kHeaderSize)); |
| 3212 __ jmp(&done, Label::kNear); |
| 3213 __ bind(&sliced_ascii_string); |
| 3214 __ movzxbl(result, FieldOperand(string, |
| 3215 offset, |
| 3216 times_1, |
| 3217 SeqAsciiString::kHeaderSize)); |
| 3218 __ jmp(&done, Label::kNear); |
3187 | 3219 |
3188 // ConsString. | 3220 // ConsString. |
3189 // Check whether the right hand side is the empty string (i.e. if | 3221 // Check whether the right hand side is the empty string (i.e. if |
3190 // this is really a flat string in a cons string). If that is not | 3222 // this is really a flat string in a cons string). If that is not |
3191 // the case we would rather go to the runtime system now to flatten | 3223 // the case we would rather go to the runtime system now to flatten |
3192 // the string. | 3224 // the string. |
| 3225 __ bind(&cons_string); |
3193 __ CompareRoot(FieldOperand(string, ConsString::kSecondOffset), | 3226 __ CompareRoot(FieldOperand(string, ConsString::kSecondOffset), |
3194 Heap::kEmptyStringRootIndex); | 3227 Heap::kEmptyStringRootIndex); |
3195 __ j(not_equal, deferred->entry()); | 3228 __ j(not_equal, deferred->entry()); |
3196 // Get the first of the two strings and load its instance type. | 3229 // Get the first of the two strings and load its instance type. |
3197 __ movq(string, FieldOperand(string, ConsString::kFirstOffset)); | 3230 __ movq(string, FieldOperand(string, ConsString::kFirstOffset)); |
3198 __ movq(result, FieldOperand(string, HeapObject::kMapOffset)); | 3231 __ movq(result, FieldOperand(string, HeapObject::kMapOffset)); |
3199 __ movzxbl(result, FieldOperand(result, Map::kInstanceTypeOffset)); | 3232 __ movzxbl(result, FieldOperand(result, Map::kInstanceTypeOffset)); |
3200 // If the first cons component is also non-flat, then go to runtime. | 3233 // If the first cons component is also non-flat, then go to runtime. |
3201 STATIC_ASSERT(kSeqStringTag == 0); | 3234 STATIC_ASSERT(kSeqStringTag == 0); |
3202 __ testb(result, Immediate(kStringRepresentationMask)); | 3235 __ testb(result, Immediate(kStringRepresentationMask)); |
(...skipping 901 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4104 RegisterEnvironmentForDeoptimization(environment); | 4137 RegisterEnvironmentForDeoptimization(environment); |
4105 ASSERT(osr_pc_offset_ == -1); | 4138 ASSERT(osr_pc_offset_ == -1); |
4106 osr_pc_offset_ = masm()->pc_offset(); | 4139 osr_pc_offset_ = masm()->pc_offset(); |
4107 } | 4140 } |
4108 | 4141 |
4109 #undef __ | 4142 #undef __ |
4110 | 4143 |
4111 } } // namespace v8::internal | 4144 } } // namespace v8::internal |
4112 | 4145 |
4113 #endif // V8_TARGET_ARCH_X64 | 4146 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |