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 4721 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4732 | 4732 |
4733 CompareStub stub(GetCondition(), strict(), NO_COMPARE_FLAGS); | 4733 CompareStub stub(GetCondition(), strict(), NO_COMPARE_FLAGS); |
4734 __ bind(&generic_stub); | 4734 __ bind(&generic_stub); |
4735 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET); | 4735 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET); |
4736 | 4736 |
4737 __ bind(&miss); | 4737 __ bind(&miss); |
4738 GenerateMiss(masm); | 4738 GenerateMiss(masm); |
4739 } | 4739 } |
4740 | 4740 |
4741 | 4741 |
| 4742 void ICCompareStub::GenerateSymbols(MacroAssembler* masm) { |
| 4743 ASSERT(state_ == CompareIC::SYMBOLS); |
| 4744 ASSERT(GetCondition() == equal); |
| 4745 |
| 4746 // Registers containing left and right operands respectively. |
| 4747 Register left = rdx; |
| 4748 Register right = rax; |
| 4749 Register tmp1 = rcx; |
| 4750 Register tmp2 = rbx; |
| 4751 |
| 4752 // Check that both operands are heap objects. |
| 4753 NearLabel miss; |
| 4754 Condition cond = masm->CheckEitherSmi(left, right, tmp1); |
| 4755 __ j(cond, &miss); |
| 4756 |
| 4757 // Check that both operands are symbols. |
| 4758 __ movq(tmp1, FieldOperand(left, HeapObject::kMapOffset)); |
| 4759 __ movq(tmp2, FieldOperand(right, HeapObject::kMapOffset)); |
| 4760 __ movzxbq(tmp1, FieldOperand(tmp1, Map::kInstanceTypeOffset)); |
| 4761 __ movzxbq(tmp2, FieldOperand(tmp2, Map::kInstanceTypeOffset)); |
| 4762 STATIC_ASSERT(kSymbolTag != 0); |
| 4763 __ and_(tmp1, tmp2); |
| 4764 __ testb(tmp1, Immediate(kIsSymbolMask)); |
| 4765 __ j(zero, &miss); |
| 4766 |
| 4767 // Symbols are compared by identity. |
| 4768 NearLabel done; |
| 4769 __ cmpq(left, right); |
| 4770 // Make sure rax is non-zero. At this point input operands are |
| 4771 // guaranteed to be non-zero. |
| 4772 ASSERT(right.is(rax)); |
| 4773 __ j(not_equal, &done); |
| 4774 STATIC_ASSERT(EQUAL == 0); |
| 4775 STATIC_ASSERT(kSmiTag == 0); |
| 4776 __ Move(rax, Smi::FromInt(EQUAL)); |
| 4777 __ bind(&done); |
| 4778 __ ret(0); |
| 4779 |
| 4780 __ bind(&miss); |
| 4781 GenerateMiss(masm); |
| 4782 } |
| 4783 |
| 4784 |
4742 void ICCompareStub::GenerateStrings(MacroAssembler* masm) { | 4785 void ICCompareStub::GenerateStrings(MacroAssembler* masm) { |
4743 ASSERT(state_ == CompareIC::STRINGS); | 4786 ASSERT(state_ == CompareIC::STRINGS); |
4744 ASSERT(GetCondition() == equal); | 4787 ASSERT(GetCondition() == equal); |
4745 Label miss; | 4788 Label miss; |
4746 | 4789 |
4747 // Registers containing left and right operands respectively. | 4790 // Registers containing left and right operands respectively. |
4748 Register left = rdx; | 4791 Register left = rdx; |
4749 Register right = rax; | 4792 Register right = rax; |
4750 Register tmp1 = rcx; | 4793 Register tmp1 = rcx; |
4751 Register tmp2 = rbx; | 4794 Register tmp2 = rbx; |
4752 Register tmp3 = rdi; | 4795 Register tmp3 = rdi; |
4753 | 4796 |
4754 // Check that both operands are heap objects. | 4797 // Check that both operands are heap objects. |
4755 Condition cond = masm->CheckEitherSmi(left, right, tmp1); | 4798 Condition cond = masm->CheckEitherSmi(left, right, tmp1); |
4756 __ j(cond, &miss); | 4799 __ j(cond, &miss); |
4757 | 4800 |
4758 // Check that both operands are strings. This leaves the instance | 4801 // Check that both operands are strings. This leaves the instance |
4759 // types loaded in tmp1 and tmp2. | 4802 // types loaded in tmp1 and tmp2. |
4760 __ movq(tmp1, FieldOperand(left, HeapObject::kMapOffset)); | 4803 __ movq(tmp1, FieldOperand(left, HeapObject::kMapOffset)); |
4761 __ movq(tmp2, FieldOperand(right, HeapObject::kMapOffset)); | 4804 __ movq(tmp2, FieldOperand(right, HeapObject::kMapOffset)); |
4762 __ movzxbq(tmp1, FieldOperand(tmp1, Map::kInstanceTypeOffset)); | 4805 __ movzxbq(tmp1, FieldOperand(tmp1, Map::kInstanceTypeOffset)); |
4763 __ movzxbq(tmp2, FieldOperand(tmp2, Map::kInstanceTypeOffset)); | 4806 __ movzxbq(tmp2, FieldOperand(tmp2, Map::kInstanceTypeOffset)); |
4764 __ movq(tmp3, tmp1); | 4807 __ movq(tmp3, tmp1); |
4765 STATIC_ASSERT(kNotStringTag != 0); | 4808 STATIC_ASSERT(kNotStringTag != 0); |
4766 __ or_(tmp3, tmp2); | 4809 __ or_(tmp3, tmp2); |
4767 __ testl(tmp3, Immediate(kIsNotStringMask)); | 4810 __ testb(tmp3, Immediate(kIsNotStringMask)); |
4768 __ j(not_zero, &miss); | 4811 __ j(not_zero, &miss); |
4769 | 4812 |
4770 // Fast check for identical strings. | 4813 // Fast check for identical strings. |
4771 NearLabel not_same; | 4814 NearLabel not_same; |
4772 __ cmpq(left, right); | 4815 __ cmpq(left, right); |
4773 __ j(not_equal, ¬_same); | 4816 __ j(not_equal, ¬_same); |
4774 STATIC_ASSERT(EQUAL == 0); | 4817 STATIC_ASSERT(EQUAL == 0); |
4775 STATIC_ASSERT(kSmiTag == 0); | 4818 STATIC_ASSERT(kSmiTag == 0); |
4776 __ Move(rax, Smi::FromInt(EQUAL)); | 4819 __ Move(rax, Smi::FromInt(EQUAL)); |
4777 __ ret(0); | 4820 __ ret(0); |
4778 | 4821 |
4779 // Handle not identical strings. | 4822 // Handle not identical strings. |
4780 __ bind(¬_same); | 4823 __ bind(¬_same); |
4781 | 4824 |
4782 // Check that both strings are symbols. If they are, we're done | 4825 // Check that both strings are symbols. If they are, we're done |
4783 // because we already know they are not identical. | 4826 // because we already know they are not identical. |
4784 NearLabel do_compare; | 4827 NearLabel do_compare; |
4785 STATIC_ASSERT(kSymbolTag != 0); | 4828 STATIC_ASSERT(kSymbolTag != 0); |
4786 __ and_(tmp1, tmp2); | 4829 __ and_(tmp1, tmp2); |
4787 __ testl(tmp1, Immediate(kIsSymbolMask)); | 4830 __ testb(tmp1, Immediate(kIsSymbolMask)); |
4788 __ j(zero, &do_compare); | 4831 __ j(zero, &do_compare); |
4789 // Make sure rax is non-zero. At this point input operands are | 4832 // Make sure rax is non-zero. At this point input operands are |
4790 // guaranteed to be non-zero. | 4833 // guaranteed to be non-zero. |
4791 ASSERT(right.is(rax)); | 4834 ASSERT(right.is(rax)); |
4792 __ ret(0); | 4835 __ ret(0); |
4793 | 4836 |
4794 // Check that both strings are sequential ASCII. | 4837 // Check that both strings are sequential ASCII. |
4795 Label runtime; | 4838 Label runtime; |
4796 __ bind(&do_compare); | 4839 __ bind(&do_compare); |
4797 __ JumpIfNotBothSequentialAsciiStrings(left, right, tmp1, tmp2, &runtime); | 4840 __ JumpIfNotBothSequentialAsciiStrings(left, right, tmp1, tmp2, &runtime); |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5059 __ Drop(1); | 5102 __ Drop(1); |
5060 __ ret(2 * kPointerSize); | 5103 __ ret(2 * kPointerSize); |
5061 } | 5104 } |
5062 | 5105 |
5063 | 5106 |
5064 #undef __ | 5107 #undef __ |
5065 | 5108 |
5066 } } // namespace v8::internal | 5109 } } // namespace v8::internal |
5067 | 5110 |
5068 #endif // V8_TARGET_ARCH_X64 | 5111 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |