Chromium Code Reviews| 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 4757 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4768 | IncludeNumberCompareField::encode(include_number_compare_) | 4768 | IncludeNumberCompareField::encode(include_number_compare_) |
| 4769 | IncludeSmiCompareField::encode(include_smi_compare_); | 4769 | IncludeSmiCompareField::encode(include_smi_compare_); |
| 4770 } | 4770 } |
| 4771 | 4771 |
| 4772 | 4772 |
| 4773 // StringCharCodeAtGenerator | 4773 // StringCharCodeAtGenerator |
| 4774 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { | 4774 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { |
| 4775 Label flat_string; | 4775 Label flat_string; |
| 4776 Label ascii_string; | 4776 Label ascii_string; |
| 4777 Label got_char_code; | 4777 Label got_char_code; |
| 4778 Label sliced_string; | |
| 4778 | 4779 |
| 4779 // If the receiver is a smi trigger the non-string case. | 4780 // If the receiver is a smi trigger the non-string case. |
| 4780 __ JumpIfSmi(object_, receiver_not_string_); | 4781 __ JumpIfSmi(object_, receiver_not_string_); |
| 4781 | 4782 |
| 4782 // Fetch the instance type of the receiver into result register. | 4783 // Fetch the instance type of the receiver into result register. |
| 4783 __ ldr(result_, FieldMemOperand(object_, HeapObject::kMapOffset)); | 4784 __ ldr(result_, FieldMemOperand(object_, HeapObject::kMapOffset)); |
| 4784 __ ldrb(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset)); | 4785 __ ldrb(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset)); |
| 4785 // If the receiver is not a string trigger the non-string case. | 4786 // If the receiver is not a string trigger the non-string case. |
| 4786 __ tst(result_, Operand(kIsNotStringMask)); | 4787 __ tst(result_, Operand(kIsNotStringMask)); |
| 4787 __ b(ne, receiver_not_string_); | 4788 __ b(ne, receiver_not_string_); |
| 4788 | 4789 |
| 4789 // If the index is non-smi trigger the non-smi case. | 4790 // If the index is non-smi trigger the non-smi case. |
| 4790 __ JumpIfNotSmi(index_, &index_not_smi_); | 4791 __ JumpIfNotSmi(index_, &index_not_smi_); |
| 4791 | 4792 |
| 4792 // Put smi-tagged index into scratch register. | 4793 // Put smi-tagged index into scratch register. |
| 4793 __ mov(scratch_, index_); | 4794 __ mov(scratch_, index_); |
| 4794 __ bind(&got_smi_index_); | 4795 __ bind(&got_smi_index_); |
| 4795 | 4796 |
| 4796 // Check for index out of range. | 4797 // Check for index out of range. |
| 4797 __ ldr(ip, FieldMemOperand(object_, String::kLengthOffset)); | 4798 __ ldr(ip, FieldMemOperand(object_, String::kLengthOffset)); |
| 4798 __ cmp(ip, Operand(scratch_)); | 4799 __ cmp(ip, Operand(scratch_)); |
| 4799 __ b(ls, index_out_of_range_); | 4800 __ b(ls, index_out_of_range_); |
| 4800 | 4801 |
| 4801 // We need special handling for non-flat strings. | 4802 // We need special handling for non-flat strings. |
| 4802 STATIC_ASSERT(kSeqStringTag == 0); | 4803 STATIC_ASSERT(kSeqStringTag == 0); |
| 4803 __ tst(result_, Operand(kStringRepresentationMask)); | 4804 __ tst(result_, Operand(kStringRepresentationMask)); |
| 4804 __ b(eq, &flat_string); | 4805 __ b(eq, &flat_string); |
| 4805 | 4806 |
| 4806 // Handle non-flat strings. | 4807 // Handle non-flat strings. |
| 4807 __ tst(result_, Operand(kIsConsStringMask)); | 4808 __ and_(result_, result_, Operand(kStringRepresentationMask)); |
| 4809 __ cmp(result_, Operand(kSlicedStringTag)); | |
| 4810 __ b(eq, &sliced_string); | |
| 4811 __ cmp(result_, Operand(kExternalStringTag)); | |
| 4808 __ b(eq, &call_runtime_); | 4812 __ b(eq, &call_runtime_); |
| 4809 | 4813 |
| 4810 // ConsString. | 4814 // ConsString. |
| 4811 // Check whether the right hand side is the empty string (i.e. if | 4815 // Check whether the right hand side is the empty string (i.e. if |
| 4812 // this is really a flat string in a cons string). If that is not | 4816 // this is really a flat string in a cons string). If that is not |
| 4813 // the case we would rather go to the runtime system now to flatten | 4817 // the case we would rather go to the runtime system now to flatten |
| 4814 // the string. | 4818 // the string. |
| 4815 __ ldr(result_, FieldMemOperand(object_, ConsString::kSecondOffset)); | 4819 __ ldr(result_, FieldMemOperand(object_, ConsString::kSecondOffset)); |
| 4816 __ LoadRoot(ip, Heap::kEmptyStringRootIndex); | 4820 __ LoadRoot(ip, Heap::kEmptyStringRootIndex); |
| 4817 __ cmp(result_, Operand(ip)); | 4821 __ cmp(result_, Operand(ip)); |
| 4818 __ b(ne, &call_runtime_); | 4822 __ b(ne, &call_runtime_); |
| 4819 // Get the first of the two strings and load its instance type. | 4823 // Get the first of the two strings and load its instance type. |
| 4820 __ ldr(object_, FieldMemOperand(object_, ConsString::kFirstOffset)); | 4824 __ ldr(object_, FieldMemOperand(object_, ConsString::kFirstOffset)); |
| 4821 __ ldr(result_, FieldMemOperand(object_, HeapObject::kMapOffset)); | 4825 __ ldr(result_, FieldMemOperand(object_, HeapObject::kMapOffset)); |
| 4822 __ ldrb(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset)); | 4826 __ ldrb(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset)); |
| 4823 // If the first cons component is also non-flat, then go to runtime. | 4827 // If the first cons component is also non-flat, then go to runtime. |
| 4824 STATIC_ASSERT(kSeqStringTag == 0); | 4828 STATIC_ASSERT(kSeqStringTag == 0); |
| 4825 __ tst(result_, Operand(kStringRepresentationMask)); | 4829 __ tst(result_, Operand(kStringRepresentationMask)); |
| 4826 __ b(ne, &call_runtime_); | 4830 __ b(ne, &call_runtime_); |
| 4831 __ jmp(&flat_string); | |
| 4832 | |
| 4833 // SlicedString, unpack and add offset. | |
| 4834 __ bind(&sliced_string); | |
| 4835 __ ldr(result_, FieldMemOperand(object_, SlicedString::kOffsetOffset)); | |
| 4836 __ add(scratch_, scratch_, result_); | |
| 4837 __ ldr(object_, FieldMemOperand(object_, SlicedString::kParentOffset)); | |
| 4838 __ ldr(result_, FieldMemOperand(object_, HeapObject::kMapOffset)); | |
| 4839 __ ldrb(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset)); | |
| 4827 | 4840 |
| 4828 // Check for 1-byte or 2-byte string. | 4841 // Check for 1-byte or 2-byte string. |
| 4829 __ bind(&flat_string); | 4842 __ bind(&flat_string); |
| 4830 STATIC_ASSERT(kAsciiStringTag != 0); | 4843 STATIC_ASSERT(kAsciiStringTag != 0); |
| 4831 __ tst(result_, Operand(kStringEncodingMask)); | 4844 __ tst(result_, Operand(kStringEncodingMask)); |
| 4832 __ b(ne, &ascii_string); | 4845 __ b(ne, &ascii_string); |
| 4833 | 4846 |
| 4834 // 2-byte string. | 4847 // 2-byte string. |
| 4835 // Load the 2-byte character code into the result register. We can | 4848 // Load the 2-byte character code into the result register. We can |
| 4836 // add without shifting since the smi tag size is the log2 of the | 4849 // add without shifting since the smi tag size is the log2 of the |
| (...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5372 // hash += hash << 15; | 5385 // hash += hash << 15; |
| 5373 __ add(hash, hash, Operand(hash, LSL, 15), SetCC); | 5386 __ add(hash, hash, Operand(hash, LSL, 15), SetCC); |
| 5374 | 5387 |
| 5375 // if (hash == 0) hash = 27; | 5388 // if (hash == 0) hash = 27; |
| 5376 __ mov(hash, Operand(27), LeaveCC, ne); | 5389 __ mov(hash, Operand(27), LeaveCC, ne); |
| 5377 } | 5390 } |
| 5378 | 5391 |
| 5379 | 5392 |
| 5380 void SubStringStub::Generate(MacroAssembler* masm) { | 5393 void SubStringStub::Generate(MacroAssembler* masm) { |
| 5381 Label runtime; | 5394 Label runtime; |
| 5382 | 5395 |
|
Yang
2011/07/27 11:51:58
Do not create string slice unless experimental fla
| |
| 5396 if (FLAG_string_slices) { | |
| 5397 __ jmp(&runtime); | |
| 5398 } | |
| 5383 // Stack frame on entry. | 5399 // Stack frame on entry. |
| 5384 // lr: return address | 5400 // lr: return address |
| 5385 // sp[0]: to | 5401 // sp[0]: to |
| 5386 // sp[4]: from | 5402 // sp[4]: from |
| 5387 // sp[8]: string | 5403 // sp[8]: string |
| 5388 | 5404 |
| 5389 // This stub is called from the native-call %_SubString(...), so | 5405 // This stub is called from the native-call %_SubString(...), so |
| 5390 // nothing can be assumed about the arguments. It is tested that: | 5406 // nothing can be assumed about the arguments. It is tested that: |
| 5391 // "string" is a sequential string, | 5407 // "string" is a sequential string, |
| 5392 // both "from" and "to" are smis, and | 5408 // both "from" and "to" are smis, and |
| (...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5911 __ ldr(r4, FieldMemOperand(r0, HeapObject::kMapOffset)); | 5927 __ ldr(r4, FieldMemOperand(r0, HeapObject::kMapOffset)); |
| 5912 __ ldr(r5, FieldMemOperand(r1, HeapObject::kMapOffset)); | 5928 __ ldr(r5, FieldMemOperand(r1, HeapObject::kMapOffset)); |
| 5913 __ ldrb(r4, FieldMemOperand(r4, Map::kInstanceTypeOffset)); | 5929 __ ldrb(r4, FieldMemOperand(r4, Map::kInstanceTypeOffset)); |
| 5914 __ ldrb(r5, FieldMemOperand(r5, Map::kInstanceTypeOffset)); | 5930 __ ldrb(r5, FieldMemOperand(r5, Map::kInstanceTypeOffset)); |
| 5915 } | 5931 } |
| 5916 // Check that both strings are sequential. | 5932 // Check that both strings are sequential. |
| 5917 STATIC_ASSERT(kSeqStringTag == 0); | 5933 STATIC_ASSERT(kSeqStringTag == 0); |
| 5918 __ tst(r4, Operand(kStringRepresentationMask)); | 5934 __ tst(r4, Operand(kStringRepresentationMask)); |
| 5919 __ tst(r5, Operand(kStringRepresentationMask), eq); | 5935 __ tst(r5, Operand(kStringRepresentationMask), eq); |
| 5920 __ b(ne, &string_add_runtime); | 5936 __ b(ne, &string_add_runtime); |
| 5937 // We cannot encounter sliced strings here since: | |
| 5938 STATIC_ASSERT(SlicedString::kMinLength >= String::kMinNonFlatLength); | |
| 5921 // Now check if both strings have the same encoding (ASCII/Two-byte). | 5939 // Now check if both strings have the same encoding (ASCII/Two-byte). |
| 5922 // r0: first string. | 5940 // r0: first string. |
| 5923 // r1: second string. | 5941 // r1: second string. |
| 5924 // r2: length of first string. | 5942 // r2: length of first string. |
| 5925 // r3: length of second string. | 5943 // r3: length of second string. |
| 5926 // r6: sum of lengths.. | 5944 // r6: sum of lengths.. |
| 5927 Label non_ascii_string_add_flat_result; | 5945 Label non_ascii_string_add_flat_result; |
| 5928 ASSERT(IsPowerOf2(kStringEncodingMask)); // Just one bit to test. | 5946 ASSERT(IsPowerOf2(kStringEncodingMask)); // Just one bit to test. |
| 5929 __ eor(r7, r4, Operand(r5)); | 5947 __ eor(r7, r4, Operand(r5)); |
| 5930 __ tst(r7, Operand(kStringEncodingMask)); | 5948 __ tst(r7, Operand(kStringEncodingMask)); |
| (...skipping 604 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6535 __ mov(result, Operand(0)); | 6553 __ mov(result, Operand(0)); |
| 6536 __ Ret(); | 6554 __ Ret(); |
| 6537 } | 6555 } |
| 6538 | 6556 |
| 6539 | 6557 |
| 6540 #undef __ | 6558 #undef __ |
| 6541 | 6559 |
| 6542 } } // namespace v8::internal | 6560 } } // namespace v8::internal |
| 6543 | 6561 |
| 6544 #endif // V8_TARGET_ARCH_ARM | 6562 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |