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

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

Issue 1308073010: Reorder KeyedStoreIC MISS code to avoid unnecessary compilation. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Code comments. Created 5 years, 3 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/ic/ic.h" 5 #include "src/ic/ic.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 1833 matching lines...) Expand 10 before | Expand all | Expand 10 after
1844 case LookupIterator::INTEGER_INDEXED_EXOTIC: 1844 case LookupIterator::INTEGER_INDEXED_EXOTIC:
1845 case LookupIterator::ACCESS_CHECK: 1845 case LookupIterator::ACCESS_CHECK:
1846 case LookupIterator::JSPROXY: 1846 case LookupIterator::JSPROXY:
1847 case LookupIterator::NOT_FOUND: 1847 case LookupIterator::NOT_FOUND:
1848 UNREACHABLE(); 1848 UNREACHABLE();
1849 } 1849 }
1850 return slow_stub(); 1850 return slow_stub();
1851 } 1851 }
1852 1852
1853 1853
1854 Handle<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver, 1854 Handle<Code> KeyedStoreIC::StoreElementStub(Handle<Map> receiver_map,
1855 KeyedAccessStoreMode store_mode) { 1855 KeyedAccessStoreMode store_mode) {
1856 // Don't handle megamorphic property accesses for INTERCEPTORS or 1856 // Don't handle megamorphic property accesses for INTERCEPTORS or
1857 // ACCESSOR_CONSTANT 1857 // ACCESSOR_CONSTANT
1858 // via megamorphic stubs, since they don't have a map in their relocation info 1858 // via megamorphic stubs, since they don't have a map in their relocation info
1859 // and so the stubs can't be harvested for the object needed for a map check. 1859 // and so the stubs can't be harvested for the object needed for a map check.
1860 if (target()->type() != Code::NORMAL) { 1860 if (target()->type() != Code::NORMAL) {
1861 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "non-NORMAL target type"); 1861 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "non-NORMAL target type");
1862 return megamorphic_stub(); 1862 return megamorphic_stub();
1863 } 1863 }
1864 1864
1865 Handle<Map> receiver_map(receiver->map(), isolate());
1866 MapHandleList target_receiver_maps; 1865 MapHandleList target_receiver_maps;
1867 TargetMaps(&target_receiver_maps); 1866 TargetMaps(&target_receiver_maps);
1868 if (target_receiver_maps.length() == 0) { 1867 if (target_receiver_maps.length() == 0) {
1869 Handle<Map> monomorphic_map = 1868 Handle<Map> monomorphic_map =
1870 ComputeTransitionedMap(receiver_map, store_mode); 1869 ComputeTransitionedMap(receiver_map, store_mode);
1871 store_mode = GetNonTransitioningStoreMode(store_mode); 1870 store_mode = GetNonTransitioningStoreMode(store_mode);
1872 return PropertyICCompiler::ComputeKeyedStoreMonomorphic( 1871 return PropertyICCompiler::ComputeKeyedStoreMonomorphic(
1873 monomorphic_map, language_mode(), store_mode); 1872 monomorphic_map, language_mode(), store_mode);
1874 } 1873 }
1875 1874
(...skipping 13 matching lines...) Expand all
1889 if ((receiver_map.is_identical_to(previous_receiver_map) && 1888 if ((receiver_map.is_identical_to(previous_receiver_map) &&
1890 IsTransitionStoreMode(store_mode)) || 1889 IsTransitionStoreMode(store_mode)) ||
1891 IsTransitionOfMonomorphicTarget(*previous_receiver_map, 1890 IsTransitionOfMonomorphicTarget(*previous_receiver_map,
1892 *transitioned_receiver_map)) { 1891 *transitioned_receiver_map)) {
1893 // If the "old" and "new" maps are in the same elements map family, or 1892 // If the "old" and "new" maps are in the same elements map family, or
1894 // if they at least come from the same origin for a transitioning store, 1893 // if they at least come from the same origin for a transitioning store,
1895 // stay MONOMORPHIC and use the map for the most generic ElementsKind. 1894 // stay MONOMORPHIC and use the map for the most generic ElementsKind.
1896 store_mode = GetNonTransitioningStoreMode(store_mode); 1895 store_mode = GetNonTransitioningStoreMode(store_mode);
1897 return PropertyICCompiler::ComputeKeyedStoreMonomorphic( 1896 return PropertyICCompiler::ComputeKeyedStoreMonomorphic(
1898 transitioned_receiver_map, language_mode(), store_mode); 1897 transitioned_receiver_map, language_mode(), store_mode);
1899 } else if (*previous_receiver_map == receiver->map() && 1898 } else if (receiver_map.is_identical_to(previous_receiver_map) &&
1900 old_store_mode == STANDARD_STORE && 1899 old_store_mode == STANDARD_STORE &&
1901 (store_mode == STORE_AND_GROW_NO_TRANSITION || 1900 (store_mode == STORE_AND_GROW_NO_TRANSITION ||
1902 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || 1901 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS ||
1903 store_mode == STORE_NO_TRANSITION_HANDLE_COW)) { 1902 store_mode == STORE_NO_TRANSITION_HANDLE_COW)) {
1904 // A "normal" IC that handles stores can switch to a version that can 1903 // A "normal" IC that handles stores can switch to a version that can
1905 // grow at the end of the array, handle OOB accesses or copy COW arrays 1904 // grow at the end of the array, handle OOB accesses or copy COW arrays
1906 // and still stay MONOMORPHIC. 1905 // and still stay MONOMORPHIC.
1907 return PropertyICCompiler::ComputeKeyedStoreMonomorphic( 1906 return PropertyICCompiler::ComputeKeyedStoreMonomorphic(
1908 receiver_map, language_mode(), store_mode); 1907 receiver_map, language_mode(), store_mode);
1909 } 1908 }
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
2153 // Don't use ICs for maps of the objects in Array's prototype chain. We 2152 // Don't use ICs for maps of the objects in Array's prototype chain. We
2154 // expect to be able to trap element sets to objects with those maps in 2153 // expect to be able to trap element sets to objects with those maps in
2155 // the runtime to enable optimization of element hole access. 2154 // the runtime to enable optimization of element hole access.
2156 Handle<HeapObject> heap_object = Handle<HeapObject>::cast(object); 2155 Handle<HeapObject> heap_object = Handle<HeapObject>::cast(object);
2157 if (heap_object->map()->IsMapInArrayPrototypeChain()) { 2156 if (heap_object->map()->IsMapInArrayPrototypeChain()) {
2158 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "map in array prototype"); 2157 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "map in array prototype");
2159 use_ic = false; 2158 use_ic = false;
2160 } 2159 }
2161 } 2160 }
2162 2161
2162 Handle<Map> old_receiver_map;
2163 bool sloppy_arguments_elements = false;
2164 bool key_is_valid_index = false;
2165 KeyedAccessStoreMode store_mode = STANDARD_STORE;
2166 if (use_ic && object->IsJSObject()) {
2167 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
2168 old_receiver_map = handle(receiver->map(), isolate());
2169 sloppy_arguments_elements =
2170 !is_sloppy(language_mode()) &&
2171 receiver->elements()->map() ==
2172 isolate()->heap()->sloppy_arguments_elements_map();
2173 if (!sloppy_arguments_elements) {
2174 key_is_valid_index = key->IsSmi() && Smi::cast(*key)->value() >= 0;
2175 if (key_is_valid_index) {
2176 uint32_t index = static_cast<uint32_t>(Smi::cast(*key)->value());
2177 store_mode = GetStoreMode(receiver, index, value);
2178 }
2179 }
2180 }
2181
2182 DCHECK(store_handle.is_null());
2183 ASSIGN_RETURN_ON_EXCEPTION(isolate(), store_handle,
2184 Runtime::SetObjectProperty(isolate(), object, key,
2185 value, language_mode()),
2186 Object);
2187
2163 if (use_ic) { 2188 if (use_ic) {
2164 if (object->IsJSObject()) { 2189 if (!old_receiver_map.is_null()) {
2165 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 2190 if (sloppy_arguments_elements) {
2166 if (receiver->elements()->map() ==
2167 isolate()->heap()->sloppy_arguments_elements_map() &&
2168 !is_sloppy(language_mode())) {
2169 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "arguments receiver"); 2191 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "arguments receiver");
2170 } else if (key->IsSmi() && Smi::cast(*key)->value() >= 0) { 2192 } else if (key_is_valid_index) {
2171 uint32_t index = static_cast<uint32_t>(Smi::cast(*key)->value());
2172 // We should go generic if receiver isn't a dictionary, but our 2193 // We should go generic if receiver isn't a dictionary, but our
2173 // prototype chain does have dictionary elements. This ensures that 2194 // prototype chain does have dictionary elements. This ensures that
2174 // other non-dictionary receivers in the polymorphic case benefit 2195 // other non-dictionary receivers in the polymorphic case benefit
2175 // from fast path keyed stores. 2196 // from fast path keyed stores.
2176 if (!receiver->map()->DictionaryElementsInPrototypeChainOnly()) { 2197 if (!old_receiver_map->DictionaryElementsInPrototypeChainOnly()) {
2177 KeyedAccessStoreMode store_mode = 2198 stub = StoreElementStub(old_receiver_map, store_mode);
2178 GetStoreMode(receiver, index, value);
2179 stub = StoreElementStub(receiver, store_mode);
2180 2199
2181 // Validate that the store_mode in the stub can also be derived 2200 // Validate that the store_mode in the stub can also be derived
2182 // from peeking in the code bits of the handlers. 2201 // from peeking in the code bits of the handlers.
2183 ValidateStoreMode(stub); 2202 ValidateStoreMode(stub);
2184 } else { 2203 } else {
2185 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "dictionary prototype"); 2204 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "dictionary prototype");
2186 } 2205 }
2187 } else { 2206 } else {
2188 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "non-smi-like key"); 2207 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "non-smi-like key");
2189 } 2208 }
2190 } else { 2209 } else {
2191 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "non-JSObject receiver"); 2210 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "non-JSObject receiver");
2192 } 2211 }
2193 } 2212 }
2194 2213
2195 if (store_handle.is_null()) {
2196 ASSIGN_RETURN_ON_EXCEPTION(
2197 isolate(), store_handle,
2198 Runtime::SetObjectProperty(isolate(), object, key, value,
2199 language_mode()),
2200 Object);
2201 }
2202
2203 if (FLAG_vector_stores) { 2214 if (FLAG_vector_stores) {
2204 if (!is_vector_set() || stub.is_null()) { 2215 if (!is_vector_set() || stub.is_null()) {
2205 Code* megamorphic = *megamorphic_stub(); 2216 Code* megamorphic = *megamorphic_stub();
2206 if (!stub.is_null() && (*stub == megamorphic || *stub == *slow_stub())) { 2217 if (!stub.is_null() && (*stub == megamorphic || *stub == *slow_stub())) {
2207 ConfigureVectorState(MEGAMORPHIC); 2218 ConfigureVectorState(MEGAMORPHIC);
2208 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", 2219 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC",
2209 *stub == megamorphic ? "set generic" : "slow stub"); 2220 *stub == megamorphic ? "set generic" : "slow stub");
2210 } 2221 }
2211 } 2222 }
2212 } else { 2223 } else {
(...skipping 907 matching lines...) Expand 10 before | Expand all | Expand 10 after
3120 KeyedLoadICNexus nexus(vector, vector_slot); 3131 KeyedLoadICNexus nexus(vector, vector_slot);
3121 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); 3132 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus);
3122 ic.UpdateState(receiver, key); 3133 ic.UpdateState(receiver, key);
3123 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); 3134 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
3124 } 3135 }
3125 3136
3126 return *result; 3137 return *result;
3127 } 3138 }
3128 } // namespace internal 3139 } // namespace internal
3129 } // namespace v8 3140 } // namespace v8
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