Chromium Code Reviews| 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 3418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3429 | 3429 |
| 3430 | 3430 |
| 3431 static void BranchIfNotInternalizedString(MacroAssembler* masm, | 3431 static void BranchIfNotInternalizedString(MacroAssembler* masm, |
| 3432 Label* label, | 3432 Label* label, |
| 3433 Register object, | 3433 Register object, |
| 3434 Register scratch) { | 3434 Register scratch) { |
| 3435 __ JumpIfSmi(object, label); | 3435 __ JumpIfSmi(object, label); |
| 3436 __ movq(scratch, FieldOperand(object, HeapObject::kMapOffset)); | 3436 __ movq(scratch, FieldOperand(object, HeapObject::kMapOffset)); |
| 3437 __ movzxbq(scratch, | 3437 __ movzxbq(scratch, |
| 3438 FieldOperand(scratch, Map::kInstanceTypeOffset)); | 3438 FieldOperand(scratch, Map::kInstanceTypeOffset)); |
| 3439 // Ensure that no non-strings have the internalized bit set. | |
| 3440 STATIC_ASSERT(LAST_TYPE < kNotStringTag + kIsInternalizedMask); | |
| 3441 STATIC_ASSERT(kInternalizedTag != 0); | 3439 STATIC_ASSERT(kInternalizedTag != 0); |
| 3442 __ testb(scratch, Immediate(kIsInternalizedMask)); | 3440 __ and_(scratch, Immediate(kIsNotStringMask | kIsInternalizedMask)); |
| 3443 __ j(zero, label); | 3441 __ cmpb(scratch, Immediate(kInternalizedTag | kStringTag)); |
| 3442 __ j(not_equal, label); | |
| 3444 } | 3443 } |
| 3445 | 3444 |
| 3446 | 3445 |
| 3447 void ICCompareStub::GenerateGeneric(MacroAssembler* masm) { | 3446 void ICCompareStub::GenerateGeneric(MacroAssembler* masm) { |
| 3448 Label check_unequal_objects, done; | 3447 Label check_unequal_objects, done; |
| 3449 Condition cc = GetCondition(); | 3448 Condition cc = GetCondition(); |
| 3450 Factory* factory = masm->isolate()->factory(); | 3449 Factory* factory = masm->isolate()->factory(); |
| 3451 | 3450 |
| 3452 Label miss; | 3451 Label miss; |
| 3453 CheckInputType(masm, rdx, left_, &miss); | 3452 CheckInputType(masm, rdx, left_, &miss); |
| (...skipping 2384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5838 Label miss; | 5837 Label miss; |
| 5839 Condition cond = masm->CheckEitherSmi(left, right, tmp1); | 5838 Condition cond = masm->CheckEitherSmi(left, right, tmp1); |
| 5840 __ j(cond, &miss, Label::kNear); | 5839 __ j(cond, &miss, Label::kNear); |
| 5841 | 5840 |
| 5842 // Check that both operands are internalized strings. | 5841 // Check that both operands are internalized strings. |
| 5843 __ movq(tmp1, FieldOperand(left, HeapObject::kMapOffset)); | 5842 __ movq(tmp1, FieldOperand(left, HeapObject::kMapOffset)); |
| 5844 __ movq(tmp2, FieldOperand(right, HeapObject::kMapOffset)); | 5843 __ movq(tmp2, FieldOperand(right, HeapObject::kMapOffset)); |
| 5845 __ movzxbq(tmp1, FieldOperand(tmp1, Map::kInstanceTypeOffset)); | 5844 __ movzxbq(tmp1, FieldOperand(tmp1, Map::kInstanceTypeOffset)); |
| 5846 __ movzxbq(tmp2, FieldOperand(tmp2, Map::kInstanceTypeOffset)); | 5845 __ movzxbq(tmp2, FieldOperand(tmp2, Map::kInstanceTypeOffset)); |
| 5847 STATIC_ASSERT(kInternalizedTag != 0); | 5846 STATIC_ASSERT(kInternalizedTag != 0); |
| 5848 __ and_(tmp1, tmp2); | 5847 __ and_(tmp1, Immediate(kIsNotStringMask | kIsInternalizedMask)); |
| 5849 __ testb(tmp1, Immediate(kIsInternalizedMask)); | 5848 __ cmpb(tmp1, Immediate(kInternalizedTag | kStringTag)); |
| 5850 __ j(zero, &miss, Label::kNear); | 5849 __ j(not_equal, &miss, Label::kNear); |
| 5850 | |
| 5851 __ and_(tmp2, Immediate(kIsNotStringMask | kIsInternalizedMask)); | |
| 5852 __ cmpb(tmp2, Immediate(kInternalizedTag | kStringTag)); | |
| 5853 __ j(not_equal, &miss, Label::kNear); | |
| 5851 | 5854 |
| 5852 // Internalized strings are compared by identity. | 5855 // Internalized strings are compared by identity. |
| 5853 Label done; | 5856 Label done; |
| 5854 __ cmpq(left, right); | 5857 __ cmpq(left, right); |
| 5855 // Make sure rax is non-zero. At this point input operands are | 5858 // Make sure rax is non-zero. At this point input operands are |
| 5856 // guaranteed to be non-zero. | 5859 // guaranteed to be non-zero. |
| 5857 ASSERT(right.is(rax)); | 5860 ASSERT(right.is(rax)); |
| 5858 __ j(not_equal, &done, Label::kNear); | 5861 __ j(not_equal, &done, Label::kNear); |
| 5859 STATIC_ASSERT(EQUAL == 0); | 5862 STATIC_ASSERT(EQUAL == 0); |
| 5860 STATIC_ASSERT(kSmiTag == 0); | 5863 STATIC_ASSERT(kSmiTag == 0); |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 5884 | 5887 |
| 5885 // Check that both operands are unique names. This leaves the instance | 5888 // Check that both operands are unique names. This leaves the instance |
| 5886 // types loaded in tmp1 and tmp2. | 5889 // types loaded in tmp1 and tmp2. |
| 5887 STATIC_ASSERT(kInternalizedTag != 0); | 5890 STATIC_ASSERT(kInternalizedTag != 0); |
| 5888 __ movq(tmp1, FieldOperand(left, HeapObject::kMapOffset)); | 5891 __ movq(tmp1, FieldOperand(left, HeapObject::kMapOffset)); |
| 5889 __ movq(tmp2, FieldOperand(right, HeapObject::kMapOffset)); | 5892 __ movq(tmp2, FieldOperand(right, HeapObject::kMapOffset)); |
| 5890 __ movzxbq(tmp1, FieldOperand(tmp1, Map::kInstanceTypeOffset)); | 5893 __ movzxbq(tmp1, FieldOperand(tmp1, Map::kInstanceTypeOffset)); |
| 5891 __ movzxbq(tmp2, FieldOperand(tmp2, Map::kInstanceTypeOffset)); | 5894 __ movzxbq(tmp2, FieldOperand(tmp2, Map::kInstanceTypeOffset)); |
| 5892 | 5895 |
| 5893 Label succeed1; | 5896 Label succeed1; |
| 5894 __ testb(tmp1, Immediate(kIsInternalizedMask)); | |
| 5895 __ j(not_zero, &succeed1, Label::kNear); | |
| 5896 __ cmpb(tmp1, Immediate(static_cast<uint8_t>(SYMBOL_TYPE))); | 5897 __ cmpb(tmp1, Immediate(static_cast<uint8_t>(SYMBOL_TYPE))); |
| 5898 __ j(equal, &succeed1, Label::kNear); | |
| 5899 __ and_(tmp1, Immediate(kIsNotStringMask | kIsInternalizedMask)); | |
| 5900 __ cmpb(tmp1, Immediate(kInternalizedTag | kStringTag)); | |
| 5897 __ j(not_equal, &miss, Label::kNear); | 5901 __ j(not_equal, &miss, Label::kNear); |
|
Yang
2013/06/26 15:00:27
We could be clever here to save one instruction:
mvstanton
2013/06/26 16:09:37
Done.
| |
| 5898 __ bind(&succeed1); | 5902 __ bind(&succeed1); |
| 5899 | 5903 |
| 5900 Label succeed2; | 5904 Label succeed2; |
| 5901 __ testb(tmp2, Immediate(kIsInternalizedMask)); | |
| 5902 __ j(not_zero, &succeed2, Label::kNear); | |
| 5903 __ cmpb(tmp2, Immediate(static_cast<uint8_t>(SYMBOL_TYPE))); | 5905 __ cmpb(tmp2, Immediate(static_cast<uint8_t>(SYMBOL_TYPE))); |
| 5906 __ j(equal, &succeed2, Label::kNear); | |
| 5907 __ and_(tmp2, Immediate(kIsNotStringMask | kIsInternalizedMask)); | |
| 5908 __ cmpb(tmp2, Immediate(kInternalizedTag | kStringTag)); | |
| 5904 __ j(not_equal, &miss, Label::kNear); | 5909 __ j(not_equal, &miss, Label::kNear); |
| 5905 __ bind(&succeed2); | 5910 __ bind(&succeed2); |
| 5906 | 5911 |
| 5907 // Unique names are compared by identity. | 5912 // Unique names are compared by identity. |
| 5908 Label done; | 5913 Label done; |
| 5909 __ cmpq(left, right); | 5914 __ cmpq(left, right); |
| 5910 // Make sure rax is non-zero. At this point input operands are | 5915 // Make sure rax is non-zero. At this point input operands are |
| 5911 // guaranteed to be non-zero. | 5916 // guaranteed to be non-zero. |
| 5912 ASSERT(right.is(rax)); | 5917 ASSERT(right.is(rax)); |
| 5913 __ j(not_equal, &done, Label::kNear); | 5918 __ j(not_equal, &done, Label::kNear); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5957 __ j(not_equal, ¬_same, Label::kNear); | 5962 __ j(not_equal, ¬_same, Label::kNear); |
| 5958 STATIC_ASSERT(EQUAL == 0); | 5963 STATIC_ASSERT(EQUAL == 0); |
| 5959 STATIC_ASSERT(kSmiTag == 0); | 5964 STATIC_ASSERT(kSmiTag == 0); |
| 5960 __ Move(rax, Smi::FromInt(EQUAL)); | 5965 __ Move(rax, Smi::FromInt(EQUAL)); |
| 5961 __ ret(0); | 5966 __ ret(0); |
| 5962 | 5967 |
| 5963 // Handle not identical strings. | 5968 // Handle not identical strings. |
| 5964 __ bind(¬_same); | 5969 __ bind(¬_same); |
| 5965 | 5970 |
| 5966 // Check that both strings are internalized strings. If they are, we're done | 5971 // Check that both strings are internalized strings. If they are, we're done |
| 5967 // because we already know they are not identical. | 5972 // because we already know they are not identical. We also know they are both |
| 5973 // strings. | |
| 5968 if (equality) { | 5974 if (equality) { |
| 5969 Label do_compare; | 5975 Label do_compare; |
| 5970 STATIC_ASSERT(kInternalizedTag != 0); | 5976 STATIC_ASSERT(kInternalizedTag != 0); |
| 5971 __ and_(tmp1, tmp2); | 5977 __ and_(tmp1, tmp2); |
| 5972 __ testb(tmp1, Immediate(kIsInternalizedMask)); | 5978 __ testb(tmp1, Immediate(kIsInternalizedMask)); |
| 5973 __ j(zero, &do_compare, Label::kNear); | 5979 __ j(zero, &do_compare, Label::kNear); |
| 5974 // Make sure rax is non-zero. At this point input operands are | 5980 // Make sure rax is non-zero. At this point input operands are |
| 5975 // guaranteed to be non-zero. | 5981 // guaranteed to be non-zero. |
| 5976 ASSERT(right.is(rax)); | 5982 ASSERT(right.is(rax)); |
| 5977 __ ret(0); | 5983 __ ret(0); |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6113 __ Cmp(entity_name, Handle<Name>(name)); | 6119 __ Cmp(entity_name, Handle<Name>(name)); |
| 6114 __ j(equal, miss); | 6120 __ j(equal, miss); |
| 6115 | 6121 |
| 6116 Label good; | 6122 Label good; |
| 6117 // Check for the hole and skip. | 6123 // Check for the hole and skip. |
| 6118 __ CompareRoot(entity_name, Heap::kTheHoleValueRootIndex); | 6124 __ CompareRoot(entity_name, Heap::kTheHoleValueRootIndex); |
| 6119 __ j(equal, &good, Label::kNear); | 6125 __ j(equal, &good, Label::kNear); |
| 6120 | 6126 |
| 6121 // Check if the entry name is not a unique name. | 6127 // Check if the entry name is not a unique name. |
| 6122 __ movq(entity_name, FieldOperand(entity_name, HeapObject::kMapOffset)); | 6128 __ movq(entity_name, FieldOperand(entity_name, HeapObject::kMapOffset)); |
| 6129 __ cmpb(FieldOperand(entity_name, Map::kInstanceTypeOffset), | |
| 6130 Immediate(static_cast<uint8_t>(SYMBOL_TYPE))); | |
| 6131 __ j(equal, &good, Label::kNear); | |
| 6132 __ testb(FieldOperand(entity_name, Map::kInstanceTypeOffset), | |
| 6133 Immediate(kIsNotStringMask)); | |
| 6134 __ j(not_zero, miss); | |
| 6123 __ testb(FieldOperand(entity_name, Map::kInstanceTypeOffset), | 6135 __ testb(FieldOperand(entity_name, Map::kInstanceTypeOffset), |
| 6124 Immediate(kIsInternalizedMask)); | 6136 Immediate(kIsInternalizedMask)); |
| 6125 __ j(not_zero, &good, Label::kNear); | 6137 __ j(zero, miss); |
| 6126 __ cmpb(FieldOperand(entity_name, Map::kInstanceTypeOffset), | |
| 6127 Immediate(static_cast<uint8_t>(SYMBOL_TYPE))); | |
| 6128 __ j(not_equal, miss); | |
| 6129 | 6138 |
| 6130 __ bind(&good); | 6139 __ bind(&good); |
| 6131 } | 6140 } |
| 6132 | 6141 |
| 6133 NameDictionaryLookupStub stub(properties, r0, r0, NEGATIVE_LOOKUP); | 6142 NameDictionaryLookupStub stub(properties, r0, r0, NEGATIVE_LOOKUP); |
| 6134 __ Push(Handle<Object>(name)); | 6143 __ Push(Handle<Object>(name)); |
| 6135 __ push(Immediate(name->Hash())); | 6144 __ push(Immediate(name->Hash())); |
| 6136 __ CallStub(&stub); | 6145 __ CallStub(&stub); |
| 6137 __ testq(r0, r0); | 6146 __ testq(r0, r0); |
| 6138 __ j(not_zero, miss); | 6147 __ j(not_zero, miss); |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6247 __ j(equal, &in_dictionary); | 6256 __ j(equal, &in_dictionary); |
| 6248 | 6257 |
| 6249 if (i != kTotalProbes - 1 && mode_ == NEGATIVE_LOOKUP) { | 6258 if (i != kTotalProbes - 1 && mode_ == NEGATIVE_LOOKUP) { |
| 6250 // If we hit a key that is not a unique name during negative | 6259 // If we hit a key that is not a unique name during negative |
| 6251 // lookup we have to bailout as this key might be equal to the | 6260 // lookup we have to bailout as this key might be equal to the |
| 6252 // key we are looking for. | 6261 // key we are looking for. |
| 6253 | 6262 |
| 6254 // Check if the entry name is not a unique name. | 6263 // Check if the entry name is not a unique name. |
| 6255 Label cont; | 6264 Label cont; |
| 6256 __ movq(scratch, FieldOperand(scratch, HeapObject::kMapOffset)); | 6265 __ movq(scratch, FieldOperand(scratch, HeapObject::kMapOffset)); |
| 6266 __ cmpb(FieldOperand(scratch, Map::kInstanceTypeOffset), | |
| 6267 Immediate(static_cast<uint8_t>(SYMBOL_TYPE))); | |
| 6268 __ j(equal, &cont); | |
| 6269 __ testb(FieldOperand(scratch, Map::kInstanceTypeOffset), | |
| 6270 Immediate(kIsNotStringMask)); | |
| 6271 __ j(not_zero, &maybe_in_dictionary); | |
| 6257 __ testb(FieldOperand(scratch, Map::kInstanceTypeOffset), | 6272 __ testb(FieldOperand(scratch, Map::kInstanceTypeOffset), |
| 6258 Immediate(kIsInternalizedMask)); | 6273 Immediate(kIsInternalizedMask)); |
| 6259 __ j(not_zero, &cont); | 6274 __ j(zero, &maybe_in_dictionary); |
|
Yang
2013/06/26 15:00:27
JumpIfNotUniqueName that I suggested above would b
mvstanton
2013/06/26 16:09:37
Done.
| |
| 6260 __ cmpb(FieldOperand(scratch, Map::kInstanceTypeOffset), | |
| 6261 Immediate(static_cast<uint8_t>(SYMBOL_TYPE))); | |
| 6262 __ j(not_equal, &maybe_in_dictionary); | |
| 6263 __ bind(&cont); | 6275 __ bind(&cont); |
| 6264 } | 6276 } |
| 6265 } | 6277 } |
| 6266 | 6278 |
| 6267 __ bind(&maybe_in_dictionary); | 6279 __ bind(&maybe_in_dictionary); |
| 6268 // If we are doing negative lookup then probing failure should be | 6280 // If we are doing negative lookup then probing failure should be |
| 6269 // treated as a lookup success. For positive lookup probing failure | 6281 // treated as a lookup success. For positive lookup probing failure |
| 6270 // should be treated as lookup failure. | 6282 // should be treated as lookup failure. |
| 6271 if (mode_ == POSITIVE_LOOKUP) { | 6283 if (mode_ == POSITIVE_LOOKUP) { |
| 6272 __ movq(scratch, Immediate(0)); | 6284 __ movq(scratch, Immediate(0)); |
| (...skipping 751 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7024 __ bind(&fast_elements_case); | 7036 __ bind(&fast_elements_case); |
| 7025 GenerateCase(masm, FAST_ELEMENTS); | 7037 GenerateCase(masm, FAST_ELEMENTS); |
| 7026 } | 7038 } |
| 7027 | 7039 |
| 7028 | 7040 |
| 7029 #undef __ | 7041 #undef __ |
| 7030 | 7042 |
| 7031 } } // namespace v8::internal | 7043 } } // namespace v8::internal |
| 7032 | 7044 |
| 7033 #endif // V8_TARGET_ARCH_X64 | 7045 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |