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