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 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 intptr_t delta = | 175 intptr_t delta = |
176 original_code->instruction_start() - code->instruction_start(); | 176 original_code->instruction_start() - code->instruction_start(); |
177 return addr + delta; | 177 return addr + delta; |
178 } | 178 } |
179 #endif | 179 #endif |
180 | 180 |
181 | 181 |
182 static bool TryRemoveInvalidPrototypeDependentStub(Code* target, | 182 static bool TryRemoveInvalidPrototypeDependentStub(Code* target, |
183 Object* receiver, | 183 Object* receiver, |
184 Object* name) { | 184 Object* name) { |
| 185 // If the code is NORMAL, it handles dictionary mode objects. Such stubs do |
| 186 // not check maps, but do positive/negative lookups. |
| 187 if (target->type() != Code::NORMAL) { |
| 188 Map* map = target->FindFirstMap(); |
| 189 if (map != NULL && map->is_deprecated()) { |
| 190 return true; |
| 191 } |
| 192 } |
| 193 |
185 InlineCacheHolderFlag cache_holder = | 194 InlineCacheHolderFlag cache_holder = |
186 Code::ExtractCacheHolderFromFlags(target->flags()); | 195 Code::ExtractCacheHolderFromFlags(target->flags()); |
187 | 196 |
188 Isolate* isolate = target->GetIsolate(); | 197 Isolate* isolate = target->GetIsolate(); |
189 if (cache_holder == OWN_MAP && !receiver->IsJSObject()) { | 198 if (cache_holder == OWN_MAP && !receiver->IsJSObject()) { |
190 // The stub was generated for JSObject but called for non-JSObject. | 199 // The stub was generated for JSObject but called for non-JSObject. |
191 // IC::GetCodeCacheHolder is not applicable. | 200 // IC::GetCodeCacheHolder is not applicable. |
192 return false; | 201 return false; |
193 } else if (cache_holder == PROTOTYPE_MAP && | 202 } else if (cache_holder == PROTOTYPE_MAP && |
194 receiver->GetPrototype(isolate)->IsNull()) { | 203 receiver->GetPrototype(isolate)->IsNull()) { |
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
498 int index = frame->ComputeExpressionsCount() - (argc + 1); | 507 int index = frame->ComputeExpressionsCount() - (argc + 1); |
499 frame->SetExpression(index, *isolate()->factory()->ToObject(object)); | 508 frame->SetExpression(index, *isolate()->factory()->ToObject(object)); |
500 } | 509 } |
501 } | 510 } |
502 | 511 |
503 | 512 |
504 MaybeObject* CallICBase::LoadFunction(State state, | 513 MaybeObject* CallICBase::LoadFunction(State state, |
505 Code::ExtraICState extra_ic_state, | 514 Code::ExtraICState extra_ic_state, |
506 Handle<Object> object, | 515 Handle<Object> object, |
507 Handle<String> name) { | 516 Handle<String> name) { |
| 517 if (object->IsJSObject()) { |
| 518 Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
| 519 if (receiver->map()->is_deprecated()) { |
| 520 JSObject::MigrateInstance(receiver); |
| 521 } |
| 522 } |
| 523 |
508 // If the object is undefined or null it's illegal to try to get any | 524 // If the object is undefined or null it's illegal to try to get any |
509 // of its properties; throw a TypeError in that case. | 525 // of its properties; throw a TypeError in that case. |
510 if (object->IsUndefined() || object->IsNull()) { | 526 if (object->IsUndefined() || object->IsNull()) { |
511 return TypeError("non_object_property_call", object, name); | 527 return TypeError("non_object_property_call", object, name); |
512 } | 528 } |
513 | 529 |
514 // Check if the name is trivially convertible to an index and get | 530 // Check if the name is trivially convertible to an index and get |
515 // the element if so. | 531 // the element if so. |
516 uint32_t index; | 532 uint32_t index; |
517 if (name->AsArrayIndex(&index)) { | 533 if (name->AsArrayIndex(&index)) { |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
769 MaybeObject* KeyedCallIC::LoadFunction(State state, | 785 MaybeObject* KeyedCallIC::LoadFunction(State state, |
770 Handle<Object> object, | 786 Handle<Object> object, |
771 Handle<Object> key) { | 787 Handle<Object> key) { |
772 if (key->IsInternalizedString()) { | 788 if (key->IsInternalizedString()) { |
773 return CallICBase::LoadFunction(state, | 789 return CallICBase::LoadFunction(state, |
774 Code::kNoExtraICState, | 790 Code::kNoExtraICState, |
775 object, | 791 object, |
776 Handle<String>::cast(key)); | 792 Handle<String>::cast(key)); |
777 } | 793 } |
778 | 794 |
| 795 if (object->IsJSObject()) { |
| 796 Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
| 797 if (receiver->map()->is_deprecated()) { |
| 798 JSObject::MigrateInstance(receiver); |
| 799 } |
| 800 } |
| 801 |
779 if (object->IsUndefined() || object->IsNull()) { | 802 if (object->IsUndefined() || object->IsNull()) { |
780 return TypeError("non_object_property_call", object, key); | 803 return TypeError("non_object_property_call", object, key); |
781 } | 804 } |
782 | 805 |
783 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded(); | 806 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded(); |
784 ASSERT(!(use_ic && object->IsJSGlobalProxy())); | 807 ASSERT(!(use_ic && object->IsJSGlobalProxy())); |
785 | 808 |
786 if (use_ic && state != MEGAMORPHIC) { | 809 if (use_ic && state != MEGAMORPHIC) { |
787 int argc = target()->arguments_count(); | 810 int argc = target()->arguments_count(); |
788 Handle<Code> stub = isolate()->stub_cache()->ComputeCallMegamorphic( | 811 Handle<Code> stub = isolate()->stub_cache()->ComputeCallMegamorphic( |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
883 | 906 |
884 // Check if the name is trivially convertible to an index and get | 907 // Check if the name is trivially convertible to an index and get |
885 // the element or char if so. | 908 // the element or char if so. |
886 uint32_t index; | 909 uint32_t index; |
887 if (kind() == Code::KEYED_LOAD_IC && name->AsArrayIndex(&index)) { | 910 if (kind() == Code::KEYED_LOAD_IC && name->AsArrayIndex(&index)) { |
888 // Rewrite to the generic keyed load stub. | 911 // Rewrite to the generic keyed load stub. |
889 if (FLAG_use_ic) set_target(*generic_stub()); | 912 if (FLAG_use_ic) set_target(*generic_stub()); |
890 return Runtime::GetElementOrCharAtOrFail(isolate(), object, index); | 913 return Runtime::GetElementOrCharAtOrFail(isolate(), object, index); |
891 } | 914 } |
892 | 915 |
| 916 if (object->IsJSObject()) { |
| 917 Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
| 918 if (receiver->map()->is_deprecated()) { |
| 919 JSObject::MigrateInstance(receiver); |
| 920 } |
| 921 } |
| 922 |
893 // Named lookup in the object. | 923 // Named lookup in the object. |
894 LookupResult lookup(isolate()); | 924 LookupResult lookup(isolate()); |
895 LookupForRead(object, name, &lookup); | 925 LookupForRead(object, name, &lookup); |
896 | 926 |
897 // If we did not find a property, check if we need to throw an exception. | 927 // If we did not find a property, check if we need to throw an exception. |
898 if (!lookup.IsFound()) { | 928 if (!lookup.IsFound()) { |
899 if (IsUndeclaredGlobal(object)) { | 929 if (IsUndeclaredGlobal(object)) { |
900 return ReferenceError("not_defined", name); | 930 return ReferenceError("not_defined", name); |
901 } | 931 } |
902 LOG(isolate(), SuspectReadEvent(*name, *object)); | 932 LOG(isolate(), SuspectReadEvent(*name, *object)); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
947 Handle<Code> code) { | 977 Handle<Code> code) { |
948 if (code->type() == Code::NORMAL) return false; | 978 if (code->type() == Code::NORMAL) return false; |
949 if (target()->ic_state() == MONOMORPHIC && | 979 if (target()->ic_state() == MONOMORPHIC && |
950 target()->type() == Code::NORMAL) { | 980 target()->type() == Code::NORMAL) { |
951 return false; | 981 return false; |
952 } | 982 } |
953 | 983 |
954 MapHandleList receiver_maps; | 984 MapHandleList receiver_maps; |
955 CodeHandleList handlers; | 985 CodeHandleList handlers; |
956 | 986 |
| 987 int number_of_valid_maps; |
957 { | 988 { |
958 AssertNoAllocation no_gc; | 989 AssertNoAllocation no_gc; |
959 target()->FindAllMaps(&receiver_maps); | 990 target()->FindAllMaps(&receiver_maps); |
960 int number_of_maps = receiver_maps.length(); | 991 int number_of_maps = receiver_maps.length(); |
961 if (number_of_maps >= 4) return false; | 992 number_of_valid_maps = number_of_maps; |
| 993 for (int i = 0; i < number_of_maps; i++) { |
| 994 if (receiver_maps.at(i)->is_deprecated()) { |
| 995 number_of_valid_maps--; |
| 996 } |
| 997 } |
| 998 |
| 999 if (number_of_valid_maps >= 4) return false; |
962 | 1000 |
963 // Only allow 0 maps in case target() was reset to UNINITIALIZED by the GC. | 1001 // Only allow 0 maps in case target() was reset to UNINITIALIZED by the GC. |
964 // In that case, allow the IC to go back monomorphic. | 1002 // In that case, allow the IC to go back monomorphic. |
965 if (number_of_maps == 0 && target()->ic_state() != UNINITIALIZED) { | 1003 if (number_of_maps == 0 && target()->ic_state() != UNINITIALIZED) { |
966 return false; | 1004 return false; |
967 } | 1005 } |
968 target()->FindAllCode(&handlers, receiver_maps.length()); | 1006 target()->FindAllCode(&handlers, receiver_maps.length()); |
969 } | 1007 } |
970 | 1008 |
971 if (!AddOneReceiverMapIfMissing(&receiver_maps, | 1009 if (!AddOneReceiverMapIfMissing(&receiver_maps, |
972 Handle<Map>(receiver->map()))) { | 1010 Handle<Map>(receiver->map()))) { |
973 return false; | 1011 return false; |
974 } | 1012 } |
975 | 1013 |
976 handlers.Add(code); | 1014 handlers.Add(code); |
977 Handle<Code> ic = isolate()->stub_cache()->ComputePolymorphicIC( | 1015 Handle<Code> ic = isolate()->stub_cache()->ComputePolymorphicIC( |
978 &receiver_maps, &handlers, name); | 1016 &receiver_maps, &handlers, number_of_valid_maps + 1, name); |
979 set_target(*ic); | 1017 set_target(*ic); |
980 return true; | 1018 return true; |
981 } | 1019 } |
982 | 1020 |
983 | 1021 |
984 void LoadIC::UpdateMonomorphicIC(Handle<JSObject> receiver, | 1022 void LoadIC::UpdateMonomorphicIC(Handle<JSObject> receiver, |
985 Handle<Code> handler, | 1023 Handle<Code> handler, |
986 Handle<String> name) { | 1024 Handle<String> name) { |
987 if (handler->type() == Code::NORMAL) return set_target(*handler); | 1025 if (handler->type() == Code::NORMAL) return set_target(*handler); |
988 Handle<Code> ic = isolate()->stub_cache()->ComputeMonomorphicIC( | 1026 Handle<Code> ic = isolate()->stub_cache()->ComputeMonomorphicIC( |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1059 UpdateMonomorphicIC(receiver, code, name); | 1097 UpdateMonomorphicIC(receiver, code, name); |
1060 break; | 1098 break; |
1061 } | 1099 } |
1062 if (UpdatePolymorphicIC(state, strict_mode, receiver, name, code)) { | 1100 if (UpdatePolymorphicIC(state, strict_mode, receiver, name, code)) { |
1063 break; | 1101 break; |
1064 } | 1102 } |
1065 } | 1103 } |
1066 if (target()->type() != Code::NORMAL) { | 1104 if (target()->type() != Code::NORMAL) { |
1067 if (target()->is_load_stub()) { | 1105 if (target()->is_load_stub()) { |
1068 CopyICToMegamorphicCache(name); | 1106 CopyICToMegamorphicCache(name); |
| 1107 } else if (target()->is_store_stub()) { |
| 1108 // Ensure that the IC stays monomorphic when replacing a monomorphic |
| 1109 // IC for a deprecated map. |
| 1110 // TODO(verwaest): Remove this code once polymorphic store ICs are |
| 1111 // implemented. Updating the polymorphic IC will keep it monomorphic |
| 1112 // by filtering deprecated maps. |
| 1113 MapHandleList maps; |
| 1114 Code* handler = target(); |
| 1115 handler->FindAllMaps(&maps); |
| 1116 for (int i = 0; i < Min(1, maps.length()); i++) { |
| 1117 if (maps.at(i)->is_deprecated()) { |
| 1118 UpdateMonomorphicIC(receiver, code, name); |
| 1119 return; |
| 1120 } |
| 1121 } |
| 1122 if (maps.length() > 0) { |
| 1123 if (receiver->map() == *maps.at(0)) { |
| 1124 UpdateMonomorphicIC(receiver, code, name); |
| 1125 return; |
| 1126 } |
| 1127 UpdateMegamorphicCache(*maps.at(0), *name, handler); |
| 1128 } |
1069 } else { | 1129 } else { |
1070 Code* handler = target(); | 1130 Code* handler = target(); |
1071 Map* map = handler->FindFirstMap(); | 1131 Map* map = handler->FindFirstMap(); |
1072 if (map != NULL) { | 1132 if (map != NULL) { |
1073 UpdateMegamorphicCache(map, *name, handler); | 1133 UpdateMegamorphicCache(map, *name, handler); |
1074 } | 1134 } |
1075 } | 1135 } |
1076 } | 1136 } |
1077 | 1137 |
1078 UpdateMegamorphicCache(receiver->map(), *name, *code); | 1138 UpdateMegamorphicCache(receiver->map(), *name, *code); |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1358 | 1418 |
1359 if (use_ic) { | 1419 if (use_ic) { |
1360 Handle<Code> stub = generic_stub(); | 1420 Handle<Code> stub = generic_stub(); |
1361 if (miss_mode != MISS_FORCE_GENERIC) { | 1421 if (miss_mode != MISS_FORCE_GENERIC) { |
1362 if (object->IsString() && key->IsNumber()) { | 1422 if (object->IsString() && key->IsNumber()) { |
1363 if (state == UNINITIALIZED) { | 1423 if (state == UNINITIALIZED) { |
1364 stub = string_stub(); | 1424 stub = string_stub(); |
1365 } | 1425 } |
1366 } else if (object->IsJSObject()) { | 1426 } else if (object->IsJSObject()) { |
1367 Handle<JSObject> receiver = Handle<JSObject>::cast(object); | 1427 Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
| 1428 if (receiver->map()->is_deprecated()) { |
| 1429 JSObject::MigrateInstance(receiver); |
| 1430 } |
| 1431 |
1368 if (receiver->elements()->map() == | 1432 if (receiver->elements()->map() == |
1369 isolate()->heap()->non_strict_arguments_elements_map()) { | 1433 isolate()->heap()->non_strict_arguments_elements_map()) { |
1370 stub = non_strict_arguments_stub(); | 1434 stub = non_strict_arguments_stub(); |
1371 } else if (receiver->HasIndexedInterceptor()) { | 1435 } else if (receiver->HasIndexedInterceptor()) { |
1372 stub = indexed_interceptor_stub(); | 1436 stub = indexed_interceptor_stub(); |
1373 } else if (!key->ToSmi()->IsFailure() && | 1437 } else if (!key->ToSmi()->IsFailure() && |
1374 (target() != *non_strict_arguments_stub())) { | 1438 (target() != *non_strict_arguments_stub())) { |
1375 stub = LoadElementStub(receiver); | 1439 stub = LoadElementStub(receiver); |
1376 } | 1440 } |
1377 } | 1441 } |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1424 // Always rewrite to the generic case so that we do not | 1488 // Always rewrite to the generic case so that we do not |
1425 // repeatedly try to rewrite. | 1489 // repeatedly try to rewrite. |
1426 return generic_stub(); | 1490 return generic_stub(); |
1427 } | 1491 } |
1428 return Handle<Code>::null(); | 1492 return Handle<Code>::null(); |
1429 } | 1493 } |
1430 | 1494 |
1431 | 1495 |
1432 static bool LookupForWrite(Handle<JSObject> receiver, | 1496 static bool LookupForWrite(Handle<JSObject> receiver, |
1433 Handle<String> name, | 1497 Handle<String> name, |
| 1498 Handle<Object> value, |
1434 LookupResult* lookup) { | 1499 LookupResult* lookup) { |
1435 Handle<JSObject> holder = receiver; | 1500 Handle<JSObject> holder = receiver; |
1436 receiver->Lookup(*name, lookup); | 1501 receiver->Lookup(*name, lookup); |
1437 if (lookup->IsFound()) { | 1502 if (lookup->IsFound()) { |
1438 if (lookup->IsReadOnly() || !lookup->IsCacheable()) return false; | 1503 if (lookup->IsReadOnly() || !lookup->IsCacheable()) return false; |
1439 | 1504 |
1440 if (lookup->holder() == *receiver) { | 1505 if (lookup->holder() == *receiver) { |
1441 if (lookup->IsInterceptor() && | 1506 if (lookup->IsInterceptor() && |
1442 receiver->GetNamedInterceptor()->setter()->IsUndefined()) { | 1507 receiver->GetNamedInterceptor()->setter()->IsUndefined()) { |
1443 receiver->LocalLookupRealNamedProperty(*name, lookup); | 1508 receiver->LocalLookupRealNamedProperty(*name, lookup); |
1444 return lookup->IsFound() && | 1509 return lookup->IsFound() && |
1445 !lookup->IsReadOnly() && | 1510 !lookup->IsReadOnly() && |
| 1511 lookup->CanHoldValue(value) && |
1446 lookup->IsCacheable(); | 1512 lookup->IsCacheable(); |
1447 } | 1513 } |
1448 return true; | 1514 return lookup->CanHoldValue(value); |
1449 } | 1515 } |
1450 | 1516 |
1451 if (lookup->IsPropertyCallbacks()) return true; | 1517 if (lookup->IsPropertyCallbacks()) return true; |
1452 | 1518 |
1453 // Currently normal holders in the prototype chain are not supported. They | 1519 // Currently normal holders in the prototype chain are not supported. They |
1454 // would require a runtime positive lookup and verification that the details | 1520 // would require a runtime positive lookup and verification that the details |
1455 // have not changed. | 1521 // have not changed. |
1456 if (lookup->IsInterceptor() || lookup->IsNormal()) return false; | 1522 if (lookup->IsInterceptor() || lookup->IsNormal()) return false; |
1457 holder = Handle<JSObject>(lookup->holder(), lookup->isolate()); | 1523 holder = Handle<JSObject>(lookup->holder(), lookup->isolate()); |
1458 } | 1524 } |
1459 | 1525 |
1460 // While normally LookupTransition gets passed the receiver, in this case we | 1526 // While normally LookupTransition gets passed the receiver, in this case we |
1461 // pass the holder of the property that we overwrite. This keeps the holder in | 1527 // pass the holder of the property that we overwrite. This keeps the holder in |
1462 // the LookupResult intact so we can later use it to generate a prototype | 1528 // the LookupResult intact so we can later use it to generate a prototype |
1463 // chain check. This avoids a double lookup, but requires us to pass in the | 1529 // chain check. This avoids a double lookup, but requires us to pass in the |
1464 // receiver when trying to fetch extra information from the transition. | 1530 // receiver when trying to fetch extra information from the transition. |
1465 receiver->map()->LookupTransition(*holder, *name, lookup); | 1531 receiver->map()->LookupTransition(*holder, *name, lookup); |
1466 return lookup->IsTransition() && | 1532 if (!lookup->IsTransition()) return false; |
1467 !lookup->GetTransitionDetails(receiver->map()).IsReadOnly(); | 1533 PropertyDetails target_details = |
| 1534 lookup->GetTransitionDetails(receiver->map()); |
| 1535 if (target_details.IsReadOnly()) return false; |
| 1536 return value->FitsRepresentation(target_details.representation()); |
1468 } | 1537 } |
1469 | 1538 |
1470 | 1539 |
1471 MaybeObject* StoreIC::Store(State state, | 1540 MaybeObject* StoreIC::Store(State state, |
1472 StrictModeFlag strict_mode, | 1541 StrictModeFlag strict_mode, |
1473 Handle<Object> object, | 1542 Handle<Object> object, |
1474 Handle<String> name, | 1543 Handle<String> name, |
1475 Handle<Object> value, | 1544 Handle<Object> value, |
1476 JSReceiver::StoreFromKeyed store_mode) { | 1545 JSReceiver::StoreFromKeyed store_mode) { |
1477 // Handle proxies. | 1546 // Handle proxies. |
(...skipping 13 matching lines...) Expand all Loading... |
1491 name->Equals(isolate()->heap()->length_string())) { | 1560 name->Equals(isolate()->heap()->length_string())) { |
1492 return TypeError("strict_read_only_property", object, name); | 1561 return TypeError("strict_read_only_property", object, name); |
1493 } | 1562 } |
1494 | 1563 |
1495 // Ignore other stores where the receiver is not a JSObject. | 1564 // Ignore other stores where the receiver is not a JSObject. |
1496 // TODO(1475): Must check prototype chains of object wrappers. | 1565 // TODO(1475): Must check prototype chains of object wrappers. |
1497 if (!object->IsJSObject()) return *value; | 1566 if (!object->IsJSObject()) return *value; |
1498 | 1567 |
1499 Handle<JSObject> receiver = Handle<JSObject>::cast(object); | 1568 Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
1500 | 1569 |
| 1570 if (receiver->map()->is_deprecated()) { |
| 1571 JSObject::MigrateInstance(receiver); |
| 1572 } |
| 1573 |
1501 // Check if the given name is an array index. | 1574 // Check if the given name is an array index. |
1502 uint32_t index; | 1575 uint32_t index; |
1503 if (name->AsArrayIndex(&index)) { | 1576 if (name->AsArrayIndex(&index)) { |
1504 Handle<Object> result = | 1577 Handle<Object> result = |
1505 JSObject::SetElement(receiver, index, value, NONE, strict_mode); | 1578 JSObject::SetElement(receiver, index, value, NONE, strict_mode); |
1506 RETURN_IF_EMPTY_HANDLE(isolate(), result); | 1579 RETURN_IF_EMPTY_HANDLE(isolate(), result); |
1507 return *value; | 1580 return *value; |
1508 } | 1581 } |
1509 | 1582 |
1510 // Observed objects are always modified through the runtime. | 1583 // Observed objects are always modified through the runtime. |
(...skipping 26 matching lines...) Expand all Loading... |
1537 ? global_proxy_stub_strict() | 1610 ? global_proxy_stub_strict() |
1538 : global_proxy_stub(); | 1611 : global_proxy_stub(); |
1539 set_target(*stub); | 1612 set_target(*stub); |
1540 TRACE_IC("StoreIC", name, state, *stub); | 1613 TRACE_IC("StoreIC", name, state, *stub); |
1541 } | 1614 } |
1542 return JSReceiver::SetPropertyOrFail( | 1615 return JSReceiver::SetPropertyOrFail( |
1543 receiver, name, value, NONE, strict_mode, store_mode); | 1616 receiver, name, value, NONE, strict_mode, store_mode); |
1544 } | 1617 } |
1545 | 1618 |
1546 LookupResult lookup(isolate()); | 1619 LookupResult lookup(isolate()); |
1547 if (LookupForWrite(receiver, name, &lookup)) { | 1620 if (LookupForWrite(receiver, name, value, &lookup)) { |
1548 if (FLAG_use_ic) { | 1621 if (FLAG_use_ic) { |
1549 UpdateCaches(&lookup, state, strict_mode, receiver, name, value); | 1622 UpdateCaches(&lookup, state, strict_mode, receiver, name, value); |
1550 } | 1623 } |
1551 } else if (strict_mode == kStrictMode && | 1624 } else if (strict_mode == kStrictMode && |
1552 !(lookup.IsProperty() && lookup.IsReadOnly()) && | 1625 !(lookup.IsProperty() && lookup.IsReadOnly()) && |
1553 IsUndeclaredGlobal(object)) { | 1626 IsUndeclaredGlobal(object)) { |
1554 // Strict mode doesn't allow setting non-existent global property. | 1627 // Strict mode doesn't allow setting non-existent global property. |
1555 return ReferenceError("not_defined", name); | 1628 return ReferenceError("not_defined", name); |
1556 } | 1629 } |
1557 | 1630 |
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1946 JSObject::cast(*object)->map()->is_observed()); | 2019 JSObject::cast(*object)->map()->is_observed()); |
1947 ASSERT(!(use_ic && object->IsJSGlobalProxy())); | 2020 ASSERT(!(use_ic && object->IsJSGlobalProxy())); |
1948 | 2021 |
1949 if (use_ic) { | 2022 if (use_ic) { |
1950 Handle<Code> stub = (strict_mode == kStrictMode) | 2023 Handle<Code> stub = (strict_mode == kStrictMode) |
1951 ? generic_stub_strict() | 2024 ? generic_stub_strict() |
1952 : generic_stub(); | 2025 : generic_stub(); |
1953 if (miss_mode != MISS_FORCE_GENERIC) { | 2026 if (miss_mode != MISS_FORCE_GENERIC) { |
1954 if (object->IsJSObject()) { | 2027 if (object->IsJSObject()) { |
1955 Handle<JSObject> receiver = Handle<JSObject>::cast(object); | 2028 Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
| 2029 if (receiver->map()->is_deprecated()) { |
| 2030 JSObject::MigrateInstance(receiver); |
| 2031 } |
1956 bool key_is_smi_like = key->IsSmi() || | 2032 bool key_is_smi_like = key->IsSmi() || |
1957 (FLAG_compiled_keyed_stores && !key->ToSmi()->IsFailure()); | 2033 (FLAG_compiled_keyed_stores && !key->ToSmi()->IsFailure()); |
1958 if (receiver->elements()->map() == | 2034 if (receiver->elements()->map() == |
1959 isolate()->heap()->non_strict_arguments_elements_map()) { | 2035 isolate()->heap()->non_strict_arguments_elements_map()) { |
1960 stub = non_strict_arguments_stub(); | 2036 stub = non_strict_arguments_stub(); |
1961 } else if (key_is_smi_like && | 2037 } else if (key_is_smi_like && |
1962 (target() != *non_strict_arguments_stub())) { | 2038 (target() != *non_strict_arguments_stub())) { |
1963 KeyedAccessStoreMode store_mode = GetStoreMode(receiver, key, value); | 2039 KeyedAccessStoreMode store_mode = GetStoreMode(receiver, key, value); |
1964 stub = StoreElementStub(receiver, store_mode, strict_mode); | 2040 stub = StoreElementStub(receiver, store_mode, strict_mode); |
1965 } else { | 2041 } else { |
(...skipping 843 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2809 #undef ADDR | 2885 #undef ADDR |
2810 }; | 2886 }; |
2811 | 2887 |
2812 | 2888 |
2813 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 2889 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
2814 return IC_utilities[id]; | 2890 return IC_utilities[id]; |
2815 } | 2891 } |
2816 | 2892 |
2817 | 2893 |
2818 } } // namespace v8::internal | 2894 } } // namespace v8::internal |
OLD | NEW |