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-arguments-inl.h" | 8 #include "src/api-arguments-inl.h" |
9 #include "src/api.h" | 9 #include "src/api.h" |
10 #include "src/arguments.h" | 10 #include "src/arguments.h" |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
251 case LookupIterator::ACCESSOR: | 251 case LookupIterator::ACCESSOR: |
252 case LookupIterator::INTEGER_INDEXED_EXOTIC: | 252 case LookupIterator::INTEGER_INDEXED_EXOTIC: |
253 case LookupIterator::DATA: | 253 case LookupIterator::DATA: |
254 return; | 254 return; |
255 } | 255 } |
256 } | 256 } |
257 } | 257 } |
258 | 258 |
259 bool IC::ShouldRecomputeHandler(Handle<Object> receiver, Handle<String> name) { | 259 bool IC::ShouldRecomputeHandler(Handle<Object> receiver, Handle<String> name) { |
260 if (!RecomputeHandlerForName(name)) return false; | 260 if (!RecomputeHandlerForName(name)) return false; |
| 261 // This is a contextual access, always just update the handler and stay |
| 262 // monomorphic. |
| 263 if (receiver->IsJSGlobalObject()) return true; |
| 264 |
261 DCHECK(UseVector()); | 265 DCHECK(UseVector()); |
262 maybe_handler_ = nexus()->FindHandlerForMap(receiver_map()); | 266 maybe_handler_ = nexus()->FindHandlerForMap(receiver_map()); |
263 | 267 |
264 // The current map wasn't handled yet. There's no reason to stay monomorphic, | 268 // The current map wasn't handled yet. There's no reason to stay monomorphic, |
265 // *unless* we're moving from a deprecated map to its replacement, or | 269 // *unless* we're moving from a deprecated map to its replacement, or |
266 // to a more general elements kind. | 270 // to a more general elements kind. |
267 // TODO(verwaest): Check if the current map is actually what the old map | 271 // TODO(verwaest): Check if the current map is actually what the old map |
268 // would transition to. | 272 // would transition to. |
269 if (maybe_handler_.is_null()) { | 273 if (maybe_handler_.is_null()) { |
270 if (!receiver_map()->IsJSObjectMap()) return false; | 274 if (!receiver_map()->IsJSObjectMap()) return false; |
271 Map* first_map = FirstTargetMap(); | 275 Map* first_map = FirstTargetMap(); |
272 if (first_map == NULL) return false; | 276 if (first_map == NULL) return false; |
273 Handle<Map> old_map(first_map); | 277 Handle<Map> old_map(first_map); |
274 if (old_map->is_deprecated()) return true; | 278 if (old_map->is_deprecated()) return true; |
275 return IsMoreGeneralElementsKindTransition(old_map->elements_kind(), | 279 return IsMoreGeneralElementsKindTransition(old_map->elements_kind(), |
276 receiver_map()->elements_kind()); | 280 receiver_map()->elements_kind()); |
277 } | 281 } |
278 | 282 |
279 if (receiver->IsJSGlobalObject()) { | |
280 Handle<JSGlobalObject> global = Handle<JSGlobalObject>::cast(receiver); | |
281 LookupIterator it(global, name, LookupIterator::OWN_SKIP_INTERCEPTOR); | |
282 if (it.state() == LookupIterator::ACCESS_CHECK) return false; | |
283 if (!it.IsFound()) return false; | |
284 if (!it.GetHolder<JSReceiver>()->IsJSGlobalObject()) return false; | |
285 return it.property_details().cell_type() == PropertyCellType::kConstant; | |
286 } | |
287 | |
288 return true; | 283 return true; |
289 } | 284 } |
290 | 285 |
291 bool IC::RecomputeHandlerForName(Handle<Object> name) { | 286 bool IC::RecomputeHandlerForName(Handle<Object> name) { |
292 if (is_keyed()) { | 287 if (is_keyed()) { |
293 // Determine whether the failure is due to a name failure. | 288 // Determine whether the failure is due to a name failure. |
294 if (!name->IsName()) return false; | 289 if (!name->IsName()) return false; |
295 DCHECK(UseVector()); | 290 DCHECK(UseVector()); |
296 Name* stub_name = nexus()->FindFirstName(); | 291 Name* stub_name = nexus()->FindFirstName(); |
297 if (*name != stub_name) return false; | 292 if (*name != stub_name) return false; |
(...skipping 2640 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2938 DCHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC, | 2933 DCHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC, |
2939 vector->GetKind(vector_slot)); | 2934 vector->GetKind(vector_slot)); |
2940 KeyedLoadICNexus nexus(vector, vector_slot); | 2935 KeyedLoadICNexus nexus(vector, vector_slot); |
2941 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); | 2936 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); |
2942 ic.UpdateState(receiver, key); | 2937 ic.UpdateState(receiver, key); |
2943 RETURN_RESULT_OR_FAILURE(isolate, ic.Load(receiver, key)); | 2938 RETURN_RESULT_OR_FAILURE(isolate, ic.Load(receiver, key)); |
2944 } | 2939 } |
2945 } | 2940 } |
2946 } // namespace internal | 2941 } // namespace internal |
2947 } // namespace v8 | 2942 } // namespace v8 |
OLD | NEW |