| 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 5619 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5630 NearLabel compare_chars; | 5630 NearLabel compare_chars; |
| 5631 __ bind(&check_zero_length); | 5631 __ bind(&check_zero_length); |
| 5632 STATIC_ASSERT(kSmiTag == 0); | 5632 STATIC_ASSERT(kSmiTag == 0); |
| 5633 __ test(length, Operand(length)); | 5633 __ test(length, Operand(length)); |
| 5634 __ j(not_zero, &compare_chars); | 5634 __ j(not_zero, &compare_chars); |
| 5635 __ Set(eax, Immediate(Smi::FromInt(EQUAL))); | 5635 __ Set(eax, Immediate(Smi::FromInt(EQUAL))); |
| 5636 __ ret(0); | 5636 __ ret(0); |
| 5637 | 5637 |
| 5638 // Compare characters. | 5638 // Compare characters. |
| 5639 __ bind(&compare_chars); | 5639 __ bind(&compare_chars); |
| 5640 | 5640 GenerateAsciiCharsCompareLoop(masm, left, right, length, scratch2, |
| 5641 // Change index to run from -length to -1 by adding length to string | 5641 &strings_not_equal); |
| 5642 // start. This means that loop ends when index reaches zero, which | |
| 5643 // doesn't need an additional compare. | |
| 5644 __ SmiUntag(length); | |
| 5645 __ lea(left, | |
| 5646 FieldOperand(left, length, times_1, SeqAsciiString::kHeaderSize)); | |
| 5647 __ lea(right, | |
| 5648 FieldOperand(right, length, times_1, SeqAsciiString::kHeaderSize)); | |
| 5649 __ neg(length); | |
| 5650 Register index = length; // index = -length; | |
| 5651 | |
| 5652 // Compare loop. | |
| 5653 NearLabel loop; | |
| 5654 __ bind(&loop); | |
| 5655 __ mov_b(scratch2, Operand(left, index, times_1, 0)); | |
| 5656 __ cmpb(scratch2, Operand(right, index, times_1, 0)); | |
| 5657 __ j(not_equal, &strings_not_equal); | |
| 5658 __ add(Operand(index), Immediate(1)); | |
| 5659 __ j(not_zero, &loop); | |
| 5660 | 5642 |
| 5661 // Characters are equal. | 5643 // Characters are equal. |
| 5662 __ Set(eax, Immediate(Smi::FromInt(EQUAL))); | 5644 __ Set(eax, Immediate(Smi::FromInt(EQUAL))); |
| 5663 __ ret(0); | 5645 __ ret(0); |
| 5664 } | 5646 } |
| 5665 | 5647 |
| 5666 | 5648 |
| 5667 void StringCompareStub::GenerateCompareFlatAsciiStrings(MacroAssembler* masm, | 5649 void StringCompareStub::GenerateCompareFlatAsciiStrings(MacroAssembler* masm, |
| 5668 Register left, | 5650 Register left, |
| 5669 Register right, | 5651 Register right, |
| 5670 Register scratch1, | 5652 Register scratch1, |
| 5671 Register scratch2, | 5653 Register scratch2, |
| 5672 Register scratch3) { | 5654 Register scratch3) { |
| 5673 Label result_not_equal; | |
| 5674 Label result_greater; | |
| 5675 Label compare_lengths; | |
| 5676 | |
| 5677 Counters* counters = masm->isolate()->counters(); | 5655 Counters* counters = masm->isolate()->counters(); |
| 5678 __ IncrementCounter(counters->string_compare_native(), 1); | 5656 __ IncrementCounter(counters->string_compare_native(), 1); |
| 5679 | 5657 |
| 5680 // Find minimum length. | 5658 // Find minimum length. |
| 5681 NearLabel left_shorter; | 5659 NearLabel left_shorter; |
| 5682 __ mov(scratch1, FieldOperand(left, String::kLengthOffset)); | 5660 __ mov(scratch1, FieldOperand(left, String::kLengthOffset)); |
| 5683 __ mov(scratch3, scratch1); | 5661 __ mov(scratch3, scratch1); |
| 5684 __ sub(scratch3, FieldOperand(right, String::kLengthOffset)); | 5662 __ sub(scratch3, FieldOperand(right, String::kLengthOffset)); |
| 5685 | 5663 |
| 5686 Register length_delta = scratch3; | 5664 Register length_delta = scratch3; |
| 5687 | 5665 |
| 5688 __ j(less_equal, &left_shorter); | 5666 __ j(less_equal, &left_shorter); |
| 5689 // Right string is shorter. Change scratch1 to be length of right string. | 5667 // Right string is shorter. Change scratch1 to be length of right string. |
| 5690 __ sub(scratch1, Operand(length_delta)); | 5668 __ sub(scratch1, Operand(length_delta)); |
| 5691 __ bind(&left_shorter); | 5669 __ bind(&left_shorter); |
| 5692 | 5670 |
| 5693 Register min_length = scratch1; | 5671 Register min_length = scratch1; |
| 5694 | 5672 |
| 5695 // If either length is zero, just compare lengths. | 5673 // If either length is zero, just compare lengths. |
| 5674 NearLabel compare_lengths; |
| 5696 __ test(min_length, Operand(min_length)); | 5675 __ test(min_length, Operand(min_length)); |
| 5697 __ j(zero, &compare_lengths); | 5676 __ j(zero, &compare_lengths); |
| 5698 | 5677 |
| 5699 // Change index to run from -min_length to -1 by adding min_length | 5678 // Compare characters. |
| 5700 // to string start. This means that loop ends when index reaches zero, | 5679 NearLabel result_not_equal; |
| 5701 // which doesn't need an additional compare. | 5680 GenerateAsciiCharsCompareLoop(masm, left, right, min_length, scratch2, |
| 5702 __ SmiUntag(min_length); | 5681 &result_not_equal); |
| 5703 __ lea(left, | |
| 5704 FieldOperand(left, | |
| 5705 min_length, times_1, | |
| 5706 SeqAsciiString::kHeaderSize)); | |
| 5707 __ lea(right, | |
| 5708 FieldOperand(right, | |
| 5709 min_length, times_1, | |
| 5710 SeqAsciiString::kHeaderSize)); | |
| 5711 __ neg(min_length); | |
| 5712 | |
| 5713 Register index = min_length; // index = -min_length; | |
| 5714 | |
| 5715 { | |
| 5716 // Compare loop. | |
| 5717 NearLabel loop; | |
| 5718 __ bind(&loop); | |
| 5719 // Compare characters. | |
| 5720 __ mov_b(scratch2, Operand(left, index, times_1, 0)); | |
| 5721 __ cmpb(scratch2, Operand(right, index, times_1, 0)); | |
| 5722 __ j(not_equal, &result_not_equal); | |
| 5723 __ add(Operand(index), Immediate(1)); | |
| 5724 __ j(not_zero, &loop); | |
| 5725 } | |
| 5726 | 5682 |
| 5727 // Compare lengths - strings up to min-length are equal. | 5683 // Compare lengths - strings up to min-length are equal. |
| 5728 __ bind(&compare_lengths); | 5684 __ bind(&compare_lengths); |
| 5729 __ test(length_delta, Operand(length_delta)); | 5685 __ test(length_delta, Operand(length_delta)); |
| 5730 __ j(not_zero, &result_not_equal); | 5686 __ j(not_zero, &result_not_equal); |
| 5731 | 5687 |
| 5732 // Result is EQUAL. | 5688 // Result is EQUAL. |
| 5733 STATIC_ASSERT(EQUAL == 0); | 5689 STATIC_ASSERT(EQUAL == 0); |
| 5734 STATIC_ASSERT(kSmiTag == 0); | 5690 STATIC_ASSERT(kSmiTag == 0); |
| 5735 __ Set(eax, Immediate(Smi::FromInt(EQUAL))); | 5691 __ Set(eax, Immediate(Smi::FromInt(EQUAL))); |
| 5736 __ ret(0); | 5692 __ ret(0); |
| 5737 | 5693 |
| 5694 NearLabel result_greater; |
| 5738 __ bind(&result_not_equal); | 5695 __ bind(&result_not_equal); |
| 5739 __ j(greater, &result_greater); | 5696 __ j(greater, &result_greater); |
| 5740 | 5697 |
| 5741 // Result is LESS. | 5698 // Result is LESS. |
| 5742 __ Set(eax, Immediate(Smi::FromInt(LESS))); | 5699 __ Set(eax, Immediate(Smi::FromInt(LESS))); |
| 5743 __ ret(0); | 5700 __ ret(0); |
| 5744 | 5701 |
| 5745 // Result is GREATER. | 5702 // Result is GREATER. |
| 5746 __ bind(&result_greater); | 5703 __ bind(&result_greater); |
| 5747 __ Set(eax, Immediate(Smi::FromInt(GREATER))); | 5704 __ Set(eax, Immediate(Smi::FromInt(GREATER))); |
| 5748 __ ret(0); | 5705 __ ret(0); |
| 5749 } | 5706 } |
| 5750 | 5707 |
| 5751 | 5708 |
| 5709 void StringCompareStub::GenerateAsciiCharsCompareLoop( |
| 5710 MacroAssembler* masm, |
| 5711 Register left, |
| 5712 Register right, |
| 5713 Register length, |
| 5714 Register scratch, |
| 5715 NearLabel* chars_not_equal) { |
| 5716 // Change index to run from -length to -1 by adding length to string |
| 5717 // start. This means that loop ends when index reaches zero, which |
| 5718 // doesn't need an additional compare. |
| 5719 __ SmiUntag(length); |
| 5720 __ lea(left, |
| 5721 FieldOperand(left, length, times_1, SeqAsciiString::kHeaderSize)); |
| 5722 __ lea(right, |
| 5723 FieldOperand(right, length, times_1, SeqAsciiString::kHeaderSize)); |
| 5724 __ neg(length); |
| 5725 Register index = length; // index = -length; |
| 5726 |
| 5727 // Compare loop. |
| 5728 NearLabel loop; |
| 5729 __ bind(&loop); |
| 5730 __ mov_b(scratch, Operand(left, index, times_1, 0)); |
| 5731 __ cmpb(scratch, Operand(right, index, times_1, 0)); |
| 5732 __ j(not_equal, chars_not_equal); |
| 5733 __ add(Operand(index), Immediate(1)); |
| 5734 __ j(not_zero, &loop); |
| 5735 } |
| 5736 |
| 5737 |
| 5752 void StringCompareStub::Generate(MacroAssembler* masm) { | 5738 void StringCompareStub::Generate(MacroAssembler* masm) { |
| 5753 Label runtime; | 5739 Label runtime; |
| 5754 | 5740 |
| 5755 // Stack frame on entry. | 5741 // Stack frame on entry. |
| 5756 // esp[0]: return address | 5742 // esp[0]: return address |
| 5757 // esp[4]: right string | 5743 // esp[4]: right string |
| 5758 // esp[8]: left string | 5744 // esp[8]: left string |
| 5759 | 5745 |
| 5760 __ mov(edx, Operand(esp, 2 * kPointerSize)); // left | 5746 __ mov(edx, Operand(esp, 2 * kPointerSize)); // left |
| 5761 __ mov(eax, Operand(esp, 1 * kPointerSize)); // right | 5747 __ mov(eax, Operand(esp, 1 * kPointerSize)); // right |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5996 // Do a tail call to the rewritten stub. | 5982 // Do a tail call to the rewritten stub. |
| 5997 __ jmp(Operand(edi)); | 5983 __ jmp(Operand(edi)); |
| 5998 } | 5984 } |
| 5999 | 5985 |
| 6000 | 5986 |
| 6001 #undef __ | 5987 #undef __ |
| 6002 | 5988 |
| 6003 } } // namespace v8::internal | 5989 } } // namespace v8::internal |
| 6004 | 5990 |
| 6005 #endif // V8_TARGET_ARCH_IA32 | 5991 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |