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 "v8.h" | 5 #include "v8.h" |
6 | 6 |
7 #include "accessors.h" | 7 #include "accessors.h" |
8 #include "api.h" | 8 #include "api.h" |
9 #include "arguments.h" | 9 #include "arguments.h" |
10 #include "codegen.h" | 10 #include "codegen.h" |
(...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
494 // through the embedded maps. | 494 // through the embedded maps. |
495 SetTargetAtAddress(address, *pre_monomorphic_stub(isolate), constant_pool); | 495 SetTargetAtAddress(address, *pre_monomorphic_stub(isolate), constant_pool); |
496 } | 496 } |
497 | 497 |
498 | 498 |
499 void CallIC::Clear(Isolate* isolate, | 499 void CallIC::Clear(Isolate* isolate, |
500 Address address, | 500 Address address, |
501 Code* target, | 501 Code* target, |
502 ConstantPoolArray* constant_pool) { | 502 ConstantPoolArray* constant_pool) { |
503 // Currently, CallIC doesn't have state changes. | 503 // Currently, CallIC doesn't have state changes. |
504 if (target->ic_state() != v8::internal::MONOMORPHIC) return; | |
505 CallIC::State existing_state(target->extra_ic_state()); | |
506 | |
507 // Monomorphic array stubs don't need to be cleared because | |
508 // 1) the stub doesn't store information that should be cleared, and | |
509 // 2) the AllocationSite stored in the type feedback vector is immune | |
510 // from gc type feedback clearing. | |
511 ASSERT(existing_state.stub_type() == MONOMORPHIC_ARRAY); | |
512 } | 504 } |
513 | 505 |
514 | 506 |
515 void LoadIC::Clear(Isolate* isolate, | 507 void LoadIC::Clear(Isolate* isolate, |
516 Address address, | 508 Address address, |
517 Code* target, | 509 Code* target, |
518 ConstantPoolArray* constant_pool) { | 510 ConstantPoolArray* constant_pool) { |
519 if (IsCleared(target)) return; | 511 if (IsCleared(target)) return; |
520 Code* code = target->GetIsolate()->stub_cache()->FindPreMonomorphicIC( | 512 Code* code = target->GetIsolate()->stub_cache()->FindPreMonomorphicIC( |
521 Code::LOAD_IC, target->extra_ic_state()); | 513 Code::LOAD_IC, target->extra_ic_state()); |
(...skipping 822 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1344 stream->Add("(args(%d), ", | 1336 stream->Add("(args(%d), ", |
1345 argc_); | 1337 argc_); |
1346 stream->Add("%s, ", | 1338 stream->Add("%s, ", |
1347 call_type_ == CallIC::METHOD ? "METHOD" : "FUNCTION"); | 1339 call_type_ == CallIC::METHOD ? "METHOD" : "FUNCTION"); |
1348 } | 1340 } |
1349 | 1341 |
1350 | 1342 |
1351 Handle<Code> CallIC::initialize_stub(Isolate* isolate, | 1343 Handle<Code> CallIC::initialize_stub(Isolate* isolate, |
1352 int argc, | 1344 int argc, |
1353 CallType call_type) { | 1345 CallType call_type) { |
1354 CallICStub stub(isolate, State::DefaultCallState(argc, call_type)); | 1346 CallICStub stub(isolate, State(argc, call_type)); |
1355 Handle<Code> code = stub.GetCode(); | 1347 Handle<Code> code = stub.GetCode(); |
1356 return code; | 1348 return code; |
1357 } | 1349 } |
1358 | 1350 |
1359 | 1351 |
1360 Handle<Code> StoreIC::initialize_stub(Isolate* isolate, | 1352 Handle<Code> StoreIC::initialize_stub(Isolate* isolate, |
1361 StrictMode strict_mode) { | 1353 StrictMode strict_mode) { |
1362 ExtraICState extra_state = ComputeExtraICState(strict_mode); | 1354 ExtraICState extra_state = ComputeExtraICState(strict_mode); |
1363 Handle<Code> ic = isolate->stub_cache()->ComputeStore( | 1355 Handle<Code> ic = isolate->stub_cache()->ComputeStore( |
1364 UNINITIALIZED, extra_state); | 1356 UNINITIALIZED, extra_state); |
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1818 set_target(*stub); | 1810 set_target(*stub); |
1819 TRACE_IC("StoreIC", key); | 1811 TRACE_IC("StoreIC", key); |
1820 } | 1812 } |
1821 | 1813 |
1822 return store_handle; | 1814 return store_handle; |
1823 } | 1815 } |
1824 | 1816 |
1825 | 1817 |
1826 CallIC::State::State(ExtraICState extra_ic_state) | 1818 CallIC::State::State(ExtraICState extra_ic_state) |
1827 : argc_(ArgcBits::decode(extra_ic_state)), | 1819 : argc_(ArgcBits::decode(extra_ic_state)), |
1828 call_type_(CallTypeBits::decode(extra_ic_state)), | 1820 call_type_(CallTypeBits::decode(extra_ic_state)) { |
1829 stub_type_(StubTypeBits::decode(extra_ic_state)) { | |
1830 } | 1821 } |
1831 | 1822 |
1832 | 1823 |
1833 ExtraICState CallIC::State::GetExtraICState() const { | 1824 ExtraICState CallIC::State::GetExtraICState() const { |
1834 ExtraICState extra_ic_state = | 1825 ExtraICState extra_ic_state = |
1835 ArgcBits::encode(argc_) | | 1826 ArgcBits::encode(argc_) | |
1836 CallTypeBits::encode(call_type_) | | 1827 CallTypeBits::encode(call_type_); |
1837 StubTypeBits::encode(stub_type_); | |
1838 return extra_ic_state; | 1828 return extra_ic_state; |
1839 } | 1829 } |
1840 | 1830 |
1841 | 1831 |
1842 bool CallIC::DoCustomHandler(Handle<Object> receiver, | 1832 bool CallIC::DoCustomHandler(Handle<Object> receiver, |
1843 Handle<Object> function, | 1833 Handle<Object> function, |
1844 Handle<FixedArray> vector, | 1834 Handle<FixedArray> vector, |
1845 Handle<Smi> slot, | 1835 Handle<Smi> slot, |
1846 const State& state) { | 1836 const State& state) { |
1847 ASSERT(FLAG_use_ic && function->IsJSFunction()); | 1837 ASSERT(FLAG_use_ic && function->IsJSFunction()); |
1848 | 1838 |
1849 // Are we the array function? | 1839 // Are we the array function? |
1850 Handle<JSFunction> array_function = Handle<JSFunction>( | 1840 Handle<JSFunction> array_function = Handle<JSFunction>( |
1851 isolate()->context()->native_context()->array_function(), isolate()); | 1841 isolate()->context()->native_context()->array_function(), isolate()); |
1852 if (array_function.is_identical_to(Handle<JSFunction>::cast(function))) { | 1842 if (array_function.is_identical_to(Handle<JSFunction>::cast(function))) { |
1853 // Alter the slot. | 1843 // Alter the slot. |
1854 Handle<AllocationSite> new_site = isolate()->factory()->NewAllocationSite(); | 1844 Handle<AllocationSite> new_site = isolate()->factory()->NewAllocationSite(); |
1855 vector->set(slot->value(), *new_site); | 1845 vector->set(slot->value(), *new_site); |
1856 State new_state = state.ToMonomorphicArrayCallState(); | 1846 CallIC_ArrayStub stub(isolate(), state); |
1857 CallICStub stub(isolate(), new_state); | |
1858 set_target(*stub.GetCode()); | 1847 set_target(*stub.GetCode()); |
1859 Handle<String> name; | 1848 Handle<String> name; |
1860 if (array_function->shared()->name()->IsString()) { | 1849 if (array_function->shared()->name()->IsString()) { |
1861 name = Handle<String>(String::cast(array_function->shared()->name()), | 1850 name = Handle<String>(String::cast(array_function->shared()->name()), |
1862 isolate()); | 1851 isolate()); |
1863 } | 1852 } |
1864 | 1853 |
1865 TRACE_IC("CallIC (Array call)", name); | 1854 TRACE_IC("CallIC (Array call)", name); |
1866 return true; | 1855 return true; |
1867 } | 1856 } |
1868 return false; | 1857 return false; |
1869 } | 1858 } |
1870 | 1859 |
1871 | 1860 |
| 1861 void CallIC::PatchMegamorphic(Handle<FixedArray> vector, |
| 1862 Handle<Smi> slot) { |
| 1863 State state(target()->extra_ic_state()); |
| 1864 |
| 1865 // We are going generic. |
| 1866 vector->set(slot->value(), |
| 1867 *TypeFeedbackInfo::MegamorphicSentinel(isolate()), |
| 1868 SKIP_WRITE_BARRIER); |
| 1869 |
| 1870 CallICStub stub(isolate(), state); |
| 1871 Handle<Code> code = stub.GetCode(); |
| 1872 set_target(*code); |
| 1873 |
| 1874 TRACE_GENERIC_IC(isolate(), "CallIC", "megamorphic"); |
| 1875 } |
| 1876 |
| 1877 |
1872 void CallIC::HandleMiss(Handle<Object> receiver, | 1878 void CallIC::HandleMiss(Handle<Object> receiver, |
1873 Handle<Object> function, | 1879 Handle<Object> function, |
1874 Handle<FixedArray> vector, | 1880 Handle<FixedArray> vector, |
1875 Handle<Smi> slot) { | 1881 Handle<Smi> slot) { |
1876 State state(target()->extra_ic_state()); | 1882 State state(target()->extra_ic_state()); |
1877 Object* feedback = vector->get(slot->value()); | 1883 Object* feedback = vector->get(slot->value()); |
1878 | 1884 |
1879 if (feedback->IsJSFunction() || !function->IsJSFunction() || | 1885 if (feedback->IsJSFunction() || !function->IsJSFunction()) { |
1880 state.stub_type() != DEFAULT) { | |
1881 // We are going generic. | 1886 // We are going generic. |
1882 vector->set(slot->value(), | 1887 vector->set(slot->value(), |
1883 *TypeFeedbackInfo::MegamorphicSentinel(isolate()), | 1888 *TypeFeedbackInfo::MegamorphicSentinel(isolate()), |
1884 SKIP_WRITE_BARRIER); | 1889 SKIP_WRITE_BARRIER); |
1885 | 1890 |
1886 State new_state = state.ToGenericState(); | |
1887 if (new_state != state) { | |
1888 // Only happens when the array ic goes generic. | |
1889 ASSERT(state.stub_type() == MONOMORPHIC_ARRAY && | |
1890 FLAG_use_ic); | |
1891 CallICStub stub(isolate(), new_state); | |
1892 Handle<Code> code = stub.GetCode(); | |
1893 set_target(*code); | |
1894 } | |
1895 | |
1896 TRACE_GENERIC_IC(isolate(), "CallIC", "megamorphic"); | 1891 TRACE_GENERIC_IC(isolate(), "CallIC", "megamorphic"); |
1897 } else { | 1892 } else { |
1898 // If we came here feedback must be the uninitialized sentinel, | 1893 // If we came here feedback must be the uninitialized sentinel, |
1899 // and we are going monomorphic. | 1894 // and we are going monomorphic. |
1900 ASSERT(feedback == *TypeFeedbackInfo::UninitializedSentinel(isolate())); | 1895 ASSERT(feedback == *TypeFeedbackInfo::UninitializedSentinel(isolate())); |
1901 | 1896 |
1902 // Do we want to install a custom handler? | 1897 // Do we want to install a custom handler? |
1903 if (FLAG_use_ic && | 1898 if (FLAG_use_ic && |
1904 DoCustomHandler(receiver, function, vector, slot, state)) { | 1899 DoCustomHandler(receiver, function, vector, slot, state)) { |
1905 return; | 1900 return; |
(...skipping 21 matching lines...) Expand all Loading... |
1927 CallIC ic(isolate); | 1922 CallIC ic(isolate); |
1928 Handle<Object> receiver = args.at<Object>(0); | 1923 Handle<Object> receiver = args.at<Object>(0); |
1929 Handle<Object> function = args.at<Object>(1); | 1924 Handle<Object> function = args.at<Object>(1); |
1930 Handle<FixedArray> vector = args.at<FixedArray>(2); | 1925 Handle<FixedArray> vector = args.at<FixedArray>(2); |
1931 Handle<Smi> slot = args.at<Smi>(3); | 1926 Handle<Smi> slot = args.at<Smi>(3); |
1932 ic.HandleMiss(receiver, function, vector, slot); | 1927 ic.HandleMiss(receiver, function, vector, slot); |
1933 return *function; | 1928 return *function; |
1934 } | 1929 } |
1935 | 1930 |
1936 | 1931 |
| 1932 RUNTIME_FUNCTION(CallIC_Customization_Miss) { |
| 1933 HandleScope scope(isolate); |
| 1934 ASSERT(args.length() == 4); |
| 1935 // A miss on a custom call ic always results in going megamorphic. |
| 1936 CallIC ic(isolate); |
| 1937 Handle<Object> function = args.at<Object>(1); |
| 1938 Handle<FixedArray> vector = args.at<FixedArray>(2); |
| 1939 Handle<Smi> slot = args.at<Smi>(3); |
| 1940 ic.PatchMegamorphic(vector, slot); |
| 1941 return *function; |
| 1942 } |
| 1943 |
| 1944 |
1937 // Used from ic-<arch>.cc. | 1945 // Used from ic-<arch>.cc. |
1938 RUNTIME_FUNCTION(LoadIC_Miss) { | 1946 RUNTIME_FUNCTION(LoadIC_Miss) { |
1939 HandleScope scope(isolate); | 1947 HandleScope scope(isolate); |
1940 ASSERT(args.length() == 2); | 1948 ASSERT(args.length() == 2); |
1941 LoadIC ic(IC::NO_EXTRA_FRAME, isolate); | 1949 LoadIC ic(IC::NO_EXTRA_FRAME, isolate); |
1942 Handle<Object> receiver = args.at<Object>(0); | 1950 Handle<Object> receiver = args.at<Object>(0); |
1943 Handle<String> key = args.at<String>(1); | 1951 Handle<String> key = args.at<String>(1); |
1944 ic.UpdateState(receiver, key); | 1952 ic.UpdateState(receiver, key); |
1945 Handle<Object> result; | 1953 Handle<Object> result; |
1946 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); | 1954 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); |
(...skipping 1095 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3042 #undef ADDR | 3050 #undef ADDR |
3043 }; | 3051 }; |
3044 | 3052 |
3045 | 3053 |
3046 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 3054 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
3047 return IC_utilities[id]; | 3055 return IC_utilities[id]; |
3048 } | 3056 } |
3049 | 3057 |
3050 | 3058 |
3051 } } // namespace v8::internal | 3059 } } // namespace v8::internal |
OLD | NEW |