| 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 |