| 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 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 422 | 422 |
| 423 void LoadIC::Clear(Isolate* isolate, Address address, Code* target) { | 423 void LoadIC::Clear(Isolate* isolate, Address address, Code* target) { |
| 424 if (IsCleared(target)) return; | 424 if (IsCleared(target)) return; |
| 425 SetTargetAtAddress(address, *pre_monomorphic_stub(isolate)); | 425 SetTargetAtAddress(address, *pre_monomorphic_stub(isolate)); |
| 426 } | 426 } |
| 427 | 427 |
| 428 | 428 |
| 429 void StoreIC::Clear(Isolate* isolate, Address address, Code* target) { | 429 void StoreIC::Clear(Isolate* isolate, Address address, Code* target) { |
| 430 if (IsCleared(target)) return; | 430 if (IsCleared(target)) return; |
| 431 SetTargetAtAddress(address, | 431 SetTargetAtAddress(address, |
| 432 (Code::GetStrictMode(target->extra_ic_state()) == kStrictMode) | 432 *pre_monomorphic_stub( |
| 433 ? *pre_monomorphic_stub_strict(isolate) | 433 isolate, Code::GetStrictMode(target->extra_ic_state()))); |
| 434 : *pre_monomorphic_stub(isolate)); | |
| 435 } | 434 } |
| 436 | 435 |
| 437 | 436 |
| 438 void KeyedStoreIC::Clear(Isolate* isolate, Address address, Code* target) { | 437 void KeyedStoreIC::Clear(Isolate* isolate, Address address, Code* target) { |
| 439 if (IsCleared(target)) return; | 438 if (IsCleared(target)) return; |
| 440 SetTargetAtAddress(address, | 439 SetTargetAtAddress(address, |
| 441 (Code::GetStrictMode(target->extra_ic_state()) == kStrictMode) | 440 *pre_monomorphic_stub( |
| 442 ? *pre_monomorphic_stub_strict(isolate) | 441 isolate, Code::GetStrictMode(target->extra_ic_state()))); |
| 443 : *pre_monomorphic_stub(isolate)); | |
| 444 } | 442 } |
| 445 | 443 |
| 446 | 444 |
| 447 void CompareIC::Clear(Isolate* isolate, Address address, Code* target) { | 445 void CompareIC::Clear(Isolate* isolate, Address address, Code* target) { |
| 448 ASSERT(target->major_key() == CodeStub::CompareIC); | 446 ASSERT(target->major_key() == CodeStub::CompareIC); |
| 449 CompareIC::State handler_state; | 447 CompareIC::State handler_state; |
| 450 Token::Value op; | 448 Token::Value op; |
| 451 ICCompareStub::DecodeMinorKey(target->stub_info(), NULL, NULL, | 449 ICCompareStub::DecodeMinorKey(target->stub_info(), NULL, NULL, |
| 452 &handler_state, &op); | 450 &handler_state, &op); |
| 453 // Only clear CompareICs that can retain objects. | 451 // Only clear CompareICs that can retain objects. |
| (...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 987 } | 985 } |
| 988 } | 986 } |
| 989 receiver_maps->Add(new_receiver_map); | 987 receiver_maps->Add(new_receiver_map); |
| 990 return true; | 988 return true; |
| 991 } | 989 } |
| 992 | 990 |
| 993 | 991 |
| 994 bool IC::UpdatePolymorphicIC(State state, | 992 bool IC::UpdatePolymorphicIC(State state, |
| 995 Handle<HeapObject> receiver, | 993 Handle<HeapObject> receiver, |
| 996 Handle<String> name, | 994 Handle<String> name, |
| 997 Handle<Code> code, | 995 Handle<Code> code) { |
| 998 StrictModeFlag strict_mode) { | |
| 999 if (!code->is_handler()) return false; | 996 if (!code->is_handler()) return false; |
| 1000 | 997 |
| 1001 MapHandleList receiver_maps; | 998 MapHandleList receiver_maps; |
| 1002 CodeHandleList handlers; | 999 CodeHandleList handlers; |
| 1003 | 1000 |
| 1004 int number_of_valid_maps; | 1001 int number_of_valid_maps; |
| 1005 int handler_to_overwrite = -1; | 1002 int handler_to_overwrite = -1; |
| 1006 Handle<Map> new_receiver_map(receiver->map()); | 1003 Handle<Map> new_receiver_map(receiver->map()); |
| 1007 { | 1004 { |
| 1008 DisallowHeapAllocation no_gc; | 1005 DisallowHeapAllocation no_gc; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1039 | 1036 |
| 1040 number_of_valid_maps++; | 1037 number_of_valid_maps++; |
| 1041 if (handler_to_overwrite >= 0) { | 1038 if (handler_to_overwrite >= 0) { |
| 1042 handlers.Set(handler_to_overwrite, code); | 1039 handlers.Set(handler_to_overwrite, code); |
| 1043 } else { | 1040 } else { |
| 1044 receiver_maps.Add(new_receiver_map); | 1041 receiver_maps.Add(new_receiver_map); |
| 1045 handlers.Add(code); | 1042 handlers.Add(code); |
| 1046 } | 1043 } |
| 1047 | 1044 |
| 1048 Handle<Code> ic = isolate()->stub_cache()->ComputePolymorphicIC( | 1045 Handle<Code> ic = isolate()->stub_cache()->ComputePolymorphicIC( |
| 1049 &receiver_maps, &handlers, number_of_valid_maps, name, strict_mode); | 1046 &receiver_maps, &handlers, number_of_valid_maps, name, strict_mode()); |
| 1050 set_target(*ic); | 1047 set_target(*ic); |
| 1051 return true; | 1048 return true; |
| 1052 } | 1049 } |
| 1053 | 1050 |
| 1054 | 1051 |
| 1055 void IC::UpdateMonomorphicIC(Handle<HeapObject> receiver, | 1052 void IC::UpdateMonomorphicIC(Handle<HeapObject> receiver, |
| 1056 Handle<Code> handler, | 1053 Handle<Code> handler, |
| 1057 Handle<String> name, | 1054 Handle<String> name) { |
| 1058 StrictModeFlag strict_mode) { | |
| 1059 if (!handler->is_handler()) return set_target(*handler); | 1055 if (!handler->is_handler()) return set_target(*handler); |
| 1060 Handle<Code> ic = isolate()->stub_cache()->ComputeMonomorphicIC( | 1056 Handle<Code> ic = isolate()->stub_cache()->ComputeMonomorphicIC( |
| 1061 receiver, handler, name, strict_mode); | 1057 receiver, handler, name, strict_mode()); |
| 1062 set_target(*ic); | 1058 set_target(*ic); |
| 1063 } | 1059 } |
| 1064 | 1060 |
| 1065 | 1061 |
| 1066 void IC::CopyICToMegamorphicCache(Handle<String> name) { | 1062 void IC::CopyICToMegamorphicCache(Handle<String> name) { |
| 1067 MapHandleList receiver_maps; | 1063 MapHandleList receiver_maps; |
| 1068 CodeHandleList handlers; | 1064 CodeHandleList handlers; |
| 1069 { | 1065 { |
| 1070 DisallowHeapAllocation no_gc; | 1066 DisallowHeapAllocation no_gc; |
| 1071 target()->FindAllMaps(&receiver_maps); | 1067 target()->FindAllMaps(&receiver_maps); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1089 ? current_map->LookupElementsTransitionMap(receiver_elements_kind) | 1085 ? current_map->LookupElementsTransitionMap(receiver_elements_kind) |
| 1090 : NULL; | 1086 : NULL; |
| 1091 | 1087 |
| 1092 return transitioned_map == receiver_map; | 1088 return transitioned_map == receiver_map; |
| 1093 } | 1089 } |
| 1094 | 1090 |
| 1095 | 1091 |
| 1096 // Since GC may have been invoked, by the time PatchCache is called, |state| is | 1092 // Since GC may have been invoked, by the time PatchCache is called, |state| is |
| 1097 // not necessarily equal to target()->state(). | 1093 // not necessarily equal to target()->state(). |
| 1098 void IC::PatchCache(State state, | 1094 void IC::PatchCache(State state, |
| 1099 StrictModeFlag strict_mode, | |
| 1100 Handle<HeapObject> receiver, | 1095 Handle<HeapObject> receiver, |
| 1101 Handle<String> name, | 1096 Handle<String> name, |
| 1102 Handle<Code> code) { | 1097 Handle<Code> code) { |
| 1103 switch (state) { | 1098 switch (state) { |
| 1104 case UNINITIALIZED: | 1099 case UNINITIALIZED: |
| 1105 case PREMONOMORPHIC: | 1100 case PREMONOMORPHIC: |
| 1106 case MONOMORPHIC_PROTOTYPE_FAILURE: | 1101 case MONOMORPHIC_PROTOTYPE_FAILURE: |
| 1107 UpdateMonomorphicIC(receiver, code, name, strict_mode); | 1102 UpdateMonomorphicIC(receiver, code, name); |
| 1108 break; | 1103 break; |
| 1109 case MONOMORPHIC: | 1104 case MONOMORPHIC: |
| 1110 // Only move to megamorphic if the target changes. | 1105 // Only move to megamorphic if the target changes. |
| 1111 if (target() != *code) { | 1106 if (target() != *code) { |
| 1112 if (target()->is_load_stub() || target()->is_store_stub()) { | 1107 if (target()->is_load_stub() || target()->is_store_stub()) { |
| 1113 bool is_same_handler = false; | 1108 bool is_same_handler = false; |
| 1114 { | 1109 { |
| 1115 DisallowHeapAllocation no_allocation; | 1110 DisallowHeapAllocation no_allocation; |
| 1116 Code* old_handler = target()->FindFirstHandler(); | 1111 Code* old_handler = target()->FindFirstHandler(); |
| 1117 is_same_handler = old_handler == *code; | 1112 is_same_handler = old_handler == *code; |
| 1118 } | 1113 } |
| 1119 if (is_same_handler | 1114 if (is_same_handler |
| 1120 && IsTransitionedMapOfMonomorphicTarget(receiver->map())) { | 1115 && IsTransitionedMapOfMonomorphicTarget(receiver->map())) { |
| 1121 UpdateMonomorphicIC(receiver, code, name, strict_mode); | 1116 UpdateMonomorphicIC(receiver, code, name); |
| 1122 break; | 1117 break; |
| 1123 } | 1118 } |
| 1124 if (UpdatePolymorphicIC(state, receiver, name, code, strict_mode)) { | 1119 if (UpdatePolymorphicIC(state, receiver, name, code)) { |
| 1125 break; | 1120 break; |
| 1126 } | 1121 } |
| 1127 | 1122 |
| 1128 CopyICToMegamorphicCache(name); | 1123 CopyICToMegamorphicCache(name); |
| 1129 } | 1124 } |
| 1130 | 1125 |
| 1131 UpdateMegamorphicCache(receiver->map(), *name, *code); | 1126 UpdateMegamorphicCache(receiver->map(), *name, *code); |
| 1132 set_target((strict_mode == kStrictMode) | 1127 set_target(*megamorphic_stub()); |
| 1133 ? *megamorphic_stub_strict() | |
| 1134 : *megamorphic_stub()); | |
| 1135 } | 1128 } |
| 1136 break; | 1129 break; |
| 1137 case MEGAMORPHIC: | 1130 case MEGAMORPHIC: |
| 1138 UpdateMegamorphicCache(receiver->map(), *name, *code); | 1131 UpdateMegamorphicCache(receiver->map(), *name, *code); |
| 1139 break; | 1132 break; |
| 1140 case POLYMORPHIC: | 1133 case POLYMORPHIC: |
| 1141 if (target()->is_load_stub() || target()->is_store_stub()) { | 1134 if (target()->is_load_stub() || target()->is_store_stub()) { |
| 1142 if (UpdatePolymorphicIC(state, receiver, name, code, strict_mode)) { | 1135 if (UpdatePolymorphicIC(state, receiver, name, code)) { |
| 1143 break; | 1136 break; |
| 1144 } | 1137 } |
| 1145 CopyICToMegamorphicCache(name); | 1138 CopyICToMegamorphicCache(name); |
| 1146 UpdateMegamorphicCache(receiver->map(), *name, *code); | 1139 UpdateMegamorphicCache(receiver->map(), *name, *code); |
| 1147 set_target((strict_mode == kStrictMode) | 1140 set_target(*megamorphic_stub()); |
| 1148 ? *megamorphic_stub_strict() | |
| 1149 : *megamorphic_stub()); | |
| 1150 } else { | 1141 } else { |
| 1151 // When trying to patch a polymorphic keyed load/store element stub | 1142 // When trying to patch a polymorphic keyed load/store element stub |
| 1152 // with anything other than another polymorphic stub, go generic. | 1143 // with anything other than another polymorphic stub, go generic. |
| 1153 set_target((strict_mode == kStrictMode) | 1144 set_target(*generic_stub()); |
| 1154 ? *generic_stub_strict() | |
| 1155 : *generic_stub()); | |
| 1156 } | 1145 } |
| 1157 break; | 1146 break; |
| 1158 case DEBUG_STUB: | 1147 case DEBUG_STUB: |
| 1159 break; | 1148 break; |
| 1160 case GENERIC: | 1149 case GENERIC: |
| 1161 UNREACHABLE(); | 1150 UNREACHABLE(); |
| 1162 break; | 1151 break; |
| 1163 } | 1152 } |
| 1164 } | 1153 } |
| 1165 | 1154 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1231 } | 1220 } |
| 1232 } else if (!object->IsJSObject()) { | 1221 } else if (!object->IsJSObject()) { |
| 1233 // TODO(jkummerow): It would be nice to support non-JSObjects in | 1222 // TODO(jkummerow): It would be nice to support non-JSObjects in |
| 1234 // ComputeLoadHandler, then we wouldn't need to go generic here. | 1223 // ComputeLoadHandler, then we wouldn't need to go generic here. |
| 1235 code = slow_stub(); | 1224 code = slow_stub(); |
| 1236 } else { | 1225 } else { |
| 1237 code = ComputeLoadHandler(lookup, Handle<JSObject>::cast(receiver), name); | 1226 code = ComputeLoadHandler(lookup, Handle<JSObject>::cast(receiver), name); |
| 1238 if (code.is_null()) code = slow_stub(); | 1227 if (code.is_null()) code = slow_stub(); |
| 1239 } | 1228 } |
| 1240 | 1229 |
| 1241 PatchCache(state, kNonStrictMode, receiver, name, code); | 1230 PatchCache(state, receiver, name, code); |
| 1242 TRACE_IC("LoadIC", name, state, target()); | 1231 TRACE_IC("LoadIC", name, state, target()); |
| 1243 } | 1232 } |
| 1244 | 1233 |
| 1245 | 1234 |
| 1246 void IC::UpdateMegamorphicCache(Map* map, Name* name, Code* code) { | 1235 void IC::UpdateMegamorphicCache(Map* map, Name* name, Code* code) { |
| 1247 // Cache code holding map should be consistent with | 1236 // Cache code holding map should be consistent with |
| 1248 // GenerateMonomorphicCacheProbe. | 1237 // GenerateMonomorphicCacheProbe. |
| 1249 isolate()->stub_cache()->Set(name, map, code); | 1238 isolate()->stub_cache()->Set(name, map, code); |
| 1250 } | 1239 } |
| 1251 | 1240 |
| (...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1600 // entirely by the migration above. | 1589 // entirely by the migration above. |
| 1601 receiver->map()->LookupTransition(*holder, *name, lookup); | 1590 receiver->map()->LookupTransition(*holder, *name, lookup); |
| 1602 if (!lookup->IsTransition()) return false; | 1591 if (!lookup->IsTransition()) return false; |
| 1603 *state = MONOMORPHIC_PROTOTYPE_FAILURE; | 1592 *state = MONOMORPHIC_PROTOTYPE_FAILURE; |
| 1604 } | 1593 } |
| 1605 return true; | 1594 return true; |
| 1606 } | 1595 } |
| 1607 | 1596 |
| 1608 | 1597 |
| 1609 MaybeObject* StoreIC::Store(State state, | 1598 MaybeObject* StoreIC::Store(State state, |
| 1610 StrictModeFlag strict_mode, | |
| 1611 Handle<Object> object, | 1599 Handle<Object> object, |
| 1612 Handle<String> name, | 1600 Handle<String> name, |
| 1613 Handle<Object> value, | 1601 Handle<Object> value, |
| 1614 JSReceiver::StoreFromKeyed store_mode) { | 1602 JSReceiver::StoreFromKeyed store_mode) { |
| 1615 // Handle proxies. | 1603 // Handle proxies. |
| 1616 if (object->IsJSProxy()) { | 1604 if (object->IsJSProxy()) { |
| 1617 Handle<Object> result = JSReceiver::SetProperty( | 1605 Handle<Object> result = JSReceiver::SetProperty( |
| 1618 Handle<JSReceiver>::cast(object), name, value, NONE, strict_mode); | 1606 Handle<JSReceiver>::cast(object), name, value, NONE, strict_mode()); |
| 1619 RETURN_IF_EMPTY_HANDLE(isolate(), result); | 1607 RETURN_IF_EMPTY_HANDLE(isolate(), result); |
| 1620 return *result; | 1608 return *result; |
| 1621 } | 1609 } |
| 1622 | 1610 |
| 1623 // If the object is undefined or null it's illegal to try to set any | 1611 // If the object is undefined or null it's illegal to try to set any |
| 1624 // properties on it; throw a TypeError in that case. | 1612 // properties on it; throw a TypeError in that case. |
| 1625 if (object->IsUndefined() || object->IsNull()) { | 1613 if (object->IsUndefined() || object->IsNull()) { |
| 1626 return TypeError("non_object_property_store", object, name); | 1614 return TypeError("non_object_property_store", object, name); |
| 1627 } | 1615 } |
| 1628 | 1616 |
| 1629 // The length property of string values is read-only. Throw in strict mode. | 1617 // The length property of string values is read-only. Throw in strict mode. |
| 1630 if (strict_mode == kStrictMode && object->IsString() && | 1618 if (strict_mode() == kStrictMode && object->IsString() && |
| 1631 name->Equals(isolate()->heap()->length_string())) { | 1619 name->Equals(isolate()->heap()->length_string())) { |
| 1632 return TypeError("strict_read_only_property", object, name); | 1620 return TypeError("strict_read_only_property", object, name); |
| 1633 } | 1621 } |
| 1634 | 1622 |
| 1635 // Ignore other stores where the receiver is not a JSObject. | 1623 // Ignore other stores where the receiver is not a JSObject. |
| 1636 // TODO(1475): Must check prototype chains of object wrappers. | 1624 // TODO(1475): Must check prototype chains of object wrappers. |
| 1637 if (!object->IsJSObject()) return *value; | 1625 if (!object->IsJSObject()) return *value; |
| 1638 | 1626 |
| 1639 Handle<JSObject> receiver = Handle<JSObject>::cast(object); | 1627 Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
| 1640 | 1628 |
| 1641 bool use_ic = FLAG_use_ic; | 1629 bool use_ic = FLAG_use_ic; |
| 1642 if (receiver->map()->is_deprecated()) { | 1630 if (receiver->map()->is_deprecated()) { |
| 1643 use_ic = false; | 1631 use_ic = false; |
| 1644 JSObject::MigrateInstance(receiver); | 1632 JSObject::MigrateInstance(receiver); |
| 1645 } | 1633 } |
| 1646 | 1634 |
| 1647 // Check if the given name is an array index. | 1635 // Check if the given name is an array index. |
| 1648 uint32_t index; | 1636 uint32_t index; |
| 1649 if (name->AsArrayIndex(&index)) { | 1637 if (name->AsArrayIndex(&index)) { |
| 1650 Handle<Object> result = | 1638 Handle<Object> result = |
| 1651 JSObject::SetElement(receiver, index, value, NONE, strict_mode); | 1639 JSObject::SetElement(receiver, index, value, NONE, strict_mode()); |
| 1652 RETURN_IF_EMPTY_HANDLE(isolate(), result); | 1640 RETURN_IF_EMPTY_HANDLE(isolate(), result); |
| 1653 return *value; | 1641 return *value; |
| 1654 } | 1642 } |
| 1655 | 1643 |
| 1656 // Observed objects are always modified through the runtime. | 1644 // Observed objects are always modified through the runtime. |
| 1657 if (FLAG_harmony_observation && receiver->map()->is_observed()) { | 1645 if (FLAG_harmony_observation && receiver->map()->is_observed()) { |
| 1658 Handle<Object> result = JSReceiver::SetProperty( | 1646 Handle<Object> result = JSReceiver::SetProperty( |
| 1659 receiver, name, value, NONE, strict_mode, store_mode); | 1647 receiver, name, value, NONE, strict_mode(), store_mode); |
| 1660 RETURN_IF_EMPTY_HANDLE(isolate(), result); | 1648 RETURN_IF_EMPTY_HANDLE(isolate(), result); |
| 1661 return *result; | 1649 return *result; |
| 1662 } | 1650 } |
| 1663 | 1651 |
| 1664 // Use specialized code for setting the length of arrays with fast | 1652 // Use specialized code for setting the length of arrays with fast |
| 1665 // properties. Slow properties might indicate redefinition of the length | 1653 // properties. Slow properties might indicate redefinition of the length |
| 1666 // property. Note that when redefined using Object.freeze, it's possible | 1654 // property. Note that when redefined using Object.freeze, it's possible |
| 1667 // to have fast properties but a read-only length. | 1655 // to have fast properties but a read-only length. |
| 1668 if (use_ic && | 1656 if (use_ic && |
| 1669 receiver->IsJSArray() && | 1657 receiver->IsJSArray() && |
| 1670 name->Equals(isolate()->heap()->length_string()) && | 1658 name->Equals(isolate()->heap()->length_string()) && |
| 1671 Handle<JSArray>::cast(receiver)->AllowsSetElementsLength() && | 1659 Handle<JSArray>::cast(receiver)->AllowsSetElementsLength() && |
| 1672 receiver->HasFastProperties() && | 1660 receiver->HasFastProperties() && |
| 1673 !receiver->map()->is_frozen()) { | 1661 !receiver->map()->is_frozen()) { |
| 1674 Handle<Code> stub = | 1662 Handle<Code> stub = |
| 1675 StoreArrayLengthStub(kind(), strict_mode).GetCode(isolate()); | 1663 StoreArrayLengthStub(kind(), strict_mode()).GetCode(isolate()); |
| 1676 set_target(*stub); | 1664 set_target(*stub); |
| 1677 TRACE_IC("StoreIC", name, state, *stub); | 1665 TRACE_IC("StoreIC", name, state, *stub); |
| 1678 Handle<Object> result = JSReceiver::SetProperty( | 1666 Handle<Object> result = JSReceiver::SetProperty( |
| 1679 receiver, name, value, NONE, strict_mode, store_mode); | 1667 receiver, name, value, NONE, strict_mode(), store_mode); |
| 1680 RETURN_IF_EMPTY_HANDLE(isolate(), result); | 1668 RETURN_IF_EMPTY_HANDLE(isolate(), result); |
| 1681 return *result; | 1669 return *result; |
| 1682 } | 1670 } |
| 1683 | 1671 |
| 1684 if (receiver->IsJSGlobalProxy()) { | 1672 if (receiver->IsJSGlobalProxy()) { |
| 1685 if (use_ic && kind() != Code::KEYED_STORE_IC) { | 1673 if (use_ic && kind() != Code::KEYED_STORE_IC) { |
| 1686 // Generate a generic stub that goes to the runtime when we see a global | 1674 // Generate a generic stub that goes to the runtime when we see a global |
| 1687 // proxy as receiver. | 1675 // proxy as receiver. |
| 1688 Handle<Code> stub = (strict_mode == kStrictMode) | 1676 Handle<Code> stub = global_proxy_stub(); |
| 1689 ? global_proxy_stub_strict() | |
| 1690 : global_proxy_stub(); | |
| 1691 set_target(*stub); | 1677 set_target(*stub); |
| 1692 TRACE_IC("StoreIC", name, state, *stub); | 1678 TRACE_IC("StoreIC", name, state, *stub); |
| 1693 } | 1679 } |
| 1694 Handle<Object> result = JSReceiver::SetProperty( | 1680 Handle<Object> result = JSReceiver::SetProperty( |
| 1695 receiver, name, value, NONE, strict_mode, store_mode); | 1681 receiver, name, value, NONE, strict_mode(), store_mode); |
| 1696 RETURN_IF_EMPTY_HANDLE(isolate(), result); | 1682 RETURN_IF_EMPTY_HANDLE(isolate(), result); |
| 1697 return *result; | 1683 return *result; |
| 1698 } | 1684 } |
| 1699 | 1685 |
| 1700 LookupResult lookup(isolate()); | 1686 LookupResult lookup(isolate()); |
| 1701 bool can_store = LookupForWrite(receiver, name, value, &lookup, &state); | 1687 bool can_store = LookupForWrite(receiver, name, value, &lookup, &state); |
| 1702 if (!can_store && | 1688 if (!can_store && |
| 1703 strict_mode == kStrictMode && | 1689 strict_mode() == kStrictMode && |
| 1704 !(lookup.IsProperty() && lookup.IsReadOnly()) && | 1690 !(lookup.IsProperty() && lookup.IsReadOnly()) && |
| 1705 IsUndeclaredGlobal(object)) { | 1691 IsUndeclaredGlobal(object)) { |
| 1706 // Strict mode doesn't allow setting non-existent global property. | 1692 // Strict mode doesn't allow setting non-existent global property. |
| 1707 return ReferenceError("not_defined", name); | 1693 return ReferenceError("not_defined", name); |
| 1708 } | 1694 } |
| 1709 if (use_ic) { | 1695 if (use_ic) { |
| 1710 if (state == UNINITIALIZED) { | 1696 if (state == UNINITIALIZED) { |
| 1711 Handle<Code> stub = (strict_mode == kStrictMode) | 1697 Handle<Code> stub = pre_monomorphic_stub(); |
| 1712 ? pre_monomorphic_stub_strict() | |
| 1713 : pre_monomorphic_stub(); | |
| 1714 set_target(*stub); | 1698 set_target(*stub); |
| 1715 TRACE_IC("StoreIC", name, state, *stub); | 1699 TRACE_IC("StoreIC", name, state, *stub); |
| 1716 } else if (can_store) { | 1700 } else if (can_store) { |
| 1717 UpdateCaches(&lookup, state, strict_mode, receiver, name, value); | 1701 UpdateCaches(&lookup, state, receiver, name, value); |
| 1718 } else if (!name->IsCacheable(isolate()) || | 1702 } else if (!name->IsCacheable(isolate()) || |
| 1719 lookup.IsNormal() || | 1703 lookup.IsNormal() || |
| 1720 (lookup.IsField() && lookup.CanHoldValue(value))) { | 1704 (lookup.IsField() && lookup.CanHoldValue(value))) { |
| 1721 Handle<Code> stub = (strict_mode == kStrictMode) ? generic_stub_strict() | 1705 Handle<Code> stub = generic_stub(); |
| 1722 : generic_stub(); | |
| 1723 set_target(*stub); | 1706 set_target(*stub); |
| 1724 } | 1707 } |
| 1725 } | 1708 } |
| 1726 | 1709 |
| 1727 // Set the property. | 1710 // Set the property. |
| 1728 Handle<Object> result = JSReceiver::SetProperty( | 1711 Handle<Object> result = JSReceiver::SetProperty( |
| 1729 receiver, name, value, NONE, strict_mode, store_mode); | 1712 receiver, name, value, NONE, strict_mode(), store_mode); |
| 1730 RETURN_IF_EMPTY_HANDLE(isolate(), result); | 1713 RETURN_IF_EMPTY_HANDLE(isolate(), result); |
| 1731 return *result; | 1714 return *result; |
| 1732 } | 1715 } |
| 1733 | 1716 |
| 1734 | 1717 |
| 1735 void StoreIC::UpdateCaches(LookupResult* lookup, | 1718 void StoreIC::UpdateCaches(LookupResult* lookup, |
| 1736 State state, | 1719 State state, |
| 1737 StrictModeFlag strict_mode, | |
| 1738 Handle<JSObject> receiver, | 1720 Handle<JSObject> receiver, |
| 1739 Handle<String> name, | 1721 Handle<String> name, |
| 1740 Handle<Object> value) { | 1722 Handle<Object> value) { |
| 1741 ASSERT(!receiver->IsJSGlobalProxy()); | 1723 ASSERT(!receiver->IsJSGlobalProxy()); |
| 1742 ASSERT(lookup->IsFound()); | 1724 ASSERT(lookup->IsFound()); |
| 1743 | 1725 |
| 1744 // These are not cacheable, so we never see such LookupResults here. | 1726 // These are not cacheable, so we never see such LookupResults here. |
| 1745 ASSERT(!lookup->IsHandler()); | 1727 ASSERT(!lookup->IsHandler()); |
| 1746 | 1728 |
| 1747 Handle<Code> code = ComputeStoreMonomorphic( | 1729 Handle<Code> code = ComputeStoreMonomorphic(lookup, receiver, name, value); |
| 1748 lookup, strict_mode, receiver, name, value); | |
| 1749 if (code.is_null()) { | 1730 if (code.is_null()) { |
| 1750 Handle<Code> stub = strict_mode == kStrictMode | 1731 set_target(*generic_stub()); |
| 1751 ? generic_stub_strict() : generic_stub(); | |
| 1752 set_target(*stub); | |
| 1753 return; | 1732 return; |
| 1754 } | 1733 } |
| 1755 | 1734 |
| 1756 PatchCache(state, strict_mode, receiver, name, code); | 1735 PatchCache(state, receiver, name, code); |
| 1757 TRACE_IC("StoreIC", name, state, target()); | 1736 TRACE_IC("StoreIC", name, state, target()); |
| 1758 } | 1737 } |
| 1759 | 1738 |
| 1760 | 1739 |
| 1761 Handle<Code> StoreIC::ComputeStoreMonomorphic(LookupResult* lookup, | 1740 Handle<Code> StoreIC::ComputeStoreMonomorphic(LookupResult* lookup, |
| 1762 StrictModeFlag strict_mode, | |
| 1763 Handle<JSObject> receiver, | 1741 Handle<JSObject> receiver, |
| 1764 Handle<String> name, | 1742 Handle<String> name, |
| 1765 Handle<Object> value) { | 1743 Handle<Object> value) { |
| 1766 Handle<JSObject> holder(lookup->holder()); | 1744 Handle<JSObject> holder(lookup->holder()); |
| 1767 switch (lookup->type()) { | 1745 switch (lookup->type()) { |
| 1768 case FIELD: | 1746 case FIELD: |
| 1769 return isolate()->stub_cache()->ComputeStoreField( | 1747 return isolate()->stub_cache()->ComputeStoreField( |
| 1770 name, receiver, lookup, strict_mode); | 1748 name, receiver, lookup, strict_mode()); |
| 1771 case NORMAL: | 1749 case NORMAL: |
| 1772 if (receiver->IsGlobalObject()) { | 1750 if (receiver->IsGlobalObject()) { |
| 1773 // The stub generated for the global object picks the value directly | 1751 // The stub generated for the global object picks the value directly |
| 1774 // from the property cell. So the property must be directly on the | 1752 // from the property cell. So the property must be directly on the |
| 1775 // global object. | 1753 // global object. |
| 1776 Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver); | 1754 Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver); |
| 1777 Handle<PropertyCell> cell( | 1755 Handle<PropertyCell> cell( |
| 1778 global->GetPropertyCell(lookup), isolate()); | 1756 global->GetPropertyCell(lookup), isolate()); |
| 1779 return isolate()->stub_cache()->ComputeStoreGlobal( | 1757 return isolate()->stub_cache()->ComputeStoreGlobal( |
| 1780 name, global, cell, value, strict_mode); | 1758 name, global, cell, value, strict_mode()); |
| 1781 } | 1759 } |
| 1782 ASSERT(holder.is_identical_to(receiver)); | 1760 ASSERT(holder.is_identical_to(receiver)); |
| 1783 return isolate()->stub_cache()->ComputeStoreNormal(strict_mode); | 1761 return isolate()->stub_cache()->ComputeStoreNormal(strict_mode()); |
| 1784 case CALLBACKS: { | 1762 case CALLBACKS: { |
| 1785 Handle<Object> callback(lookup->GetCallbackObject(), isolate()); | 1763 Handle<Object> callback(lookup->GetCallbackObject(), isolate()); |
| 1786 if (callback->IsExecutableAccessorInfo()) { | 1764 if (callback->IsExecutableAccessorInfo()) { |
| 1787 Handle<ExecutableAccessorInfo> info = | 1765 Handle<ExecutableAccessorInfo> info = |
| 1788 Handle<ExecutableAccessorInfo>::cast(callback); | 1766 Handle<ExecutableAccessorInfo>::cast(callback); |
| 1789 if (v8::ToCData<Address>(info->setter()) == 0) break; | 1767 if (v8::ToCData<Address>(info->setter()) == 0) break; |
| 1790 if (!holder->HasFastProperties()) break; | 1768 if (!holder->HasFastProperties()) break; |
| 1791 if (!info->IsCompatibleReceiver(*receiver)) break; | 1769 if (!info->IsCompatibleReceiver(*receiver)) break; |
| 1792 return isolate()->stub_cache()->ComputeStoreCallback( | 1770 return isolate()->stub_cache()->ComputeStoreCallback( |
| 1793 name, receiver, holder, info, strict_mode); | 1771 name, receiver, holder, info, strict_mode()); |
| 1794 } else if (callback->IsAccessorPair()) { | 1772 } else if (callback->IsAccessorPair()) { |
| 1795 Handle<Object> setter( | 1773 Handle<Object> setter( |
| 1796 Handle<AccessorPair>::cast(callback)->setter(), isolate()); | 1774 Handle<AccessorPair>::cast(callback)->setter(), isolate()); |
| 1797 if (!setter->IsJSFunction()) break; | 1775 if (!setter->IsJSFunction()) break; |
| 1798 if (holder->IsGlobalObject()) break; | 1776 if (holder->IsGlobalObject()) break; |
| 1799 if (!holder->HasFastProperties()) break; | 1777 if (!holder->HasFastProperties()) break; |
| 1800 Handle<JSFunction> function = Handle<JSFunction>::cast(setter); | 1778 Handle<JSFunction> function = Handle<JSFunction>::cast(setter); |
| 1801 CallOptimization call_optimization(function); | 1779 CallOptimization call_optimization(function); |
| 1802 if (call_optimization.is_simple_api_call() && | 1780 if (call_optimization.is_simple_api_call() && |
| 1803 call_optimization.IsCompatibleReceiver(*receiver)) { | 1781 call_optimization.IsCompatibleReceiver(*receiver)) { |
| 1804 return isolate()->stub_cache()->ComputeStoreCallback( | 1782 return isolate()->stub_cache()->ComputeStoreCallback( |
| 1805 name, receiver, holder, call_optimization, strict_mode); | 1783 name, receiver, holder, call_optimization, strict_mode()); |
| 1806 } | 1784 } |
| 1807 return isolate()->stub_cache()->ComputeStoreViaSetter( | 1785 return isolate()->stub_cache()->ComputeStoreViaSetter( |
| 1808 name, receiver, holder, Handle<JSFunction>::cast(setter), | 1786 name, receiver, holder, Handle<JSFunction>::cast(setter), |
| 1809 strict_mode); | 1787 strict_mode()); |
| 1810 } | 1788 } |
| 1811 // TODO(dcarney): Handle correctly. | 1789 // TODO(dcarney): Handle correctly. |
| 1812 if (callback->IsDeclaredAccessorInfo()) break; | 1790 if (callback->IsDeclaredAccessorInfo()) break; |
| 1813 ASSERT(callback->IsForeign()); | 1791 ASSERT(callback->IsForeign()); |
| 1814 // No IC support for old-style native accessors. | 1792 // No IC support for old-style native accessors. |
| 1815 break; | 1793 break; |
| 1816 } | 1794 } |
| 1817 case INTERCEPTOR: | 1795 case INTERCEPTOR: |
| 1818 ASSERT(!receiver->GetNamedInterceptor()->setter()->IsUndefined()); | 1796 ASSERT(!receiver->GetNamedInterceptor()->setter()->IsUndefined()); |
| 1819 return isolate()->stub_cache()->ComputeStoreInterceptor( | 1797 return isolate()->stub_cache()->ComputeStoreInterceptor( |
| 1820 name, receiver, strict_mode); | 1798 name, receiver, strict_mode()); |
| 1821 case CONSTANT: | 1799 case CONSTANT: |
| 1822 break; | 1800 break; |
| 1823 case TRANSITION: { | 1801 case TRANSITION: { |
| 1824 // Explicitly pass in the receiver map since LookupForWrite may have | 1802 // Explicitly pass in the receiver map since LookupForWrite may have |
| 1825 // stored something else than the receiver in the holder. | 1803 // stored something else than the receiver in the holder. |
| 1826 Handle<Map> transition( | 1804 Handle<Map> transition( |
| 1827 lookup->GetTransitionTarget(receiver->map()), isolate()); | 1805 lookup->GetTransitionTarget(receiver->map()), isolate()); |
| 1828 int descriptor = transition->LastAdded(); | 1806 int descriptor = transition->LastAdded(); |
| 1829 | 1807 |
| 1830 DescriptorArray* target_descriptors = transition->instance_descriptors(); | 1808 DescriptorArray* target_descriptors = transition->instance_descriptors(); |
| 1831 PropertyDetails details = target_descriptors->GetDetails(descriptor); | 1809 PropertyDetails details = target_descriptors->GetDetails(descriptor); |
| 1832 | 1810 |
| 1833 if (details.type() == CALLBACKS || details.attributes() != NONE) break; | 1811 if (details.type() == CALLBACKS || details.attributes() != NONE) break; |
| 1834 | 1812 |
| 1835 return isolate()->stub_cache()->ComputeStoreTransition( | 1813 return isolate()->stub_cache()->ComputeStoreTransition( |
| 1836 name, receiver, lookup, transition, strict_mode); | 1814 name, receiver, lookup, transition, strict_mode()); |
| 1837 } | 1815 } |
| 1838 case NONEXISTENT: | 1816 case NONEXISTENT: |
| 1839 case HANDLER: | 1817 case HANDLER: |
| 1840 UNREACHABLE(); | 1818 UNREACHABLE(); |
| 1841 break; | 1819 break; |
| 1842 } | 1820 } |
| 1843 return Handle<Code>::null(); | 1821 return Handle<Code>::null(); |
| 1844 } | 1822 } |
| 1845 | 1823 |
| 1846 | 1824 |
| 1847 Handle<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver, | 1825 Handle<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver, |
| 1848 KeyedAccessStoreMode store_mode, | 1826 KeyedAccessStoreMode store_mode) { |
| 1849 StrictModeFlag strict_mode) { | |
| 1850 // Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS | 1827 // Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS |
| 1851 // via megamorphic stubs, since they don't have a map in their relocation info | 1828 // via megamorphic stubs, since they don't have a map in their relocation info |
| 1852 // and so the stubs can't be harvested for the object needed for a map check. | 1829 // and so the stubs can't be harvested for the object needed for a map check. |
| 1853 if (target()->type() != Code::NORMAL) { | 1830 if (target()->type() != Code::NORMAL) { |
| 1854 TRACE_GENERIC_IC(isolate(), "KeyedIC", "non-NORMAL target type"); | 1831 TRACE_GENERIC_IC(isolate(), "KeyedIC", "non-NORMAL target type"); |
| 1855 return strict_mode == kStrictMode ? generic_stub_strict() : generic_stub(); | 1832 return generic_stub(); |
| 1856 } | 1833 } |
| 1857 | 1834 |
| 1858 State ic_state = target()->ic_state(); | 1835 State ic_state = target()->ic_state(); |
| 1859 Handle<Map> receiver_map(receiver->map(), isolate()); | 1836 Handle<Map> receiver_map(receiver->map(), isolate()); |
| 1860 if (ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) { | 1837 if (ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) { |
| 1861 // Optimistically assume that ICs that haven't reached the MONOMORPHIC state | 1838 // Optimistically assume that ICs that haven't reached the MONOMORPHIC state |
| 1862 // yet will do so and stay there. | 1839 // yet will do so and stay there. |
| 1863 Handle<Map> monomorphic_map = ComputeTransitionedMap(receiver, store_mode); | 1840 Handle<Map> monomorphic_map = ComputeTransitionedMap(receiver, store_mode); |
| 1864 store_mode = GetNonTransitioningStoreMode(store_mode); | 1841 store_mode = GetNonTransitioningStoreMode(store_mode); |
| 1865 return isolate()->stub_cache()->ComputeKeyedStoreElement( | 1842 return isolate()->stub_cache()->ComputeKeyedStoreElement( |
| 1866 monomorphic_map, strict_mode, store_mode); | 1843 monomorphic_map, strict_mode(), store_mode); |
| 1867 } | 1844 } |
| 1868 | 1845 |
| 1869 MapHandleList target_receiver_maps; | 1846 MapHandleList target_receiver_maps; |
| 1870 target()->FindAllMaps(&target_receiver_maps); | 1847 target()->FindAllMaps(&target_receiver_maps); |
| 1871 if (target_receiver_maps.length() == 0) { | 1848 if (target_receiver_maps.length() == 0) { |
| 1872 // In the case that there is a non-map-specific IC is installed (e.g. keyed | 1849 // In the case that there is a non-map-specific IC is installed (e.g. keyed |
| 1873 // stores into properties in dictionary mode), then there will be not | 1850 // stores into properties in dictionary mode), then there will be not |
| 1874 // receiver maps in the target. | 1851 // receiver maps in the target. |
| 1875 return strict_mode == kStrictMode | 1852 return generic_stub(); |
| 1876 ? generic_stub_strict() | |
| 1877 : generic_stub(); | |
| 1878 } | 1853 } |
| 1879 | 1854 |
| 1880 // There are several special cases where an IC that is MONOMORPHIC can still | 1855 // There are several special cases where an IC that is MONOMORPHIC can still |
| 1881 // transition to a different GetNonTransitioningStoreMode IC that handles a | 1856 // transition to a different GetNonTransitioningStoreMode IC that handles a |
| 1882 // superset of the original IC. Handle those here if the receiver map hasn't | 1857 // superset of the original IC. Handle those here if the receiver map hasn't |
| 1883 // changed or it has transitioned to a more general kind. | 1858 // changed or it has transitioned to a more general kind. |
| 1884 KeyedAccessStoreMode old_store_mode = | 1859 KeyedAccessStoreMode old_store_mode = |
| 1885 Code::GetKeyedAccessStoreMode(target()->extra_ic_state()); | 1860 Code::GetKeyedAccessStoreMode(target()->extra_ic_state()); |
| 1886 Handle<Map> previous_receiver_map = target_receiver_maps.at(0); | 1861 Handle<Map> previous_receiver_map = target_receiver_maps.at(0); |
| 1887 if (ic_state == MONOMORPHIC) { | 1862 if (ic_state == MONOMORPHIC) { |
| 1888 // If the "old" and "new" maps are in the same elements map family, stay | 1863 // If the "old" and "new" maps are in the same elements map family, stay |
| 1889 // MONOMORPHIC and use the map for the most generic ElementsKind. | 1864 // MONOMORPHIC and use the map for the most generic ElementsKind. |
| 1890 Handle<Map> transitioned_receiver_map = receiver_map; | 1865 Handle<Map> transitioned_receiver_map = receiver_map; |
| 1891 if (IsTransitionStoreMode(store_mode)) { | 1866 if (IsTransitionStoreMode(store_mode)) { |
| 1892 transitioned_receiver_map = | 1867 transitioned_receiver_map = |
| 1893 ComputeTransitionedMap(receiver, store_mode); | 1868 ComputeTransitionedMap(receiver, store_mode); |
| 1894 } | 1869 } |
| 1895 if (IsTransitionedMapOfMonomorphicTarget(*transitioned_receiver_map)) { | 1870 if (IsTransitionedMapOfMonomorphicTarget(*transitioned_receiver_map)) { |
| 1896 // Element family is the same, use the "worst" case map. | 1871 // Element family is the same, use the "worst" case map. |
| 1897 store_mode = GetNonTransitioningStoreMode(store_mode); | 1872 store_mode = GetNonTransitioningStoreMode(store_mode); |
| 1898 return isolate()->stub_cache()->ComputeKeyedStoreElement( | 1873 return isolate()->stub_cache()->ComputeKeyedStoreElement( |
| 1899 transitioned_receiver_map, strict_mode, store_mode); | 1874 transitioned_receiver_map, strict_mode(), store_mode); |
| 1900 } else if (*previous_receiver_map == receiver->map() && | 1875 } else if (*previous_receiver_map == receiver->map() && |
| 1901 old_store_mode == STANDARD_STORE && | 1876 old_store_mode == STANDARD_STORE && |
| 1902 (IsGrowStoreMode(store_mode) || | 1877 (IsGrowStoreMode(store_mode) || |
| 1903 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || | 1878 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || |
| 1904 store_mode == STORE_NO_TRANSITION_HANDLE_COW)) { | 1879 store_mode == STORE_NO_TRANSITION_HANDLE_COW)) { |
| 1905 // A "normal" IC that handles stores can switch to a version that can | 1880 // A "normal" IC that handles stores can switch to a version that can |
| 1906 // grow at the end of the array, handle OOB accesses or copy COW arrays | 1881 // grow at the end of the array, handle OOB accesses or copy COW arrays |
| 1907 // and still stay MONOMORPHIC. | 1882 // and still stay MONOMORPHIC. |
| 1908 return isolate()->stub_cache()->ComputeKeyedStoreElement( | 1883 return isolate()->stub_cache()->ComputeKeyedStoreElement( |
| 1909 receiver_map, strict_mode, store_mode); | 1884 receiver_map, strict_mode(), store_mode); |
| 1910 } | 1885 } |
| 1911 } | 1886 } |
| 1912 | 1887 |
| 1913 ASSERT(ic_state != GENERIC); | 1888 ASSERT(ic_state != GENERIC); |
| 1914 | 1889 |
| 1915 bool map_added = | 1890 bool map_added = |
| 1916 AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map); | 1891 AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map); |
| 1917 | 1892 |
| 1918 if (IsTransitionStoreMode(store_mode)) { | 1893 if (IsTransitionStoreMode(store_mode)) { |
| 1919 Handle<Map> transitioned_receiver_map = | 1894 Handle<Map> transitioned_receiver_map = |
| 1920 ComputeTransitionedMap(receiver, store_mode); | 1895 ComputeTransitionedMap(receiver, store_mode); |
| 1921 map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps, | 1896 map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps, |
| 1922 transitioned_receiver_map); | 1897 transitioned_receiver_map); |
| 1923 } | 1898 } |
| 1924 | 1899 |
| 1925 if (!map_added) { | 1900 if (!map_added) { |
| 1926 // If the miss wasn't due to an unseen map, a polymorphic stub | 1901 // If the miss wasn't due to an unseen map, a polymorphic stub |
| 1927 // won't help, use the generic stub. | 1902 // won't help, use the generic stub. |
| 1928 TRACE_GENERIC_IC(isolate(), "KeyedIC", "same map added twice"); | 1903 TRACE_GENERIC_IC(isolate(), "KeyedIC", "same map added twice"); |
| 1929 return strict_mode == kStrictMode ? generic_stub_strict() : generic_stub(); | 1904 return generic_stub(); |
| 1930 } | 1905 } |
| 1931 | 1906 |
| 1932 // If the maximum number of receiver maps has been exceeded, use the generic | 1907 // If the maximum number of receiver maps has been exceeded, use the generic |
| 1933 // version of the IC. | 1908 // version of the IC. |
| 1934 if (target_receiver_maps.length() > kMaxKeyedPolymorphism) { | 1909 if (target_receiver_maps.length() > kMaxKeyedPolymorphism) { |
| 1935 TRACE_GENERIC_IC(isolate(), "KeyedIC", "max polymorph exceeded"); | 1910 TRACE_GENERIC_IC(isolate(), "KeyedIC", "max polymorph exceeded"); |
| 1936 return strict_mode == kStrictMode ? generic_stub_strict() : generic_stub(); | 1911 return generic_stub(); |
| 1937 } | 1912 } |
| 1938 | 1913 |
| 1939 // Make sure all polymorphic handlers have the same store mode, otherwise the | 1914 // Make sure all polymorphic handlers have the same store mode, otherwise the |
| 1940 // generic stub must be used. | 1915 // generic stub must be used. |
| 1941 store_mode = GetNonTransitioningStoreMode(store_mode); | 1916 store_mode = GetNonTransitioningStoreMode(store_mode); |
| 1942 if (old_store_mode != STANDARD_STORE) { | 1917 if (old_store_mode != STANDARD_STORE) { |
| 1943 if (store_mode == STANDARD_STORE) { | 1918 if (store_mode == STANDARD_STORE) { |
| 1944 store_mode = old_store_mode; | 1919 store_mode = old_store_mode; |
| 1945 } else if (store_mode != old_store_mode) { | 1920 } else if (store_mode != old_store_mode) { |
| 1946 TRACE_GENERIC_IC(isolate(), "KeyedIC", "store mode mismatch"); | 1921 TRACE_GENERIC_IC(isolate(), "KeyedIC", "store mode mismatch"); |
| 1947 return strict_mode == kStrictMode | 1922 return generic_stub(); |
| 1948 ? generic_stub_strict() | |
| 1949 : generic_stub(); | |
| 1950 } | 1923 } |
| 1951 } | 1924 } |
| 1952 | 1925 |
| 1953 // If the store mode isn't the standard mode, make sure that all polymorphic | 1926 // If the store mode isn't the standard mode, make sure that all polymorphic |
| 1954 // receivers are either external arrays, or all "normal" arrays. Otherwise, | 1927 // receivers are either external arrays, or all "normal" arrays. Otherwise, |
| 1955 // use the generic stub. | 1928 // use the generic stub. |
| 1956 if (store_mode != STANDARD_STORE) { | 1929 if (store_mode != STANDARD_STORE) { |
| 1957 int external_arrays = 0; | 1930 int external_arrays = 0; |
| 1958 for (int i = 0; i < target_receiver_maps.length(); ++i) { | 1931 for (int i = 0; i < target_receiver_maps.length(); ++i) { |
| 1959 if (target_receiver_maps[i]->has_external_array_elements()) { | 1932 if (target_receiver_maps[i]->has_external_array_elements()) { |
| 1960 external_arrays++; | 1933 external_arrays++; |
| 1961 } | 1934 } |
| 1962 } | 1935 } |
| 1963 if (external_arrays != 0 && | 1936 if (external_arrays != 0 && |
| 1964 external_arrays != target_receiver_maps.length()) { | 1937 external_arrays != target_receiver_maps.length()) { |
| 1965 TRACE_GENERIC_IC(isolate(), "KeyedIC", | 1938 TRACE_GENERIC_IC(isolate(), "KeyedIC", |
| 1966 "unsupported combination of external and normal arrays"); | 1939 "unsupported combination of external and normal arrays"); |
| 1967 return strict_mode == kStrictMode | 1940 return generic_stub(); |
| 1968 ? generic_stub_strict() | |
| 1969 : generic_stub(); | |
| 1970 } | 1941 } |
| 1971 } | 1942 } |
| 1972 | 1943 |
| 1973 return isolate()->stub_cache()->ComputeStoreElementPolymorphic( | 1944 return isolate()->stub_cache()->ComputeStoreElementPolymorphic( |
| 1974 &target_receiver_maps, store_mode, strict_mode); | 1945 &target_receiver_maps, store_mode, strict_mode()); |
| 1975 } | 1946 } |
| 1976 | 1947 |
| 1977 | 1948 |
| 1978 Handle<Map> KeyedStoreIC::ComputeTransitionedMap( | 1949 Handle<Map> KeyedStoreIC::ComputeTransitionedMap( |
| 1979 Handle<JSObject> receiver, | 1950 Handle<JSObject> receiver, |
| 1980 KeyedAccessStoreMode store_mode) { | 1951 KeyedAccessStoreMode store_mode) { |
| 1981 switch (store_mode) { | 1952 switch (store_mode) { |
| 1982 case STORE_TRANSITION_SMI_TO_OBJECT: | 1953 case STORE_TRANSITION_SMI_TO_OBJECT: |
| 1983 case STORE_TRANSITION_DOUBLE_TO_OBJECT: | 1954 case STORE_TRANSITION_DOUBLE_TO_OBJECT: |
| 1984 case STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT: | 1955 case STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT: |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2088 if (receiver->elements()->map() == heap->fixed_cow_array_map()) { | 2059 if (receiver->elements()->map() == heap->fixed_cow_array_map()) { |
| 2089 return STORE_NO_TRANSITION_HANDLE_COW; | 2060 return STORE_NO_TRANSITION_HANDLE_COW; |
| 2090 } else { | 2061 } else { |
| 2091 return STANDARD_STORE; | 2062 return STANDARD_STORE; |
| 2092 } | 2063 } |
| 2093 } | 2064 } |
| 2094 } | 2065 } |
| 2095 | 2066 |
| 2096 | 2067 |
| 2097 MaybeObject* KeyedStoreIC::Store(State state, | 2068 MaybeObject* KeyedStoreIC::Store(State state, |
| 2098 StrictModeFlag strict_mode, | |
| 2099 Handle<Object> object, | 2069 Handle<Object> object, |
| 2100 Handle<Object> key, | 2070 Handle<Object> key, |
| 2101 Handle<Object> value, | 2071 Handle<Object> value, |
| 2102 ICMissMode miss_mode) { | 2072 ICMissMode miss_mode) { |
| 2103 // Check for values that can be converted into an internalized string directly | 2073 // Check for values that can be converted into an internalized string directly |
| 2104 // or is representable as a smi. | 2074 // or is representable as a smi. |
| 2105 key = TryConvertKey(key, isolate()); | 2075 key = TryConvertKey(key, isolate()); |
| 2106 | 2076 |
| 2107 if (key->IsInternalizedString()) { | 2077 if (key->IsInternalizedString()) { |
| 2108 return StoreIC::Store(state, | 2078 return StoreIC::Store(state, |
| 2109 strict_mode, | |
| 2110 object, | 2079 object, |
| 2111 Handle<String>::cast(key), | 2080 Handle<String>::cast(key), |
| 2112 value, | 2081 value, |
| 2113 JSReceiver::MAY_BE_STORE_FROM_KEYED); | 2082 JSReceiver::MAY_BE_STORE_FROM_KEYED); |
| 2114 } | 2083 } |
| 2115 | 2084 |
| 2116 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded() && | 2085 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded() && |
| 2117 !(FLAG_harmony_observation && object->IsJSObject() && | 2086 !(FLAG_harmony_observation && object->IsJSObject() && |
| 2118 JSObject::cast(*object)->map()->is_observed()); | 2087 JSObject::cast(*object)->map()->is_observed()); |
| 2119 if (use_ic && !object->IsSmi()) { | 2088 if (use_ic && !object->IsSmi()) { |
| 2120 // Don't use ICs for maps of the objects in Array's prototype chain. We | 2089 // Don't use ICs for maps of the objects in Array's prototype chain. We |
| 2121 // expect to be able to trap element sets to objects with those maps in the | 2090 // expect to be able to trap element sets to objects with those maps in the |
| 2122 // runtime to enable optimization of element hole access. | 2091 // runtime to enable optimization of element hole access. |
| 2123 Handle<HeapObject> heap_object = Handle<HeapObject>::cast(object); | 2092 Handle<HeapObject> heap_object = Handle<HeapObject>::cast(object); |
| 2124 if (heap_object->map()->IsMapInArrayPrototypeChain()) use_ic = false; | 2093 if (heap_object->map()->IsMapInArrayPrototypeChain()) use_ic = false; |
| 2125 } | 2094 } |
| 2126 ASSERT(!(use_ic && object->IsJSGlobalProxy())); | 2095 ASSERT(!(use_ic && object->IsJSGlobalProxy())); |
| 2127 | 2096 |
| 2128 if (use_ic) { | 2097 if (use_ic) { |
| 2129 Handle<Code> stub = (strict_mode == kStrictMode) | 2098 Handle<Code> stub = generic_stub(); |
| 2130 ? generic_stub_strict() | |
| 2131 : generic_stub(); | |
| 2132 if (miss_mode != MISS_FORCE_GENERIC) { | 2099 if (miss_mode != MISS_FORCE_GENERIC) { |
| 2133 if (object->IsJSObject()) { | 2100 if (object->IsJSObject()) { |
| 2134 Handle<JSObject> receiver = Handle<JSObject>::cast(object); | 2101 Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
| 2135 if (receiver->map()->is_deprecated()) { | 2102 if (receiver->map()->is_deprecated()) { |
| 2136 JSObject::MigrateInstance(receiver); | 2103 JSObject::MigrateInstance(receiver); |
| 2137 } | 2104 } |
| 2138 bool key_is_smi_like = key->IsSmi() || !key->ToSmi()->IsFailure(); | 2105 bool key_is_smi_like = key->IsSmi() || !key->ToSmi()->IsFailure(); |
| 2139 if (receiver->elements()->map() == | 2106 if (receiver->elements()->map() == |
| 2140 isolate()->heap()->non_strict_arguments_elements_map()) { | 2107 isolate()->heap()->non_strict_arguments_elements_map()) { |
| 2141 stub = non_strict_arguments_stub(); | 2108 stub = non_strict_arguments_stub(); |
| 2142 } else if (key_is_smi_like && | 2109 } else if (key_is_smi_like && |
| 2143 (target() != *non_strict_arguments_stub())) { | 2110 (target() != *non_strict_arguments_stub())) { |
| 2144 KeyedAccessStoreMode store_mode = GetStoreMode(receiver, key, value); | 2111 KeyedAccessStoreMode store_mode = GetStoreMode(receiver, key, value); |
| 2145 stub = StoreElementStub(receiver, store_mode, strict_mode); | 2112 stub = StoreElementStub(receiver, store_mode); |
| 2146 } else { | 2113 } else { |
| 2147 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "key not a number"); | 2114 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "key not a number"); |
| 2148 } | 2115 } |
| 2149 } else { | 2116 } else { |
| 2150 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "not an object"); | 2117 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "not an object"); |
| 2151 } | 2118 } |
| 2152 } else { | 2119 } else { |
| 2153 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "force generic"); | 2120 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "force generic"); |
| 2154 } | 2121 } |
| 2155 ASSERT(!stub.is_null()); | 2122 ASSERT(!stub.is_null()); |
| 2156 set_target(*stub); | 2123 set_target(*stub); |
| 2157 TRACE_IC("KeyedStoreIC", key, state, target()); | 2124 TRACE_IC("KeyedStoreIC", key, state, target()); |
| 2158 } | 2125 } |
| 2159 | 2126 |
| 2160 return Runtime::SetObjectPropertyOrFail( | 2127 return Runtime::SetObjectPropertyOrFail( |
| 2161 isolate(), object , key, value, NONE, strict_mode); | 2128 isolate(), object , key, value, NONE, strict_mode()); |
| 2162 } | 2129 } |
| 2163 | 2130 |
| 2164 | 2131 |
| 2165 Handle<Code> KeyedStoreIC::ComputeStoreMonomorphic(LookupResult* lookup, | 2132 Handle<Code> KeyedStoreIC::ComputeStoreMonomorphic(LookupResult* lookup, |
| 2166 StrictModeFlag strict_mode, | |
| 2167 Handle<JSObject> receiver, | 2133 Handle<JSObject> receiver, |
| 2168 Handle<String> name, | 2134 Handle<String> name, |
| 2169 Handle<Object> value) { | 2135 Handle<Object> value) { |
| 2170 // If the property has a non-field type allowing map transitions | 2136 // If the property has a non-field type allowing map transitions |
| 2171 // where there is extra room in the object, we leave the IC in its | 2137 // where there is extra room in the object, we leave the IC in its |
| 2172 // current state. | 2138 // current state. |
| 2173 switch (lookup->type()) { | 2139 switch (lookup->type()) { |
| 2174 case FIELD: | 2140 case FIELD: |
| 2175 return isolate()->stub_cache()->ComputeKeyedStoreField( | 2141 return isolate()->stub_cache()->ComputeKeyedStoreField( |
| 2176 name, receiver, lookup, strict_mode); | 2142 name, receiver, lookup, strict_mode()); |
| 2177 case TRANSITION: { | 2143 case TRANSITION: { |
| 2178 // Explicitly pass in the receiver map since LookupForWrite may have | 2144 // Explicitly pass in the receiver map since LookupForWrite may have |
| 2179 // stored something else than the receiver in the holder. | 2145 // stored something else than the receiver in the holder. |
| 2180 Handle<Map> transition( | 2146 Handle<Map> transition( |
| 2181 lookup->GetTransitionTarget(receiver->map()), isolate()); | 2147 lookup->GetTransitionTarget(receiver->map()), isolate()); |
| 2182 int descriptor = transition->LastAdded(); | 2148 int descriptor = transition->LastAdded(); |
| 2183 | 2149 |
| 2184 DescriptorArray* target_descriptors = transition->instance_descriptors(); | 2150 DescriptorArray* target_descriptors = transition->instance_descriptors(); |
| 2185 PropertyDetails details = target_descriptors->GetDetails(descriptor); | 2151 PropertyDetails details = target_descriptors->GetDetails(descriptor); |
| 2186 | 2152 |
| 2187 if (details.type() != CALLBACKS && details.attributes() == NONE) { | 2153 if (details.type() != CALLBACKS && details.attributes() == NONE) { |
| 2188 return isolate()->stub_cache()->ComputeKeyedStoreTransition( | 2154 return isolate()->stub_cache()->ComputeKeyedStoreTransition( |
| 2189 name, receiver, lookup, transition, strict_mode); | 2155 name, receiver, lookup, transition, strict_mode()); |
| 2190 } | 2156 } |
| 2191 // fall through. | 2157 // fall through. |
| 2192 } | 2158 } |
| 2193 case NORMAL: | 2159 case NORMAL: |
| 2194 case CONSTANT: | 2160 case CONSTANT: |
| 2195 case CALLBACKS: | 2161 case CALLBACKS: |
| 2196 case INTERCEPTOR: | 2162 case INTERCEPTOR: |
| 2197 // Always rewrite to the generic case so that we do not | 2163 // Always rewrite to the generic case so that we do not |
| 2198 // repeatedly try to rewrite. | 2164 // repeatedly try to rewrite. |
| 2199 return (strict_mode == kStrictMode) | 2165 return generic_stub(); |
| 2200 ? generic_stub_strict() | |
| 2201 : generic_stub(); | |
| 2202 case HANDLER: | 2166 case HANDLER: |
| 2203 case NONEXISTENT: | 2167 case NONEXISTENT: |
| 2204 UNREACHABLE(); | 2168 UNREACHABLE(); |
| 2205 break; | 2169 break; |
| 2206 } | 2170 } |
| 2207 return Handle<Code>::null(); | 2171 return Handle<Code>::null(); |
| 2208 } | 2172 } |
| 2209 | 2173 |
| 2210 | 2174 |
| 2211 #undef TRACE_IC | 2175 #undef TRACE_IC |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2302 MISS_FORCE_GENERIC); | 2266 MISS_FORCE_GENERIC); |
| 2303 } | 2267 } |
| 2304 | 2268 |
| 2305 | 2269 |
| 2306 // Used from ic-<arch>.cc. | 2270 // Used from ic-<arch>.cc. |
| 2307 RUNTIME_FUNCTION(MaybeObject*, StoreIC_Miss) { | 2271 RUNTIME_FUNCTION(MaybeObject*, StoreIC_Miss) { |
| 2308 HandleScope scope(isolate); | 2272 HandleScope scope(isolate); |
| 2309 ASSERT(args.length() == 3); | 2273 ASSERT(args.length() == 3); |
| 2310 StoreIC ic(IC::NO_EXTRA_FRAME, isolate); | 2274 StoreIC ic(IC::NO_EXTRA_FRAME, isolate); |
| 2311 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); | 2275 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); |
| 2312 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); | |
| 2313 return ic.Store(state, | 2276 return ic.Store(state, |
| 2314 Code::GetStrictMode(extra_ic_state), | |
| 2315 args.at<Object>(0), | 2277 args.at<Object>(0), |
| 2316 args.at<String>(1), | 2278 args.at<String>(1), |
| 2317 args.at<Object>(2)); | 2279 args.at<Object>(2)); |
| 2318 } | 2280 } |
| 2319 | 2281 |
| 2320 | 2282 |
| 2321 RUNTIME_FUNCTION(MaybeObject*, StoreIC_MissFromStubFailure) { | 2283 RUNTIME_FUNCTION(MaybeObject*, StoreIC_MissFromStubFailure) { |
| 2322 HandleScope scope(isolate); | 2284 HandleScope scope(isolate); |
| 2323 ASSERT(args.length() == 3); | 2285 ASSERT(args.length() == 3); |
| 2324 StoreIC ic(IC::EXTRA_CALL_FRAME, isolate); | 2286 StoreIC ic(IC::EXTRA_CALL_FRAME, isolate); |
| 2325 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); | 2287 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); |
| 2326 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); | |
| 2327 return ic.Store(state, | 2288 return ic.Store(state, |
| 2328 Code::GetStrictMode(extra_ic_state), | |
| 2329 args.at<Object>(0), | 2289 args.at<Object>(0), |
| 2330 args.at<String>(1), | 2290 args.at<String>(1), |
| 2331 args.at<Object>(2)); | 2291 args.at<Object>(2)); |
| 2332 } | 2292 } |
| 2333 | 2293 |
| 2334 | 2294 |
| 2335 RUNTIME_FUNCTION(MaybeObject*, StoreIC_ArrayLength) { | 2295 RUNTIME_FUNCTION(MaybeObject*, StoreIC_ArrayLength) { |
| 2336 SealHandleScope shs(isolate); | 2296 SealHandleScope shs(isolate); |
| 2337 | 2297 |
| 2338 ASSERT(args.length() == 2); | 2298 ASSERT(args.length() == 2); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2405 return value; | 2365 return value; |
| 2406 } | 2366 } |
| 2407 | 2367 |
| 2408 | 2368 |
| 2409 // Used from ic-<arch>.cc. | 2369 // Used from ic-<arch>.cc. |
| 2410 RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Miss) { | 2370 RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Miss) { |
| 2411 HandleScope scope(isolate); | 2371 HandleScope scope(isolate); |
| 2412 ASSERT(args.length() == 3); | 2372 ASSERT(args.length() == 3); |
| 2413 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate); | 2373 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate); |
| 2414 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); | 2374 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); |
| 2415 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); | |
| 2416 return ic.Store(state, | 2375 return ic.Store(state, |
| 2417 Code::GetStrictMode(extra_ic_state), | |
| 2418 args.at<Object>(0), | 2376 args.at<Object>(0), |
| 2419 args.at<Object>(1), | 2377 args.at<Object>(1), |
| 2420 args.at<Object>(2), | 2378 args.at<Object>(2), |
| 2421 MISS); | 2379 MISS); |
| 2422 } | 2380 } |
| 2423 | 2381 |
| 2424 | 2382 |
| 2425 RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissFromStubFailure) { | 2383 RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissFromStubFailure) { |
| 2426 HandleScope scope(isolate); | 2384 HandleScope scope(isolate); |
| 2427 ASSERT(args.length() == 3); | 2385 ASSERT(args.length() == 3); |
| 2428 KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate); | 2386 KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate); |
| 2429 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); | 2387 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); |
| 2430 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); | |
| 2431 return ic.Store(state, | 2388 return ic.Store(state, |
| 2432 Code::GetStrictMode(extra_ic_state), | |
| 2433 args.at<Object>(0), | 2389 args.at<Object>(0), |
| 2434 args.at<Object>(1), | 2390 args.at<Object>(1), |
| 2435 args.at<Object>(2), | 2391 args.at<Object>(2), |
| 2436 MISS); | 2392 MISS); |
| 2437 } | 2393 } |
| 2438 | 2394 |
| 2439 | 2395 |
| 2440 RUNTIME_FUNCTION(MaybeObject*, StoreIC_Slow) { | 2396 RUNTIME_FUNCTION(MaybeObject*, StoreIC_Slow) { |
| 2441 SealHandleScope shs(isolate); | 2397 SealHandleScope shs(isolate); |
| 2442 ASSERT(args.length() == 3); | 2398 ASSERT(args.length() == 3); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 2471 NONE, | 2427 NONE, |
| 2472 strict_mode); | 2428 strict_mode); |
| 2473 } | 2429 } |
| 2474 | 2430 |
| 2475 | 2431 |
| 2476 RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissForceGeneric) { | 2432 RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissForceGeneric) { |
| 2477 HandleScope scope(isolate); | 2433 HandleScope scope(isolate); |
| 2478 ASSERT(args.length() == 3); | 2434 ASSERT(args.length() == 3); |
| 2479 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate); | 2435 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate); |
| 2480 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); | 2436 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); |
| 2481 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); | |
| 2482 return ic.Store(state, | 2437 return ic.Store(state, |
| 2483 Code::GetStrictMode(extra_ic_state), | |
| 2484 args.at<Object>(0), | 2438 args.at<Object>(0), |
| 2485 args.at<Object>(1), | 2439 args.at<Object>(1), |
| 2486 args.at<Object>(2), | 2440 args.at<Object>(2), |
| 2487 MISS_FORCE_GENERIC); | 2441 MISS_FORCE_GENERIC); |
| 2488 } | 2442 } |
| 2489 | 2443 |
| 2490 | 2444 |
| 2491 RUNTIME_FUNCTION(MaybeObject*, ElementsTransitionAndStoreIC_Miss) { | 2445 RUNTIME_FUNCTION(MaybeObject*, ElementsTransitionAndStoreIC_Miss) { |
| 2492 SealHandleScope scope(isolate); | 2446 SealHandleScope scope(isolate); |
| 2493 ASSERT(args.length() == 4); | 2447 ASSERT(args.length() == 4); |
| (...skipping 608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3102 #undef ADDR | 3056 #undef ADDR |
| 3103 }; | 3057 }; |
| 3104 | 3058 |
| 3105 | 3059 |
| 3106 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 3060 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
| 3107 return IC_utilities[id]; | 3061 return IC_utilities[id]; |
| 3108 } | 3062 } |
| 3109 | 3063 |
| 3110 | 3064 |
| 3111 } } // namespace v8::internal | 3065 } } // namespace v8::internal |
| OLD | NEW |