| 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 2753 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2764 __ movq(r15, rdi); | 2764 __ movq(r15, rdi); |
| 2765 __ movq(rbx, FieldOperand(rdi, HeapObject::kMapOffset)); | 2765 __ movq(rbx, FieldOperand(rdi, HeapObject::kMapOffset)); |
| 2766 __ movzxbl(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset)); | 2766 __ movzxbl(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset)); |
| 2767 // First check for flat two byte string. | 2767 // First check for flat two byte string. |
| 2768 __ andb(rbx, Immediate(kIsNotStringMask | | 2768 __ andb(rbx, Immediate(kIsNotStringMask | |
| 2769 kStringRepresentationMask | | 2769 kStringRepresentationMask | |
| 2770 kStringEncodingMask | | 2770 kStringEncodingMask | |
| 2771 kShortExternalStringMask)); | 2771 kShortExternalStringMask)); |
| 2772 STATIC_ASSERT((kStringTag | kSeqStringTag | kTwoByteStringTag) == 0); | 2772 STATIC_ASSERT((kStringTag | kSeqStringTag | kTwoByteStringTag) == 0); |
| 2773 __ j(zero, &seq_two_byte_string, Label::kNear); | 2773 __ j(zero, &seq_two_byte_string, Label::kNear); |
| 2774 // Any other flat string must be a flat ascii string. None of the following | 2774 // Any other flat string must be a flat ASCII string. None of the following |
| 2775 // string type tests will succeed if subject is not a string or a short | 2775 // string type tests will succeed if subject is not a string or a short |
| 2776 // external string. | 2776 // external string. |
| 2777 __ andb(rbx, Immediate(kIsNotStringMask | | 2777 __ andb(rbx, Immediate(kIsNotStringMask | |
| 2778 kStringRepresentationMask | | 2778 kStringRepresentationMask | |
| 2779 kShortExternalStringMask)); | 2779 kShortExternalStringMask)); |
| 2780 __ j(zero, &seq_ascii_string, Label::kNear); | 2780 __ j(zero, &seq_ascii_string, Label::kNear); |
| 2781 | 2781 |
| 2782 // rbx: whether subject is a string and if yes, its string representation | 2782 // rbx: whether subject is a string and if yes, its string representation |
| 2783 // Check for flat cons string or sliced string. | 2783 // Check for flat cons string or sliced string. |
| 2784 // A flat cons string is a cons string where the second part is the empty | 2784 // A flat cons string is a cons string where the second part is the empty |
| (...skipping 30 matching lines...) Expand all Loading... |
| 2815 __ movq(rdi, FieldOperand(rdi, ConsString::kFirstOffset)); | 2815 __ movq(rdi, FieldOperand(rdi, ConsString::kFirstOffset)); |
| 2816 // rdi: first part of cons string or parent of sliced string. | 2816 // rdi: first part of cons string or parent of sliced string. |
| 2817 // rbx: map of first part of cons string or map of parent of sliced string. | 2817 // rbx: map of first part of cons string or map of parent of sliced string. |
| 2818 // Is first part of cons or parent of slice a flat two byte string? | 2818 // Is first part of cons or parent of slice a flat two byte string? |
| 2819 __ bind(&check_encoding); | 2819 __ bind(&check_encoding); |
| 2820 __ movq(rbx, FieldOperand(rdi, HeapObject::kMapOffset)); | 2820 __ movq(rbx, FieldOperand(rdi, HeapObject::kMapOffset)); |
| 2821 __ testb(FieldOperand(rbx, Map::kInstanceTypeOffset), | 2821 __ testb(FieldOperand(rbx, Map::kInstanceTypeOffset), |
| 2822 Immediate(kStringRepresentationMask | kStringEncodingMask)); | 2822 Immediate(kStringRepresentationMask | kStringEncodingMask)); |
| 2823 STATIC_ASSERT((kSeqStringTag | kTwoByteStringTag) == 0); | 2823 STATIC_ASSERT((kSeqStringTag | kTwoByteStringTag) == 0); |
| 2824 __ j(zero, &seq_two_byte_string, Label::kNear); | 2824 __ j(zero, &seq_two_byte_string, Label::kNear); |
| 2825 // Any other flat string must be sequential ascii or external. | 2825 // Any other flat string must be sequential ASCII or external. |
| 2826 __ testb(FieldOperand(rbx, Map::kInstanceTypeOffset), | 2826 __ testb(FieldOperand(rbx, Map::kInstanceTypeOffset), |
| 2827 Immediate(kStringRepresentationMask)); | 2827 Immediate(kStringRepresentationMask)); |
| 2828 __ j(not_zero, &external_string); | 2828 __ j(not_zero, &external_string); |
| 2829 | 2829 |
| 2830 __ bind(&seq_ascii_string); | 2830 __ bind(&seq_ascii_string); |
| 2831 // rdi: subject string (sequential ascii) | 2831 // rdi: subject string (sequential ASCII) |
| 2832 // rax: RegExp data (FixedArray) | 2832 // rax: RegExp data (FixedArray) |
| 2833 __ movq(r11, FieldOperand(rax, JSRegExp::kDataAsciiCodeOffset)); | 2833 __ movq(r11, FieldOperand(rax, JSRegExp::kDataAsciiCodeOffset)); |
| 2834 __ Set(rcx, 1); // Type is ascii. | 2834 __ Set(rcx, 1); // Type is ASCII. |
| 2835 __ jmp(&check_code, Label::kNear); | 2835 __ jmp(&check_code, Label::kNear); |
| 2836 | 2836 |
| 2837 __ bind(&seq_two_byte_string); | 2837 __ bind(&seq_two_byte_string); |
| 2838 // rdi: subject string (flat two-byte) | 2838 // rdi: subject string (flat two-byte) |
| 2839 // rax: RegExp data (FixedArray) | 2839 // rax: RegExp data (FixedArray) |
| 2840 __ movq(r11, FieldOperand(rax, JSRegExp::kDataUC16CodeOffset)); | 2840 __ movq(r11, FieldOperand(rax, JSRegExp::kDataUC16CodeOffset)); |
| 2841 __ Set(rcx, 0); // Type is two byte. | 2841 __ Set(rcx, 0); // Type is two byte. |
| 2842 | 2842 |
| 2843 __ bind(&check_code); | 2843 __ bind(&check_code); |
| 2844 // Check that the irregexp code has been generated for the actual string | 2844 // Check that the irregexp code has been generated for the actual string |
| 2845 // encoding. If it has, the field contains a code object otherwise it contains | 2845 // encoding. If it has, the field contains a code object otherwise it contains |
| 2846 // smi (code flushing support) | 2846 // smi (code flushing support) |
| 2847 __ JumpIfSmi(r11, &runtime); | 2847 __ JumpIfSmi(r11, &runtime); |
| 2848 | 2848 |
| 2849 // rdi: subject string | 2849 // rdi: subject string |
| 2850 // rcx: encoding of subject string (1 if ascii, 0 if two_byte); | 2850 // rcx: encoding of subject string (1 if ASCII, 0 if two_byte); |
| 2851 // r11: code | 2851 // r11: code |
| 2852 // Load used arguments before starting to push arguments for call to native | 2852 // Load used arguments before starting to push arguments for call to native |
| 2853 // RegExp code to avoid handling changing stack height. | 2853 // RegExp code to avoid handling changing stack height. |
| 2854 __ SmiToInteger64(rbx, Operand(rsp, kPreviousIndexOffset)); | 2854 __ SmiToInteger64(rbx, Operand(rsp, kPreviousIndexOffset)); |
| 2855 | 2855 |
| 2856 // rdi: subject string | 2856 // rdi: subject string |
| 2857 // rbx: previous index | 2857 // rbx: previous index |
| 2858 // rcx: encoding of subject string (1 if ascii 0 if two_byte); | 2858 // rcx: encoding of subject string (1 if ASCII 0 if two_byte); |
| 2859 // r11: code | 2859 // r11: code |
| 2860 // All checks done. Now push arguments for native regexp code. | 2860 // All checks done. Now push arguments for native regexp code. |
| 2861 Counters* counters = masm->isolate()->counters(); | 2861 Counters* counters = masm->isolate()->counters(); |
| 2862 __ IncrementCounter(counters->regexp_entry_native(), 1); | 2862 __ IncrementCounter(counters->regexp_entry_native(), 1); |
| 2863 | 2863 |
| 2864 // Isolates: note we add an additional parameter here (isolate pointer). | 2864 // Isolates: note we add an additional parameter here (isolate pointer). |
| 2865 static const int kRegExpExecuteArguments = 8; | 2865 static const int kRegExpExecuteArguments = 8; |
| 2866 int argument_slots_on_stack = | 2866 int argument_slots_on_stack = |
| 2867 masm->ArgumentStackSlotsForCFunctionCall(kRegExpExecuteArguments); | 2867 masm->ArgumentStackSlotsForCFunctionCall(kRegExpExecuteArguments); |
| 2868 __ EnterApiExitFrame(argument_slots_on_stack); | 2868 __ EnterApiExitFrame(argument_slots_on_stack); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2905 #else | 2905 #else |
| 2906 Register arg4 = rcx; | 2906 Register arg4 = rcx; |
| 2907 Register arg3 = rdx; | 2907 Register arg3 = rdx; |
| 2908 Register arg2 = rsi; | 2908 Register arg2 = rsi; |
| 2909 Register arg1 = rdi; | 2909 Register arg1 = rdi; |
| 2910 #endif | 2910 #endif |
| 2911 | 2911 |
| 2912 // Keep track on aliasing between argX defined above and the registers used. | 2912 // Keep track on aliasing between argX defined above and the registers used. |
| 2913 // rdi: subject string | 2913 // rdi: subject string |
| 2914 // rbx: previous index | 2914 // rbx: previous index |
| 2915 // rcx: encoding of subject string (1 if ascii 0 if two_byte); | 2915 // rcx: encoding of subject string (1 if ASCII 0 if two_byte); |
| 2916 // r11: code | 2916 // r11: code |
| 2917 // r14: slice offset | 2917 // r14: slice offset |
| 2918 // r15: original subject string | 2918 // r15: original subject string |
| 2919 | 2919 |
| 2920 // Argument 2: Previous index. | 2920 // Argument 2: Previous index. |
| 2921 __ movq(arg2, rbx); | 2921 __ movq(arg2, rbx); |
| 2922 | 2922 |
| 2923 // Argument 4: End of string data | 2923 // Argument 4: End of string data |
| 2924 // Argument 3: Start of string data | 2924 // Argument 3: Start of string data |
| 2925 Label setup_two_byte, setup_rest, got_length, length_not_from_slice; | 2925 Label setup_two_byte, setup_rest, got_length, length_not_from_slice; |
| (...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3476 // are symbols they aren't equal. Register eax (not rax) already holds a | 3476 // are symbols they aren't equal. Register eax (not rax) already holds a |
| 3477 // non-zero value, which indicates not equal, so just return. | 3477 // non-zero value, which indicates not equal, so just return. |
| 3478 __ ret(0); | 3478 __ ret(0); |
| 3479 } | 3479 } |
| 3480 | 3480 |
| 3481 __ bind(&check_for_strings); | 3481 __ bind(&check_for_strings); |
| 3482 | 3482 |
| 3483 __ JumpIfNotBothSequentialAsciiStrings( | 3483 __ JumpIfNotBothSequentialAsciiStrings( |
| 3484 rdx, rax, rcx, rbx, &check_unequal_objects); | 3484 rdx, rax, rcx, rbx, &check_unequal_objects); |
| 3485 | 3485 |
| 3486 // Inline comparison of ascii strings. | 3486 // Inline comparison of ASCII strings. |
| 3487 if (cc_ == equal) { | 3487 if (cc_ == equal) { |
| 3488 StringCompareStub::GenerateFlatAsciiStringEquals(masm, | 3488 StringCompareStub::GenerateFlatAsciiStringEquals(masm, |
| 3489 rdx, | 3489 rdx, |
| 3490 rax, | 3490 rax, |
| 3491 rcx, | 3491 rcx, |
| 3492 rbx); | 3492 rbx); |
| 3493 } else { | 3493 } else { |
| 3494 StringCompareStub::GenerateCompareFlatAsciiStrings(masm, | 3494 StringCompareStub::GenerateCompareFlatAsciiStrings(masm, |
| 3495 rdx, | 3495 rdx, |
| 3496 rax, | 3496 rax, |
| (...skipping 1014 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4511 __ movzxbl(r9, FieldOperand(r9, Map::kInstanceTypeOffset)); | 4511 __ movzxbl(r9, FieldOperand(r9, Map::kInstanceTypeOffset)); |
| 4512 | 4512 |
| 4513 // Look at the length of the result of adding the two strings. | 4513 // Look at the length of the result of adding the two strings. |
| 4514 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue / 2); | 4514 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue / 2); |
| 4515 __ SmiAdd(rbx, rbx, rcx); | 4515 __ SmiAdd(rbx, rbx, rcx); |
| 4516 // Use the symbol table when adding two one character strings, as it | 4516 // Use the symbol table when adding two one character strings, as it |
| 4517 // helps later optimizations to return a symbol here. | 4517 // helps later optimizations to return a symbol here. |
| 4518 __ SmiCompare(rbx, Smi::FromInt(2)); | 4518 __ SmiCompare(rbx, Smi::FromInt(2)); |
| 4519 __ j(not_equal, &longer_than_two); | 4519 __ j(not_equal, &longer_than_two); |
| 4520 | 4520 |
| 4521 // Check that both strings are non-external ascii strings. | 4521 // Check that both strings are non-external ASCII strings. |
| 4522 __ JumpIfBothInstanceTypesAreNotSequentialAscii(r8, r9, rbx, rcx, | 4522 __ JumpIfBothInstanceTypesAreNotSequentialAscii(r8, r9, rbx, rcx, |
| 4523 &call_runtime); | 4523 &call_runtime); |
| 4524 | 4524 |
| 4525 // Get the two characters forming the sub string. | 4525 // Get the two characters forming the sub string. |
| 4526 __ movzxbq(rbx, FieldOperand(rax, SeqAsciiString::kHeaderSize)); | 4526 __ movzxbq(rbx, FieldOperand(rax, SeqAsciiString::kHeaderSize)); |
| 4527 __ movzxbq(rcx, FieldOperand(rdx, SeqAsciiString::kHeaderSize)); | 4527 __ movzxbq(rcx, FieldOperand(rdx, SeqAsciiString::kHeaderSize)); |
| 4528 | 4528 |
| 4529 // Try to lookup two character string in symbol table. If it is not found | 4529 // Try to lookup two character string in symbol table. If it is not found |
| 4530 // just allocate a new one. | 4530 // just allocate a new one. |
| 4531 Label make_two_character_string, make_flat_ascii_string; | 4531 Label make_two_character_string, make_flat_ascii_string; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 4551 __ bind(&longer_than_two); | 4551 __ bind(&longer_than_two); |
| 4552 // Check if resulting string will be flat. | 4552 // Check if resulting string will be flat. |
| 4553 __ SmiCompare(rbx, Smi::FromInt(String::kMinNonFlatLength)); | 4553 __ SmiCompare(rbx, Smi::FromInt(String::kMinNonFlatLength)); |
| 4554 __ j(below, &string_add_flat_result); | 4554 __ j(below, &string_add_flat_result); |
| 4555 // Handle exceptionally long strings in the runtime system. | 4555 // Handle exceptionally long strings in the runtime system. |
| 4556 STATIC_ASSERT((String::kMaxLength & 0x80000000) == 0); | 4556 STATIC_ASSERT((String::kMaxLength & 0x80000000) == 0); |
| 4557 __ SmiCompare(rbx, Smi::FromInt(String::kMaxLength)); | 4557 __ SmiCompare(rbx, Smi::FromInt(String::kMaxLength)); |
| 4558 __ j(above, &call_runtime); | 4558 __ j(above, &call_runtime); |
| 4559 | 4559 |
| 4560 // If result is not supposed to be flat, allocate a cons string object. If | 4560 // If result is not supposed to be flat, allocate a cons string object. If |
| 4561 // both strings are ascii the result is an ascii cons string. | 4561 // both strings are ASCII the result is an ASCII cons string. |
| 4562 // rax: first string | 4562 // rax: first string |
| 4563 // rbx: length of resulting flat string | 4563 // rbx: length of resulting flat string |
| 4564 // rdx: second string | 4564 // rdx: second string |
| 4565 // r8: instance type of first string | 4565 // r8: instance type of first string |
| 4566 // r9: instance type of second string | 4566 // r9: instance type of second string |
| 4567 Label non_ascii, allocated, ascii_data; | 4567 Label non_ascii, allocated, ascii_data; |
| 4568 __ movl(rcx, r8); | 4568 __ movl(rcx, r8); |
| 4569 __ and_(rcx, r9); | 4569 __ and_(rcx, r9); |
| 4570 STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0); | 4570 STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0); |
| 4571 STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0); | 4571 STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0); |
| 4572 __ testl(rcx, Immediate(kStringEncodingMask)); | 4572 __ testl(rcx, Immediate(kStringEncodingMask)); |
| 4573 __ j(zero, &non_ascii); | 4573 __ j(zero, &non_ascii); |
| 4574 __ bind(&ascii_data); | 4574 __ bind(&ascii_data); |
| 4575 // Allocate an acsii cons string. | 4575 // Allocate an ASCII cons string. |
| 4576 __ AllocateAsciiConsString(rcx, rdi, no_reg, &call_runtime); | 4576 __ AllocateAsciiConsString(rcx, rdi, no_reg, &call_runtime); |
| 4577 __ bind(&allocated); | 4577 __ bind(&allocated); |
| 4578 // Fill the fields of the cons string. | 4578 // Fill the fields of the cons string. |
| 4579 __ movq(FieldOperand(rcx, ConsString::kLengthOffset), rbx); | 4579 __ movq(FieldOperand(rcx, ConsString::kLengthOffset), rbx); |
| 4580 __ movq(FieldOperand(rcx, ConsString::kHashFieldOffset), | 4580 __ movq(FieldOperand(rcx, ConsString::kHashFieldOffset), |
| 4581 Immediate(String::kEmptyHashField)); | 4581 Immediate(String::kEmptyHashField)); |
| 4582 __ movq(FieldOperand(rcx, ConsString::kFirstOffset), rax); | 4582 __ movq(FieldOperand(rcx, ConsString::kFirstOffset), rax); |
| 4583 __ movq(FieldOperand(rcx, ConsString::kSecondOffset), rdx); | 4583 __ movq(FieldOperand(rcx, ConsString::kSecondOffset), rdx); |
| 4584 __ movq(rax, rcx); | 4584 __ movq(rax, rcx); |
| 4585 __ IncrementCounter(counters->string_add_native(), 1); | 4585 __ IncrementCounter(counters->string_add_native(), 1); |
| 4586 __ ret(2 * kPointerSize); | 4586 __ ret(2 * kPointerSize); |
| 4587 __ bind(&non_ascii); | 4587 __ bind(&non_ascii); |
| 4588 // At least one of the strings is two-byte. Check whether it happens | 4588 // At least one of the strings is two-byte. Check whether it happens |
| 4589 // to contain only ascii characters. | 4589 // to contain only ASCII characters. |
| 4590 // rcx: first instance type AND second instance type. | 4590 // rcx: first instance type AND second instance type. |
| 4591 // r8: first instance type. | 4591 // r8: first instance type. |
| 4592 // r9: second instance type. | 4592 // r9: second instance type. |
| 4593 __ testb(rcx, Immediate(kAsciiDataHintMask)); | 4593 __ testb(rcx, Immediate(kAsciiDataHintMask)); |
| 4594 __ j(not_zero, &ascii_data); | 4594 __ j(not_zero, &ascii_data); |
| 4595 __ xor_(r8, r9); | 4595 __ xor_(r8, r9); |
| 4596 STATIC_ASSERT(kAsciiStringTag != 0 && kAsciiDataHintTag != 0); | 4596 STATIC_ASSERT(kAsciiStringTag != 0 && kAsciiDataHintTag != 0); |
| 4597 __ andb(r8, Immediate(kAsciiStringTag | kAsciiDataHintTag)); | 4597 __ andb(r8, Immediate(kAsciiStringTag | kAsciiDataHintTag)); |
| 4598 __ cmpb(r8, Immediate(kAsciiStringTag | kAsciiDataHintTag)); | 4598 __ cmpb(r8, Immediate(kAsciiStringTag | kAsciiDataHintTag)); |
| 4599 __ j(equal, &ascii_data); | 4599 __ j(equal, &ascii_data); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4653 | 4653 |
| 4654 Label non_ascii_string_add_flat_result; | 4654 Label non_ascii_string_add_flat_result; |
| 4655 // r9: instance type of second string | 4655 // r9: instance type of second string |
| 4656 // First string and second string have the same encoding. | 4656 // First string and second string have the same encoding. |
| 4657 STATIC_ASSERT(kTwoByteStringTag == 0); | 4657 STATIC_ASSERT(kTwoByteStringTag == 0); |
| 4658 __ SmiToInteger32(rbx, rbx); | 4658 __ SmiToInteger32(rbx, rbx); |
| 4659 __ testb(r9, Immediate(kStringEncodingMask)); | 4659 __ testb(r9, Immediate(kStringEncodingMask)); |
| 4660 __ j(zero, &non_ascii_string_add_flat_result); | 4660 __ j(zero, &non_ascii_string_add_flat_result); |
| 4661 | 4661 |
| 4662 __ bind(&make_flat_ascii_string); | 4662 __ bind(&make_flat_ascii_string); |
| 4663 // Both strings are ascii strings. As they are short they are both flat. | 4663 // Both strings are ASCII strings. As they are short they are both flat. |
| 4664 __ AllocateAsciiString(rax, rbx, rdi, r8, r9, &call_runtime); | 4664 __ AllocateAsciiString(rax, rbx, rdi, r8, r9, &call_runtime); |
| 4665 // rax: result string | 4665 // rax: result string |
| 4666 // Locate first character of result. | 4666 // Locate first character of result. |
| 4667 __ lea(rbx, FieldOperand(rax, SeqAsciiString::kHeaderSize)); | 4667 __ lea(rbx, FieldOperand(rax, SeqAsciiString::kHeaderSize)); |
| 4668 // rcx: first char of first string | 4668 // rcx: first char of first string |
| 4669 // rbx: first character of result | 4669 // rbx: first character of result |
| 4670 // r14: length of first string | 4670 // r14: length of first string |
| 4671 StringHelper::GenerateCopyCharacters(masm, rbx, rcx, r14, true); | 4671 StringHelper::GenerateCopyCharacters(masm, rbx, rcx, r14, true); |
| 4672 // rbx: next character of result | 4672 // rbx: next character of result |
| 4673 // rdx: first char of second string | 4673 // rdx: first char of second string |
| 4674 // r15: length of second string | 4674 // r15: length of second string |
| 4675 StringHelper::GenerateCopyCharacters(masm, rbx, rdx, r15, true); | 4675 StringHelper::GenerateCopyCharacters(masm, rbx, rdx, r15, true); |
| 4676 __ IncrementCounter(counters->string_add_native(), 1); | 4676 __ IncrementCounter(counters->string_add_native(), 1); |
| 4677 __ ret(2 * kPointerSize); | 4677 __ ret(2 * kPointerSize); |
| 4678 | 4678 |
| 4679 __ bind(&non_ascii_string_add_flat_result); | 4679 __ bind(&non_ascii_string_add_flat_result); |
| 4680 // Both strings are ascii strings. As they are short they are both flat. | 4680 // Both strings are ASCII strings. As they are short they are both flat. |
| 4681 __ AllocateTwoByteString(rax, rbx, rdi, r8, r9, &call_runtime); | 4681 __ AllocateTwoByteString(rax, rbx, rdi, r8, r9, &call_runtime); |
| 4682 // rax: result string | 4682 // rax: result string |
| 4683 // Locate first character of result. | 4683 // Locate first character of result. |
| 4684 __ lea(rbx, FieldOperand(rax, SeqTwoByteString::kHeaderSize)); | 4684 __ lea(rbx, FieldOperand(rax, SeqTwoByteString::kHeaderSize)); |
| 4685 // rcx: first char of first string | 4685 // rcx: first char of first string |
| 4686 // rbx: first character of result | 4686 // rbx: first character of result |
| 4687 // r14: length of first string | 4687 // r14: length of first string |
| 4688 StringHelper::GenerateCopyCharacters(masm, rbx, rcx, r14, false); | 4688 StringHelper::GenerateCopyCharacters(masm, rbx, rcx, r14, false); |
| 4689 // rbx: next character of result | 4689 // rbx: next character of result |
| 4690 // rdx: first char of second string | 4690 // rdx: first char of second string |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4924 | 4924 |
| 4925 // If length is not 2 the string is not a candidate. | 4925 // If length is not 2 the string is not a candidate. |
| 4926 __ SmiCompare(FieldOperand(candidate, String::kLengthOffset), | 4926 __ SmiCompare(FieldOperand(candidate, String::kLengthOffset), |
| 4927 Smi::FromInt(2)); | 4927 Smi::FromInt(2)); |
| 4928 __ j(not_equal, &next_probe[i]); | 4928 __ j(not_equal, &next_probe[i]); |
| 4929 | 4929 |
| 4930 // We use kScratchRegister as a temporary register in assumption that | 4930 // We use kScratchRegister as a temporary register in assumption that |
| 4931 // JumpIfInstanceTypeIsNotSequentialAscii does not use it implicitly | 4931 // JumpIfInstanceTypeIsNotSequentialAscii does not use it implicitly |
| 4932 Register temp = kScratchRegister; | 4932 Register temp = kScratchRegister; |
| 4933 | 4933 |
| 4934 // Check that the candidate is a non-external ascii string. | 4934 // Check that the candidate is a non-external ASCII string. |
| 4935 __ movzxbl(temp, FieldOperand(map, Map::kInstanceTypeOffset)); | 4935 __ movzxbl(temp, FieldOperand(map, Map::kInstanceTypeOffset)); |
| 4936 __ JumpIfInstanceTypeIsNotSequentialAscii( | 4936 __ JumpIfInstanceTypeIsNotSequentialAscii( |
| 4937 temp, temp, &next_probe[i]); | 4937 temp, temp, &next_probe[i]); |
| 4938 | 4938 |
| 4939 // Check if the two characters match. | 4939 // Check if the two characters match. |
| 4940 __ movl(temp, FieldOperand(candidate, SeqAsciiString::kHeaderSize)); | 4940 __ movl(temp, FieldOperand(candidate, SeqAsciiString::kHeaderSize)); |
| 4941 __ andl(temp, Immediate(0x0000ffff)); | 4941 __ andl(temp, Immediate(0x0000ffff)); |
| 4942 __ cmpl(chars, temp); | 4942 __ cmpl(chars, temp); |
| 4943 __ j(equal, &found_in_symbol_table); | 4943 __ j(equal, &found_in_symbol_table); |
| 4944 __ bind(&next_probe[i]); | 4944 __ bind(&next_probe[i]); |
| (...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5404 __ Move(rax, Smi::FromInt(EQUAL)); | 5404 __ Move(rax, Smi::FromInt(EQUAL)); |
| 5405 Counters* counters = masm->isolate()->counters(); | 5405 Counters* counters = masm->isolate()->counters(); |
| 5406 __ IncrementCounter(counters->string_compare_native(), 1); | 5406 __ IncrementCounter(counters->string_compare_native(), 1); |
| 5407 __ ret(2 * kPointerSize); | 5407 __ ret(2 * kPointerSize); |
| 5408 | 5408 |
| 5409 __ bind(¬_same); | 5409 __ bind(¬_same); |
| 5410 | 5410 |
| 5411 // Check that both are sequential ASCII strings. | 5411 // Check that both are sequential ASCII strings. |
| 5412 __ JumpIfNotBothSequentialAsciiStrings(rdx, rax, rcx, rbx, &runtime); | 5412 __ JumpIfNotBothSequentialAsciiStrings(rdx, rax, rcx, rbx, &runtime); |
| 5413 | 5413 |
| 5414 // Inline comparison of ascii strings. | 5414 // Inline comparison of ASCII strings. |
| 5415 __ IncrementCounter(counters->string_compare_native(), 1); | 5415 __ IncrementCounter(counters->string_compare_native(), 1); |
| 5416 // Drop arguments from the stack | 5416 // Drop arguments from the stack |
| 5417 __ pop(rcx); | 5417 __ pop(rcx); |
| 5418 __ addq(rsp, Immediate(2 * kPointerSize)); | 5418 __ addq(rsp, Immediate(2 * kPointerSize)); |
| 5419 __ push(rcx); | 5419 __ push(rcx); |
| 5420 GenerateCompareFlatAsciiStrings(masm, rdx, rax, rcx, rbx, rdi, r8); | 5420 GenerateCompareFlatAsciiStrings(masm, rdx, rax, rcx, rbx, rdi, r8); |
| 5421 | 5421 |
| 5422 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) | 5422 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) |
| 5423 // tagged as a small integer. | 5423 // tagged as a small integer. |
| 5424 __ bind(&runtime); | 5424 __ bind(&runtime); |
| (...skipping 810 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6235 xmm0, | 6235 xmm0, |
| 6236 &slow_elements); | 6236 &slow_elements); |
| 6237 __ ret(0); | 6237 __ ret(0); |
| 6238 } | 6238 } |
| 6239 | 6239 |
| 6240 #undef __ | 6240 #undef __ |
| 6241 | 6241 |
| 6242 } } // namespace v8::internal | 6242 } } // namespace v8::internal |
| 6243 | 6243 |
| 6244 #endif // V8_TARGET_ARCH_X64 | 6244 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |