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 4809 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4820 } | 4820 } |
4821 | 4821 |
4822 | 4822 |
4823 // ------------------------------------------------------------------------- | 4823 // ------------------------------------------------------------------------- |
4824 // StringCharCodeAtGenerator | 4824 // StringCharCodeAtGenerator |
4825 | 4825 |
4826 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { | 4826 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { |
4827 Label flat_string; | 4827 Label flat_string; |
4828 Label ascii_string; | 4828 Label ascii_string; |
4829 Label got_char_code; | 4829 Label got_char_code; |
4830 Label sliced_string; | |
4830 | 4831 |
4831 // If the receiver is a smi trigger the non-string case. | 4832 // If the receiver is a smi trigger the non-string case. |
4832 STATIC_ASSERT(kSmiTag == 0); | 4833 STATIC_ASSERT(kSmiTag == 0); |
4833 __ JumpIfSmi(object_, receiver_not_string_); | 4834 __ JumpIfSmi(object_, receiver_not_string_); |
4834 | 4835 |
4835 // Fetch the instance type of the receiver into result register. | 4836 // Fetch the instance type of the receiver into result register. |
4836 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset)); | 4837 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset)); |
4837 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); | 4838 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); |
4838 // If the receiver is not a string trigger the non-string case. | 4839 // If the receiver is not a string trigger the non-string case. |
4839 __ test(result_, Immediate(kIsNotStringMask)); | 4840 __ test(result_, Immediate(kIsNotStringMask)); |
(...skipping 10 matching lines...) Expand all Loading... | |
4850 // Check for index out of range. | 4851 // Check for index out of range. |
4851 __ cmp(scratch_, FieldOperand(object_, String::kLengthOffset)); | 4852 __ cmp(scratch_, FieldOperand(object_, String::kLengthOffset)); |
4852 __ j(above_equal, index_out_of_range_); | 4853 __ j(above_equal, index_out_of_range_); |
4853 | 4854 |
4854 // We need special handling for non-flat strings. | 4855 // We need special handling for non-flat strings. |
4855 STATIC_ASSERT(kSeqStringTag == 0); | 4856 STATIC_ASSERT(kSeqStringTag == 0); |
4856 __ test(result_, Immediate(kStringRepresentationMask)); | 4857 __ test(result_, Immediate(kStringRepresentationMask)); |
4857 __ j(zero, &flat_string); | 4858 __ j(zero, &flat_string); |
4858 | 4859 |
4859 // Handle non-flat strings. | 4860 // Handle non-flat strings. |
4860 __ test(result_, Immediate(kIsConsStringMask)); | 4861 __ and_(result_, kStringRepresentationMask); |
4861 __ j(zero, &call_runtime_); | 4862 __ cmp(result_, kSlicedStringTag); |
4863 __ j(equal, &sliced_string); | |
4864 __ cmp(result_, kExternalStringTag); | |
4865 __ j(equal, &call_runtime_); | |
4862 | 4866 |
4863 // ConsString. | 4867 // ConsString. |
4864 // Check whether the right hand side is the empty string (i.e. if | 4868 // Check whether the right hand side is the empty string (i.e. if |
4865 // this is really a flat string in a cons string). If that is not | 4869 // this is really a flat string in a cons string). If that is not |
4866 // the case we would rather go to the runtime system now to flatten | 4870 // the case we would rather go to the runtime system now to flatten |
4867 // the string. | 4871 // the string. |
4868 __ cmp(FieldOperand(object_, ConsString::kSecondOffset), | 4872 __ cmp(FieldOperand(object_, ConsString::kSecondOffset), |
4869 Immediate(masm->isolate()->factory()->empty_string())); | 4873 Immediate(masm->isolate()->factory()->empty_string())); |
4870 __ j(not_equal, &call_runtime_); | 4874 __ j(not_equal, &call_runtime_); |
4871 // Get the first of the two strings and load its instance type. | 4875 // Get the first of the two strings and load its instance type. |
4872 __ mov(object_, FieldOperand(object_, ConsString::kFirstOffset)); | 4876 __ mov(object_, FieldOperand(object_, ConsString::kFirstOffset)); |
4873 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset)); | 4877 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset)); |
4874 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); | 4878 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); |
4875 // If the first cons component is also non-flat, then go to runtime. | 4879 // If the first cons component is also non-flat, then go to runtime. |
4876 STATIC_ASSERT(kSeqStringTag == 0); | 4880 STATIC_ASSERT(kSeqStringTag == 0); |
4877 __ test(result_, Immediate(kStringRepresentationMask)); | 4881 __ test(result_, Immediate(kStringRepresentationMask)); |
4878 __ j(not_zero, &call_runtime_); | 4882 __ j(not_zero, &call_runtime_); |
4883 __ jmp(&flat_string); | |
4884 | |
4885 // SlicedString, unpack and add offset. | |
4886 __ bind(&sliced_string); | |
4887 __ add(scratch_, FieldOperand(object_, SlicedString::kOffsetOffset)); | |
4888 __ mov(object_, FieldOperand(object_, SlicedString::kParentOffset)); | |
4889 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset)); | |
4890 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); | |
4879 | 4891 |
4880 // Check for 1-byte or 2-byte string. | 4892 // Check for 1-byte or 2-byte string. |
4881 __ bind(&flat_string); | 4893 __ bind(&flat_string); |
4882 STATIC_ASSERT(kAsciiStringTag != 0); | 4894 STATIC_ASSERT(kAsciiStringTag != 0); |
4883 __ test(result_, Immediate(kStringEncodingMask)); | 4895 __ test(result_, Immediate(kStringEncodingMask)); |
4884 __ j(not_zero, &ascii_string); | 4896 __ j(not_zero, &ascii_string); |
4885 | 4897 |
4886 // 2-byte string. | 4898 // 2-byte string. |
4887 // Load the 2-byte character code into the result register. | 4899 // Load the 2-byte character code into the result register. |
4888 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1); | 4900 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1); |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5194 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset)); | 5206 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset)); |
5195 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); | 5207 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); |
5196 __ and_(ecx, kStringRepresentationMask); | 5208 __ and_(ecx, kStringRepresentationMask); |
5197 __ cmp(ecx, kExternalStringTag); | 5209 __ cmp(ecx, kExternalStringTag); |
5198 __ j(equal, &string_add_runtime); | 5210 __ j(equal, &string_add_runtime); |
5199 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); | 5211 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); |
5200 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); | 5212 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); |
5201 __ and_(ecx, kStringRepresentationMask); | 5213 __ and_(ecx, kStringRepresentationMask); |
5202 __ cmp(ecx, kExternalStringTag); | 5214 __ cmp(ecx, kExternalStringTag); |
5203 __ j(equal, &string_add_runtime); | 5215 __ j(equal, &string_add_runtime); |
5216 // We cannot encounter sliced strings here since: | |
5217 STATIC_ASSERT(SlicedString::kMinLength >= String::kMinNonFlatLength); | |
5204 // Now check if both strings are ascii strings. | 5218 // Now check if both strings are ascii strings. |
5205 // eax: first string | 5219 // eax: first string |
5206 // ebx: length of resulting flat string as a smi | 5220 // ebx: length of resulting flat string as a smi |
5207 // edx: second string | 5221 // edx: second string |
5208 Label non_ascii_string_add_flat_result; | 5222 Label non_ascii_string_add_flat_result; |
5209 STATIC_ASSERT(kStringEncodingMask == kAsciiStringTag); | 5223 STATIC_ASSERT(kStringEncodingMask == kAsciiStringTag); |
5210 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset)); | 5224 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset)); |
5211 __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kAsciiStringTag); | 5225 __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kAsciiStringTag); |
5212 __ j(zero, &non_ascii_string_add_flat_result); | 5226 __ j(zero, &non_ascii_string_add_flat_result); |
5213 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); | 5227 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); |
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5604 Label hash_not_zero; | 5618 Label hash_not_zero; |
5605 __ test(hash, Operand(hash)); | 5619 __ test(hash, Operand(hash)); |
5606 __ j(not_zero, &hash_not_zero, Label::kNear); | 5620 __ j(not_zero, &hash_not_zero, Label::kNear); |
5607 __ mov(hash, Immediate(27)); | 5621 __ mov(hash, Immediate(27)); |
5608 __ bind(&hash_not_zero); | 5622 __ bind(&hash_not_zero); |
5609 } | 5623 } |
5610 | 5624 |
5611 | 5625 |
5612 void SubStringStub::Generate(MacroAssembler* masm) { | 5626 void SubStringStub::Generate(MacroAssembler* masm) { |
5613 Label runtime; | 5627 Label runtime; |
5614 | 5628 |
Yang
2011/07/27 11:51:58
Do not create string slice unless experimental fla
| |
5629 if (FLAG_string_slices) { | |
5630 __ jmp(&runtime); | |
5631 } | |
5615 // Stack frame on entry. | 5632 // Stack frame on entry. |
5616 // esp[0]: return address | 5633 // esp[0]: return address |
5617 // esp[4]: to | 5634 // esp[4]: to |
5618 // esp[8]: from | 5635 // esp[8]: from |
5619 // esp[12]: string | 5636 // esp[12]: string |
5620 | 5637 |
5621 // Make sure first argument is a string. | 5638 // Make sure first argument is a string. |
5622 __ mov(eax, Operand(esp, 3 * kPointerSize)); | 5639 __ mov(eax, Operand(esp, 3 * kPointerSize)); |
5623 STATIC_ASSERT(kSmiTag == 0); | 5640 STATIC_ASSERT(kSmiTag == 0); |
5624 __ JumpIfSmi(eax, &runtime); | 5641 __ JumpIfSmi(eax, &runtime); |
(...skipping 756 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6381 __ Drop(1); | 6398 __ Drop(1); |
6382 __ ret(2 * kPointerSize); | 6399 __ ret(2 * kPointerSize); |
6383 } | 6400 } |
6384 | 6401 |
6385 | 6402 |
6386 #undef __ | 6403 #undef __ |
6387 | 6404 |
6388 } } // namespace v8::internal | 6405 } } // namespace v8::internal |
6389 | 6406 |
6390 #endif // V8_TARGET_ARCH_IA32 | 6407 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |