| 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 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_X64 | 7 #if V8_TARGET_ARCH_X64 |
| 8 | 8 |
| 9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
| 10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
| (...skipping 1548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1559 // Two identical objects are equal unless they are both NaN or undefined. | 1559 // Two identical objects are equal unless they are both NaN or undefined. |
| 1560 { | 1560 { |
| 1561 Label not_identical; | 1561 Label not_identical; |
| 1562 __ cmpp(rax, rdx); | 1562 __ cmpp(rax, rdx); |
| 1563 __ j(not_equal, ¬_identical, Label::kNear); | 1563 __ j(not_equal, ¬_identical, Label::kNear); |
| 1564 | 1564 |
| 1565 if (cc != equal) { | 1565 if (cc != equal) { |
| 1566 // Check for undefined. undefined OP undefined is false even though | 1566 // Check for undefined. undefined OP undefined is false even though |
| 1567 // undefined == undefined. | 1567 // undefined == undefined. |
| 1568 __ CompareRoot(rdx, Heap::kUndefinedValueRootIndex); | 1568 __ CompareRoot(rdx, Heap::kUndefinedValueRootIndex); |
| 1569 if (strong()) { | 1569 if (is_strong(strength())) { |
| 1570 // In strong mode, this comparison must throw, so call the runtime. | 1570 // In strong mode, this comparison must throw, so call the runtime. |
| 1571 __ j(equal, &runtime_call, Label::kFar); | 1571 __ j(equal, &runtime_call, Label::kFar); |
| 1572 } else { | 1572 } else { |
| 1573 Label check_for_nan; | 1573 Label check_for_nan; |
| 1574 __ j(not_equal, &check_for_nan, Label::kNear); | 1574 __ j(not_equal, &check_for_nan, Label::kNear); |
| 1575 __ Set(rax, NegativeComparisonResult(cc)); | 1575 __ Set(rax, NegativeComparisonResult(cc)); |
| 1576 __ ret(0); | 1576 __ ret(0); |
| 1577 __ bind(&check_for_nan); | 1577 __ bind(&check_for_nan); |
| 1578 } | 1578 } |
| 1579 } | 1579 } |
| 1580 | 1580 |
| 1581 // Test for NaN. Sadly, we can't just compare to Factory::nan_value(), | 1581 // Test for NaN. Sadly, we can't just compare to Factory::nan_value(), |
| 1582 // so we do the second best thing - test it ourselves. | 1582 // so we do the second best thing - test it ourselves. |
| 1583 Label heap_number; | 1583 Label heap_number; |
| 1584 // If it's not a heap number, then return equal for (in)equality operator. | 1584 // If it's not a heap number, then return equal for (in)equality operator. |
| 1585 __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset), | 1585 __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset), |
| 1586 factory->heap_number_map()); | 1586 factory->heap_number_map()); |
| 1587 __ j(equal, &heap_number, Label::kNear); | 1587 __ j(equal, &heap_number, Label::kNear); |
| 1588 if (cc != equal) { | 1588 if (cc != equal) { |
| 1589 __ movp(rcx, FieldOperand(rax, HeapObject::kMapOffset)); | 1589 __ movp(rcx, FieldOperand(rax, HeapObject::kMapOffset)); |
| 1590 __ movzxbl(rcx, FieldOperand(rcx, Map::kInstanceTypeOffset)); | 1590 __ movzxbl(rcx, FieldOperand(rcx, Map::kInstanceTypeOffset)); |
| 1591 // Call runtime on identical objects. Otherwise return equal. | 1591 // Call runtime on identical objects. Otherwise return equal. |
| 1592 __ cmpb(rcx, Immediate(static_cast<uint8_t>(FIRST_SPEC_OBJECT_TYPE))); | 1592 __ cmpb(rcx, Immediate(static_cast<uint8_t>(FIRST_SPEC_OBJECT_TYPE))); |
| 1593 __ j(above_equal, &runtime_call, Label::kFar); | 1593 __ j(above_equal, &runtime_call, Label::kFar); |
| 1594 // Call runtime on identical symbols since we need to throw a TypeError. | 1594 // Call runtime on identical symbols since we need to throw a TypeError. |
| 1595 __ cmpb(rcx, Immediate(static_cast<uint8_t>(SYMBOL_TYPE))); | 1595 __ cmpb(rcx, Immediate(static_cast<uint8_t>(SYMBOL_TYPE))); |
| 1596 __ j(equal, &runtime_call, Label::kFar); | 1596 __ j(equal, &runtime_call, Label::kFar); |
| 1597 if (strong()) { | 1597 if (is_strong(strength())) { |
| 1598 // We have already tested for smis and heap numbers, so if both | 1598 // We have already tested for smis and heap numbers, so if both |
| 1599 // arguments are not strings we must proceed to the slow case. | 1599 // arguments are not strings we must proceed to the slow case. |
| 1600 __ testb(rcx, Immediate(kIsNotStringMask)); | 1600 __ testb(rcx, Immediate(kIsNotStringMask)); |
| 1601 __ j(not_zero, &runtime_call, Label::kFar); | 1601 __ j(not_zero, &runtime_call, Label::kFar); |
| 1602 } | 1602 } |
| 1603 } | 1603 } |
| 1604 __ Set(rax, EQUAL); | 1604 __ Set(rax, EQUAL); |
| 1605 __ ret(0); | 1605 __ ret(0); |
| 1606 | 1606 |
| 1607 __ bind(&heap_number); | 1607 __ bind(&heap_number); |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1778 // Push arguments below the return address to prepare jump to builtin. | 1778 // Push arguments below the return address to prepare jump to builtin. |
| 1779 __ PopReturnAddressTo(rcx); | 1779 __ PopReturnAddressTo(rcx); |
| 1780 __ Push(rdx); | 1780 __ Push(rdx); |
| 1781 __ Push(rax); | 1781 __ Push(rax); |
| 1782 | 1782 |
| 1783 // Figure out which native to call and setup the arguments. | 1783 // Figure out which native to call and setup the arguments. |
| 1784 Builtins::JavaScript builtin; | 1784 Builtins::JavaScript builtin; |
| 1785 if (cc == equal) { | 1785 if (cc == equal) { |
| 1786 builtin = strict() ? Builtins::STRICT_EQUALS : Builtins::EQUALS; | 1786 builtin = strict() ? Builtins::STRICT_EQUALS : Builtins::EQUALS; |
| 1787 } else { | 1787 } else { |
| 1788 builtin = strong() ? Builtins::COMPARE_STRONG : Builtins::COMPARE; | 1788 builtin = |
| 1789 is_strong(strength()) ? Builtins::COMPARE_STRONG : Builtins::COMPARE; |
| 1789 __ Push(Smi::FromInt(NegativeComparisonResult(cc))); | 1790 __ Push(Smi::FromInt(NegativeComparisonResult(cc))); |
| 1790 } | 1791 } |
| 1791 | 1792 |
| 1792 __ PushReturnAddressFrom(rcx); | 1793 __ PushReturnAddressFrom(rcx); |
| 1793 | 1794 |
| 1794 // Call the native; it returns -1 (less), 0 (equal), or 1 (greater) | 1795 // Call the native; it returns -1 (less), 0 (equal), or 1 (greater) |
| 1795 // tagged as a small integer. | 1796 // tagged as a small integer. |
| 1796 __ InvokeBuiltin(builtin, JUMP_FUNCTION); | 1797 __ InvokeBuiltin(builtin, JUMP_FUNCTION); |
| 1797 | 1798 |
| 1798 __ bind(&miss); | 1799 __ bind(&miss); |
| (...skipping 1804 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3603 // Return a result of -1, 0, or 1, based on EFLAGS. | 3604 // Return a result of -1, 0, or 1, based on EFLAGS. |
| 3604 // Performing mov, because xor would destroy the flag register. | 3605 // Performing mov, because xor would destroy the flag register. |
| 3605 __ movl(rax, Immediate(0)); | 3606 __ movl(rax, Immediate(0)); |
| 3606 __ movl(rcx, Immediate(0)); | 3607 __ movl(rcx, Immediate(0)); |
| 3607 __ setcc(above, rax); // Add one to zero if carry clear and not equal. | 3608 __ setcc(above, rax); // Add one to zero if carry clear and not equal. |
| 3608 __ sbbp(rax, rcx); // Subtract one if below (aka. carry set). | 3609 __ sbbp(rax, rcx); // Subtract one if below (aka. carry set). |
| 3609 __ ret(0); | 3610 __ ret(0); |
| 3610 | 3611 |
| 3611 __ bind(&unordered); | 3612 __ bind(&unordered); |
| 3612 __ bind(&generic_stub); | 3613 __ bind(&generic_stub); |
| 3613 CompareICStub stub(isolate(), op(), strong(), CompareICState::GENERIC, | 3614 CompareICStub stub(isolate(), op(), strength(), CompareICState::GENERIC, |
| 3614 CompareICState::GENERIC, CompareICState::GENERIC); | 3615 CompareICState::GENERIC, CompareICState::GENERIC); |
| 3615 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET); | 3616 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET); |
| 3616 | 3617 |
| 3617 __ bind(&maybe_undefined1); | 3618 __ bind(&maybe_undefined1); |
| 3618 if (Token::IsOrderedRelationalCompareOp(op())) { | 3619 if (Token::IsOrderedRelationalCompareOp(op())) { |
| 3619 __ Cmp(rax, isolate()->factory()->undefined_value()); | 3620 __ Cmp(rax, isolate()->factory()->undefined_value()); |
| 3620 __ j(not_equal, &miss); | 3621 __ j(not_equal, &miss); |
| 3621 __ JumpIfSmi(rdx, &unordered); | 3622 __ JumpIfSmi(rdx, &unordered); |
| 3622 __ CmpObjectType(rdx, HEAP_NUMBER_TYPE, rcx); | 3623 __ CmpObjectType(rdx, HEAP_NUMBER_TYPE, rcx); |
| 3623 __ j(not_equal, &maybe_undefined2, Label::kNear); | 3624 __ j(not_equal, &maybe_undefined2, Label::kNear); |
| (...skipping 1801 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5425 kStackSpace, nullptr, return_value_operand, NULL); | 5426 kStackSpace, nullptr, return_value_operand, NULL); |
| 5426 } | 5427 } |
| 5427 | 5428 |
| 5428 | 5429 |
| 5429 #undef __ | 5430 #undef __ |
| 5430 | 5431 |
| 5431 } // namespace internal | 5432 } // namespace internal |
| 5432 } // namespace v8 | 5433 } // namespace v8 |
| 5433 | 5434 |
| 5434 #endif // V8_TARGET_ARCH_X64 | 5435 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |