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

Side by Side Diff: src/ic/ic.cc

Issue 847963004: Replace generic KeyedStore stub with megamorphic version (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 11 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
« no previous file with comments | « src/ic/ic.h ('k') | no next file » | 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 "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 1601 matching lines...) Expand 10 before | Expand all | Expand 10 after
1612 DCHECK(kind() == Code::KEYED_STORE_IC); 1612 DCHECK(kind() == Code::KEYED_STORE_IC);
1613 if (strict_mode() == STRICT) { 1613 if (strict_mode() == STRICT) {
1614 return isolate()->builtins()->KeyedStoreIC_Megamorphic_Strict(); 1614 return isolate()->builtins()->KeyedStoreIC_Megamorphic_Strict();
1615 } else { 1615 } else {
1616 return isolate()->builtins()->KeyedStoreIC_Megamorphic(); 1616 return isolate()->builtins()->KeyedStoreIC_Megamorphic();
1617 } 1617 }
1618 } 1618 }
1619 } 1619 }
1620 1620
1621 1621
1622 Handle<Code> StoreIC::generic_stub() const {
1623 if (kind() == Code::STORE_IC) {
1624 return PropertyICCompiler::ComputeStore(isolate(), GENERIC,
1625 extra_ic_state());
1626 } else {
1627 DCHECK(kind() == Code::KEYED_STORE_IC);
1628 if (strict_mode() == STRICT) {
1629 return isolate()->builtins()->KeyedStoreIC_Generic_Strict();
1630 } else {
1631 return isolate()->builtins()->KeyedStoreIC_Generic();
1632 }
1633 }
1634 }
1635
1636
1637 Handle<Code> StoreIC::slow_stub() const { 1622 Handle<Code> StoreIC::slow_stub() const {
1638 if (kind() == Code::STORE_IC) { 1623 if (kind() == Code::STORE_IC) {
1639 return isolate()->builtins()->StoreIC_Slow(); 1624 return isolate()->builtins()->StoreIC_Slow();
1640 } else { 1625 } else {
1641 DCHECK(kind() == Code::KEYED_STORE_IC); 1626 DCHECK(kind() == Code::KEYED_STORE_IC);
1642 return isolate()->builtins()->KeyedStoreIC_Slow(); 1627 return isolate()->builtins()->KeyedStoreIC_Slow();
1643 } 1628 }
1644 } 1629 }
1645 1630
1646 1631
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
1794 1779
1795 1780
1796 Handle<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver, 1781 Handle<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver,
1797 KeyedAccessStoreMode store_mode) { 1782 KeyedAccessStoreMode store_mode) {
1798 // Don't handle megamorphic property accesses for INTERCEPTORS or 1783 // Don't handle megamorphic property accesses for INTERCEPTORS or
1799 // ACCESSOR_CONSTANT 1784 // ACCESSOR_CONSTANT
1800 // via megamorphic stubs, since they don't have a map in their relocation info 1785 // via megamorphic stubs, since they don't have a map in their relocation info
1801 // and so the stubs can't be harvested for the object needed for a map check. 1786 // and so the stubs can't be harvested for the object needed for a map check.
1802 if (target()->type() != Code::NORMAL) { 1787 if (target()->type() != Code::NORMAL) {
1803 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "non-NORMAL target type"); 1788 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "non-NORMAL target type");
1804 return generic_stub(); 1789 return megamorphic_stub();
1805 } 1790 }
1806 1791
1807 Handle<Map> receiver_map(receiver->map(), isolate()); 1792 Handle<Map> receiver_map(receiver->map(), isolate());
1808 MapHandleList target_receiver_maps; 1793 MapHandleList target_receiver_maps;
1809 TargetMaps(&target_receiver_maps); 1794 TargetMaps(&target_receiver_maps);
1810 if (target_receiver_maps.length() == 0) { 1795 if (target_receiver_maps.length() == 0) {
1811 Handle<Map> monomorphic_map = 1796 Handle<Map> monomorphic_map =
1812 ComputeTransitionedMap(receiver_map, store_mode); 1797 ComputeTransitionedMap(receiver_map, store_mode);
1813 store_mode = GetNonTransitioningStoreMode(store_mode); 1798 store_mode = GetNonTransitioningStoreMode(store_mode);
1814 return PropertyICCompiler::ComputeKeyedStoreMonomorphic( 1799 return PropertyICCompiler::ComputeKeyedStoreMonomorphic(
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1858 1843
1859 if (IsTransitionStoreMode(store_mode)) { 1844 if (IsTransitionStoreMode(store_mode)) {
1860 Handle<Map> transitioned_receiver_map = 1845 Handle<Map> transitioned_receiver_map =
1861 ComputeTransitionedMap(receiver_map, store_mode); 1846 ComputeTransitionedMap(receiver_map, store_mode);
1862 map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps, 1847 map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps,
1863 transitioned_receiver_map); 1848 transitioned_receiver_map);
1864 } 1849 }
1865 1850
1866 if (!map_added) { 1851 if (!map_added) {
1867 // If the miss wasn't due to an unseen map, a polymorphic stub 1852 // If the miss wasn't due to an unseen map, a polymorphic stub
1868 // won't help. In theory we should use the generic stub, but in 1853 // won't help, use the megamorphic stub which can handle everything.
1869 // practice there are a number of hard-to-avoid reasons why this
1870 // can happen occasionally, and where the additional logic in the
1871 // megamorphic stub is beneficial because it can handle most cases
1872 // without calling into the runtime.
1873 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "same map added twice"); 1854 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "same map added twice");
1874 return megamorphic_stub(); 1855 return megamorphic_stub();
1875 } 1856 }
1876 1857
1877 // If the maximum number of receiver maps has been exceeded, use the 1858 // If the maximum number of receiver maps has been exceeded, use the
1878 // megamorphic version of the IC. 1859 // megamorphic version of the IC.
1879 if (target_receiver_maps.length() > kMaxKeyedPolymorphism) { 1860 if (target_receiver_maps.length() > kMaxKeyedPolymorphism) {
1880 return megamorphic_stub(); 1861 return megamorphic_stub();
1881 } 1862 }
1882 1863
1883 // Make sure all polymorphic handlers have the same store mode, otherwise the 1864 // Make sure all polymorphic handlers have the same store mode, otherwise the
1884 // generic stub must be used. 1865 // megamorphic stub must be used.
1885 store_mode = GetNonTransitioningStoreMode(store_mode); 1866 store_mode = GetNonTransitioningStoreMode(store_mode);
1886 if (old_store_mode != STANDARD_STORE) { 1867 if (old_store_mode != STANDARD_STORE) {
1887 if (store_mode == STANDARD_STORE) { 1868 if (store_mode == STANDARD_STORE) {
1888 store_mode = old_store_mode; 1869 store_mode = old_store_mode;
1889 } else if (store_mode != old_store_mode) { 1870 } else if (store_mode != old_store_mode) {
1890 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "store mode mismatch"); 1871 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "store mode mismatch");
1891 return generic_stub(); 1872 return megamorphic_stub();
1892 } 1873 }
1893 } 1874 }
1894 1875
1895 // If the store mode isn't the standard mode, make sure that all polymorphic 1876 // If the store mode isn't the standard mode, make sure that all polymorphic
1896 // receivers are either external arrays, or all "normal" arrays. Otherwise, 1877 // receivers are either external arrays, or all "normal" arrays. Otherwise,
1897 // use the generic stub. 1878 // use the megamorphic stub.
1898 if (store_mode != STANDARD_STORE) { 1879 if (store_mode != STANDARD_STORE) {
1899 int external_arrays = 0; 1880 int external_arrays = 0;
1900 for (int i = 0; i < target_receiver_maps.length(); ++i) { 1881 for (int i = 0; i < target_receiver_maps.length(); ++i) {
1901 if (target_receiver_maps[i]->has_external_array_elements() || 1882 if (target_receiver_maps[i]->has_external_array_elements() ||
1902 target_receiver_maps[i]->has_fixed_typed_array_elements()) { 1883 target_receiver_maps[i]->has_fixed_typed_array_elements()) {
1903 external_arrays++; 1884 external_arrays++;
1904 } 1885 }
1905 } 1886 }
1906 if (external_arrays != 0 && 1887 if (external_arrays != 0 &&
1907 external_arrays != target_receiver_maps.length()) { 1888 external_arrays != target_receiver_maps.length()) {
1908 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", 1889 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC",
1909 "unsupported combination of external and normal arrays"); 1890 "unsupported combination of external and normal arrays");
1910 return generic_stub(); 1891 return megamorphic_stub();
1911 } 1892 }
1912 } 1893 }
1913 1894
1914 return PropertyICCompiler::ComputeKeyedStorePolymorphic( 1895 return PropertyICCompiler::ComputeKeyedStorePolymorphic(
1915 &target_receiver_maps, store_mode, strict_mode()); 1896 &target_receiver_maps, store_mode, strict_mode());
1916 } 1897 }
1917 1898
1918 1899
1919 Handle<Map> KeyedStoreIC::ComputeTransitionedMap( 1900 Handle<Map> KeyedStoreIC::ComputeTransitionedMap(
1920 Handle<Map> map, KeyedAccessStoreMode store_mode) { 1901 Handle<Map> map, KeyedAccessStoreMode store_mode) {
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
2045 value, strict_mode()), 2026 value, strict_mode()),
2046 Object); 2027 Object);
2047 return result; 2028 return result;
2048 } 2029 }
2049 2030
2050 // Check for non-string values that can be converted into an 2031 // Check for non-string values that can be converted into an
2051 // internalized string directly or is representable as a smi. 2032 // internalized string directly or is representable as a smi.
2052 key = TryConvertKey(key, isolate()); 2033 key = TryConvertKey(key, isolate());
2053 2034
2054 Handle<Object> store_handle; 2035 Handle<Object> store_handle;
2055 Handle<Code> stub = generic_stub(); 2036 Handle<Code> stub = megamorphic_stub();
2056 2037
2057 if (key->IsInternalizedString()) { 2038 if (key->IsInternalizedString()) {
2058 ASSIGN_RETURN_ON_EXCEPTION( 2039 ASSIGN_RETURN_ON_EXCEPTION(
2059 isolate(), store_handle, 2040 isolate(), store_handle,
2060 StoreIC::Store(object, Handle<String>::cast(key), value, 2041 StoreIC::Store(object, Handle<String>::cast(key), value,
2061 JSReceiver::MAY_BE_STORE_FROM_KEYED), 2042 JSReceiver::MAY_BE_STORE_FROM_KEYED),
2062 Object); 2043 Object);
2063 if (!is_target_set()) { 2044 if (!is_target_set()) {
2064 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", 2045 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC",
2065 "unhandled internalized string key"); 2046 "unhandled internalized string key");
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2119 2100
2120 if (store_handle.is_null()) { 2101 if (store_handle.is_null()) {
2121 ASSIGN_RETURN_ON_EXCEPTION( 2102 ASSIGN_RETURN_ON_EXCEPTION(
2122 isolate(), store_handle, 2103 isolate(), store_handle,
2123 Runtime::SetObjectProperty(isolate(), object, key, value, 2104 Runtime::SetObjectProperty(isolate(), object, key, value,
2124 strict_mode()), 2105 strict_mode()),
2125 Object); 2106 Object);
2126 } 2107 }
2127 2108
2128 DCHECK(!is_target_set()); 2109 DCHECK(!is_target_set());
2129 Code* generic = *generic_stub(); 2110 Code* megamorphic = *megamorphic_stub();
2130 if (*stub == generic) { 2111 if (*stub == megamorphic) {
2131 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "set generic"); 2112 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "set generic");
2132 } 2113 }
2133 if (*stub == *slow_stub()) { 2114 if (*stub == *slow_stub()) {
2134 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "slow stub"); 2115 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "slow stub");
2135 } 2116 }
2136 DCHECK(!stub.is_null()); 2117 DCHECK(!stub.is_null());
2137 set_target(*stub); 2118 set_target(*stub);
2138 TRACE_IC("StoreIC", key); 2119 TRACE_IC("StoreIC", key);
2139 2120
2140 return store_handle; 2121 return store_handle;
2141 } 2122 }
2142 2123
2143 2124
2144 // static
2145 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
2146 StrictMode strict_mode) {
2147 PropertyICCompiler::GenerateRuntimeSetProperty(masm, strict_mode);
2148 }
2149
2150
2151 bool CallIC::DoCustomHandler(Handle<Object> receiver, Handle<Object> function, 2125 bool CallIC::DoCustomHandler(Handle<Object> receiver, Handle<Object> function,
2152 const CallICState& callic_state) { 2126 const CallICState& callic_state) {
2153 DCHECK(FLAG_use_ic && function->IsJSFunction()); 2127 DCHECK(FLAG_use_ic && function->IsJSFunction());
2154 2128
2155 // Are we the array function? 2129 // Are we the array function?
2156 Handle<JSFunction> array_function = 2130 Handle<JSFunction> array_function =
2157 Handle<JSFunction>(isolate()->native_context()->array_function()); 2131 Handle<JSFunction>(isolate()->native_context()->array_function());
2158 if (array_function.is_identical_to(Handle<JSFunction>::cast(function))) { 2132 if (array_function.is_identical_to(Handle<JSFunction>::cast(function))) {
2159 // Alter the slot. 2133 // Alter the slot.
2160 CallICNexus* nexus = casted_nexus<CallICNexus>(); 2134 CallICNexus* nexus = casted_nexus<CallICNexus>();
(...skipping 834 matching lines...) Expand 10 before | Expand all | Expand 10 after
2995 static const Address IC_utilities[] = { 2969 static const Address IC_utilities[] = {
2996 #define ADDR(name) FUNCTION_ADDR(name), 2970 #define ADDR(name) FUNCTION_ADDR(name),
2997 IC_UTIL_LIST(ADDR) NULL 2971 IC_UTIL_LIST(ADDR) NULL
2998 #undef ADDR 2972 #undef ADDR
2999 }; 2973 };
3000 2974
3001 2975
3002 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; } 2976 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; }
3003 } 2977 }
3004 } // namespace v8::internal 2978 } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic/ic.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698