OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1805 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1816 } | 1816 } |
1817 | 1817 |
1818 | 1818 |
1819 void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) { | 1819 void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) { |
1820 class DeferredInstanceOfKnownGlobal: public LDeferredCode { | 1820 class DeferredInstanceOfKnownGlobal: public LDeferredCode { |
1821 public: | 1821 public: |
1822 DeferredInstanceOfKnownGlobal(LCodeGen* codegen, | 1822 DeferredInstanceOfKnownGlobal(LCodeGen* codegen, |
1823 LInstanceOfKnownGlobal* instr) | 1823 LInstanceOfKnownGlobal* instr) |
1824 : LDeferredCode(codegen), instr_(instr) { } | 1824 : LDeferredCode(codegen), instr_(instr) { } |
1825 virtual void Generate() { | 1825 virtual void Generate() { |
1826 codegen()->DoDeferredLInstanceOfKnownGlobal(instr_); | 1826 codegen()->DoDeferredLInstanceOfKnownGlobal(instr_, &map_check_); |
1827 } | 1827 } |
1828 | 1828 |
| 1829 Label* map_check() { return &map_check_; } |
| 1830 |
1829 private: | 1831 private: |
1830 LInstanceOfKnownGlobal* instr_; | 1832 LInstanceOfKnownGlobal* instr_; |
| 1833 Label map_check_; |
1831 }; | 1834 }; |
1832 | 1835 |
1833 | 1836 |
1834 DeferredInstanceOfKnownGlobal* deferred; | 1837 DeferredInstanceOfKnownGlobal* deferred; |
1835 deferred = new DeferredInstanceOfKnownGlobal(this, instr); | 1838 deferred = new DeferredInstanceOfKnownGlobal(this, instr); |
1836 | 1839 |
1837 Label false_result; | 1840 Label done, false_result; |
1838 Register object = ToRegister(instr->InputAt(0)); | 1841 Register object = ToRegister(instr->InputAt(0)); |
1839 | 1842 |
1840 // A Smi is not an instance of anything. | 1843 // A Smi is not an instance of anything. |
1841 __ JumpIfSmi(object, &false_result); | 1844 __ JumpIfSmi(object, &false_result); |
1842 | 1845 |
1843 // Null is not an instance of anything. | 1846 // This is the inlined call site instanceof cache. The two occurences of the |
| 1847 // hole value will be patched to the last map/result pair generated by the |
| 1848 // instanceof stub. |
| 1849 NearLabel cache_miss; |
| 1850 // Use a temp register to avoid memory operands with variable lengths. |
| 1851 Register map = ToRegister(instr->TempAt(0)); |
| 1852 __ movq(map, FieldOperand(object, HeapObject::kMapOffset)); |
| 1853 __ bind(deferred->map_check()); // Label for calculating code patching. |
| 1854 __ Move(kScratchRegister, Factory::the_hole_value()); |
| 1855 __ cmpq(map, kScratchRegister); // Patched to cached map. |
| 1856 __ j(not_equal, &cache_miss); |
| 1857 // Patched to load either true or false. |
| 1858 __ LoadRoot(ToRegister(instr->result()), Heap::kTheHoleValueRootIndex); |
| 1859 #ifdef DEBUG |
| 1860 // Check that the code size between patch label and patch sites is invariant. |
| 1861 Label end_of_patched_code; |
| 1862 __ bind(&end_of_patched_code); |
| 1863 ASSERT(true); |
| 1864 #endif |
| 1865 __ jmp(&done); |
| 1866 |
| 1867 // The inlined call site cache did not match. Check for null and string |
| 1868 // before calling the deferred code. |
| 1869 __ bind(&cache_miss); // Null is not an instance of anything. |
1844 __ CompareRoot(object, Heap::kNullValueRootIndex); | 1870 __ CompareRoot(object, Heap::kNullValueRootIndex); |
1845 __ j(equal, &false_result); | 1871 __ j(equal, &false_result); |
1846 | 1872 |
1847 // String values are not instances of anything. | 1873 // String values are not instances of anything. |
1848 __ JumpIfNotString(object, kScratchRegister, deferred->entry()); | 1874 __ JumpIfNotString(object, kScratchRegister, deferred->entry()); |
1849 | 1875 |
1850 __ bind(&false_result); | 1876 __ bind(&false_result); |
1851 __ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex); | 1877 __ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex); |
1852 | 1878 |
1853 __ bind(deferred->exit()); | 1879 __ bind(deferred->exit()); |
| 1880 __ bind(&done); |
1854 } | 1881 } |
1855 | 1882 |
1856 | 1883 |
1857 void LCodeGen::DoDeferredLInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) { | 1884 void LCodeGen::DoDeferredLInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, |
| 1885 Label* map_check) { |
1858 __ PushSafepointRegisters(); | 1886 __ PushSafepointRegisters(); |
1859 | 1887 InstanceofStub::Flags flags = static_cast<InstanceofStub::Flags>( |
1860 InstanceofStub stub(InstanceofStub::kNoFlags); | 1888 InstanceofStub::kNoFlags | InstanceofStub::kCallSiteInlineCheck); |
| 1889 InstanceofStub stub(flags); |
1861 | 1890 |
1862 __ push(ToRegister(instr->InputAt(0))); | 1891 __ push(ToRegister(instr->InputAt(0))); |
1863 __ Push(instr->function()); | 1892 __ Push(instr->function()); |
1864 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 1893 Register temp = ToRegister(instr->TempAt(0)); |
| 1894 ASSERT(temp.is(rdi)); |
| 1895 static const int kAdditionalDelta = 16; |
| 1896 int delta = |
| 1897 masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta; |
| 1898 __ movq(temp, Immediate(delta)); |
| 1899 __ push(temp); |
1865 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); | 1900 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
1866 __ movq(kScratchRegister, rax); | 1901 __ movq(kScratchRegister, rax); |
1867 __ PopSafepointRegisters(); | 1902 __ PopSafepointRegisters(); |
1868 __ testq(kScratchRegister, kScratchRegister); | 1903 __ testq(kScratchRegister, kScratchRegister); |
1869 Label load_false; | 1904 Label load_false; |
1870 Label done; | 1905 Label done; |
1871 __ j(not_zero, &load_false); | 1906 __ j(not_zero, &load_false); |
1872 __ LoadRoot(rax, Heap::kTrueValueRootIndex); | 1907 __ LoadRoot(rax, Heap::kTrueValueRootIndex); |
1873 __ jmp(&done); | 1908 __ jmp(&done); |
1874 __ bind(&load_false); | 1909 __ bind(&load_false); |
(...skipping 1781 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3656 RegisterEnvironmentForDeoptimization(environment); | 3691 RegisterEnvironmentForDeoptimization(environment); |
3657 ASSERT(osr_pc_offset_ == -1); | 3692 ASSERT(osr_pc_offset_ == -1); |
3658 osr_pc_offset_ = masm()->pc_offset(); | 3693 osr_pc_offset_ = masm()->pc_offset(); |
3659 } | 3694 } |
3660 | 3695 |
3661 #undef __ | 3696 #undef __ |
3662 | 3697 |
3663 } } // namespace v8::internal | 3698 } } // namespace v8::internal |
3664 | 3699 |
3665 #endif // V8_TARGET_ARCH_X64 | 3700 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |