Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(46)

Side by Side Diff: src/ic.cc

Issue 295383004: Refactor CallICStub to use a different stub for each customization. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Ports. Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ic.h ('k') | src/mips/code-stubs-mips.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/ic.h ('k') | src/mips/code-stubs-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698