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 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 // receiver itself or changes to one of its prototypes. | 210 // receiver itself or changes to one of its prototypes. |
211 // | 211 // |
212 // If there are changes to the receiver itself, the map of the | 212 // If there are changes to the receiver itself, the map of the |
213 // receiver will have changed and the current target will not be in | 213 // receiver will have changed and the current target will not be in |
214 // the receiver map's code cache. Therefore, if the current target | 214 // the receiver map's code cache. Therefore, if the current target |
215 // is in the receiver map's code cache, the inline cache failed due | 215 // is in the receiver map's code cache, the inline cache failed due |
216 // to prototype check failure. | 216 // to prototype check failure. |
217 int index = map->IndexInCodeCache(name, target); | 217 int index = map->IndexInCodeCache(name, target); |
218 if (index >= 0) { | 218 if (index >= 0) { |
219 map->RemoveFromCodeCache(String::cast(name), target, index); | 219 map->RemoveFromCodeCache(String::cast(name), target, index); |
220 // For loads, handlers are stored in addition to the ICs on the map. Remove | 220 // For loads and stores, handlers are stored in addition to the ICs on the |
221 // those, too. | 221 // map. Remove those, too. |
222 if (target->is_load_stub() || target->is_keyed_load_stub()) { | 222 if ((target->is_load_stub() || target->is_keyed_load_stub() || |
| 223 target->is_store_stub() || target->is_keyed_store_stub()) && |
| 224 target->type() != Code::NORMAL) { |
223 Code* handler = target->FindFirstCode(); | 225 Code* handler = target->FindFirstCode(); |
224 index = map->IndexInCodeCache(name, handler); | 226 index = map->IndexInCodeCache(name, handler); |
225 if (index >= 0) { | 227 if (index >= 0) { |
226 map->RemoveFromCodeCache(String::cast(name), handler, index); | 228 map->RemoveFromCodeCache(String::cast(name), handler, index); |
227 } | 229 } |
228 } | 230 } |
229 return true; | 231 return true; |
230 } | 232 } |
231 | 233 |
232 // If the IC is shared between multiple receivers (slow dictionary mode), then | 234 // If the IC is shared between multiple receivers (slow dictionary mode), then |
(...skipping 732 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
965 receiver_maps->at(current).is_identical_to(new_receiver_map)) { | 967 receiver_maps->at(current).is_identical_to(new_receiver_map)) { |
966 return false; | 968 return false; |
967 } | 969 } |
968 } | 970 } |
969 receiver_maps->Add(new_receiver_map); | 971 receiver_maps->Add(new_receiver_map); |
970 return true; | 972 return true; |
971 } | 973 } |
972 | 974 |
973 | 975 |
974 bool IC::UpdatePolymorphicIC(State state, | 976 bool IC::UpdatePolymorphicIC(State state, |
975 StrictModeFlag strict_mode, | |
976 Handle<JSObject> receiver, | 977 Handle<JSObject> receiver, |
977 Handle<String> name, | 978 Handle<String> name, |
978 Handle<Code> code) { | 979 Handle<Code> code, |
| 980 StrictModeFlag strict_mode) { |
979 if (code->type() == Code::NORMAL) return false; | 981 if (code->type() == Code::NORMAL) return false; |
980 if (target()->ic_state() == MONOMORPHIC && | 982 if (target()->ic_state() == MONOMORPHIC && |
981 target()->type() == Code::NORMAL) { | 983 target()->type() == Code::NORMAL) { |
982 return false; | 984 return false; |
983 } | 985 } |
984 | 986 |
985 MapHandleList receiver_maps; | 987 MapHandleList receiver_maps; |
986 CodeHandleList handlers; | 988 CodeHandleList handlers; |
987 | 989 |
988 int number_of_valid_maps; | 990 int number_of_valid_maps; |
(...skipping 30 matching lines...) Expand all Loading... |
1019 } | 1021 } |
1020 | 1022 |
1021 number_of_valid_maps++; | 1023 number_of_valid_maps++; |
1022 if (handler_to_overwrite >= 0) { | 1024 if (handler_to_overwrite >= 0) { |
1023 handlers.Set(handler_to_overwrite, code); | 1025 handlers.Set(handler_to_overwrite, code); |
1024 } else { | 1026 } else { |
1025 receiver_maps.Add(new_receiver_map); | 1027 receiver_maps.Add(new_receiver_map); |
1026 handlers.Add(code); | 1028 handlers.Add(code); |
1027 } | 1029 } |
1028 | 1030 |
1029 Handle<Code> ic = isolate()->stub_cache()->ComputePolymorphicIC( | 1031 Handle<Code> ic = ComputePolymorphicIC( |
1030 &receiver_maps, &handlers, number_of_valid_maps, name); | 1032 &receiver_maps, &handlers, number_of_valid_maps, name, strict_mode); |
1031 set_target(*ic); | 1033 set_target(*ic); |
1032 return true; | 1034 return true; |
1033 } | 1035 } |
1034 | 1036 |
1035 | 1037 |
| 1038 Handle<Code> LoadIC::ComputePolymorphicIC(MapHandleList* receiver_maps, |
| 1039 CodeHandleList* handlers, |
| 1040 int number_of_valid_maps, |
| 1041 Handle<Name> name, |
| 1042 StrictModeFlag strict_mode) { |
| 1043 return isolate()->stub_cache()->ComputePolymorphicLoadIC( |
| 1044 receiver_maps, handlers, number_of_valid_maps, name); |
| 1045 } |
| 1046 |
| 1047 |
| 1048 Handle<Code> StoreIC::ComputePolymorphicIC(MapHandleList* receiver_maps, |
| 1049 CodeHandleList* handlers, |
| 1050 int number_of_valid_maps, |
| 1051 Handle<Name> name, |
| 1052 StrictModeFlag strict_mode) { |
| 1053 return isolate()->stub_cache()->ComputePolymorphicStoreIC( |
| 1054 receiver_maps, handlers, number_of_valid_maps, name, strict_mode); |
| 1055 } |
| 1056 |
| 1057 |
1036 void LoadIC::UpdateMonomorphicIC(Handle<JSObject> receiver, | 1058 void LoadIC::UpdateMonomorphicIC(Handle<JSObject> receiver, |
1037 Handle<Code> handler, | 1059 Handle<Code> handler, |
1038 Handle<String> name) { | 1060 Handle<String> name, |
| 1061 StrictModeFlag strict_mode) { |
1039 if (handler->type() == Code::NORMAL) return set_target(*handler); | 1062 if (handler->type() == Code::NORMAL) return set_target(*handler); |
1040 Handle<Code> ic = isolate()->stub_cache()->ComputeMonomorphicIC( | 1063 Handle<Code> ic = isolate()->stub_cache()->ComputeMonomorphicLoadIC( |
1041 receiver, handler, name); | 1064 receiver, handler, name); |
1042 set_target(*ic); | 1065 set_target(*ic); |
1043 } | 1066 } |
1044 | 1067 |
1045 | 1068 |
1046 void KeyedLoadIC::UpdateMonomorphicIC(Handle<JSObject> receiver, | 1069 void KeyedLoadIC::UpdateMonomorphicIC(Handle<JSObject> receiver, |
1047 Handle<Code> handler, | 1070 Handle<Code> handler, |
1048 Handle<String> name) { | 1071 Handle<String> name, |
| 1072 StrictModeFlag strict_mode) { |
1049 if (handler->type() == Code::NORMAL) return set_target(*handler); | 1073 if (handler->type() == Code::NORMAL) return set_target(*handler); |
1050 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedMonomorphicIC( | 1074 Handle<Code> ic = isolate()->stub_cache()->ComputeMonomorphicKeyedLoadIC( |
1051 receiver, handler, name); | 1075 receiver, handler, name); |
1052 set_target(*ic); | 1076 set_target(*ic); |
1053 } | 1077 } |
1054 | 1078 |
1055 | 1079 |
| 1080 void StoreIC::UpdateMonomorphicIC(Handle<JSObject> receiver, |
| 1081 Handle<Code> handler, |
| 1082 Handle<String> name, |
| 1083 StrictModeFlag strict_mode) { |
| 1084 if (handler->type() == Code::NORMAL) return set_target(*handler); |
| 1085 Handle<Code> ic = isolate()->stub_cache()->ComputeMonomorphicStoreIC( |
| 1086 receiver, handler, name, strict_mode); |
| 1087 set_target(*ic); |
| 1088 } |
| 1089 |
| 1090 |
| 1091 void KeyedStoreIC::UpdateMonomorphicIC(Handle<JSObject> receiver, |
| 1092 Handle<Code> handler, |
| 1093 Handle<String> name, |
| 1094 StrictModeFlag strict_mode) { |
| 1095 if (handler->type() == Code::NORMAL) return set_target(*handler); |
| 1096 Handle<Code> ic = isolate()->stub_cache()->ComputeMonomorphicKeyedStoreIC( |
| 1097 receiver, handler, name, strict_mode); |
| 1098 set_target(*ic); |
| 1099 } |
| 1100 |
| 1101 |
1056 void IC::CopyICToMegamorphicCache(Handle<String> name) { | 1102 void IC::CopyICToMegamorphicCache(Handle<String> name) { |
1057 MapHandleList receiver_maps; | 1103 MapHandleList receiver_maps; |
1058 CodeHandleList handlers; | 1104 CodeHandleList handlers; |
1059 { | 1105 { |
1060 DisallowHeapAllocation no_gc; | 1106 DisallowHeapAllocation no_gc; |
1061 target()->FindAllMaps(&receiver_maps); | 1107 target()->FindAllMaps(&receiver_maps); |
1062 target()->FindAllCode(&handlers, receiver_maps.length()); | 1108 target()->FindAllCode(&handlers, receiver_maps.length()); |
1063 } | 1109 } |
1064 for (int i = 0; i < receiver_maps.length(); i++) { | 1110 for (int i = 0; i < receiver_maps.length(); i++) { |
1065 UpdateMegamorphicCache(*receiver_maps.at(i), *name, *handlers.at(i)); | 1111 UpdateMegamorphicCache(*receiver_maps.at(i), *name, *handlers.at(i)); |
(...skipping 21 matching lines...) Expand all Loading... |
1087 // not necessarily equal to target()->state(). | 1133 // not necessarily equal to target()->state(). |
1088 void IC::PatchCache(State state, | 1134 void IC::PatchCache(State state, |
1089 StrictModeFlag strict_mode, | 1135 StrictModeFlag strict_mode, |
1090 Handle<JSObject> receiver, | 1136 Handle<JSObject> receiver, |
1091 Handle<String> name, | 1137 Handle<String> name, |
1092 Handle<Code> code) { | 1138 Handle<Code> code) { |
1093 switch (state) { | 1139 switch (state) { |
1094 case UNINITIALIZED: | 1140 case UNINITIALIZED: |
1095 case PREMONOMORPHIC: | 1141 case PREMONOMORPHIC: |
1096 case MONOMORPHIC_PROTOTYPE_FAILURE: | 1142 case MONOMORPHIC_PROTOTYPE_FAILURE: |
1097 UpdateMonomorphicIC(receiver, code, name); | 1143 UpdateMonomorphicIC(receiver, code, name, strict_mode); |
1098 break; | 1144 break; |
1099 case MONOMORPHIC: | 1145 case MONOMORPHIC: |
1100 // Only move to megamorphic if the target changes. | 1146 // Only move to megamorphic if the target changes. |
1101 if (target() != *code) { | 1147 if (target() != *code) { |
1102 if (target()->is_load_stub()) { | 1148 if (target()->is_load_stub() || target()->is_store_stub()) { |
1103 bool is_same_handler = false; | 1149 bool is_same_handler = false; |
1104 { | 1150 { |
1105 DisallowHeapAllocation no_allocation; | 1151 DisallowHeapAllocation no_allocation; |
1106 Code* old_handler = target()->FindFirstCode(); | 1152 Code* old_handler = target()->FindFirstCode(); |
1107 is_same_handler = old_handler == *code; | 1153 is_same_handler = old_handler == *code; |
1108 } | 1154 } |
1109 if (is_same_handler | 1155 if (is_same_handler |
1110 && IsTransitionedMapOfMonomorphicTarget(receiver->map())) { | 1156 && IsTransitionedMapOfMonomorphicTarget(receiver->map())) { |
1111 UpdateMonomorphicIC(receiver, code, name); | 1157 UpdateMonomorphicIC(receiver, code, name, strict_mode); |
1112 break; | 1158 break; |
1113 } | 1159 } |
1114 if (UpdatePolymorphicIC(state, strict_mode, receiver, name, code)) { | 1160 if (UpdatePolymorphicIC(state, receiver, name, code, strict_mode)) { |
1115 break; | 1161 break; |
1116 } | 1162 } |
1117 | 1163 |
1118 if (target()->type() != Code::NORMAL) { | 1164 if (target()->type() != Code::NORMAL) { |
1119 CopyICToMegamorphicCache(name); | 1165 CopyICToMegamorphicCache(name); |
1120 } | 1166 } |
1121 } | 1167 } |
1122 | 1168 |
1123 UpdateMegamorphicCache(receiver->map(), *name, *code); | 1169 UpdateMegamorphicCache(receiver->map(), *name, *code); |
1124 set_target((strict_mode == kStrictMode) | 1170 set_target((strict_mode == kStrictMode) |
1125 ? *megamorphic_stub_strict() | 1171 ? *megamorphic_stub_strict() |
1126 : *megamorphic_stub()); | 1172 : *megamorphic_stub()); |
1127 } | 1173 } |
1128 break; | 1174 break; |
1129 case MEGAMORPHIC: | 1175 case MEGAMORPHIC: |
1130 // Update the stub cache. | 1176 // Update the stub cache. |
1131 UpdateMegamorphicCache(receiver->map(), *name, *code); | 1177 UpdateMegamorphicCache(receiver->map(), *name, *code); |
1132 break; | 1178 break; |
1133 case POLYMORPHIC: | 1179 case POLYMORPHIC: |
1134 if (target()->is_load_stub()) { | 1180 if (target()->is_load_stub() || target()->is_store_stub()) { |
1135 if (UpdatePolymorphicIC(state, strict_mode, receiver, name, code)) { | 1181 if (UpdatePolymorphicIC(state, receiver, name, code, strict_mode)) { |
1136 break; | 1182 break; |
1137 } | 1183 } |
1138 CopyICToMegamorphicCache(name); | 1184 CopyICToMegamorphicCache(name); |
1139 UpdateMegamorphicCache(receiver->map(), *name, *code); | 1185 UpdateMegamorphicCache(receiver->map(), *name, *code); |
1140 set_target(*megamorphic_stub()); | 1186 set_target((strict_mode == kStrictMode) |
| 1187 ? *megamorphic_stub_strict() |
| 1188 : *megamorphic_stub()); |
1141 } else { | 1189 } else { |
1142 // When trying to patch a polymorphic keyed load/store element stub | 1190 // When trying to patch a polymorphic keyed load/store element stub |
1143 // with anything other than another polymorphic stub, go generic. | 1191 // with anything other than another polymorphic stub, go generic. |
1144 set_target((strict_mode == kStrictMode) | 1192 set_target((strict_mode == kStrictMode) |
1145 ? *generic_stub_strict() | 1193 ? *generic_stub_strict() |
1146 : *generic_stub()); | 1194 : *generic_stub()); |
1147 } | 1195 } |
1148 break; | 1196 break; |
1149 case DEBUG_STUB: | 1197 case DEBUG_STUB: |
1150 break; | 1198 break; |
(...skipping 1882 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3033 #undef ADDR | 3081 #undef ADDR |
3034 }; | 3082 }; |
3035 | 3083 |
3036 | 3084 |
3037 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 3085 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
3038 return IC_utilities[id]; | 3086 return IC_utilities[id]; |
3039 } | 3087 } |
3040 | 3088 |
3041 | 3089 |
3042 } } // namespace v8::internal | 3090 } } // namespace v8::internal |
OLD | NEW |