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 5788 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5799 | 5799 |
5800 CompareStub stub(GetCondition(), strict(), NO_COMPARE_FLAGS); | 5800 CompareStub stub(GetCondition(), strict(), NO_COMPARE_FLAGS); |
5801 __ bind(&generic_stub); | 5801 __ bind(&generic_stub); |
5802 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET); | 5802 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET); |
5803 | 5803 |
5804 __ bind(&miss); | 5804 __ bind(&miss); |
5805 GenerateMiss(masm); | 5805 GenerateMiss(masm); |
5806 } | 5806 } |
5807 | 5807 |
5808 | 5808 |
| 5809 void ICCompareStub::GenerateStrings(MacroAssembler* masm) { |
| 5810 ASSERT(state_ == CompareIC::STRINGS); |
| 5811 Label miss; |
| 5812 |
| 5813 // Registers containing left and right operands respectively. |
| 5814 Register left = edx; |
| 5815 Register right = eax; |
| 5816 Register tmp1 = ecx; |
| 5817 Register tmp2 = ebx; |
| 5818 Register tmp3 = edi; |
| 5819 |
| 5820 // Check that both operands are heap objects. |
| 5821 __ mov(tmp1, Operand(left)); |
| 5822 STATIC_ASSERT(kSmiTag == 0); |
| 5823 __ and_(tmp1, Operand(right)); |
| 5824 __ test(tmp1, Immediate(kSmiTagMask)); |
| 5825 __ j(zero, &miss); |
| 5826 |
| 5827 // Check that both operands are strings. This leaves the instance |
| 5828 // types loaded in tmp1 and tmp2. |
| 5829 __ mov(tmp1, FieldOperand(left, HeapObject::kMapOffset)); |
| 5830 __ mov(tmp2, FieldOperand(right, HeapObject::kMapOffset)); |
| 5831 __ movzx_b(tmp1, FieldOperand(tmp1, Map::kInstanceTypeOffset)); |
| 5832 __ movzx_b(tmp2, FieldOperand(tmp2, Map::kInstanceTypeOffset)); |
| 5833 __ mov(tmp3, tmp1); |
| 5834 STATIC_ASSERT(kNotStringTag != 0); |
| 5835 __ or_(tmp3, Operand(tmp2)); |
| 5836 __ test(tmp3, Immediate(kIsNotStringMask)); |
| 5837 __ j(not_zero, &miss); |
| 5838 |
| 5839 // Fast check for identical strings. |
| 5840 NearLabel not_same; |
| 5841 __ cmp(left, Operand(right)); |
| 5842 __ j(not_equal, ¬_same); |
| 5843 STATIC_ASSERT(EQUAL == 0); |
| 5844 STATIC_ASSERT(kSmiTag == 0); |
| 5845 __ Set(eax, Immediate(Smi::FromInt(EQUAL))); |
| 5846 __ ret(0); |
| 5847 |
| 5848 // Handle not identical strings. |
| 5849 __ bind(¬_same); |
| 5850 |
| 5851 // Check that both strings are symbols. If they are, we're done |
| 5852 // because we already know they are not identical. |
| 5853 NearLabel do_compare; |
| 5854 ASSERT(GetCondition() == equal); |
| 5855 STATIC_ASSERT(kSymbolTag != 0); |
| 5856 __ and_(tmp1, Operand(tmp2)); |
| 5857 __ test(tmp1, Immediate(kIsSymbolMask)); |
| 5858 __ j(zero, &do_compare); |
| 5859 // Make sure eax is non-zero. At this point input operands are |
| 5860 // guaranteed to be non-zero. |
| 5861 ASSERT(right.is(eax)); |
| 5862 __ ret(0); |
| 5863 |
| 5864 // Check that both strings are sequential ASCII. |
| 5865 Label runtime; |
| 5866 __ bind(&do_compare); |
| 5867 __ JumpIfNotBothSequentialAsciiStrings(left, right, tmp1, tmp2, &runtime); |
| 5868 |
| 5869 // Compare flat ASCII strings. Returns when done. |
| 5870 StringCompareStub::GenerateCompareFlatAsciiStrings( |
| 5871 masm, left, right, tmp1, tmp2, tmp3); |
| 5872 |
| 5873 // Handle more complex cases in runtime. |
| 5874 __ bind(&runtime); |
| 5875 __ pop(tmp1); // Return address. |
| 5876 __ push(left); |
| 5877 __ push(right); |
| 5878 __ push(tmp1); |
| 5879 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
| 5880 |
| 5881 __ bind(&miss); |
| 5882 GenerateMiss(masm); |
| 5883 } |
| 5884 |
| 5885 |
5809 void ICCompareStub::GenerateObjects(MacroAssembler* masm) { | 5886 void ICCompareStub::GenerateObjects(MacroAssembler* masm) { |
5810 ASSERT(state_ == CompareIC::OBJECTS); | 5887 ASSERT(state_ == CompareIC::OBJECTS); |
5811 NearLabel miss; | 5888 NearLabel miss; |
5812 __ mov(ecx, Operand(edx)); | 5889 __ mov(ecx, Operand(edx)); |
5813 __ and_(ecx, Operand(eax)); | 5890 __ and_(ecx, Operand(eax)); |
5814 __ test(ecx, Immediate(kSmiTagMask)); | 5891 __ test(ecx, Immediate(kSmiTagMask)); |
5815 __ j(zero, &miss, not_taken); | 5892 __ j(zero, &miss, not_taken); |
5816 | 5893 |
5817 __ CmpObjectType(eax, JS_OBJECT_TYPE, ecx); | 5894 __ CmpObjectType(eax, JS_OBJECT_TYPE, ecx); |
5818 __ j(not_equal, &miss, not_taken); | 5895 __ j(not_equal, &miss, not_taken); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5857 // Do a tail call to the rewritten stub. | 5934 // Do a tail call to the rewritten stub. |
5858 __ jmp(Operand(edi)); | 5935 __ jmp(Operand(edi)); |
5859 } | 5936 } |
5860 | 5937 |
5861 | 5938 |
5862 #undef __ | 5939 #undef __ |
5863 | 5940 |
5864 } } // namespace v8::internal | 5941 } } // namespace v8::internal |
5865 | 5942 |
5866 #endif // V8_TARGET_ARCH_IA32 | 5943 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |