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 ASSERT(target->ic_state() == v8::internal::GENERIC); | 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 return; | |
danno
2014/05/22 08:20:43
nit: you don't need the return at the end.
mvstanton
2014/05/22 09:29:47
Done.
| |
505 } | 513 } |
506 | 514 |
507 | 515 |
508 void LoadIC::Clear(Isolate* isolate, | 516 void LoadIC::Clear(Isolate* isolate, |
509 Address address, | 517 Address address, |
510 Code* target, | 518 Code* target, |
511 ConstantPoolArray* constant_pool) { | 519 ConstantPoolArray* constant_pool) { |
512 if (IsCleared(target)) return; | 520 if (IsCleared(target)) return; |
513 Code* code = target->GetIsolate()->stub_cache()->FindPreMonomorphicIC( | 521 Code* code = target->GetIsolate()->stub_cache()->FindPreMonomorphicIC( |
514 Code::LOAD_IC, target->extra_ic_state()); | 522 Code::LOAD_IC, target->extra_ic_state()); |
(...skipping 1295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1810 result, | 1818 result, |
1811 Runtime::SetObjectProperty( | 1819 Runtime::SetObjectProperty( |
1812 isolate(), object, key, value, NONE, strict_mode()), | 1820 isolate(), object, key, value, NONE, strict_mode()), |
1813 Object); | 1821 Object); |
1814 return result; | 1822 return result; |
1815 } | 1823 } |
1816 | 1824 |
1817 | 1825 |
1818 CallIC::State::State(ExtraICState extra_ic_state) | 1826 CallIC::State::State(ExtraICState extra_ic_state) |
1819 : argc_(ArgcBits::decode(extra_ic_state)), | 1827 : argc_(ArgcBits::decode(extra_ic_state)), |
1820 call_type_(CallTypeBits::decode(extra_ic_state)) { | 1828 call_type_(CallTypeBits::decode(extra_ic_state)), |
1829 stub_type_(StubTypeBits::decode(extra_ic_state)) { | |
1821 } | 1830 } |
1822 | 1831 |
1823 | 1832 |
1824 ExtraICState CallIC::State::GetExtraICState() const { | 1833 ExtraICState CallIC::State::GetExtraICState() const { |
1825 ExtraICState extra_ic_state = | 1834 ExtraICState extra_ic_state = |
1826 ArgcBits::encode(argc_) | | 1835 ArgcBits::encode(argc_) | |
1827 CallTypeBits::encode(call_type_); | 1836 CallTypeBits::encode(call_type_) | |
1837 StubTypeBits::encode(stub_type_); | |
1828 return extra_ic_state; | 1838 return extra_ic_state; |
1829 } | 1839 } |
1830 | 1840 |
1831 | 1841 |
1842 bool CallIC::DoCustomHandler(Handle<Object> receiver, | |
1843 Handle<Object> function, | |
1844 Handle<FixedArray> vector, | |
1845 Handle<Smi> slot, | |
1846 const State& state) { | |
1847 ASSERT(function->IsJSFunction()); | |
1848 // Are we the array function? | |
1849 Handle<JSFunction> array_function = Handle<JSFunction>( | |
1850 isolate()->context()->native_context()->array_function(), | |
danno
2014/05/22 08:20:43
nit: strange indentations
mvstanton
2014/05/22 09:29:47
Done.
| |
1851 isolate()); | |
1852 if (array_function.is_identical_to(Handle<JSFunction>::cast(function))) { | |
1853 // Alter the slot. | |
1854 vector->set(slot->value(), *isolate()->factory()->NewAllocationSite()); | |
1855 State new_state = state.ToMonomorphicArrayCallState(); | |
1856 CallICStub stub(isolate(), new_state); | |
1857 set_target(*stub.GetCode()); | |
1858 Handle<String> name; | |
1859 if (array_function->shared()->name()->IsString()) { | |
1860 name = Handle<String>(String::cast(array_function->shared()->name()), | |
1861 isolate()); | |
1862 } | |
1863 | |
1864 TRACE_IC("CallIC (Array call)", name); | |
1865 return true; | |
1866 } | |
1867 return false; | |
1868 } | |
1869 | |
1870 | |
1832 void CallIC::HandleMiss(Handle<Object> receiver, | 1871 void CallIC::HandleMiss(Handle<Object> receiver, |
1833 Handle<Object> function, | 1872 Handle<Object> function, |
1834 Handle<FixedArray> vector, | 1873 Handle<FixedArray> vector, |
1835 Handle<Smi> slot) { | 1874 Handle<Smi> slot) { |
1836 State state(target()->extra_ic_state()); | 1875 State state(target()->extra_ic_state()); |
1837 Object* feedback = vector->get(slot->value()); | 1876 Object* feedback = vector->get(slot->value()); |
1838 | 1877 |
1839 if (feedback->IsJSFunction() || !function->IsJSFunction()) { | 1878 if (feedback->IsJSFunction() || !function->IsJSFunction() || |
1879 state.stub_type() != DEFAULT) { | |
1840 // We are going generic. | 1880 // We are going generic. |
1841 ASSERT(!function->IsJSFunction() || *function != feedback); | |
1842 | |
1843 vector->set(slot->value(), | 1881 vector->set(slot->value(), |
1844 *TypeFeedbackInfo::MegamorphicSentinel(isolate()), | 1882 *TypeFeedbackInfo::MegamorphicSentinel(isolate()), |
1845 SKIP_WRITE_BARRIER); | 1883 SKIP_WRITE_BARRIER); |
1884 | |
1885 State new_state = state.ToGenericState(); | |
1886 if (new_state != state) { | |
1887 // Only happens when the array ic goes generic. | |
1888 ASSERT(state.stub_type() == MONOMORPHIC_ARRAY); | |
1889 CallICStub stub(isolate(), new_state); | |
1890 Handle<Code> code = stub.GetCode(); | |
1891 set_target(*code); | |
1892 } | |
1893 | |
1846 TRACE_GENERIC_IC(isolate(), "CallIC", "megamorphic"); | 1894 TRACE_GENERIC_IC(isolate(), "CallIC", "megamorphic"); |
1847 } else { | 1895 } else { |
1848 // If we came here feedback must be the uninitialized sentinel, | 1896 // If we came here feedback must be the uninitialized sentinel, |
1849 // and we are going monomorphic. | 1897 // and we are going monomorphic. |
1850 ASSERT(feedback == *TypeFeedbackInfo::UninitializedSentinel(isolate())); | 1898 ASSERT(feedback == *TypeFeedbackInfo::UninitializedSentinel(isolate())); |
1899 | |
1900 // Do we want to install a custom handler? | |
1901 if (DoCustomHandler(receiver, function, vector, slot, state)) { | |
1902 return; | |
1903 } | |
1904 | |
1851 Handle<JSFunction> js_function = Handle<JSFunction>::cast(function); | 1905 Handle<JSFunction> js_function = Handle<JSFunction>::cast(function); |
1852 Handle<Object> name(js_function->shared()->name(), isolate()); | 1906 Handle<Object> name(js_function->shared()->name(), isolate()); |
1853 TRACE_IC("CallIC", name); | 1907 TRACE_IC("CallIC", name); |
1854 vector->set(slot->value(), *function); | 1908 vector->set(slot->value(), *function); |
1855 } | 1909 } |
1856 } | 1910 } |
1857 | 1911 |
1858 | 1912 |
1859 #undef TRACE_IC | 1913 #undef TRACE_IC |
1860 | 1914 |
(...skipping 1124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2985 #undef ADDR | 3039 #undef ADDR |
2986 }; | 3040 }; |
2987 | 3041 |
2988 | 3042 |
2989 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 3043 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
2990 return IC_utilities[id]; | 3044 return IC_utilities[id]; |
2991 } | 3045 } |
2992 | 3046 |
2993 | 3047 |
2994 } } // namespace v8::internal | 3048 } } // namespace v8::internal |
OLD | NEW |