| 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 5250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5261 | 5261 |
| 5262 // If the index is non-smi trigger the non-smi case. | 5262 // If the index is non-smi trigger the non-smi case. |
| 5263 __ JumpIfNotSmi(index_, &index_not_smi_); | 5263 __ JumpIfNotSmi(index_, &index_not_smi_); |
| 5264 | 5264 |
| 5265 __ bind(&got_smi_index_); | 5265 __ bind(&got_smi_index_); |
| 5266 | 5266 |
| 5267 // Check for index out of range. | 5267 // Check for index out of range. |
| 5268 __ lw(t0, FieldMemOperand(object_, String::kLengthOffset)); | 5268 __ lw(t0, FieldMemOperand(object_, String::kLengthOffset)); |
| 5269 __ Branch(index_out_of_range_, ls, t0, Operand(index_)); | 5269 __ Branch(index_out_of_range_, ls, t0, Operand(index_)); |
| 5270 | 5270 |
| 5271 // We need special handling for non-flat strings. | 5271 __ sra(index_, index_, kSmiTagSize); |
| 5272 STATIC_ASSERT(kSeqStringTag == 0); | |
| 5273 __ And(t0, result_, Operand(kStringRepresentationMask)); | |
| 5274 __ Branch(&flat_string, eq, t0, Operand(zero_reg)); | |
| 5275 | 5272 |
| 5276 // Handle non-flat strings. | 5273 StringCharLoadGenerator::Generate(masm, |
| 5277 __ And(result_, result_, Operand(kStringRepresentationMask)); | 5274 object_, |
| 5278 STATIC_ASSERT(kConsStringTag < kExternalStringTag); | 5275 index_, |
| 5279 STATIC_ASSERT(kSlicedStringTag > kExternalStringTag); | 5276 result_, |
| 5280 __ Branch(&sliced_string, gt, result_, Operand(kExternalStringTag)); | 5277 &call_runtime_); |
| 5281 __ Branch(&call_runtime_, eq, result_, Operand(kExternalStringTag)); | |
| 5282 | 5278 |
| 5283 // ConsString. | |
| 5284 // Check whether the right hand side is the empty string (i.e. if | |
| 5285 // this is really a flat string in a cons string). If that is not | |
| 5286 // the case we would rather go to the runtime system now to flatten | |
| 5287 // the string. | |
| 5288 Label assure_seq_string; | |
| 5289 __ lw(result_, FieldMemOperand(object_, ConsString::kSecondOffset)); | |
| 5290 __ LoadRoot(t0, Heap::kEmptyStringRootIndex); | |
| 5291 __ Branch(&call_runtime_, ne, result_, Operand(t0)); | |
| 5292 | |
| 5293 // Get the first of the two parts. | |
| 5294 __ lw(object_, FieldMemOperand(object_, ConsString::kFirstOffset)); | |
| 5295 __ jmp(&assure_seq_string); | |
| 5296 | |
| 5297 // SlicedString, unpack and add offset. | |
| 5298 __ bind(&sliced_string); | |
| 5299 __ lw(result_, FieldMemOperand(object_, SlicedString::kOffsetOffset)); | |
| 5300 __ Addu(index_, index_, result_); | |
| 5301 __ lw(object_, FieldMemOperand(object_, SlicedString::kParentOffset)); | |
| 5302 | |
| 5303 // Assure that we are dealing with a sequential string. Go to runtime if not. | |
| 5304 __ bind(&assure_seq_string); | |
| 5305 __ lw(result_, FieldMemOperand(object_, HeapObject::kMapOffset)); | |
| 5306 __ lbu(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset)); | |
| 5307 // Check that parent is not an external string. Go to runtime otherwise. | |
| 5308 // Note that if the original string is a cons or slice with an external | |
| 5309 // string as underlying string, we pass that unpacked underlying string with | |
| 5310 // the adjusted index to the runtime function. | |
| 5311 STATIC_ASSERT(kSeqStringTag == 0); | |
| 5312 | |
| 5313 __ And(t0, result_, Operand(kStringRepresentationMask)); | |
| 5314 __ Branch(&call_runtime_, ne, t0, Operand(zero_reg)); | |
| 5315 | |
| 5316 // Check for 1-byte or 2-byte string. | |
| 5317 __ bind(&flat_string); | |
| 5318 STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0); | |
| 5319 STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0); | |
| 5320 __ And(t0, result_, Operand(kStringEncodingMask)); | |
| 5321 __ Branch(&ascii_string, ne, t0, Operand(zero_reg)); | |
| 5322 | |
| 5323 // 2-byte string. | |
| 5324 // Load the 2-byte character code into the result register. We can | |
| 5325 // add without shifting since the smi tag size is the log2 of the | |
| 5326 // number of bytes in a two-byte character. | |
| 5327 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1 && kSmiShiftSize == 0); | |
| 5328 __ Addu(index_, object_, Operand(index_)); | |
| 5329 __ lhu(result_, FieldMemOperand(index_, SeqTwoByteString::kHeaderSize)); | |
| 5330 __ Branch(&got_char_code); | |
| 5331 | |
| 5332 // ASCII string. | |
| 5333 // Load the byte into the result register. | |
| 5334 __ bind(&ascii_string); | |
| 5335 | |
| 5336 __ srl(t0, index_, kSmiTagSize); | |
| 5337 __ Addu(index_, object_, t0); | |
| 5338 | |
| 5339 __ lbu(result_, FieldMemOperand(index_, SeqAsciiString::kHeaderSize)); | |
| 5340 | |
| 5341 __ bind(&got_char_code); | |
| 5342 __ sll(result_, result_, kSmiTagSize); | 5279 __ sll(result_, result_, kSmiTagSize); |
| 5343 __ bind(&exit_); | 5280 __ bind(&exit_); |
| 5344 } | 5281 } |
| 5345 | 5282 |
| 5346 | 5283 |
| 5347 void StringCharCodeAtGenerator::GenerateSlow( | 5284 void StringCharCodeAtGenerator::GenerateSlow( |
| 5348 MacroAssembler* masm, | 5285 MacroAssembler* masm, |
| 5349 const RuntimeCallHelper& call_helper) { | 5286 const RuntimeCallHelper& call_helper) { |
| 5350 __ Abort("Unexpected fallthrough to CharCodeAt slow case"); | 5287 __ Abort("Unexpected fallthrough to CharCodeAt slow case"); |
| 5351 | 5288 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 5380 // If index is still not a smi, it must be out of range. | 5317 // If index is still not a smi, it must be out of range. |
| 5381 __ JumpIfNotSmi(index_, index_out_of_range_); | 5318 __ JumpIfNotSmi(index_, index_out_of_range_); |
| 5382 // Otherwise, return to the fast path. | 5319 // Otherwise, return to the fast path. |
| 5383 __ Branch(&got_smi_index_); | 5320 __ Branch(&got_smi_index_); |
| 5384 | 5321 |
| 5385 // Call runtime. We get here when the receiver is a string and the | 5322 // Call runtime. We get here when the receiver is a string and the |
| 5386 // index is a number, but the code of getting the actual character | 5323 // index is a number, but the code of getting the actual character |
| 5387 // is too complex (e.g., when the string needs to be flattened). | 5324 // is too complex (e.g., when the string needs to be flattened). |
| 5388 __ bind(&call_runtime_); | 5325 __ bind(&call_runtime_); |
| 5389 call_helper.BeforeCall(masm); | 5326 call_helper.BeforeCall(masm); |
| 5327 __ sll(index_, index_, kSmiTagSize); |
| 5390 __ Push(object_, index_); | 5328 __ Push(object_, index_); |
| 5391 __ CallRuntime(Runtime::kStringCharCodeAt, 2); | 5329 __ CallRuntime(Runtime::kStringCharCodeAt, 2); |
| 5392 | 5330 |
| 5393 __ Move(result_, v0); | 5331 __ Move(result_, v0); |
| 5394 | 5332 |
| 5395 call_helper.AfterCall(masm); | 5333 call_helper.AfterCall(masm); |
| 5396 __ jmp(&exit_); | 5334 __ jmp(&exit_); |
| 5397 | 5335 |
| 5398 __ Abort("Unexpected fallthrough from CharCodeAt slow case"); | 5336 __ Abort("Unexpected fallthrough from CharCodeAt slow case"); |
| 5399 } | 5337 } |
| (...skipping 2061 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7461 &slow_elements); | 7399 &slow_elements); |
| 7462 __ Ret(); | 7400 __ Ret(); |
| 7463 } | 7401 } |
| 7464 | 7402 |
| 7465 | 7403 |
| 7466 #undef __ | 7404 #undef __ |
| 7467 | 7405 |
| 7468 } } // namespace v8::internal | 7406 } } // namespace v8::internal |
| 7469 | 7407 |
| 7470 #endif // V8_TARGET_ARCH_MIPS | 7408 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |