Chromium Code Reviews| Index: src/x64/code-stubs-x64.cc |
| diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc |
| index cbdc022bf5c62cb3723b6024cc4a85f1d9eb0e8c..1f94870a1ffaaff94b60009089e94bbc5c3cb125 100644 |
| --- a/src/x64/code-stubs-x64.cc |
| +++ b/src/x64/code-stubs-x64.cc |
| @@ -2835,13 +2835,21 @@ void CompareStub::Generate(MacroAssembler* masm) { |
| rdx, rax, rcx, rbx, &check_unequal_objects); |
| // Inline comparison of ascii strings. |
| - StringCompareStub::GenerateCompareFlatAsciiStrings(masm, |
| + if (cc_ == equal) { |
| + StringCompareStub::GenerateFlatAsciiStringEquals(masm, |
| rdx, |
| rax, |
| rcx, |
| - rbx, |
| - rdi, |
| - r8); |
| + rbx); |
| + } else { |
| + StringCompareStub::GenerateCompareFlatAsciiStrings(masm, |
| + rdx, |
| + rax, |
| + rcx, |
| + rbx, |
| + rdi, |
| + r8); |
| + } |
| #ifdef DEBUG |
| __ Abort("Unexpected fall-through from string comparison"); |
| @@ -4489,6 +4497,64 @@ void SubStringStub::Generate(MacroAssembler* masm) { |
| } |
| +void StringCompareStub::GenerateFlatAsciiStringEquals(MacroAssembler* masm, |
| + Register left, |
| + Register right, |
| + Register scratch1, |
| + Register scratch2) { |
| + Register length = scratch1; |
| + |
| + // Compare lengths. |
| + NearLabel check_zero_length; |
| + __ movq(length, FieldOperand(left, String::kLengthOffset)); |
| + __ SmiCompare(length, FieldOperand(right, String::kLengthOffset)); |
| + __ j(equal, &check_zero_length); |
| + __ Move(rax, Smi::FromInt(NOT_EQUAL)); |
| + __ ret(0); |
| + |
| + // Check if the length is zero. |
| + NearLabel compare_chars; |
| + __ bind(&check_zero_length); |
| + STATIC_ASSERT(kSmiTag == 0); |
| + __ SmiTest(length); |
| + __ j(not_zero, &compare_chars); |
| + __ Move(rax, Smi::FromInt(EQUAL)); |
| + __ ret(0); |
| + |
| + // Compare characters. |
| + __ bind(&compare_chars); |
| + |
| + // Change index to run from -length to -1 by adding length to string |
| + // start. This means that loop ends when index reaches zero, which |
| + // doesn't need an additional compare. |
| + __ SmiToInteger32(length, length); |
| + __ lea(left, |
| + FieldOperand(left, length, times_1, SeqAsciiString::kHeaderSize)); |
| + __ lea(right, |
| + FieldOperand(right, length, times_1, SeqAsciiString::kHeaderSize)); |
| + __ neg(length); |
| + Register index = length; // index = -length; |
| + |
| + // Compare loop. |
| + NearLabel strings_not_equal, loop; |
| + __ bind(&loop); |
| + __ movb(scratch2, Operand(left, index, times_1, 0)); |
|
Mads Ager (chromium)
2011/05/05 07:42:24
Do you need "times_1, 0" here?
Vitaly Repeshko
2011/05/05 11:40:18
Same here.
|
| + __ cmpb(scratch2, Operand(right, index, times_1, 0)); |
| + __ j(not_equal, &strings_not_equal); |
| + __ addq(index, Immediate(1)); |
| + __ j(not_zero, &loop); |
| + |
| + // Characters are equal. |
| + __ Move(rax, Smi::FromInt(EQUAL)); |
| + __ ret(0); |
| + |
| + // Characters are not equal. |
| + __ bind(&strings_not_equal); |
| + __ Move(rax, Smi::FromInt(NOT_EQUAL)); |
| + __ ret(0); |
| +} |
| + |
| + |
| void StringCompareStub::GenerateCompareFlatAsciiStrings(MacroAssembler* masm, |
| Register left, |
| Register right, |
| @@ -4687,6 +4753,7 @@ void ICCompareStub::GenerateHeapNumbers(MacroAssembler* masm) { |
| void ICCompareStub::GenerateStrings(MacroAssembler* masm) { |
| ASSERT(state_ == CompareIC::STRINGS); |
| + ASSERT(GetCondition() == equal); |
| Label miss; |
| // Registers containing left and right operands respectively. |
| @@ -4695,7 +4762,6 @@ void ICCompareStub::GenerateStrings(MacroAssembler* masm) { |
| Register tmp1 = rcx; |
| Register tmp2 = rbx; |
| Register tmp3 = rdi; |
| - Register tmp4 = r8; |
| // Check that both operands are heap objects. |
| Condition cond = masm->CheckEitherSmi(left, right, tmp1); |
| @@ -4728,7 +4794,6 @@ void ICCompareStub::GenerateStrings(MacroAssembler* masm) { |
| // Check that both strings are symbols. If they are, we're done |
| // because we already know they are not identical. |
| NearLabel do_compare; |
| - ASSERT(GetCondition() == equal); |
| STATIC_ASSERT(kSymbolTag != 0); |
| __ and_(tmp1, tmp2); |
| __ testl(tmp1, Immediate(kIsSymbolMask)); |
| @@ -4744,8 +4809,8 @@ void ICCompareStub::GenerateStrings(MacroAssembler* masm) { |
| __ JumpIfNotBothSequentialAsciiStrings(left, right, tmp1, tmp2, &runtime); |
| // Compare flat ASCII strings. Returns when done. |
| - StringCompareStub::GenerateCompareFlatAsciiStrings( |
| - masm, left, right, tmp1, tmp2, tmp3, tmp4); |
| + StringCompareStub::GenerateFlatAsciiStringEquals( |
| + masm, left, right, tmp1, tmp2); |
| // Handle more complex cases in runtime. |
| __ bind(&runtime); |
| @@ -4753,7 +4818,7 @@ void ICCompareStub::GenerateStrings(MacroAssembler* masm) { |
| __ push(left); |
| __ push(right); |
| __ push(tmp1); |
| - __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
| + __ TailCallRuntime(Runtime::kStringEquals, 2, 1); |
| __ bind(&miss); |
| GenerateMiss(masm); |