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