Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/ia32/code-stubs-ia32.cc

Issue 6927044: Extract common code in string compare loops. (Closed)
Patch Set: Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/ia32/code-stubs-ia32.h ('k') | src/x64/code-stubs-x64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « src/ia32/code-stubs-ia32.h ('k') | src/x64/code-stubs-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698