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 |