OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 5436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5447 FieldOperand(right, length, times_1, SeqAsciiString::kHeaderSize)); | 5447 FieldOperand(right, length, times_1, SeqAsciiString::kHeaderSize)); |
5448 __ neg(length); | 5448 __ neg(length); |
5449 Register index = length; // index = -length; | 5449 Register index = length; // index = -length; |
5450 | 5450 |
5451 // Compare loop. | 5451 // Compare loop. |
5452 Label loop; | 5452 Label loop; |
5453 __ bind(&loop); | 5453 __ bind(&loop); |
5454 __ movb(scratch, Operand(left, index, times_1, 0)); | 5454 __ movb(scratch, Operand(left, index, times_1, 0)); |
5455 __ cmpb(scratch, Operand(right, index, times_1, 0)); | 5455 __ cmpb(scratch, Operand(right, index, times_1, 0)); |
5456 __ j(not_equal, chars_not_equal, near_jump); | 5456 __ j(not_equal, chars_not_equal, near_jump); |
5457 __ addq(index, Immediate(1)); | 5457 __ incq(index); |
5458 __ j(not_zero, &loop); | 5458 __ j(not_zero, &loop); |
5459 } | 5459 } |
5460 | 5460 |
5461 | 5461 |
5462 void StringCompareStub::Generate(MacroAssembler* masm) { | 5462 void StringCompareStub::Generate(MacroAssembler* masm) { |
5463 Label runtime; | 5463 Label runtime; |
5464 | 5464 |
5465 // Stack frame on entry. | 5465 // Stack frame on entry. |
5466 // rsp[0]: return address | 5466 // rsp[0]: return address |
5467 // rsp[8]: right string | 5467 // rsp[8]: right string |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5618 __ bind(&done); | 5618 __ bind(&done); |
5619 __ ret(0); | 5619 __ ret(0); |
5620 | 5620 |
5621 __ bind(&miss); | 5621 __ bind(&miss); |
5622 GenerateMiss(masm); | 5622 GenerateMiss(masm); |
5623 } | 5623 } |
5624 | 5624 |
5625 | 5625 |
5626 void ICCompareStub::GenerateStrings(MacroAssembler* masm) { | 5626 void ICCompareStub::GenerateStrings(MacroAssembler* masm) { |
5627 ASSERT(state_ == CompareIC::STRINGS); | 5627 ASSERT(state_ == CompareIC::STRINGS); |
5628 ASSERT(GetCondition() == equal); | |
5629 Label miss; | 5628 Label miss; |
5630 | 5629 |
| 5630 bool equality = Token::IsEqualityOp(op_); |
| 5631 |
5631 // Registers containing left and right operands respectively. | 5632 // Registers containing left and right operands respectively. |
5632 Register left = rdx; | 5633 Register left = rdx; |
5633 Register right = rax; | 5634 Register right = rax; |
5634 Register tmp1 = rcx; | 5635 Register tmp1 = rcx; |
5635 Register tmp2 = rbx; | 5636 Register tmp2 = rbx; |
5636 Register tmp3 = rdi; | 5637 Register tmp3 = rdi; |
5637 | 5638 |
5638 // Check that both operands are heap objects. | 5639 // Check that both operands are heap objects. |
5639 Condition cond = masm->CheckEitherSmi(left, right, tmp1); | 5640 Condition cond = masm->CheckEitherSmi(left, right, tmp1); |
5640 __ j(cond, &miss); | 5641 __ j(cond, &miss); |
(...skipping 17 matching lines...) Expand all Loading... |
5658 STATIC_ASSERT(EQUAL == 0); | 5659 STATIC_ASSERT(EQUAL == 0); |
5659 STATIC_ASSERT(kSmiTag == 0); | 5660 STATIC_ASSERT(kSmiTag == 0); |
5660 __ Move(rax, Smi::FromInt(EQUAL)); | 5661 __ Move(rax, Smi::FromInt(EQUAL)); |
5661 __ ret(0); | 5662 __ ret(0); |
5662 | 5663 |
5663 // Handle not identical strings. | 5664 // Handle not identical strings. |
5664 __ bind(¬_same); | 5665 __ bind(¬_same); |
5665 | 5666 |
5666 // Check that both strings are symbols. If they are, we're done | 5667 // Check that both strings are symbols. If they are, we're done |
5667 // because we already know they are not identical. | 5668 // because we already know they are not identical. |
5668 Label do_compare; | 5669 if (equality) { |
5669 STATIC_ASSERT(kSymbolTag != 0); | 5670 Label do_compare; |
5670 __ and_(tmp1, tmp2); | 5671 STATIC_ASSERT(kSymbolTag != 0); |
5671 __ testb(tmp1, Immediate(kIsSymbolMask)); | 5672 __ and_(tmp1, tmp2); |
5672 __ j(zero, &do_compare, Label::kNear); | 5673 __ testb(tmp1, Immediate(kIsSymbolMask)); |
5673 // Make sure rax is non-zero. At this point input operands are | 5674 __ j(zero, &do_compare, Label::kNear); |
5674 // guaranteed to be non-zero. | 5675 // Make sure rax is non-zero. At this point input operands are |
5675 ASSERT(right.is(rax)); | 5676 // guaranteed to be non-zero. |
5676 __ ret(0); | 5677 ASSERT(right.is(rax)); |
| 5678 __ ret(0); |
| 5679 __ bind(&do_compare); |
| 5680 } |
5677 | 5681 |
5678 // Check that both strings are sequential ASCII. | 5682 // Check that both strings are sequential ASCII. |
5679 Label runtime; | 5683 Label runtime; |
5680 __ bind(&do_compare); | |
5681 __ JumpIfNotBothSequentialAsciiStrings(left, right, tmp1, tmp2, &runtime); | 5684 __ JumpIfNotBothSequentialAsciiStrings(left, right, tmp1, tmp2, &runtime); |
5682 | 5685 |
5683 // Compare flat ASCII strings. Returns when done. | 5686 // Compare flat ASCII strings. Returns when done. |
5684 StringCompareStub::GenerateFlatAsciiStringEquals( | 5687 if (equality) { |
5685 masm, left, right, tmp1, tmp2); | 5688 StringCompareStub::GenerateFlatAsciiStringEquals( |
| 5689 masm, left, right, tmp1, tmp2); |
| 5690 } else { |
| 5691 StringCompareStub::GenerateCompareFlatAsciiStrings( |
| 5692 masm, left, right, tmp1, tmp2, tmp3, kScratchRegister); |
| 5693 } |
5686 | 5694 |
5687 // Handle more complex cases in runtime. | 5695 // Handle more complex cases in runtime. |
5688 __ bind(&runtime); | 5696 __ bind(&runtime); |
5689 __ pop(tmp1); // Return address. | 5697 __ pop(tmp1); // Return address. |
5690 __ push(left); | 5698 __ push(left); |
5691 __ push(right); | 5699 __ push(right); |
5692 __ push(tmp1); | 5700 __ push(tmp1); |
5693 __ TailCallRuntime(Runtime::kStringEquals, 2, 1); | 5701 if (equality) { |
| 5702 __ TailCallRuntime(Runtime::kStringEquals, 2, 1); |
| 5703 } else { |
| 5704 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
| 5705 } |
5694 | 5706 |
5695 __ bind(&miss); | 5707 __ bind(&miss); |
5696 GenerateMiss(masm); | 5708 GenerateMiss(masm); |
5697 } | 5709 } |
5698 | 5710 |
5699 | 5711 |
5700 void ICCompareStub::GenerateObjects(MacroAssembler* masm) { | 5712 void ICCompareStub::GenerateObjects(MacroAssembler* masm) { |
5701 ASSERT(state_ == CompareIC::OBJECTS); | 5713 ASSERT(state_ == CompareIC::OBJECTS); |
5702 Label miss; | 5714 Label miss; |
5703 Condition either_smi = masm->CheckEitherSmi(rdx, rax); | 5715 Condition either_smi = masm->CheckEitherSmi(rdx, rax); |
(...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6331 xmm0, | 6343 xmm0, |
6332 &slow_elements); | 6344 &slow_elements); |
6333 __ ret(0); | 6345 __ ret(0); |
6334 } | 6346 } |
6335 | 6347 |
6336 #undef __ | 6348 #undef __ |
6337 | 6349 |
6338 } } // namespace v8::internal | 6350 } } // namespace v8::internal |
6339 | 6351 |
6340 #endif // V8_TARGET_ARCH_X64 | 6352 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |