| 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 |