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 "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 2041 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2052 Heap* heap = receiver->GetHeap(); | 2052 Heap* heap = receiver->GetHeap(); |
2053 if (receiver->elements()->map() == heap->fixed_cow_array_map()) { | 2053 if (receiver->elements()->map() == heap->fixed_cow_array_map()) { |
2054 return STORE_NO_TRANSITION_HANDLE_COW; | 2054 return STORE_NO_TRANSITION_HANDLE_COW; |
2055 } else { | 2055 } else { |
2056 return STANDARD_STORE; | 2056 return STANDARD_STORE; |
2057 } | 2057 } |
2058 } | 2058 } |
2059 } | 2059 } |
2060 | 2060 |
2061 | 2061 |
| 2062 void KeyedStoreIC::ValidateStoreMode(Handle<Code> stub) { |
| 2063 #ifdef DEBUG |
| 2064 DCHECK(!FLAG_vector_stores); |
| 2065 if (stub.is_null() || *stub == *megamorphic_stub() || *stub == *slow_stub()) { |
| 2066 return; |
| 2067 } |
| 2068 |
| 2069 // Query the keyed store mode. |
| 2070 ExtraICState state = stub->extra_ic_state(); |
| 2071 KeyedAccessStoreMode stub_mode = GetKeyedAccessStoreMode(state); |
| 2072 |
| 2073 MapHandleList map_list; |
| 2074 stub->FindAllMaps(&map_list); |
| 2075 CodeHandleList list; |
| 2076 stub->FindHandlers(&list, map_list.length()); |
| 2077 for (int i = 0; i < list.length(); i++) { |
| 2078 Handle<Code> handler = list.at(i); |
| 2079 CHECK(handler->is_handler()); |
| 2080 CodeStub::Major major_key = CodeStub::MajorKeyFromKey(handler->stub_key()); |
| 2081 uint32_t minor_key = CodeStub::MinorKeyFromKey(handler->stub_key()); |
| 2082 // Ensure that we only see handlers we know have the store mode embedded. |
| 2083 CHECK(major_key == CodeStub::KeyedStoreSloppyArguments || |
| 2084 major_key == CodeStub::StoreFastElement || |
| 2085 major_key == CodeStub::StoreElement || |
| 2086 major_key == CodeStub::ElementsTransitionAndStore || |
| 2087 *handler == *isolate()->builtins()->KeyedStoreIC_Slow()); |
| 2088 // Ensure that the store mode matches that of the IC. |
| 2089 CHECK(major_key == CodeStub::NoCache || |
| 2090 stub_mode == CommonStoreModeBits::decode(minor_key)); |
| 2091 // The one exception is the keyed store slow builtin, which doesn't include |
| 2092 // store mode. |
| 2093 CHECK(major_key != CodeStub::NoCache || |
| 2094 *handler == *isolate()->builtins()->KeyedStoreIC_Slow()); |
| 2095 } |
| 2096 #endif // DEBUG |
| 2097 } |
| 2098 |
| 2099 |
2062 MaybeHandle<Object> KeyedStoreIC::Store(Handle<Object> object, | 2100 MaybeHandle<Object> KeyedStoreIC::Store(Handle<Object> object, |
2063 Handle<Object> key, | 2101 Handle<Object> key, |
2064 Handle<Object> value) { | 2102 Handle<Object> value) { |
2065 // TODO(verwaest): Let SetProperty do the migration, since storing a property | 2103 // TODO(verwaest): Let SetProperty do the migration, since storing a property |
2066 // might deprecate the current map again, if value does not fit. | 2104 // might deprecate the current map again, if value does not fit. |
2067 if (MigrateDeprecated(object)) { | 2105 if (MigrateDeprecated(object)) { |
2068 Handle<Object> result; | 2106 Handle<Object> result; |
2069 ASSIGN_RETURN_ON_EXCEPTION( | 2107 ASSIGN_RETURN_ON_EXCEPTION( |
2070 isolate(), result, Runtime::SetObjectProperty(isolate(), object, key, | 2108 isolate(), result, Runtime::SetObjectProperty(isolate(), object, key, |
2071 value, language_mode()), | 2109 value, language_mode()), |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2132 } else if (key->IsSmi() && Smi::cast(*key)->value() >= 0) { | 2170 } else if (key->IsSmi() && Smi::cast(*key)->value() >= 0) { |
2133 uint32_t index = static_cast<uint32_t>(Smi::cast(*key)->value()); | 2171 uint32_t index = static_cast<uint32_t>(Smi::cast(*key)->value()); |
2134 // We should go generic if receiver isn't a dictionary, but our | 2172 // We should go generic if receiver isn't a dictionary, but our |
2135 // prototype chain does have dictionary elements. This ensures that | 2173 // prototype chain does have dictionary elements. This ensures that |
2136 // other non-dictionary receivers in the polymorphic case benefit | 2174 // other non-dictionary receivers in the polymorphic case benefit |
2137 // from fast path keyed stores. | 2175 // from fast path keyed stores. |
2138 if (!receiver->map()->DictionaryElementsInPrototypeChainOnly()) { | 2176 if (!receiver->map()->DictionaryElementsInPrototypeChainOnly()) { |
2139 KeyedAccessStoreMode store_mode = | 2177 KeyedAccessStoreMode store_mode = |
2140 GetStoreMode(receiver, index, value); | 2178 GetStoreMode(receiver, index, value); |
2141 stub = StoreElementStub(receiver, store_mode); | 2179 stub = StoreElementStub(receiver, store_mode); |
| 2180 |
| 2181 // Validate that the store_mode in the stub can also be derived |
| 2182 // from peeking in the code bits of the handlers. |
| 2183 ValidateStoreMode(stub); |
2142 } else { | 2184 } else { |
2143 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "dictionary prototype"); | 2185 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "dictionary prototype"); |
2144 } | 2186 } |
2145 } else { | 2187 } else { |
2146 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "non-smi-like key"); | 2188 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "non-smi-like key"); |
2147 } | 2189 } |
2148 } else { | 2190 } else { |
2149 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "non-JSObject receiver"); | 2191 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "non-JSObject receiver"); |
2150 } | 2192 } |
2151 } | 2193 } |
(...skipping 905 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3057 KeyedLoadICNexus nexus(vector, vector_slot); | 3099 KeyedLoadICNexus nexus(vector, vector_slot); |
3058 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); | 3100 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); |
3059 ic.UpdateState(receiver, key); | 3101 ic.UpdateState(receiver, key); |
3060 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); | 3102 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); |
3061 } | 3103 } |
3062 | 3104 |
3063 return *result; | 3105 return *result; |
3064 } | 3106 } |
3065 } // namespace internal | 3107 } // namespace internal |
3066 } // namespace v8 | 3108 } // namespace v8 |
OLD | NEW |