OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 9619 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9630 | 9630 |
9631 // Just jump to runtime to create the sub string. | 9631 // Just jump to runtime to create the sub string. |
9632 __ bind(&runtime); | 9632 __ bind(&runtime); |
9633 __ TailCallRuntime(ExternalReference(Runtime::kSubString), 3, 1); | 9633 __ TailCallRuntime(ExternalReference(Runtime::kSubString), 3, 1); |
9634 } | 9634 } |
9635 | 9635 |
9636 | 9636 |
9637 void StringCompareStub::GenerateCompareFlatAsciiStrings(MacroAssembler* masm, | 9637 void StringCompareStub::GenerateCompareFlatAsciiStrings(MacroAssembler* masm, |
9638 Register left, | 9638 Register left, |
9639 Register right, | 9639 Register right, |
9640 Register counter, | |
9641 Register scratch1, | 9640 Register scratch1, |
9642 Register scratch2) { | 9641 Register scratch2, |
9643 ASSERT(counter.is(ecx)); | 9642 Register scratch3) { |
9644 Label compare_lengths, compare_lengths_1; | 9643 Label compare_lengths, compare_lengths_1; |
9645 | 9644 |
9646 // Find minimum length. If either length is zero just compare lengths. | 9645 // Find minimum length. If either length is zero just compare lengths. |
9647 __ mov(counter, FieldOperand(left, String::kLengthOffset)); | 9646 __ mov(scratch1, FieldOperand(left, String::kLengthOffset)); |
9648 __ test(counter, Operand(counter)); | |
9649 __ j(zero, &compare_lengths_1); | |
9650 __ mov(scratch1, FieldOperand(right, String::kLengthOffset)); | |
9651 __ test(scratch1, Operand(scratch1)); | 9647 __ test(scratch1, Operand(scratch1)); |
9652 __ j(zero, &compare_lengths_1); | 9648 __ j(zero, &compare_lengths_1); |
9653 __ cmp(counter, Operand(scratch1)); | 9649 __ mov(scratch2, FieldOperand(right, String::kLengthOffset)); |
| 9650 __ test(scratch2, Operand(scratch2)); |
| 9651 __ j(zero, &compare_lengths_1); |
| 9652 __ cmp(scratch1, Operand(scratch2)); |
9654 if (CpuFeatures::IsSupported(CMOV)) { | 9653 if (CpuFeatures::IsSupported(CMOV)) { |
9655 CpuFeatures::Scope use_cmov(CMOV); | 9654 CpuFeatures::Scope use_cmov(CMOV); |
9656 __ cmov(greater, counter, Operand(scratch1)); | 9655 __ cmov(greater, scratch1, Operand(scratch2)); |
9657 } else { | 9656 } else { |
9658 Label l; | 9657 Label l; |
9659 __ j(less, &l); | 9658 __ j(less, &l); |
9660 __ mov(counter, scratch1); | 9659 __ mov(scratch1, scratch2); |
9661 __ bind(&l); | 9660 __ bind(&l); |
9662 } | 9661 } |
9663 | 9662 |
9664 Label result_greater, result_less; | 9663 Label result_greater, result_less; |
9665 Label loop; | 9664 Label loop; |
9666 // Compare next character. | 9665 // Compare next character. |
9667 __ mov(scratch2, Immediate(-1)); // Index into strings. | 9666 __ mov(scratch3, Immediate(-1)); // Index into strings. |
9668 __ bind(&loop); | 9667 __ bind(&loop); |
9669 // Compare characters. | 9668 // Compare characters. |
9670 __ add(Operand(scratch2), Immediate(1)); | 9669 Label character_compare_done; |
9671 __ mov_b(scratch1, Operand(left, | 9670 __ add(Operand(scratch3), Immediate(1)); |
9672 scratch2, | 9671 __ mov_b(scratch2, Operand(left, |
| 9672 scratch3, |
9673 times_1, | 9673 times_1, |
9674 SeqAsciiString::kHeaderSize - kHeapObjectTag)); | 9674 SeqAsciiString::kHeaderSize - kHeapObjectTag)); |
9675 __ subb(scratch1, Operand(right, | 9675 __ subb(scratch2, Operand(right, |
9676 scratch2, | 9676 scratch3, |
9677 times_1, | 9677 times_1, |
9678 SeqAsciiString::kHeaderSize - kHeapObjectTag)); | 9678 SeqAsciiString::kHeaderSize - kHeapObjectTag)); |
9679 __ loope(&loop); | 9679 __ j(not_equal, &character_compare_done); |
| 9680 __ sub(Operand(scratch1), Immediate(1)); |
| 9681 __ j(not_zero, &loop); |
9680 // If min length characters match compare lengths otherwise last character | 9682 // If min length characters match compare lengths otherwise last character |
9681 // compare is the result. | 9683 // compare is the result. |
| 9684 __ bind(&character_compare_done); |
9682 __ j(equal, &compare_lengths); | 9685 __ j(equal, &compare_lengths); |
9683 __ j(less, &result_less); | 9686 __ j(less, &result_less); |
9684 __ jmp(&result_greater); | 9687 __ jmp(&result_greater); |
9685 | 9688 |
9686 // Compare lengths. | 9689 // Compare lengths. |
9687 Label result_not_equal; | 9690 Label result_not_equal; |
9688 __ bind(&compare_lengths); | 9691 __ bind(&compare_lengths); |
9689 __ mov(counter, FieldOperand(left, String::kLengthOffset)); | 9692 __ mov(scratch1, FieldOperand(left, String::kLengthOffset)); |
9690 __ bind(&compare_lengths_1); | 9693 __ bind(&compare_lengths_1); |
9691 __ sub(counter, FieldOperand(right, String::kLengthOffset)); | 9694 __ sub(scratch1, FieldOperand(right, String::kLengthOffset)); |
9692 __ j(not_zero, &result_not_equal); | 9695 __ j(not_zero, &result_not_equal); |
9693 | 9696 |
9694 // Result is EQUAL. | 9697 // Result is EQUAL. |
9695 ASSERT_EQ(0, EQUAL); | 9698 ASSERT_EQ(0, EQUAL); |
9696 ASSERT_EQ(0, kSmiTag); | 9699 ASSERT_EQ(0, kSmiTag); |
9697 __ xor_(eax, Operand(eax)); | 9700 __ xor_(eax, Operand(eax)); |
9698 __ IncrementCounter(&Counters::string_compare_native, 1); | 9701 __ IncrementCounter(&Counters::string_compare_native, 1); |
9699 __ ret(2 * kPointerSize); | 9702 __ ret(2 * kPointerSize); |
9700 __ bind(&result_not_equal); | 9703 __ bind(&result_not_equal); |
9701 __ j(greater, &result_greater); | 9704 __ j(greater, &result_greater); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9767 | 9770 |
9768 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) | 9771 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) |
9769 // tagged as a small integer. | 9772 // tagged as a small integer. |
9770 __ bind(&runtime); | 9773 __ bind(&runtime); |
9771 __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1); | 9774 __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1); |
9772 } | 9775 } |
9773 | 9776 |
9774 #undef __ | 9777 #undef __ |
9775 | 9778 |
9776 } } // namespace v8::internal | 9779 } } // namespace v8::internal |
OLD | NEW |