Chromium Code Reviews| 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 ASSERT(IsNameCompatibleWithMonomorphicPrototypeFailure(name)); |
| 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 | |
| 258 InlineCacheHolderFlag cache_holder = | 252 InlineCacheHolderFlag cache_holder = |
| 259 Code::ExtractCacheHolderFromFlags(target()->flags()); | 253 Code::ExtractCacheHolderFromFlags(target()->flags()); |
| 260 | 254 |
| 261 switch (cache_holder) { | 255 switch (cache_holder) { |
| 262 case OWN_MAP: | 256 case OWN_MAP: |
| 263 // The stub was generated for JSObject but called for non-JSObject. | 257 // The stub was generated for JSObject but called for non-JSObject. |
| 264 // IC::GetCodeCacheHolder is not applicable. | 258 // IC::GetCodeCacheHolder is not applicable. |
| 265 if (!receiver->IsJSObject()) return false; | 259 if (!receiver->IsJSObject()) return false; |
| 266 break; | 260 break; |
| 267 case PROTOTYPE_MAP: | 261 case PROTOTYPE_MAP: |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 329 Handle<Code> handler = handlers.at(i); | 323 Handle<Code> handler = handlers.at(i); |
| 330 int index = map->IndexInCodeCache(*name, *handler); | 324 int index = map->IndexInCodeCache(*name, *handler); |
| 331 if (index >= 0) { | 325 if (index >= 0) { |
| 332 map->RemoveFromCodeCache(*name, *handler, index); | 326 map->RemoveFromCodeCache(*name, *handler, index); |
| 333 return; | 327 return; |
| 334 } | 328 } |
| 335 } | 329 } |
| 336 } | 330 } |
| 337 | 331 |
| 338 | 332 |
| 333 bool IC::IsNameCompatibleWithMonomorphicPrototypeFailure(Handle<Object> name) { | |
| 334 if (target()->is_keyed_stub()) { | |
| 335 // Determine whether the failure is due to a name failure. | |
| 336 if (!name->IsName()) return false; | |
| 337 Name* stub_name = target()->FindFirstName(); | |
| 338 if (*name != stub_name) return false; | |
| 339 } | |
| 340 | |
| 341 return true; | |
| 342 } | |
| 343 | |
| 344 | |
| 339 void IC::UpdateState(Handle<Object> receiver, Handle<Object> name) { | 345 void IC::UpdateState(Handle<Object> receiver, Handle<Object> name) { |
| 340 if (!name->IsString()) return; | 346 if (!name->IsString()) return; |
| 341 if (state() != MONOMORPHIC) { | 347 if (state() != MONOMORPHIC) { |
| 342 if (state() == POLYMORPHIC && receiver->IsHeapObject()) { | 348 if (state() == POLYMORPHIC && receiver->IsHeapObject()) { |
| 343 TryRemoveInvalidHandlers( | 349 TryRemoveInvalidHandlers( |
| 344 handle(Handle<HeapObject>::cast(receiver)->map()), | 350 handle(Handle<HeapObject>::cast(receiver)->map()), |
| 345 Handle<String>::cast(name)); | 351 Handle<String>::cast(name)); |
| 346 } | 352 } |
| 347 return; | 353 return; |
| 348 } | 354 } |
| 349 if (receiver->IsUndefined() || receiver->IsNull()) return; | 355 if (receiver->IsUndefined() || receiver->IsNull()) return; |
| 350 | 356 |
| 351 // Remove the target from the code cache if it became invalid | 357 // Remove the target from the code cache if it became invalid |
| 352 // because of changes in the prototype chain to avoid hitting it | 358 // because of changes in the prototype chain to avoid hitting it |
| 353 // again. | 359 // again. |
| 354 if (TryRemoveInvalidPrototypeDependentStub( | 360 if (IsNameCompatibleWithMonomorphicPrototypeFailure(name) && |
| 361 TryRemoveInvalidPrototypeDependentStub( | |
| 355 receiver, Handle<String>::cast(name))) { | 362 receiver, Handle<String>::cast(name))) { |
| 356 return MarkMonomorphicPrototypeFailure(); | 363 MarkMonomorphicPrototypeFailure(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 801 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1168 PropertyDetails target_details = lookup->GetTransitionDetails(); | 1176 PropertyDetails target_details = lookup->GetTransitionDetails(); |
| 1169 if (target_details.IsReadOnly()) return false; | 1177 if (target_details.IsReadOnly()) return false; |
| 1170 | 1178 |
| 1171 // If the value that's being stored does not fit in the field that the | 1179 // If the value that's being stored does not fit in the field that the |
| 1172 // instance would transition to, create a new transition that fits the value. | 1180 // instance would transition to, create a new transition that fits the value. |
| 1173 // This has to be done before generating the IC, since that IC will embed the | 1181 // This has to be done before generating the IC, since that IC will embed the |
| 1174 // transition target. | 1182 // transition target. |
| 1175 // Ensure the instance and its map were migrated before trying to update the | 1183 // Ensure the instance and its map were migrated before trying to update the |
| 1176 // transition target. | 1184 // transition target. |
| 1177 ASSERT(!receiver->map()->is_deprecated()); | 1185 ASSERT(!receiver->map()->is_deprecated()); |
| 1186 | |
| 1187 if (!ic->IsNameCompatibleWithMonomorphicPrototypeFailure(name)) return false; | |
|
Toon Verwaest
2014/03/31 12:34:44
This is not exactly the same...
The name only has
mvstanton
2014/03/31 13:30:57
I ran into an issue with that idea. TryRemoiveInva
| |
| 1178 if (!value->FitsRepresentation(target_details.representation())) { | 1188 if (!value->FitsRepresentation(target_details.representation())) { |
| 1179 Handle<Map> target(lookup->GetTransitionTarget()); | 1189 Handle<Map> target(lookup->GetTransitionTarget()); |
| 1180 Map::GeneralizeRepresentation( | 1190 Map::GeneralizeRepresentation( |
| 1181 target, target->LastAdded(), | 1191 target, target->LastAdded(), |
| 1182 value->OptimalRepresentation(), FORCE_FIELD); | 1192 value->OptimalRepresentation(), FORCE_FIELD); |
| 1183 // Lookup the transition again since the transition tree may have changed | 1193 // Lookup the transition again since the transition tree may have changed |
| 1184 // entirely by the migration above. | 1194 // entirely by the migration above. |
| 1185 receiver->map()->LookupTransition(*holder, *name, lookup); | 1195 receiver->map()->LookupTransition(*holder, *name, lookup); |
| 1186 if (!lookup->IsTransition()) return false; | 1196 if (!lookup->IsTransition()) return false; |
| 1187 ic->MarkMonomorphicPrototypeFailure(); | 1197 ic->MarkMonomorphicPrototypeFailure(name); |
| 1188 } | 1198 } |
| 1189 return true; | 1199 return true; |
| 1190 } | 1200 } |
| 1191 | 1201 |
| 1192 | 1202 |
| 1193 MaybeObject* StoreIC::Store(Handle<Object> object, | 1203 MaybeObject* StoreIC::Store(Handle<Object> object, |
| 1194 Handle<String> name, | 1204 Handle<String> name, |
| 1195 Handle<Object> value, | 1205 Handle<Object> value, |
| 1196 JSReceiver::StoreFromKeyed store_mode) { | 1206 JSReceiver::StoreFromKeyed store_mode) { |
| 1197 if (MigrateDeprecated(object) || object->IsJSProxy()) { | 1207 if (MigrateDeprecated(object) || object->IsJSProxy()) { |
| (...skipping 1640 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2838 #undef ADDR | 2848 #undef ADDR |
| 2839 }; | 2849 }; |
| 2840 | 2850 |
| 2841 | 2851 |
| 2842 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 2852 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
| 2843 return IC_utilities[id]; | 2853 return IC_utilities[id]; |
| 2844 } | 2854 } |
| 2845 | 2855 |
| 2846 | 2856 |
| 2847 } } // namespace v8::internal | 2857 } } // namespace v8::internal |
| OLD | NEW |