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 1760 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1771 | 1771 |
1772 // Call the native; it returns -1 (less), 0 (equal), or 1 (greater) | 1772 // Call the native; it returns -1 (less), 0 (equal), or 1 (greater) |
1773 // tagged as a small integer. | 1773 // tagged as a small integer. |
1774 __ InvokeBuiltin(builtin, JUMP_FUNCTION); | 1774 __ InvokeBuiltin(builtin, JUMP_FUNCTION); |
1775 | 1775 |
1776 __ bind(&miss); | 1776 __ bind(&miss); |
1777 GenerateMiss(masm); | 1777 GenerateMiss(masm); |
1778 } | 1778 } |
1779 | 1779 |
1780 | 1780 |
| 1781 static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub) { |
| 1782 // eax : number of arguments to the construct function |
| 1783 // ebx : Feedback vector |
| 1784 // edx : slot in feedback vector (Smi) |
| 1785 // edi : the function to call |
| 1786 FrameScope scope(masm, StackFrame::INTERNAL); |
| 1787 |
| 1788 // Arguments register must be smi-tagged to call out. |
| 1789 __ Integer32ToSmi(rax, rax); |
| 1790 __ Push(rax); |
| 1791 __ Push(rdi); |
| 1792 __ Integer32ToSmi(rdx, rdx); |
| 1793 __ Push(rdx); |
| 1794 __ Push(rbx); |
| 1795 |
| 1796 __ CallStub(stub); |
| 1797 |
| 1798 __ Pop(rbx); |
| 1799 __ Pop(rdx); |
| 1800 __ Pop(rdi); |
| 1801 __ Pop(rax); |
| 1802 __ SmiToInteger32(rax, rax); |
| 1803 } |
| 1804 |
| 1805 |
1781 static void GenerateRecordCallTarget(MacroAssembler* masm) { | 1806 static void GenerateRecordCallTarget(MacroAssembler* masm) { |
1782 // Cache the called function in a feedback vector slot. Cache states | 1807 // Cache the called function in a feedback vector slot. Cache states |
1783 // are uninitialized, monomorphic (indicated by a JSFunction), and | 1808 // are uninitialized, monomorphic (indicated by a JSFunction), and |
1784 // megamorphic. | 1809 // megamorphic. |
1785 // rax : number of arguments to the construct function | 1810 // rax : number of arguments to the construct function |
1786 // rbx : Feedback vector | 1811 // rbx : Feedback vector |
1787 // rdx : slot in feedback vector (Smi) | 1812 // rdx : slot in feedback vector (Smi) |
1788 // rdi : the function to call | 1813 // rdi : the function to call |
1789 Isolate* isolate = masm->isolate(); | 1814 Isolate* isolate = masm->isolate(); |
1790 Label initialize, done, miss, megamorphic, not_array_function, | 1815 Label initialize, done, miss, megamorphic, not_array_function, |
1791 done_no_smi_convert; | 1816 done_no_smi_convert; |
1792 | 1817 |
1793 // Load the cache state into rcx. | 1818 // Load the cache state into rcx. |
1794 __ SmiToInteger32(rdx, rdx); | 1819 __ SmiToInteger32(rdx, rdx); |
1795 __ movp(rcx, FieldOperand(rbx, rdx, times_pointer_size, | 1820 __ movp(rcx, FieldOperand(rbx, rdx, times_pointer_size, |
1796 FixedArray::kHeaderSize)); | 1821 FixedArray::kHeaderSize)); |
1797 | 1822 |
1798 // A monomorphic cache hit or an already megamorphic state: invoke the | 1823 // A monomorphic cache hit or an already megamorphic state: invoke the |
1799 // function without changing the state. | 1824 // function without changing the state. |
1800 __ cmpp(rcx, rdi); | 1825 Label check_allocation_site; |
1801 __ j(equal, &done); | 1826 __ cmpp(rdi, FieldOperand(rcx, WeakCell::kValueOffset)); |
1802 __ Cmp(rcx, TypeFeedbackVector::MegamorphicSentinel(isolate)); | 1827 __ j(equal, &done, Label::kFar); |
1803 __ j(equal, &done); | 1828 __ CompareRoot(rcx, Heap::kmegamorphic_symbolRootIndex); |
| 1829 __ j(equal, &done, Label::kFar); |
| 1830 __ CompareRoot(FieldOperand(rcx, 0), Heap::kWeakCellMapRootIndex); |
| 1831 __ j(not_equal, FLAG_pretenuring_call_new ? &miss : &check_allocation_site); |
| 1832 |
| 1833 // If edi is not equal to the weak cell value, and the weak cell value is |
| 1834 // cleared, we have a new chance to become monomorphic. Otherwise, we |
| 1835 // need to go megamorphic. |
| 1836 __ CheckSmi(FieldOperand(rcx, WeakCell::kValueOffset)); |
| 1837 __ j(equal, &initialize); |
| 1838 __ jmp(&megamorphic); |
1804 | 1839 |
1805 if (!FLAG_pretenuring_call_new) { | 1840 if (!FLAG_pretenuring_call_new) { |
| 1841 __ bind(&check_allocation_site); |
1806 // If we came here, we need to see if we are the array function. | 1842 // If we came here, we need to see if we are the array function. |
1807 // If we didn't have a matching function, and we didn't find the megamorph | 1843 // If we didn't have a matching function, and we didn't find the megamorph |
1808 // sentinel, then we have in the slot either some other function or an | 1844 // sentinel, then we have in the slot either some other function or an |
1809 // AllocationSite. Do a map check on the object in rcx. | 1845 // AllocationSite. Do a map check on the object in rcx. |
1810 Handle<Map> allocation_site_map = | 1846 __ CompareRoot(FieldOperand(rcx, 0), Heap::kAllocationSiteMapRootIndex); |
1811 masm->isolate()->factory()->allocation_site_map(); | |
1812 __ Cmp(FieldOperand(rcx, 0), allocation_site_map); | |
1813 __ j(not_equal, &miss); | 1847 __ j(not_equal, &miss); |
1814 | 1848 |
1815 // Make sure the function is the Array() function | 1849 // Make sure the function is the Array() function |
1816 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, rcx); | 1850 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, rcx); |
1817 __ cmpp(rdi, rcx); | 1851 __ cmpp(rdi, rcx); |
1818 __ j(not_equal, &megamorphic); | 1852 __ j(not_equal, &megamorphic); |
1819 __ jmp(&done); | 1853 __ jmp(&done); |
1820 } | 1854 } |
1821 | 1855 |
1822 __ bind(&miss); | 1856 __ bind(&miss); |
1823 | 1857 |
1824 // A monomorphic miss (i.e, here the cache is not uninitialized) goes | 1858 // A monomorphic miss (i.e, here the cache is not uninitialized) goes |
1825 // megamorphic. | 1859 // megamorphic. |
1826 __ Cmp(rcx, TypeFeedbackVector::UninitializedSentinel(isolate)); | 1860 __ CompareRoot(rcx, Heap::kuninitialized_symbolRootIndex); |
1827 __ j(equal, &initialize); | 1861 __ j(equal, &initialize); |
1828 // MegamorphicSentinel is an immortal immovable object (undefined) so no | 1862 // MegamorphicSentinel is an immortal immovable object (undefined) so no |
1829 // write-barrier is needed. | 1863 // write-barrier is needed. |
1830 __ bind(&megamorphic); | 1864 __ bind(&megamorphic); |
1831 __ Move(FieldOperand(rbx, rdx, times_pointer_size, FixedArray::kHeaderSize), | 1865 __ Move(FieldOperand(rbx, rdx, times_pointer_size, FixedArray::kHeaderSize), |
1832 TypeFeedbackVector::MegamorphicSentinel(isolate)); | 1866 TypeFeedbackVector::MegamorphicSentinel(isolate)); |
1833 __ jmp(&done); | 1867 __ jmp(&done); |
1834 | 1868 |
1835 // An uninitialized cache is patched with the function or sentinel to | 1869 // An uninitialized cache is patched with the function or sentinel to |
1836 // indicate the ElementsKind if function is the Array constructor. | 1870 // indicate the ElementsKind if function is the Array constructor. |
1837 __ bind(&initialize); | 1871 __ bind(&initialize); |
1838 | 1872 |
1839 if (!FLAG_pretenuring_call_new) { | 1873 if (!FLAG_pretenuring_call_new) { |
1840 // Make sure the function is the Array() function | 1874 // Make sure the function is the Array() function |
1841 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, rcx); | 1875 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, rcx); |
1842 __ cmpp(rdi, rcx); | 1876 __ cmpp(rdi, rcx); |
1843 __ j(not_equal, ¬_array_function); | 1877 __ j(not_equal, ¬_array_function); |
1844 | 1878 |
1845 { | 1879 CreateAllocationSiteStub create_stub(isolate); |
1846 FrameScope scope(masm, StackFrame::INTERNAL); | 1880 CallStubInRecordCallTarget(masm, &create_stub); |
1847 | |
1848 // Arguments register must be smi-tagged to call out. | |
1849 __ Integer32ToSmi(rax, rax); | |
1850 __ Push(rax); | |
1851 __ Push(rdi); | |
1852 __ Integer32ToSmi(rdx, rdx); | |
1853 __ Push(rdx); | |
1854 __ Push(rbx); | |
1855 | |
1856 CreateAllocationSiteStub create_stub(isolate); | |
1857 __ CallStub(&create_stub); | |
1858 | |
1859 __ Pop(rbx); | |
1860 __ Pop(rdx); | |
1861 __ Pop(rdi); | |
1862 __ Pop(rax); | |
1863 __ SmiToInteger32(rax, rax); | |
1864 } | |
1865 __ jmp(&done_no_smi_convert); | 1881 __ jmp(&done_no_smi_convert); |
1866 | 1882 |
1867 __ bind(¬_array_function); | 1883 __ bind(¬_array_function); |
1868 } | 1884 } |
1869 | 1885 |
1870 __ movp(FieldOperand(rbx, rdx, times_pointer_size, FixedArray::kHeaderSize), | 1886 CreateWeakCellStub create_stub(isolate); |
1871 rdi); | 1887 CallStubInRecordCallTarget(masm, &create_stub); |
1872 | 1888 __ jmp(&done_no_smi_convert); |
1873 // We won't need rdx or rbx anymore, just save rdi | |
1874 __ Push(rdi); | |
1875 __ Push(rbx); | |
1876 __ Push(rdx); | |
1877 __ RecordWriteArray(rbx, rdi, rdx, kDontSaveFPRegs, | |
1878 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); | |
1879 __ Pop(rdx); | |
1880 __ Pop(rbx); | |
1881 __ Pop(rdi); | |
1882 | 1889 |
1883 __ bind(&done); | 1890 __ bind(&done); |
1884 __ Integer32ToSmi(rdx, rdx); | 1891 __ Integer32ToSmi(rdx, rdx); |
1885 | 1892 |
1886 __ bind(&done_no_smi_convert); | 1893 __ bind(&done_no_smi_convert); |
1887 } | 1894 } |
1888 | 1895 |
1889 | 1896 |
1890 static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) { | 1897 static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) { |
1891 // Do not transform the receiver for strict mode functions. | 1898 // Do not transform the receiver for strict mode functions. |
(...skipping 3467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5359 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, getter_arg, | 5366 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, getter_arg, |
5360 kStackSpace, nullptr, return_value_operand, NULL); | 5367 kStackSpace, nullptr, return_value_operand, NULL); |
5361 } | 5368 } |
5362 | 5369 |
5363 | 5370 |
5364 #undef __ | 5371 #undef __ |
5365 | 5372 |
5366 } } // namespace v8::internal | 5373 } } // namespace v8::internal |
5367 | 5374 |
5368 #endif // V8_TARGET_ARCH_X64 | 5375 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |