| 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 | 
|---|