Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(208)

Side by Side Diff: src/ia32/code-stubs-ia32.cc

Issue 1130283002: [strong] Disallow implicit conversions for comparison (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: cl feedback Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/hydrogen.cc ('k') | src/ia32/full-codegen-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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_IA32 7 #if V8_TARGET_ARCH_IA32
8 8
9 #include "src/base/bits.h" 9 #include "src/base/bits.h"
10 #include "src/bootstrapper.h" 10 #include "src/bootstrapper.h"
(...skipping 1648 matching lines...) Expand 10 before | Expand all | Expand 10 after
1659 __ JumpIfSmi(object, label); 1659 __ JumpIfSmi(object, label);
1660 __ mov(scratch, FieldOperand(object, HeapObject::kMapOffset)); 1660 __ mov(scratch, FieldOperand(object, HeapObject::kMapOffset));
1661 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); 1661 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset));
1662 STATIC_ASSERT(kInternalizedTag == 0 && kStringTag == 0); 1662 STATIC_ASSERT(kInternalizedTag == 0 && kStringTag == 0);
1663 __ test(scratch, Immediate(kIsNotStringMask | kIsNotInternalizedMask)); 1663 __ test(scratch, Immediate(kIsNotStringMask | kIsNotInternalizedMask));
1664 __ j(not_zero, label); 1664 __ j(not_zero, label);
1665 } 1665 }
1666 1666
1667 1667
1668 void CompareICStub::GenerateGeneric(MacroAssembler* masm) { 1668 void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
1669 Label check_unequal_objects; 1669 Label runtime_call, check_unequal_objects;
1670 Condition cc = GetCondition(); 1670 Condition cc = GetCondition();
1671 1671
1672 Label miss; 1672 Label miss;
1673 CheckInputType(masm, edx, left(), &miss); 1673 CheckInputType(masm, edx, left(), &miss);
1674 CheckInputType(masm, eax, right(), &miss); 1674 CheckInputType(masm, eax, right(), &miss);
1675 1675
1676 // Compare two smis. 1676 // Compare two smis.
1677 Label non_smi, smi_done; 1677 Label non_smi, smi_done;
1678 __ mov(ecx, edx); 1678 __ mov(ecx, edx);
1679 __ or_(ecx, eax); 1679 __ or_(ecx, eax);
(...skipping 13 matching lines...) Expand all
1693 // for NaN and undefined. 1693 // for NaN and undefined.
1694 Label generic_heap_number_comparison; 1694 Label generic_heap_number_comparison;
1695 { 1695 {
1696 Label not_identical; 1696 Label not_identical;
1697 __ cmp(eax, edx); 1697 __ cmp(eax, edx);
1698 __ j(not_equal, &not_identical); 1698 __ j(not_equal, &not_identical);
1699 1699
1700 if (cc != equal) { 1700 if (cc != equal) {
1701 // Check for undefined. undefined OP undefined is false even though 1701 // Check for undefined. undefined OP undefined is false even though
1702 // undefined == undefined. 1702 // undefined == undefined.
1703 Label check_for_nan;
1704 __ cmp(edx, isolate()->factory()->undefined_value()); 1703 __ cmp(edx, isolate()->factory()->undefined_value());
1705 __ j(not_equal, &check_for_nan, Label::kNear); 1704 if (strong()) {
1706 __ Move(eax, Immediate(Smi::FromInt(NegativeComparisonResult(cc)))); 1705 // In strong mode, this comparison must throw, so call the runtime.
1707 __ ret(0); 1706 __ j(equal, &runtime_call, Label::kFar);
1708 __ bind(&check_for_nan); 1707 } else {
1708 Label check_for_nan;
1709 __ j(not_equal, &check_for_nan, Label::kNear);
1710 __ Move(eax, Immediate(Smi::FromInt(NegativeComparisonResult(cc))));
1711 __ ret(0);
1712 __ bind(&check_for_nan);
1713 }
1709 } 1714 }
1710 1715
1711 // Test for NaN. Compare heap numbers in a general way, 1716 // Test for NaN. Compare heap numbers in a general way,
1712 // to hanlde NaNs correctly. 1717 // to hanlde NaNs correctly.
1713 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), 1718 __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
1714 Immediate(isolate()->factory()->heap_number_map())); 1719 Immediate(isolate()->factory()->heap_number_map()));
1715 __ j(equal, &generic_heap_number_comparison, Label::kNear); 1720 __ j(equal, &generic_heap_number_comparison, Label::kNear);
1716 if (cc != equal) { 1721 if (cc != equal) {
1722 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
1723 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
1717 // Call runtime on identical JSObjects. Otherwise return equal. 1724 // Call runtime on identical JSObjects. Otherwise return equal.
1718 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx); 1725 __ cmpb(ecx, static_cast<uint8_t>(FIRST_SPEC_OBJECT_TYPE));
1719 __ j(above_equal, &not_identical); 1726 __ j(above_equal, &runtime_call, Label::kFar);
1720 // Call runtime on identical symbols since we need to throw a TypeError. 1727 // Call runtime on identical symbols since we need to throw a TypeError.
1721 __ CmpObjectType(eax, SYMBOL_TYPE, ecx); 1728 __ cmpb(ecx, static_cast<uint8_t>(SYMBOL_TYPE));
1722 __ j(equal, &not_identical); 1729 __ j(equal, &runtime_call, Label::kFar);
1730 if (strong()) {
1731 // We have already tested for smis and heap numbers, so if both
1732 // arguments are not strings we must proceed to the slow case.
1733 __ test(ecx, Immediate(kIsNotStringMask));
1734 __ j(not_zero, &runtime_call, Label::kFar);
1735 }
1723 } 1736 }
1724 __ Move(eax, Immediate(Smi::FromInt(EQUAL))); 1737 __ Move(eax, Immediate(Smi::FromInt(EQUAL)));
1725 __ ret(0); 1738 __ ret(0);
1726 1739
1727 1740
1728 __ bind(&not_identical); 1741 __ bind(&not_identical);
1729 } 1742 }
1730 1743
1731 // Strict equality can quickly decide whether objects are equal. 1744 // Strict equality can quickly decide whether objects are equal.
1732 // Non-strict object equality is slower, so it is handled later in the stub. 1745 // Non-strict object equality is slower, so it is handled later in the stub.
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
1857 } 1870 }
1858 #ifdef DEBUG 1871 #ifdef DEBUG
1859 __ Abort(kUnexpectedFallThroughFromStringComparison); 1872 __ Abort(kUnexpectedFallThroughFromStringComparison);
1860 #endif 1873 #endif
1861 1874
1862 __ bind(&check_unequal_objects); 1875 __ bind(&check_unequal_objects);
1863 if (cc == equal && !strict()) { 1876 if (cc == equal && !strict()) {
1864 // Non-strict equality. Objects are unequal if 1877 // Non-strict equality. Objects are unequal if
1865 // they are both JSObjects and not undetectable, 1878 // they are both JSObjects and not undetectable,
1866 // and their pointers are different. 1879 // and their pointers are different.
1867 Label not_both_objects;
1868 Label return_unequal; 1880 Label return_unequal;
1869 // At most one is a smi, so we can test for smi by adding the two. 1881 // At most one is a smi, so we can test for smi by adding the two.
1870 // A smi plus a heap object has the low bit set, a heap object plus 1882 // A smi plus a heap object has the low bit set, a heap object plus
1871 // a heap object has the low bit clear. 1883 // a heap object has the low bit clear.
1872 STATIC_ASSERT(kSmiTag == 0); 1884 STATIC_ASSERT(kSmiTag == 0);
1873 STATIC_ASSERT(kSmiTagMask == 1); 1885 STATIC_ASSERT(kSmiTagMask == 1);
1874 __ lea(ecx, Operand(eax, edx, times_1, 0)); 1886 __ lea(ecx, Operand(eax, edx, times_1, 0));
1875 __ test(ecx, Immediate(kSmiTagMask)); 1887 __ test(ecx, Immediate(kSmiTagMask));
1876 __ j(not_zero, &not_both_objects, Label::kNear); 1888 __ j(not_zero, &runtime_call, Label::kNear);
1877 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx); 1889 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx);
1878 __ j(below, &not_both_objects, Label::kNear); 1890 __ j(below, &runtime_call, Label::kNear);
1879 __ CmpObjectType(edx, FIRST_SPEC_OBJECT_TYPE, ebx); 1891 __ CmpObjectType(edx, FIRST_SPEC_OBJECT_TYPE, ebx);
1880 __ j(below, &not_both_objects, Label::kNear); 1892 __ j(below, &runtime_call, Label::kNear);
1881 // We do not bail out after this point. Both are JSObjects, and 1893 // We do not bail out after this point. Both are JSObjects, and
1882 // they are equal if and only if both are undetectable. 1894 // they are equal if and only if both are undetectable.
1883 // The and of the undetectable flags is 1 if and only if they are equal. 1895 // The and of the undetectable flags is 1 if and only if they are equal.
1884 __ test_b(FieldOperand(ecx, Map::kBitFieldOffset), 1896 __ test_b(FieldOperand(ecx, Map::kBitFieldOffset),
1885 1 << Map::kIsUndetectable); 1897 1 << Map::kIsUndetectable);
1886 __ j(zero, &return_unequal, Label::kNear); 1898 __ j(zero, &return_unequal, Label::kNear);
1887 __ test_b(FieldOperand(ebx, Map::kBitFieldOffset), 1899 __ test_b(FieldOperand(ebx, Map::kBitFieldOffset),
1888 1 << Map::kIsUndetectable); 1900 1 << Map::kIsUndetectable);
1889 __ j(zero, &return_unequal, Label::kNear); 1901 __ j(zero, &return_unequal, Label::kNear);
1890 // The objects are both undetectable, so they both compare as the value 1902 // The objects are both undetectable, so they both compare as the value
1891 // undefined, and are equal. 1903 // undefined, and are equal.
1892 __ Move(eax, Immediate(EQUAL)); 1904 __ Move(eax, Immediate(EQUAL));
1893 __ bind(&return_unequal); 1905 __ bind(&return_unequal);
1894 // Return non-equal by returning the non-zero object pointer in eax, 1906 // Return non-equal by returning the non-zero object pointer in eax,
1895 // or return equal if we fell through to here. 1907 // or return equal if we fell through to here.
1896 __ ret(0); // rax, rdx were pushed 1908 __ ret(0); // rax, rdx were pushed
1897 __ bind(&not_both_objects);
1898 } 1909 }
1910 __ bind(&runtime_call);
1899 1911
1900 // Push arguments below the return address. 1912 // Push arguments below the return address.
1901 __ pop(ecx); 1913 __ pop(ecx);
1902 __ push(edx); 1914 __ push(edx);
1903 __ push(eax); 1915 __ push(eax);
1904 1916
1905 // Figure out which native to call and setup the arguments. 1917 // Figure out which native to call and setup the arguments.
1906 Builtins::JavaScript builtin; 1918 Builtins::JavaScript builtin;
1907 if (cc == equal) { 1919 if (cc == equal) {
1908 builtin = strict() ? Builtins::STRICT_EQUALS : Builtins::EQUALS; 1920 builtin = strict() ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
1909 } else { 1921 } else {
1910 builtin = Builtins::COMPARE; 1922 builtin = strong() ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
1911 __ push(Immediate(Smi::FromInt(NegativeComparisonResult(cc)))); 1923 __ push(Immediate(Smi::FromInt(NegativeComparisonResult(cc))));
1912 } 1924 }
1913 1925
1914 // Restore return address on the stack. 1926 // Restore return address on the stack.
1915 __ push(ecx); 1927 __ push(ecx);
1916 1928
1917 // Call the native; it returns -1 (less), 0 (equal), or 1 (greater) 1929 // Call the native; it returns -1 (less), 0 (equal), or 1 (greater)
1918 // tagged as a small integer. 1930 // tagged as a small integer.
1919 __ InvokeBuiltin(builtin, JUMP_FUNCTION); 1931 __ InvokeBuiltin(builtin, JUMP_FUNCTION);
1920 1932
(...skipping 1710 matching lines...) Expand 10 before | Expand all | Expand 10 after
3631 // Performing mov, because xor would destroy the flag register. 3643 // Performing mov, because xor would destroy the flag register.
3632 __ mov(eax, 0); // equal 3644 __ mov(eax, 0); // equal
3633 __ mov(ecx, Immediate(Smi::FromInt(1))); 3645 __ mov(ecx, Immediate(Smi::FromInt(1)));
3634 __ cmov(above, eax, ecx); 3646 __ cmov(above, eax, ecx);
3635 __ mov(ecx, Immediate(Smi::FromInt(-1))); 3647 __ mov(ecx, Immediate(Smi::FromInt(-1)));
3636 __ cmov(below, eax, ecx); 3648 __ cmov(below, eax, ecx);
3637 __ ret(0); 3649 __ ret(0);
3638 3650
3639 __ bind(&unordered); 3651 __ bind(&unordered);
3640 __ bind(&generic_stub); 3652 __ bind(&generic_stub);
3641 CompareICStub stub(isolate(), op(), CompareICState::GENERIC, 3653 CompareICStub stub(isolate(), op(), strong(), CompareICState::GENERIC,
3642 CompareICState::GENERIC, CompareICState::GENERIC); 3654 CompareICState::GENERIC, CompareICState::GENERIC);
3643 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET); 3655 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET);
3644 3656
3645 __ bind(&maybe_undefined1); 3657 __ bind(&maybe_undefined1);
3646 if (Token::IsOrderedRelationalCompareOp(op())) { 3658 if (Token::IsOrderedRelationalCompareOp(op())) {
3647 __ cmp(eax, Immediate(isolate()->factory()->undefined_value())); 3659 __ cmp(eax, Immediate(isolate()->factory()->undefined_value()));
3648 __ j(not_equal, &miss); 3660 __ j(not_equal, &miss);
3649 __ JumpIfSmi(edx, &unordered); 3661 __ JumpIfSmi(edx, &unordered);
3650 __ CmpObjectType(edx, HEAP_NUMBER_TYPE, ecx); 3662 __ CmpObjectType(edx, HEAP_NUMBER_TYPE, ecx);
3651 __ j(not_equal, &maybe_undefined2, Label::kNear); 3663 __ j(not_equal, &maybe_undefined2, Label::kNear);
(...skipping 1767 matching lines...) Expand 10 before | Expand all | Expand 10 after
5419 ApiParameterOperand(2), kStackSpace, nullptr, 5431 ApiParameterOperand(2), kStackSpace, nullptr,
5420 Operand(ebp, 7 * kPointerSize), NULL); 5432 Operand(ebp, 7 * kPointerSize), NULL);
5421 } 5433 }
5422 5434
5423 5435
5424 #undef __ 5436 #undef __
5425 5437
5426 } } // namespace v8::internal 5438 } } // namespace v8::internal
5427 5439
5428 #endif // V8_TARGET_ARCH_IA32 5440 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/hydrogen.cc ('k') | src/ia32/full-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698