OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
241 return; | 241 return; |
242 } | 242 } |
243 | 243 |
244 object = proto; | 244 object = proto; |
245 } | 245 } |
246 } | 246 } |
247 | 247 |
248 | 248 |
249 bool IC::TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver, | 249 bool IC::TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver, |
250 Handle<String> name) { | 250 Handle<String> name) { |
251 if (target()->is_keyed_stub()) { | 251 if (!IsNameCompatibleWithMonomorphicPrototypeFailure(name)) return false; |
252 // Determine whether the failure is due to a name failure. | |
253 if (!name->IsName()) return false; | |
254 Name* stub_name = target()->FindFirstName(); | |
255 if (*name != stub_name) return false; | |
256 } | |
257 | 252 |
258 InlineCacheHolderFlag cache_holder = | 253 InlineCacheHolderFlag cache_holder = |
259 Code::ExtractCacheHolderFromFlags(target()->flags()); | 254 Code::ExtractCacheHolderFromFlags(target()->flags()); |
260 | 255 |
261 switch (cache_holder) { | 256 switch (cache_holder) { |
262 case OWN_MAP: | 257 case OWN_MAP: |
263 // The stub was generated for JSObject but called for non-JSObject. | 258 // The stub was generated for JSObject but called for non-JSObject. |
264 // IC::GetCodeCacheHolder is not applicable. | 259 // IC::GetCodeCacheHolder is not applicable. |
265 if (!receiver->IsJSObject()) return false; | 260 if (!receiver->IsJSObject()) return false; |
266 break; | 261 break; |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
329 Handle<Code> handler = handlers.at(i); | 324 Handle<Code> handler = handlers.at(i); |
330 int index = map->IndexInCodeCache(*name, *handler); | 325 int index = map->IndexInCodeCache(*name, *handler); |
331 if (index >= 0) { | 326 if (index >= 0) { |
332 map->RemoveFromCodeCache(*name, *handler, index); | 327 map->RemoveFromCodeCache(*name, *handler, index); |
333 return; | 328 return; |
334 } | 329 } |
335 } | 330 } |
336 } | 331 } |
337 | 332 |
338 | 333 |
| 334 bool IC::IsNameCompatibleWithMonomorphicPrototypeFailure(Handle<Object> name) { |
| 335 if (target()->is_keyed_stub()) { |
| 336 // Determine whether the failure is due to a name failure. |
| 337 if (!name->IsName()) return false; |
| 338 Name* stub_name = target()->FindFirstName(); |
| 339 if (*name != stub_name) return false; |
| 340 } |
| 341 |
| 342 return true; |
| 343 } |
| 344 |
| 345 |
339 void IC::UpdateState(Handle<Object> receiver, Handle<Object> name) { | 346 void IC::UpdateState(Handle<Object> receiver, Handle<Object> name) { |
340 if (!name->IsString()) return; | 347 if (!name->IsString()) return; |
341 if (state() != MONOMORPHIC) { | 348 if (state() != MONOMORPHIC) { |
342 if (state() == POLYMORPHIC && receiver->IsHeapObject()) { | 349 if (state() == POLYMORPHIC && receiver->IsHeapObject()) { |
343 TryRemoveInvalidHandlers( | 350 TryRemoveInvalidHandlers( |
344 handle(Handle<HeapObject>::cast(receiver)->map()), | 351 handle(Handle<HeapObject>::cast(receiver)->map()), |
345 Handle<String>::cast(name)); | 352 Handle<String>::cast(name)); |
346 } | 353 } |
347 return; | 354 return; |
348 } | 355 } |
349 if (receiver->IsUndefined() || receiver->IsNull()) return; | 356 if (receiver->IsUndefined() || receiver->IsNull()) return; |
350 | 357 |
351 // Remove the target from the code cache if it became invalid | 358 // Remove the target from the code cache if it became invalid |
352 // because of changes in the prototype chain to avoid hitting it | 359 // because of changes in the prototype chain to avoid hitting it |
353 // again. | 360 // again. |
354 if (TryRemoveInvalidPrototypeDependentStub( | 361 if (TryRemoveInvalidPrototypeDependentStub( |
355 receiver, Handle<String>::cast(name))) { | 362 receiver, Handle<String>::cast(name)) && |
356 return MarkMonomorphicPrototypeFailure(); | 363 TryMarkMonomorphicPrototypeFailure(name)) { |
| 364 return; |
357 } | 365 } |
358 | 366 |
359 // The builtins object is special. It only changes when JavaScript | 367 // The builtins object is special. It only changes when JavaScript |
360 // builtins are loaded lazily. It is important to keep inline | 368 // builtins are loaded lazily. It is important to keep inline |
361 // caches for the builtins object monomorphic. Therefore, if we get | 369 // caches for the builtins object monomorphic. Therefore, if we get |
362 // an inline cache miss for the builtins object after lazily loading | 370 // an inline cache miss for the builtins object after lazily loading |
363 // JavaScript builtins, we return uninitialized as the state to | 371 // JavaScript builtins, we return uninitialized as the state to |
364 // force the inline cache back to monomorphic state. | 372 // force the inline cache back to monomorphic state. |
365 if (receiver->IsJSBuiltinsObject()) state_ = UNINITIALIZED; | 373 if (receiver->IsJSBuiltinsObject()) state_ = UNINITIALIZED; |
366 } | 374 } |
(...skipping 810 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1177 ASSERT(!receiver->map()->is_deprecated()); | 1185 ASSERT(!receiver->map()->is_deprecated()); |
1178 if (!value->FitsRepresentation(target_details.representation())) { | 1186 if (!value->FitsRepresentation(target_details.representation())) { |
1179 Handle<Map> target(lookup->GetTransitionTarget()); | 1187 Handle<Map> target(lookup->GetTransitionTarget()); |
1180 Map::GeneralizeRepresentation( | 1188 Map::GeneralizeRepresentation( |
1181 target, target->LastAdded(), | 1189 target, target->LastAdded(), |
1182 value->OptimalRepresentation(), FORCE_FIELD); | 1190 value->OptimalRepresentation(), FORCE_FIELD); |
1183 // Lookup the transition again since the transition tree may have changed | 1191 // Lookup the transition again since the transition tree may have changed |
1184 // entirely by the migration above. | 1192 // entirely by the migration above. |
1185 receiver->map()->LookupTransition(*holder, *name, lookup); | 1193 receiver->map()->LookupTransition(*holder, *name, lookup); |
1186 if (!lookup->IsTransition()) return false; | 1194 if (!lookup->IsTransition()) return false; |
1187 ic->MarkMonomorphicPrototypeFailure(); | 1195 return ic->TryMarkMonomorphicPrototypeFailure(name); |
1188 } | 1196 } |
| 1197 |
1189 return true; | 1198 return true; |
1190 } | 1199 } |
1191 | 1200 |
1192 | 1201 |
1193 MaybeObject* StoreIC::Store(Handle<Object> object, | 1202 MaybeObject* StoreIC::Store(Handle<Object> object, |
1194 Handle<String> name, | 1203 Handle<String> name, |
1195 Handle<Object> value, | 1204 Handle<Object> value, |
1196 JSReceiver::StoreFromKeyed store_mode) { | 1205 JSReceiver::StoreFromKeyed store_mode) { |
1197 if (MigrateDeprecated(object) || object->IsJSProxy()) { | 1206 if (MigrateDeprecated(object) || object->IsJSProxy()) { |
1198 Handle<Object> result = JSReceiver::SetProperty( | 1207 Handle<Object> result = JSReceiver::SetProperty( |
(...skipping 1639 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2838 #undef ADDR | 2847 #undef ADDR |
2839 }; | 2848 }; |
2840 | 2849 |
2841 | 2850 |
2842 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 2851 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
2843 return IC_utilities[id]; | 2852 return IC_utilities[id]; |
2844 } | 2853 } |
2845 | 2854 |
2846 | 2855 |
2847 } } // namespace v8::internal | 2856 } } // namespace v8::internal |
OLD | NEW |