| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #if V8_TARGET_ARCH_X64 | 5 #if V8_TARGET_ARCH_X64 |
| 6 | 6 |
| 7 #include "src/bootstrapper.h" | 7 #include "src/bootstrapper.h" |
| 8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
| 9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
| 10 #include "src/ic/handler-compiler.h" | 10 #include "src/ic/handler-compiler.h" |
| (...skipping 1520 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1531 // so we do the second best thing - test it ourselves. | 1531 // so we do the second best thing - test it ourselves. |
| 1532 Label heap_number; | 1532 Label heap_number; |
| 1533 // If it's not a heap number, then return equal for (in)equality operator. | 1533 // If it's not a heap number, then return equal for (in)equality operator. |
| 1534 __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset), | 1534 __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset), |
| 1535 factory->heap_number_map()); | 1535 factory->heap_number_map()); |
| 1536 __ j(equal, &heap_number, Label::kNear); | 1536 __ j(equal, &heap_number, Label::kNear); |
| 1537 if (cc != equal) { | 1537 if (cc != equal) { |
| 1538 __ movp(rcx, FieldOperand(rax, HeapObject::kMapOffset)); | 1538 __ movp(rcx, FieldOperand(rax, HeapObject::kMapOffset)); |
| 1539 __ movzxbl(rcx, FieldOperand(rcx, Map::kInstanceTypeOffset)); | 1539 __ movzxbl(rcx, FieldOperand(rcx, Map::kInstanceTypeOffset)); |
| 1540 // Call runtime on identical objects. Otherwise return equal. | 1540 // Call runtime on identical objects. Otherwise return equal. |
| 1541 __ cmpb(rcx, Immediate(static_cast<uint8_t>(FIRST_SPEC_OBJECT_TYPE))); | 1541 __ cmpb(rcx, Immediate(static_cast<uint8_t>(FIRST_JS_RECEIVER_TYPE))); |
| 1542 __ j(above_equal, &runtime_call, Label::kFar); | 1542 __ j(above_equal, &runtime_call, Label::kFar); |
| 1543 // Call runtime on identical symbols since we need to throw a TypeError. | 1543 // Call runtime on identical symbols since we need to throw a TypeError. |
| 1544 __ cmpb(rcx, Immediate(static_cast<uint8_t>(SYMBOL_TYPE))); | 1544 __ cmpb(rcx, Immediate(static_cast<uint8_t>(SYMBOL_TYPE))); |
| 1545 __ j(equal, &runtime_call, Label::kFar); | 1545 __ j(equal, &runtime_call, Label::kFar); |
| 1546 // Call runtime on identical SIMD values since we must throw a TypeError. | 1546 // Call runtime on identical SIMD values since we must throw a TypeError. |
| 1547 __ cmpb(rcx, Immediate(static_cast<uint8_t>(SIMD128_VALUE_TYPE))); | 1547 __ cmpb(rcx, Immediate(static_cast<uint8_t>(SIMD128_VALUE_TYPE))); |
| 1548 __ j(equal, &runtime_call, Label::kFar); | 1548 __ j(equal, &runtime_call, Label::kFar); |
| 1549 if (is_strong(strength())) { | 1549 if (is_strong(strength())) { |
| 1550 // We have already tested for smis and heap numbers, so if both | 1550 // We have already tested for smis and heap numbers, so if both |
| 1551 // arguments are not strings we must proceed to the slow case. | 1551 // arguments are not strings we must proceed to the slow case. |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1598 __ ret(0); | 1598 __ ret(0); |
| 1599 | 1599 |
| 1600 __ bind(¬_smis); | 1600 __ bind(¬_smis); |
| 1601 } | 1601 } |
| 1602 | 1602 |
| 1603 // If either operand is a JSObject or an oddball value, then they are not | 1603 // If either operand is a JSObject or an oddball value, then they are not |
| 1604 // equal since their pointers are different | 1604 // equal since their pointers are different |
| 1605 // There is no test for undetectability in strict equality. | 1605 // There is no test for undetectability in strict equality. |
| 1606 | 1606 |
| 1607 // If the first object is a JS object, we have done pointer comparison. | 1607 // If the first object is a JS object, we have done pointer comparison. |
| 1608 STATIC_ASSERT(LAST_TYPE == LAST_SPEC_OBJECT_TYPE); | 1608 STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE); |
| 1609 Label first_non_object; | 1609 Label first_non_object; |
| 1610 __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rcx); | 1610 __ CmpObjectType(rax, FIRST_JS_RECEIVER_TYPE, rcx); |
| 1611 __ j(below, &first_non_object, Label::kNear); | 1611 __ j(below, &first_non_object, Label::kNear); |
| 1612 // Return non-zero (rax (not rax) is not zero) | 1612 // Return non-zero (rax (not rax) is not zero) |
| 1613 Label return_not_equal; | 1613 Label return_not_equal; |
| 1614 STATIC_ASSERT(kHeapObjectTag != 0); | 1614 STATIC_ASSERT(kHeapObjectTag != 0); |
| 1615 __ bind(&return_not_equal); | 1615 __ bind(&return_not_equal); |
| 1616 __ ret(0); | 1616 __ ret(0); |
| 1617 | 1617 |
| 1618 __ bind(&first_non_object); | 1618 __ bind(&first_non_object); |
| 1619 // Check for oddballs: true, false, null, undefined. | 1619 // Check for oddballs: true, false, null, undefined. |
| 1620 __ CmpInstanceType(rcx, ODDBALL_TYPE); | 1620 __ CmpInstanceType(rcx, ODDBALL_TYPE); |
| 1621 __ j(equal, &return_not_equal); | 1621 __ j(equal, &return_not_equal); |
| 1622 | 1622 |
| 1623 __ CmpObjectType(rdx, FIRST_SPEC_OBJECT_TYPE, rcx); | 1623 __ CmpObjectType(rdx, FIRST_JS_RECEIVER_TYPE, rcx); |
| 1624 __ j(above_equal, &return_not_equal); | 1624 __ j(above_equal, &return_not_equal); |
| 1625 | 1625 |
| 1626 // Check for oddballs: true, false, null, undefined. | 1626 // Check for oddballs: true, false, null, undefined. |
| 1627 __ CmpInstanceType(rcx, ODDBALL_TYPE); | 1627 __ CmpInstanceType(rcx, ODDBALL_TYPE); |
| 1628 __ j(equal, &return_not_equal); | 1628 __ j(equal, &return_not_equal); |
| 1629 | 1629 |
| 1630 // Fall through to the general case. | 1630 // Fall through to the general case. |
| 1631 } | 1631 } |
| 1632 __ bind(&slow); | 1632 __ bind(&slow); |
| 1633 } | 1633 } |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1700 // and their pointers are different. | 1700 // and their pointers are different. |
| 1701 Label return_unequal; | 1701 Label return_unequal; |
| 1702 // At most one is a smi, so we can test for smi by adding the two. | 1702 // At most one is a smi, so we can test for smi by adding the two. |
| 1703 // A smi plus a heap object has the low bit set, a heap object plus | 1703 // A smi plus a heap object has the low bit set, a heap object plus |
| 1704 // a heap object has the low bit clear. | 1704 // a heap object has the low bit clear. |
| 1705 STATIC_ASSERT(kSmiTag == 0); | 1705 STATIC_ASSERT(kSmiTag == 0); |
| 1706 STATIC_ASSERT(kSmiTagMask == 1); | 1706 STATIC_ASSERT(kSmiTagMask == 1); |
| 1707 __ leap(rcx, Operand(rax, rdx, times_1, 0)); | 1707 __ leap(rcx, Operand(rax, rdx, times_1, 0)); |
| 1708 __ testb(rcx, Immediate(kSmiTagMask)); | 1708 __ testb(rcx, Immediate(kSmiTagMask)); |
| 1709 __ j(not_zero, &runtime_call, Label::kNear); | 1709 __ j(not_zero, &runtime_call, Label::kNear); |
| 1710 __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rbx); | 1710 __ CmpObjectType(rax, FIRST_JS_RECEIVER_TYPE, rbx); |
| 1711 __ j(below, &runtime_call, Label::kNear); | 1711 __ j(below, &runtime_call, Label::kNear); |
| 1712 __ CmpObjectType(rdx, FIRST_SPEC_OBJECT_TYPE, rcx); | 1712 __ CmpObjectType(rdx, FIRST_JS_RECEIVER_TYPE, rcx); |
| 1713 __ j(below, &runtime_call, Label::kNear); | 1713 __ j(below, &runtime_call, Label::kNear); |
| 1714 __ testb(FieldOperand(rbx, Map::kBitFieldOffset), | 1714 __ testb(FieldOperand(rbx, Map::kBitFieldOffset), |
| 1715 Immediate(1 << Map::kIsUndetectable)); | 1715 Immediate(1 << Map::kIsUndetectable)); |
| 1716 __ j(zero, &return_unequal, Label::kNear); | 1716 __ j(zero, &return_unequal, Label::kNear); |
| 1717 __ testb(FieldOperand(rcx, Map::kBitFieldOffset), | 1717 __ testb(FieldOperand(rcx, Map::kBitFieldOffset), |
| 1718 Immediate(1 << Map::kIsUndetectable)); | 1718 Immediate(1 << Map::kIsUndetectable)); |
| 1719 __ j(zero, &return_unequal, Label::kNear); | 1719 __ j(zero, &return_unequal, Label::kNear); |
| 1720 // The objects are both undetectable, so they both compare as the value | 1720 // The objects are both undetectable, so they both compare as the value |
| 1721 // undefined, and are equal. | 1721 // undefined, and are equal. |
| 1722 __ Set(rax, EQUAL); | 1722 __ Set(rax, EQUAL); |
| (...skipping 3398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5121 Label ok; | 5121 Label ok; |
| 5122 Register return_value = rax; | 5122 Register return_value = rax; |
| 5123 Register map = rcx; | 5123 Register map = rcx; |
| 5124 | 5124 |
| 5125 __ JumpIfSmi(return_value, &ok, Label::kNear); | 5125 __ JumpIfSmi(return_value, &ok, Label::kNear); |
| 5126 __ movp(map, FieldOperand(return_value, HeapObject::kMapOffset)); | 5126 __ movp(map, FieldOperand(return_value, HeapObject::kMapOffset)); |
| 5127 | 5127 |
| 5128 __ CmpInstanceType(map, LAST_NAME_TYPE); | 5128 __ CmpInstanceType(map, LAST_NAME_TYPE); |
| 5129 __ j(below_equal, &ok, Label::kNear); | 5129 __ j(below_equal, &ok, Label::kNear); |
| 5130 | 5130 |
| 5131 __ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE); | 5131 __ CmpInstanceType(map, FIRST_JS_RECEIVER_TYPE); |
| 5132 __ j(above_equal, &ok, Label::kNear); | 5132 __ j(above_equal, &ok, Label::kNear); |
| 5133 | 5133 |
| 5134 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex); | 5134 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex); |
| 5135 __ j(equal, &ok, Label::kNear); | 5135 __ j(equal, &ok, Label::kNear); |
| 5136 | 5136 |
| 5137 __ CompareRoot(return_value, Heap::kUndefinedValueRootIndex); | 5137 __ CompareRoot(return_value, Heap::kUndefinedValueRootIndex); |
| 5138 __ j(equal, &ok, Label::kNear); | 5138 __ j(equal, &ok, Label::kNear); |
| 5139 | 5139 |
| 5140 __ CompareRoot(return_value, Heap::kTrueValueRootIndex); | 5140 __ CompareRoot(return_value, Heap::kTrueValueRootIndex); |
| 5141 __ j(equal, &ok, Label::kNear); | 5141 __ j(equal, &ok, Label::kNear); |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5387 kStackSpace, nullptr, return_value_operand, NULL); | 5387 kStackSpace, nullptr, return_value_operand, NULL); |
| 5388 } | 5388 } |
| 5389 | 5389 |
| 5390 | 5390 |
| 5391 #undef __ | 5391 #undef __ |
| 5392 | 5392 |
| 5393 } // namespace internal | 5393 } // namespace internal |
| 5394 } // namespace v8 | 5394 } // namespace v8 |
| 5395 | 5395 |
| 5396 #endif // V8_TARGET_ARCH_X64 | 5396 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |