OLD | NEW |
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 #if V8_TARGET_ARCH_X87 | 5 #if V8_TARGET_ARCH_X87 |
6 | 6 |
7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
8 #include "src/bootstrapper.h" | 8 #include "src/bootstrapper.h" |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 1774 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1785 | 1785 |
1786 // Unreachable. | 1786 // Unreachable. |
1787 } | 1787 } |
1788 | 1788 |
1789 | 1789 |
1790 void CallICStub::Generate(MacroAssembler* masm) { | 1790 void CallICStub::Generate(MacroAssembler* masm) { |
1791 // edi - function | 1791 // edi - function |
1792 // edx - slot id | 1792 // edx - slot id |
1793 // ebx - vector | 1793 // ebx - vector |
1794 Isolate* isolate = masm->isolate(); | 1794 Isolate* isolate = masm->isolate(); |
1795 const int with_types_offset = | |
1796 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex); | |
1797 const int generic_offset = | |
1798 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex); | |
1799 Label extra_checks_or_miss, call, call_function; | 1795 Label extra_checks_or_miss, call, call_function; |
1800 int argc = arg_count(); | 1796 int argc = arg_count(); |
1801 ParameterCount actual(argc); | 1797 ParameterCount actual(argc); |
1802 | 1798 |
1803 // The checks. First, does edi match the recorded monomorphic target? | 1799 // The checks. First, does edi match the recorded monomorphic target? |
1804 __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size, | 1800 __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size, |
1805 FixedArray::kHeaderSize)); | 1801 FixedArray::kHeaderSize)); |
1806 | 1802 |
1807 // We don't know that we have a weak cell. We might have a private symbol | 1803 // We don't know that we have a weak cell. We might have a private symbol |
1808 // or an AllocationSite, but the memory is safe to examine. | 1804 // or an AllocationSite, but the memory is safe to examine. |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1861 __ j(equal, &uninitialized); | 1857 __ j(equal, &uninitialized); |
1862 | 1858 |
1863 // We are going megamorphic. If the feedback is a JSFunction, it is fine | 1859 // We are going megamorphic. If the feedback is a JSFunction, it is fine |
1864 // to handle it here. More complex cases are dealt with in the runtime. | 1860 // to handle it here. More complex cases are dealt with in the runtime. |
1865 __ AssertNotSmi(ecx); | 1861 __ AssertNotSmi(ecx); |
1866 __ CmpObjectType(ecx, JS_FUNCTION_TYPE, ecx); | 1862 __ CmpObjectType(ecx, JS_FUNCTION_TYPE, ecx); |
1867 __ j(not_equal, &miss); | 1863 __ j(not_equal, &miss); |
1868 __ mov( | 1864 __ mov( |
1869 FieldOperand(ebx, edx, times_half_pointer_size, FixedArray::kHeaderSize), | 1865 FieldOperand(ebx, edx, times_half_pointer_size, FixedArray::kHeaderSize), |
1870 Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate))); | 1866 Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate))); |
1871 // We have to update statistics for runtime profiling. | |
1872 __ sub(FieldOperand(ebx, with_types_offset), Immediate(Smi::FromInt(1))); | |
1873 __ add(FieldOperand(ebx, generic_offset), Immediate(Smi::FromInt(1))); | |
1874 | 1867 |
1875 __ bind(&call); | 1868 __ bind(&call); |
1876 __ Set(eax, argc); | 1869 __ Set(eax, argc); |
1877 __ Jump(masm->isolate()->builtins()->Call(convert_mode()), | 1870 __ Jump(masm->isolate()->builtins()->Call(convert_mode()), |
1878 RelocInfo::CODE_TARGET); | 1871 RelocInfo::CODE_TARGET); |
1879 | 1872 |
1880 __ bind(&uninitialized); | 1873 __ bind(&uninitialized); |
1881 | 1874 |
1882 // We are going monomorphic, provided we actually have a JSFunction. | 1875 // We are going monomorphic, provided we actually have a JSFunction. |
1883 __ JumpIfSmi(edi, &miss); | 1876 __ JumpIfSmi(edi, &miss); |
1884 | 1877 |
1885 // Goto miss case if we do not have a function. | 1878 // Goto miss case if we do not have a function. |
1886 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); | 1879 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); |
1887 __ j(not_equal, &miss); | 1880 __ j(not_equal, &miss); |
1888 | 1881 |
1889 // Make sure the function is not the Array() function, which requires special | 1882 // Make sure the function is not the Array() function, which requires special |
1890 // behavior on MISS. | 1883 // behavior on MISS. |
1891 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, ecx); | 1884 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, ecx); |
1892 __ cmp(edi, ecx); | 1885 __ cmp(edi, ecx); |
1893 __ j(equal, &miss); | 1886 __ j(equal, &miss); |
1894 | 1887 |
1895 // Make sure the function belongs to the same native context. | 1888 // Make sure the function belongs to the same native context. |
1896 __ mov(ecx, FieldOperand(edi, JSFunction::kContextOffset)); | 1889 __ mov(ecx, FieldOperand(edi, JSFunction::kContextOffset)); |
1897 __ mov(ecx, ContextOperand(ecx, Context::NATIVE_CONTEXT_INDEX)); | 1890 __ mov(ecx, ContextOperand(ecx, Context::NATIVE_CONTEXT_INDEX)); |
1898 __ cmp(ecx, NativeContextOperand()); | 1891 __ cmp(ecx, NativeContextOperand()); |
1899 __ j(not_equal, &miss); | 1892 __ j(not_equal, &miss); |
1900 | 1893 |
1901 // Update stats. | |
1902 __ add(FieldOperand(ebx, with_types_offset), Immediate(Smi::FromInt(1))); | |
1903 | |
1904 // Initialize the call counter. | 1894 // Initialize the call counter. |
1905 __ mov(FieldOperand(ebx, edx, times_half_pointer_size, | 1895 __ mov(FieldOperand(ebx, edx, times_half_pointer_size, |
1906 FixedArray::kHeaderSize + kPointerSize), | 1896 FixedArray::kHeaderSize + kPointerSize), |
1907 Immediate(Smi::FromInt(CallICNexus::kCallCountIncrement))); | 1897 Immediate(Smi::FromInt(CallICNexus::kCallCountIncrement))); |
1908 | 1898 |
1909 // Store the function. Use a stub since we need a frame for allocation. | 1899 // Store the function. Use a stub since we need a frame for allocation. |
1910 // ebx - vector | 1900 // ebx - vector |
1911 // edx - slot | 1901 // edx - slot |
1912 // edi - function | 1902 // edi - function |
1913 { | 1903 { |
(...skipping 3422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5336 Operand(ebp, 7 * kPointerSize), NULL); | 5326 Operand(ebp, 7 * kPointerSize), NULL); |
5337 } | 5327 } |
5338 | 5328 |
5339 | 5329 |
5340 #undef __ | 5330 #undef __ |
5341 | 5331 |
5342 } // namespace internal | 5332 } // namespace internal |
5343 } // namespace v8 | 5333 } // namespace v8 |
5344 | 5334 |
5345 #endif // V8_TARGET_ARCH_X87 | 5335 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |