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 874 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
885 | 885 |
886 __ CompareObjectType(lhs, r3, r3, FIRST_SPEC_OBJECT_TYPE); | 886 __ CompareObjectType(lhs, r3, r3, FIRST_SPEC_OBJECT_TYPE); |
887 __ b(ge, &return_not_equal); | 887 __ b(ge, &return_not_equal); |
888 | 888 |
889 // Check for oddballs: true, false, null, undefined. | 889 // Check for oddballs: true, false, null, undefined. |
890 __ cmp(r3, Operand(ODDBALL_TYPE)); | 890 __ cmp(r3, Operand(ODDBALL_TYPE)); |
891 __ b(eq, &return_not_equal); | 891 __ b(eq, &return_not_equal); |
892 | 892 |
893 // Now that we have the types we might as well check for | 893 // Now that we have the types we might as well check for |
894 // internalized-internalized. | 894 // internalized-internalized. |
895 // Ensure that no non-strings have the internalized bit set. | 895 Label not_internalized; |
896 STATIC_ASSERT(LAST_TYPE < kNotStringTag + kIsInternalizedMask); | |
897 STATIC_ASSERT(kInternalizedTag != 0); | 896 STATIC_ASSERT(kInternalizedTag != 0); |
898 __ and_(r2, r2, Operand(r3)); | 897 __ and_(r2, r2, Operand(kIsNotStringMask | kIsInternalizedMask)); |
899 __ tst(r2, Operand(kIsInternalizedMask)); | 898 __ cmp(r2, Operand(kInternalizedTag | kStringTag)); |
900 __ b(ne, &return_not_equal); | 899 __ b(ne, ¬_internalized); // r2 (rhs) is not an internalized string |
| 900 |
| 901 __ and_(r3, r3, Operand(kIsNotStringMask | kIsInternalizedMask)); |
| 902 __ cmp(r3, Operand(kInternalizedTag | kStringTag)); |
| 903 __ b(eq, &return_not_equal); // both rhs and lhs are internalized strings |
| 904 |
| 905 __ bind(¬_internalized); |
901 } | 906 } |
902 | 907 |
903 | 908 |
904 // See comment at call site. | 909 // See comment at call site. |
905 static void EmitCheckForTwoHeapNumbers(MacroAssembler* masm, | 910 static void EmitCheckForTwoHeapNumbers(MacroAssembler* masm, |
906 Register lhs, | 911 Register lhs, |
907 Register rhs, | 912 Register rhs, |
908 Label* both_loaded_as_doubles, | 913 Label* both_loaded_as_doubles, |
909 Label* not_heap_numbers, | 914 Label* not_heap_numbers, |
910 Label* slow) { | 915 Label* slow) { |
(...skipping 19 matching lines...) Expand all Loading... |
930 // Fast negative check for internalized-to-internalized equality. | 935 // Fast negative check for internalized-to-internalized equality. |
931 static void EmitCheckForInternalizedStringsOrObjects(MacroAssembler* masm, | 936 static void EmitCheckForInternalizedStringsOrObjects(MacroAssembler* masm, |
932 Register lhs, | 937 Register lhs, |
933 Register rhs, | 938 Register rhs, |
934 Label* possible_strings, | 939 Label* possible_strings, |
935 Label* not_both_strings) { | 940 Label* not_both_strings) { |
936 ASSERT((lhs.is(r0) && rhs.is(r1)) || | 941 ASSERT((lhs.is(r0) && rhs.is(r1)) || |
937 (lhs.is(r1) && rhs.is(r0))); | 942 (lhs.is(r1) && rhs.is(r0))); |
938 | 943 |
939 // r2 is object type of rhs. | 944 // r2 is object type of rhs. |
940 // Ensure that no non-strings have the internalized bit set. | |
941 Label object_test; | 945 Label object_test; |
942 STATIC_ASSERT(kInternalizedTag != 0); | 946 STATIC_ASSERT(kInternalizedTag != 0); |
943 __ tst(r2, Operand(kIsNotStringMask)); | 947 __ tst(r2, Operand(kIsNotStringMask)); |
944 __ b(ne, &object_test); | 948 __ b(ne, &object_test); |
945 __ tst(r2, Operand(kIsInternalizedMask)); | 949 __ tst(r2, Operand(kIsInternalizedMask)); |
946 __ b(eq, possible_strings); | 950 __ b(eq, possible_strings); |
947 __ CompareObjectType(lhs, r3, r3, FIRST_NONSTRING_TYPE); | 951 __ CompareObjectType(lhs, r3, r3, FIRST_NONSTRING_TYPE); |
948 __ b(ge, not_both_strings); | 952 __ b(ge, not_both_strings); |
949 __ tst(r3, Operand(kIsInternalizedMask)); | 953 __ tst(r3, Operand(kIsInternalizedMask)); |
950 __ b(eq, possible_strings); | 954 __ b(eq, possible_strings); |
(...skipping 5255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6206 | 6210 |
6207 // Check that both operands are heap objects. | 6211 // Check that both operands are heap objects. |
6208 __ JumpIfEitherSmi(left, right, &miss); | 6212 __ JumpIfEitherSmi(left, right, &miss); |
6209 | 6213 |
6210 // Check that both operands are internalized strings. | 6214 // Check that both operands are internalized strings. |
6211 __ ldr(tmp1, FieldMemOperand(left, HeapObject::kMapOffset)); | 6215 __ ldr(tmp1, FieldMemOperand(left, HeapObject::kMapOffset)); |
6212 __ ldr(tmp2, FieldMemOperand(right, HeapObject::kMapOffset)); | 6216 __ ldr(tmp2, FieldMemOperand(right, HeapObject::kMapOffset)); |
6213 __ ldrb(tmp1, FieldMemOperand(tmp1, Map::kInstanceTypeOffset)); | 6217 __ ldrb(tmp1, FieldMemOperand(tmp1, Map::kInstanceTypeOffset)); |
6214 __ ldrb(tmp2, FieldMemOperand(tmp2, Map::kInstanceTypeOffset)); | 6218 __ ldrb(tmp2, FieldMemOperand(tmp2, Map::kInstanceTypeOffset)); |
6215 STATIC_ASSERT(kInternalizedTag != 0); | 6219 STATIC_ASSERT(kInternalizedTag != 0); |
6216 __ and_(tmp1, tmp1, Operand(tmp2)); | 6220 |
6217 __ tst(tmp1, Operand(kIsInternalizedMask)); | 6221 __ and_(tmp1, tmp1, Operand(kIsNotStringMask | kIsInternalizedMask)); |
6218 __ b(eq, &miss); | 6222 __ cmp(tmp1, Operand(kInternalizedTag | kStringTag)); |
| 6223 __ b(ne, &miss); |
| 6224 |
| 6225 __ and_(tmp2, tmp2, Operand(kIsNotStringMask | kIsInternalizedMask)); |
| 6226 __ cmp(tmp2, Operand(kInternalizedTag | kStringTag)); |
| 6227 __ b(ne, &miss); |
6219 | 6228 |
6220 // Internalized strings are compared by identity. | 6229 // Internalized strings are compared by identity. |
6221 __ cmp(left, right); | 6230 __ cmp(left, right); |
6222 // Make sure r0 is non-zero. At this point input operands are | 6231 // Make sure r0 is non-zero. At this point input operands are |
6223 // guaranteed to be non-zero. | 6232 // guaranteed to be non-zero. |
6224 ASSERT(right.is(r0)); | 6233 ASSERT(right.is(r0)); |
6225 STATIC_ASSERT(EQUAL == 0); | 6234 STATIC_ASSERT(EQUAL == 0); |
6226 STATIC_ASSERT(kSmiTag == 0); | 6235 STATIC_ASSERT(kSmiTag == 0); |
6227 __ mov(r0, Operand(Smi::FromInt(EQUAL)), LeaveCC, eq); | 6236 __ mov(r0, Operand(Smi::FromInt(EQUAL)), LeaveCC, eq); |
6228 __ Ret(); | 6237 __ Ret(); |
(...skipping 18 matching lines...) Expand all Loading... |
6247 __ JumpIfEitherSmi(left, right, &miss); | 6256 __ JumpIfEitherSmi(left, right, &miss); |
6248 | 6257 |
6249 // Check that both operands are unique names. This leaves the instance | 6258 // Check that both operands are unique names. This leaves the instance |
6250 // types loaded in tmp1 and tmp2. | 6259 // types loaded in tmp1 and tmp2. |
6251 STATIC_ASSERT(kInternalizedTag != 0); | 6260 STATIC_ASSERT(kInternalizedTag != 0); |
6252 __ ldr(tmp1, FieldMemOperand(left, HeapObject::kMapOffset)); | 6261 __ ldr(tmp1, FieldMemOperand(left, HeapObject::kMapOffset)); |
6253 __ ldr(tmp2, FieldMemOperand(right, HeapObject::kMapOffset)); | 6262 __ ldr(tmp2, FieldMemOperand(right, HeapObject::kMapOffset)); |
6254 __ ldrb(tmp1, FieldMemOperand(tmp1, Map::kInstanceTypeOffset)); | 6263 __ ldrb(tmp1, FieldMemOperand(tmp1, Map::kInstanceTypeOffset)); |
6255 __ ldrb(tmp2, FieldMemOperand(tmp2, Map::kInstanceTypeOffset)); | 6264 __ ldrb(tmp2, FieldMemOperand(tmp2, Map::kInstanceTypeOffset)); |
6256 | 6265 |
6257 Label succeed1; | 6266 __ JumpIfNotUniqueName(tmp1, &miss); |
6258 __ tst(tmp1, Operand(kIsInternalizedMask)); | 6267 __ JumpIfNotUniqueName(tmp2, &miss); |
6259 __ b(ne, &succeed1); | |
6260 __ cmp(tmp1, Operand(SYMBOL_TYPE)); | |
6261 __ b(ne, &miss); | |
6262 __ bind(&succeed1); | |
6263 | |
6264 Label succeed2; | |
6265 __ tst(tmp2, Operand(kIsInternalizedMask)); | |
6266 __ b(ne, &succeed2); | |
6267 __ cmp(tmp2, Operand(SYMBOL_TYPE)); | |
6268 __ b(ne, &miss); | |
6269 __ bind(&succeed2); | |
6270 | 6268 |
6271 // Unique names are compared by identity. | 6269 // Unique names are compared by identity. |
6272 __ cmp(left, right); | 6270 __ cmp(left, right); |
6273 // Make sure r0 is non-zero. At this point input operands are | 6271 // Make sure r0 is non-zero. At this point input operands are |
6274 // guaranteed to be non-zero. | 6272 // guaranteed to be non-zero. |
6275 ASSERT(right.is(r0)); | 6273 ASSERT(right.is(r0)); |
6276 STATIC_ASSERT(EQUAL == 0); | 6274 STATIC_ASSERT(EQUAL == 0); |
6277 STATIC_ASSERT(kSmiTag == 0); | 6275 STATIC_ASSERT(kSmiTag == 0); |
6278 __ mov(r0, Operand(Smi::FromInt(EQUAL)), LeaveCC, eq); | 6276 __ mov(r0, Operand(Smi::FromInt(EQUAL)), LeaveCC, eq); |
6279 __ Ret(); | 6277 __ Ret(); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6314 // Fast check for identical strings. | 6312 // Fast check for identical strings. |
6315 __ cmp(left, right); | 6313 __ cmp(left, right); |
6316 STATIC_ASSERT(EQUAL == 0); | 6314 STATIC_ASSERT(EQUAL == 0); |
6317 STATIC_ASSERT(kSmiTag == 0); | 6315 STATIC_ASSERT(kSmiTag == 0); |
6318 __ mov(r0, Operand(Smi::FromInt(EQUAL)), LeaveCC, eq); | 6316 __ mov(r0, Operand(Smi::FromInt(EQUAL)), LeaveCC, eq); |
6319 __ Ret(eq); | 6317 __ Ret(eq); |
6320 | 6318 |
6321 // Handle not identical strings. | 6319 // Handle not identical strings. |
6322 | 6320 |
6323 // Check that both strings are internalized strings. If they are, we're done | 6321 // Check that both strings are internalized strings. If they are, we're done |
6324 // because we already know they are not identical. | 6322 // because we already know they are not identical. We know they are both |
| 6323 // strings. |
6325 if (equality) { | 6324 if (equality) { |
6326 ASSERT(GetCondition() == eq); | 6325 ASSERT(GetCondition() == eq); |
6327 STATIC_ASSERT(kInternalizedTag != 0); | 6326 STATIC_ASSERT(kInternalizedTag != 0); |
6328 __ and_(tmp3, tmp1, Operand(tmp2)); | 6327 __ and_(tmp3, tmp1, Operand(tmp2)); |
6329 __ tst(tmp3, Operand(kIsInternalizedMask)); | 6328 __ tst(tmp3, Operand(kIsInternalizedMask)); |
6330 // Make sure r0 is non-zero. At this point input operands are | 6329 // Make sure r0 is non-zero. At this point input operands are |
6331 // guaranteed to be non-zero. | 6330 // guaranteed to be non-zero. |
6332 ASSERT(right.is(r0)); | 6331 ASSERT(right.is(r0)); |
6333 __ Ret(ne); | 6332 __ Ret(ne); |
6334 } | 6333 } |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6500 __ b(eq, miss); | 6499 __ b(eq, miss); |
6501 | 6500 |
6502 Label good; | 6501 Label good; |
6503 __ cmp(entity_name, tmp); | 6502 __ cmp(entity_name, tmp); |
6504 __ b(eq, &good); | 6503 __ b(eq, &good); |
6505 | 6504 |
6506 // Check if the entry name is not a unique name. | 6505 // Check if the entry name is not a unique name. |
6507 __ ldr(entity_name, FieldMemOperand(entity_name, HeapObject::kMapOffset)); | 6506 __ ldr(entity_name, FieldMemOperand(entity_name, HeapObject::kMapOffset)); |
6508 __ ldrb(entity_name, | 6507 __ ldrb(entity_name, |
6509 FieldMemOperand(entity_name, Map::kInstanceTypeOffset)); | 6508 FieldMemOperand(entity_name, Map::kInstanceTypeOffset)); |
6510 __ tst(entity_name, Operand(kIsInternalizedMask)); | 6509 __ JumpIfNotUniqueName(entity_name, miss); |
6511 __ b(ne, &good); | |
6512 __ cmp(entity_name, Operand(SYMBOL_TYPE)); | |
6513 __ b(ne, miss); | |
6514 | |
6515 __ bind(&good); | 6510 __ bind(&good); |
6516 | 6511 |
6517 // Restore the properties. | 6512 // Restore the properties. |
6518 __ ldr(properties, | 6513 __ ldr(properties, |
6519 FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | 6514 FieldMemOperand(receiver, JSObject::kPropertiesOffset)); |
6520 } | 6515 } |
6521 | 6516 |
6522 const int spill_mask = | 6517 const int spill_mask = |
6523 (lr.bit() | r6.bit() | r5.bit() | r4.bit() | r3.bit() | | 6518 (lr.bit() | r6.bit() | r5.bit() | r4.bit() | r3.bit() | |
6524 r2.bit() | r1.bit() | r0.bit()); | 6519 r2.bit() | r1.bit() | r0.bit()); |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6671 // Having undefined at this place means the name is not contained. | 6666 // Having undefined at this place means the name is not contained. |
6672 __ cmp(entry_key, Operand(undefined)); | 6667 __ cmp(entry_key, Operand(undefined)); |
6673 __ b(eq, ¬_in_dictionary); | 6668 __ b(eq, ¬_in_dictionary); |
6674 | 6669 |
6675 // Stop if found the property. | 6670 // Stop if found the property. |
6676 __ cmp(entry_key, Operand(key)); | 6671 __ cmp(entry_key, Operand(key)); |
6677 __ b(eq, &in_dictionary); | 6672 __ b(eq, &in_dictionary); |
6678 | 6673 |
6679 if (i != kTotalProbes - 1 && mode_ == NEGATIVE_LOOKUP) { | 6674 if (i != kTotalProbes - 1 && mode_ == NEGATIVE_LOOKUP) { |
6680 // Check if the entry name is not a unique name. | 6675 // Check if the entry name is not a unique name. |
6681 Label cont; | |
6682 __ ldr(entry_key, FieldMemOperand(entry_key, HeapObject::kMapOffset)); | 6676 __ ldr(entry_key, FieldMemOperand(entry_key, HeapObject::kMapOffset)); |
6683 __ ldrb(entry_key, | 6677 __ ldrb(entry_key, |
6684 FieldMemOperand(entry_key, Map::kInstanceTypeOffset)); | 6678 FieldMemOperand(entry_key, Map::kInstanceTypeOffset)); |
6685 __ tst(entry_key, Operand(kIsInternalizedMask)); | 6679 __ JumpIfNotUniqueName(entry_key, &maybe_in_dictionary); |
6686 __ b(ne, &cont); | |
6687 __ cmp(entry_key, Operand(SYMBOL_TYPE)); | |
6688 __ b(ne, &maybe_in_dictionary); | |
6689 __ bind(&cont); | |
6690 } | 6680 } |
6691 } | 6681 } |
6692 | 6682 |
6693 __ bind(&maybe_in_dictionary); | 6683 __ bind(&maybe_in_dictionary); |
6694 // If we are doing negative lookup then probing failure should be | 6684 // If we are doing negative lookup then probing failure should be |
6695 // treated as a lookup success. For positive lookup probing failure | 6685 // treated as a lookup success. For positive lookup probing failure |
6696 // should be treated as lookup failure. | 6686 // should be treated as lookup failure. |
6697 if (mode_ == POSITIVE_LOOKUP) { | 6687 if (mode_ == POSITIVE_LOOKUP) { |
6698 __ mov(result, Operand::Zero()); | 6688 __ mov(result, Operand::Zero()); |
6699 __ Ret(); | 6689 __ Ret(); |
(...skipping 711 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7411 __ bind(&fast_elements_case); | 7401 __ bind(&fast_elements_case); |
7412 GenerateCase(masm, FAST_ELEMENTS); | 7402 GenerateCase(masm, FAST_ELEMENTS); |
7413 } | 7403 } |
7414 | 7404 |
7415 | 7405 |
7416 #undef __ | 7406 #undef __ |
7417 | 7407 |
7418 } } // namespace v8::internal | 7408 } } // namespace v8::internal |
7419 | 7409 |
7420 #endif // V8_TARGET_ARCH_ARM | 7410 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |