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 |