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 5629 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5640 // edx: second string | 5640 // edx: second string |
5641 Label first_prepared, second_prepared; | 5641 Label first_prepared, second_prepared; |
5642 Label first_is_sequential, second_is_sequential; | 5642 Label first_is_sequential, second_is_sequential; |
5643 __ bind(&string_add_flat_result); | 5643 __ bind(&string_add_flat_result); |
5644 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset)); | 5644 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset)); |
5645 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); | 5645 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); |
5646 // ecx: instance type of first string | 5646 // ecx: instance type of first string |
5647 STATIC_ASSERT(kSeqStringTag == 0); | 5647 STATIC_ASSERT(kSeqStringTag == 0); |
5648 __ test_b(ecx, kStringRepresentationMask); | 5648 __ test_b(ecx, kStringRepresentationMask); |
5649 __ j(zero, &first_is_sequential, Label::kNear); | 5649 __ j(zero, &first_is_sequential, Label::kNear); |
5650 // Rule out short external string and prepare it so that offset-wise, it | 5650 // Rule out short external string and load string resource. |
5651 // looks like a sequential string. | |
5652 STATIC_ASSERT(kShortExternalStringTag != 0); | 5651 STATIC_ASSERT(kShortExternalStringTag != 0); |
5653 __ test_b(ecx, kShortExternalStringMask); | 5652 __ test_b(ecx, kShortExternalStringMask); |
5654 __ j(not_zero, &call_runtime); | 5653 __ j(not_zero, &call_runtime); |
5655 __ mov(eax, FieldOperand(eax, ExternalString::kResourceDataOffset)); | 5654 __ mov(eax, FieldOperand(eax, ExternalString::kResourceDataOffset)); |
5656 STATIC_ASSERT(SeqAsciiString::kHeaderSize == SeqTwoByteString::kHeaderSize); | 5655 STATIC_ASSERT(SeqAsciiString::kHeaderSize == SeqTwoByteString::kHeaderSize); |
5657 __ jmp(&first_prepared, Label::kNear); | 5656 __ jmp(&first_prepared, Label::kNear); |
5658 __ bind(&first_is_sequential); | 5657 __ bind(&first_is_sequential); |
5659 __ add(eax, Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag)); | 5658 __ add(eax, Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag)); |
5660 __ bind(&first_prepared); | 5659 __ bind(&first_prepared); |
5661 | 5660 |
5662 __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset)); | 5661 __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset)); |
5663 __ movzx_b(edi, FieldOperand(edi, Map::kInstanceTypeOffset)); | 5662 __ movzx_b(edi, FieldOperand(edi, Map::kInstanceTypeOffset)); |
5664 // Check whether both strings have same encoding. | 5663 // Check whether both strings have same encoding. |
5665 // edi: instance type of second string | 5664 // edi: instance type of second string |
5666 __ xor_(ecx, edi); | 5665 __ xor_(ecx, edi); |
5667 __ test_b(ecx, kStringEncodingMask); | 5666 __ test_b(ecx, kStringEncodingMask); |
5668 __ j(not_zero, &call_runtime); | 5667 __ j(not_zero, &call_runtime); |
5669 STATIC_ASSERT(kSeqStringTag == 0); | 5668 STATIC_ASSERT(kSeqStringTag == 0); |
5670 __ test_b(edi, kStringRepresentationMask); | 5669 __ test_b(edi, kStringRepresentationMask); |
5671 __ j(zero, &second_is_sequential, Label::kNear); | 5670 __ j(zero, &second_is_sequential, Label::kNear); |
5672 // Rule out short external string and prepare it so that offset-wise, it | 5671 // Rule out short external string and load string resource. |
5673 // looks like a sequential string. | |
5674 STATIC_ASSERT(kShortExternalStringTag != 0); | 5672 STATIC_ASSERT(kShortExternalStringTag != 0); |
5675 __ test_b(edi, kShortExternalStringMask); | 5673 __ test_b(edi, kShortExternalStringMask); |
5676 __ j(not_zero, &call_runtime); | 5674 __ j(not_zero, &call_runtime); |
5677 __ mov(edx, FieldOperand(edx, ExternalString::kResourceDataOffset)); | 5675 __ mov(edx, FieldOperand(edx, ExternalString::kResourceDataOffset)); |
5678 STATIC_ASSERT(SeqAsciiString::kHeaderSize == SeqTwoByteString::kHeaderSize); | 5676 STATIC_ASSERT(SeqAsciiString::kHeaderSize == SeqTwoByteString::kHeaderSize); |
5679 __ jmp(&second_prepared, Label::kNear); | 5677 __ jmp(&second_prepared, Label::kNear); |
5680 __ bind(&second_is_sequential); | 5678 __ bind(&second_is_sequential); |
5681 __ add(edx, Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag)); | 5679 __ add(edx, Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag)); |
5682 __ bind(&second_prepared); | 5680 __ bind(&second_prepared); |
5683 | 5681 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5729 // eax: first string - known to be two byte | 5727 // eax: first string - known to be two byte |
5730 // ebx: length of resulting flat string as a smi | 5728 // ebx: length of resulting flat string as a smi |
5731 // edx: second string | 5729 // edx: second string |
5732 __ bind(&non_ascii_string_add_flat_result); | 5730 __ bind(&non_ascii_string_add_flat_result); |
5733 // Both strings are two byte strings. | 5731 // Both strings are two byte strings. |
5734 __ SmiUntag(ebx); | 5732 __ SmiUntag(ebx); |
5735 __ AllocateTwoByteString(eax, ebx, ecx, edx, edi, &call_runtime_drop_two); | 5733 __ AllocateTwoByteString(eax, ebx, ecx, edx, edi, &call_runtime_drop_two); |
5736 // eax: result string | 5734 // eax: result string |
5737 __ mov(ecx, eax); | 5735 __ mov(ecx, eax); |
5738 // Locate first character of result. | 5736 // Locate first character of result. |
5739 __ add(ecx, | 5737 __ add(ecx, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); |
5740 Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); | |
5741 // Load second argument's length and first character location. Account for | 5738 // Load second argument's length and first character location. Account for |
5742 // values currently on the stack when fetching arguments from it. | 5739 // values currently on the stack when fetching arguments from it. |
5743 __ mov(edx, Operand(esp, 4 * kPointerSize)); | 5740 __ mov(edx, Operand(esp, 4 * kPointerSize)); |
5744 __ mov(edi, FieldOperand(edx, String::kLengthOffset)); | 5741 __ mov(edi, FieldOperand(edx, String::kLengthOffset)); |
5745 __ SmiUntag(edi); | 5742 __ SmiUntag(edi); |
5746 __ pop(edx); | 5743 __ pop(edx); |
5747 // eax: result string | 5744 // eax: result string |
5748 // ecx: first character of result | 5745 // ecx: first character of result |
5749 // edx: first char of first argument | 5746 // edx: first char of first argument |
5750 // edi: length of first argument | 5747 // edi: length of first argument |
(...skipping 1584 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7335 false); | 7332 false); |
7336 __ pop(edx); | 7333 __ pop(edx); |
7337 __ ret(0); | 7334 __ ret(0); |
7338 } | 7335 } |
7339 | 7336 |
7340 #undef __ | 7337 #undef __ |
7341 | 7338 |
7342 } } // namespace v8::internal | 7339 } } // namespace v8::internal |
7343 | 7340 |
7344 #endif // V8_TARGET_ARCH_IA32 | 7341 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |