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 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/api.h" | 8 #include "src/api.h" |
9 #include "src/arguments.h" | 9 #include "src/arguments.h" |
10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
(...skipping 1808 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1819 } | 1819 } |
1820 DCHECK(!stub.is_null()); | 1820 DCHECK(!stub.is_null()); |
1821 set_target(*stub); | 1821 set_target(*stub); |
1822 TRACE_IC("StoreIC", key); | 1822 TRACE_IC("StoreIC", key); |
1823 | 1823 |
1824 return store_handle; | 1824 return store_handle; |
1825 } | 1825 } |
1826 | 1826 |
1827 | 1827 |
1828 bool CallIC::DoCustomHandler(Handle<Object> receiver, Handle<Object> function, | 1828 bool CallIC::DoCustomHandler(Handle<Object> receiver, Handle<Object> function, |
1829 Handle<FixedArray> vector, Handle<Smi> slot, | 1829 Handle<TypeFeedbackVector> vector, |
1830 const CallICState& state) { | 1830 Handle<Smi> slot, const CallICState& state) { |
1831 DCHECK(FLAG_use_ic && function->IsJSFunction()); | 1831 DCHECK(FLAG_use_ic && function->IsJSFunction()); |
1832 | 1832 |
1833 // Are we the array function? | 1833 // Are we the array function? |
1834 Handle<JSFunction> array_function = | 1834 Handle<JSFunction> array_function = |
1835 Handle<JSFunction>(isolate()->native_context()->array_function()); | 1835 Handle<JSFunction>(isolate()->native_context()->array_function()); |
1836 if (array_function.is_identical_to(Handle<JSFunction>::cast(function))) { | 1836 if (array_function.is_identical_to(Handle<JSFunction>::cast(function))) { |
1837 // Alter the slot. | 1837 // Alter the slot. |
1838 IC::State old_state = FeedbackToState(vector, slot); | 1838 IC::State old_state = FeedbackToState(vector, slot); |
1839 Object* feedback = vector->get(slot->value()); | 1839 Object* feedback = vector->get(slot->value()); |
1840 if (!feedback->IsAllocationSite()) { | 1840 if (!feedback->IsAllocationSite()) { |
(...skipping 13 matching lines...) Expand all Loading... |
1854 IC::State new_state = FeedbackToState(vector, slot); | 1854 IC::State new_state = FeedbackToState(vector, slot); |
1855 OnTypeFeedbackChanged(isolate(), address(), old_state, new_state, true); | 1855 OnTypeFeedbackChanged(isolate(), address(), old_state, new_state, true); |
1856 TRACE_VECTOR_IC("CallIC (custom handler)", name, old_state, new_state); | 1856 TRACE_VECTOR_IC("CallIC (custom handler)", name, old_state, new_state); |
1857 return true; | 1857 return true; |
1858 } | 1858 } |
1859 return false; | 1859 return false; |
1860 } | 1860 } |
1861 | 1861 |
1862 | 1862 |
1863 void CallIC::PatchMegamorphic(Handle<Object> function, | 1863 void CallIC::PatchMegamorphic(Handle<Object> function, |
1864 Handle<FixedArray> vector, Handle<Smi> slot) { | 1864 Handle<TypeFeedbackVector> vector, |
| 1865 Handle<Smi> slot) { |
1865 CallICState state(target()->extra_ic_state()); | 1866 CallICState state(target()->extra_ic_state()); |
1866 IC::State old_state = FeedbackToState(vector, slot); | 1867 IC::State old_state = FeedbackToState(vector, slot); |
1867 | 1868 |
1868 // We are going generic. | 1869 // We are going generic. |
1869 vector->set(slot->value(), *TypeFeedbackInfo::MegamorphicSentinel(isolate()), | 1870 vector->set(slot->value(), |
| 1871 *TypeFeedbackVector::MegamorphicSentinel(isolate()), |
1870 SKIP_WRITE_BARRIER); | 1872 SKIP_WRITE_BARRIER); |
1871 | 1873 |
1872 CallICStub stub(isolate(), state); | 1874 CallICStub stub(isolate(), state); |
1873 Handle<Code> code = stub.GetCode(); | 1875 Handle<Code> code = stub.GetCode(); |
1874 set_target(*code); | 1876 set_target(*code); |
1875 | 1877 |
1876 Handle<Object> name = isolate()->factory()->empty_string(); | 1878 Handle<Object> name = isolate()->factory()->empty_string(); |
1877 if (function->IsJSFunction()) { | 1879 if (function->IsJSFunction()) { |
1878 Handle<JSFunction> js_function = Handle<JSFunction>::cast(function); | 1880 Handle<JSFunction> js_function = Handle<JSFunction>::cast(function); |
1879 name = handle(js_function->shared()->name(), isolate()); | 1881 name = handle(js_function->shared()->name(), isolate()); |
1880 } | 1882 } |
1881 | 1883 |
1882 IC::State new_state = FeedbackToState(vector, slot); | 1884 IC::State new_state = FeedbackToState(vector, slot); |
1883 OnTypeFeedbackChanged(isolate(), address(), old_state, new_state, true); | 1885 OnTypeFeedbackChanged(isolate(), address(), old_state, new_state, true); |
1884 TRACE_VECTOR_IC("CallIC", name, old_state, new_state); | 1886 TRACE_VECTOR_IC("CallIC", name, old_state, new_state); |
1885 } | 1887 } |
1886 | 1888 |
1887 | 1889 |
1888 void CallIC::HandleMiss(Handle<Object> receiver, Handle<Object> function, | 1890 void CallIC::HandleMiss(Handle<Object> receiver, Handle<Object> function, |
1889 Handle<FixedArray> vector, Handle<Smi> slot) { | 1891 Handle<TypeFeedbackVector> vector, Handle<Smi> slot) { |
1890 CallICState state(target()->extra_ic_state()); | 1892 CallICState state(target()->extra_ic_state()); |
1891 IC::State old_state = FeedbackToState(vector, slot); | 1893 IC::State old_state = FeedbackToState(vector, slot); |
1892 Handle<Object> name = isolate()->factory()->empty_string(); | 1894 Handle<Object> name = isolate()->factory()->empty_string(); |
1893 Object* feedback = vector->get(slot->value()); | 1895 Object* feedback = vector->get(slot->value()); |
1894 | 1896 |
1895 // Hand-coded MISS handling is easier if CallIC slots don't contain smis. | 1897 // Hand-coded MISS handling is easier if CallIC slots don't contain smis. |
1896 DCHECK(!feedback->IsSmi()); | 1898 DCHECK(!feedback->IsSmi()); |
1897 | 1899 |
1898 if (feedback->IsJSFunction() || !function->IsJSFunction()) { | 1900 if (feedback->IsJSFunction() || !function->IsJSFunction()) { |
1899 // We are going generic. | 1901 // We are going generic. |
1900 vector->set(slot->value(), | 1902 vector->set(slot->value(), |
1901 *TypeFeedbackInfo::MegamorphicSentinel(isolate()), | 1903 *TypeFeedbackVector::MegamorphicSentinel(isolate()), |
1902 SKIP_WRITE_BARRIER); | 1904 SKIP_WRITE_BARRIER); |
1903 } else { | 1905 } else { |
1904 // The feedback is either uninitialized or an allocation site. | 1906 // The feedback is either uninitialized or an allocation site. |
1905 // It might be an allocation site because if we re-compile the full code | 1907 // It might be an allocation site because if we re-compile the full code |
1906 // to add deoptimization support, we call with the default call-ic, and | 1908 // to add deoptimization support, we call with the default call-ic, and |
1907 // merely need to patch the target to match the feedback. | 1909 // merely need to patch the target to match the feedback. |
1908 // TODO(mvstanton): the better approach is to dispense with patching | 1910 // TODO(mvstanton): the better approach is to dispense with patching |
1909 // altogether, which is in progress. | 1911 // altogether, which is in progress. |
1910 DCHECK(feedback == *TypeFeedbackInfo::UninitializedSentinel(isolate()) || | 1912 DCHECK(feedback == *TypeFeedbackVector::UninitializedSentinel(isolate()) || |
1911 feedback->IsAllocationSite()); | 1913 feedback->IsAllocationSite()); |
1912 | 1914 |
1913 // Do we want to install a custom handler? | 1915 // Do we want to install a custom handler? |
1914 if (FLAG_use_ic && | 1916 if (FLAG_use_ic && |
1915 DoCustomHandler(receiver, function, vector, slot, state)) { | 1917 DoCustomHandler(receiver, function, vector, slot, state)) { |
1916 return; | 1918 return; |
1917 } | 1919 } |
1918 | 1920 |
1919 vector->set(slot->value(), *function); | 1921 vector->set(slot->value(), *function); |
1920 } | 1922 } |
(...skipping 17 matching lines...) Expand all Loading... |
1938 // | 1940 // |
1939 | 1941 |
1940 // Used from ic-<arch>.cc. | 1942 // Used from ic-<arch>.cc. |
1941 RUNTIME_FUNCTION(CallIC_Miss) { | 1943 RUNTIME_FUNCTION(CallIC_Miss) { |
1942 TimerEventScope<TimerEventIcMiss> timer(isolate); | 1944 TimerEventScope<TimerEventIcMiss> timer(isolate); |
1943 HandleScope scope(isolate); | 1945 HandleScope scope(isolate); |
1944 DCHECK(args.length() == 4); | 1946 DCHECK(args.length() == 4); |
1945 CallIC ic(isolate); | 1947 CallIC ic(isolate); |
1946 Handle<Object> receiver = args.at<Object>(0); | 1948 Handle<Object> receiver = args.at<Object>(0); |
1947 Handle<Object> function = args.at<Object>(1); | 1949 Handle<Object> function = args.at<Object>(1); |
1948 Handle<FixedArray> vector = args.at<FixedArray>(2); | 1950 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(2); |
1949 Handle<Smi> slot = args.at<Smi>(3); | 1951 Handle<Smi> slot = args.at<Smi>(3); |
1950 ic.HandleMiss(receiver, function, vector, slot); | 1952 ic.HandleMiss(receiver, function, vector, slot); |
1951 return *function; | 1953 return *function; |
1952 } | 1954 } |
1953 | 1955 |
1954 | 1956 |
1955 RUNTIME_FUNCTION(CallIC_Customization_Miss) { | 1957 RUNTIME_FUNCTION(CallIC_Customization_Miss) { |
1956 TimerEventScope<TimerEventIcMiss> timer(isolate); | 1958 TimerEventScope<TimerEventIcMiss> timer(isolate); |
1957 HandleScope scope(isolate); | 1959 HandleScope scope(isolate); |
1958 DCHECK(args.length() == 4); | 1960 DCHECK(args.length() == 4); |
1959 // A miss on a custom call ic always results in going megamorphic. | 1961 // A miss on a custom call ic always results in going megamorphic. |
1960 CallIC ic(isolate); | 1962 CallIC ic(isolate); |
1961 Handle<Object> function = args.at<Object>(1); | 1963 Handle<Object> function = args.at<Object>(1); |
1962 Handle<FixedArray> vector = args.at<FixedArray>(2); | 1964 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(2); |
1963 Handle<Smi> slot = args.at<Smi>(3); | 1965 Handle<Smi> slot = args.at<Smi>(3); |
1964 ic.PatchMegamorphic(function, vector, slot); | 1966 ic.PatchMegamorphic(function, vector, slot); |
1965 return *function; | 1967 return *function; |
1966 } | 1968 } |
1967 | 1969 |
1968 | 1970 |
1969 // Used from ic-<arch>.cc. | 1971 // Used from ic-<arch>.cc. |
1970 RUNTIME_FUNCTION(LoadIC_Miss) { | 1972 RUNTIME_FUNCTION(LoadIC_Miss) { |
1971 TimerEventScope<TimerEventIcMiss> timer(isolate); | 1973 TimerEventScope<TimerEventIcMiss> timer(isolate); |
1972 HandleScope scope(isolate); | 1974 HandleScope scope(isolate); |
(...skipping 642 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2615 static const Address IC_utilities[] = { | 2617 static const Address IC_utilities[] = { |
2616 #define ADDR(name) FUNCTION_ADDR(name), | 2618 #define ADDR(name) FUNCTION_ADDR(name), |
2617 IC_UTIL_LIST(ADDR) NULL | 2619 IC_UTIL_LIST(ADDR) NULL |
2618 #undef ADDR | 2620 #undef ADDR |
2619 }; | 2621 }; |
2620 | 2622 |
2621 | 2623 |
2622 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; } | 2624 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; } |
2623 } | 2625 } |
2624 } // namespace v8::internal | 2626 } // namespace v8::internal |
OLD | NEW |