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 and stores, handlers are stored in addition to the ICs on the | 220 // Handlers are stored in addition to the ICs on the map. Remove those, too. |
221 // map. Remove those, too. | 221 Code* handler = target->FindFirstHandler(); |
222 if ((target->is_load_stub() || target->is_keyed_load_stub() || | 222 if (handler != NULL) { |
223 target->is_store_stub() || target->is_keyed_store_stub()) && | |
224 target->type() != Code::NORMAL) { | |
225 Code* handler = target->FindFirstCode(); | |
226 index = map->IndexInCodeCache(name, handler); | 223 index = map->IndexInCodeCache(name, handler); |
227 if (index >= 0) { | 224 if (index >= 0) { |
228 map->RemoveFromCodeCache(String::cast(name), handler, index); | 225 map->RemoveFromCodeCache(String::cast(name), handler, index); |
229 } | 226 } |
230 } | 227 } |
231 return true; | 228 return true; |
232 } | 229 } |
233 | 230 |
234 // The stub is not in the cache. We've ruled out all other kinds of failure | 231 // The stub is not in the cache. We've ruled out all other kinds of failure |
235 // except for proptotype chain changes, a deprecated map, a map that's | 232 // except for proptotype chain changes, a deprecated map, a map that's |
(...skipping 757 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
993 return true; | 990 return true; |
994 } | 991 } |
995 | 992 |
996 | 993 |
997 bool IC::UpdatePolymorphicIC(State state, | 994 bool IC::UpdatePolymorphicIC(State state, |
998 Handle<HeapObject> receiver, | 995 Handle<HeapObject> receiver, |
999 Handle<String> name, | 996 Handle<String> name, |
1000 Handle<Code> code, | 997 Handle<Code> code, |
1001 StrictModeFlag strict_mode) { | 998 StrictModeFlag strict_mode) { |
1002 if (code->kind() != Code::HANDLER) return false; | 999 if (code->kind() != Code::HANDLER) return false; |
1003 if (target()->ic_state() == MONOMORPHIC && | |
1004 target()->type() == Code::NORMAL) { | |
1005 return false; | |
1006 } | |
1007 | 1000 |
1008 MapHandleList receiver_maps; | 1001 MapHandleList receiver_maps; |
1009 CodeHandleList handlers; | 1002 CodeHandleList handlers; |
1010 | 1003 |
1011 int number_of_valid_maps; | 1004 int number_of_valid_maps; |
1012 int handler_to_overwrite = -1; | 1005 int handler_to_overwrite = -1; |
1013 Handle<Map> new_receiver_map(receiver->map()); | 1006 Handle<Map> new_receiver_map(receiver->map()); |
1014 { | 1007 { |
1015 DisallowHeapAllocation no_gc; | 1008 DisallowHeapAllocation no_gc; |
1016 target()->FindAllMaps(&receiver_maps); | 1009 target()->FindAllMaps(&receiver_maps); |
(...skipping 14 matching lines...) Expand all Loading... |
1031 } | 1024 } |
1032 } | 1025 } |
1033 | 1026 |
1034 if (number_of_valid_maps >= 4) return false; | 1027 if (number_of_valid_maps >= 4) return false; |
1035 | 1028 |
1036 // Only allow 0 maps in case target() was reset to UNINITIALIZED by the GC. | 1029 // Only allow 0 maps in case target() was reset to UNINITIALIZED by the GC. |
1037 // In that case, allow the IC to go back monomorphic. | 1030 // In that case, allow the IC to go back monomorphic. |
1038 if (number_of_maps == 0 && target()->ic_state() != UNINITIALIZED) { | 1031 if (number_of_maps == 0 && target()->ic_state() != UNINITIALIZED) { |
1039 return false; | 1032 return false; |
1040 } | 1033 } |
1041 target()->FindAllCode(&handlers, receiver_maps.length()); | 1034 |
| 1035 if (!target()->FindHandlers(&handlers, receiver_maps.length())) { |
| 1036 return false; |
| 1037 } |
1042 } | 1038 } |
1043 | 1039 |
1044 number_of_valid_maps++; | 1040 number_of_valid_maps++; |
1045 if (handler_to_overwrite >= 0) { | 1041 if (handler_to_overwrite >= 0) { |
1046 handlers.Set(handler_to_overwrite, code); | 1042 handlers.Set(handler_to_overwrite, code); |
1047 } else { | 1043 } else { |
1048 receiver_maps.Add(new_receiver_map); | 1044 receiver_maps.Add(new_receiver_map); |
1049 handlers.Add(code); | 1045 handlers.Add(code); |
1050 } | 1046 } |
1051 | 1047 |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1119 set_target(*ic); | 1115 set_target(*ic); |
1120 } | 1116 } |
1121 | 1117 |
1122 | 1118 |
1123 void IC::CopyICToMegamorphicCache(Handle<String> name) { | 1119 void IC::CopyICToMegamorphicCache(Handle<String> name) { |
1124 MapHandleList receiver_maps; | 1120 MapHandleList receiver_maps; |
1125 CodeHandleList handlers; | 1121 CodeHandleList handlers; |
1126 { | 1122 { |
1127 DisallowHeapAllocation no_gc; | 1123 DisallowHeapAllocation no_gc; |
1128 target()->FindAllMaps(&receiver_maps); | 1124 target()->FindAllMaps(&receiver_maps); |
1129 target()->FindAllCode(&handlers, receiver_maps.length()); | 1125 if (!target()->FindHandlers(&handlers, receiver_maps.length())) return; |
1130 } | 1126 } |
1131 for (int i = 0; i < receiver_maps.length(); i++) { | 1127 for (int i = 0; i < receiver_maps.length(); i++) { |
1132 UpdateMegamorphicCache(*receiver_maps.at(i), *name, *handlers.at(i)); | 1128 UpdateMegamorphicCache(*receiver_maps.at(i), *name, *handlers.at(i)); |
1133 } | 1129 } |
1134 } | 1130 } |
1135 | 1131 |
1136 | 1132 |
1137 bool IC::IsTransitionedMapOfMonomorphicTarget(Map* receiver_map) { | 1133 bool IC::IsTransitionedMapOfMonomorphicTarget(Map* receiver_map) { |
1138 DisallowHeapAllocation no_allocation; | 1134 DisallowHeapAllocation no_allocation; |
1139 | 1135 |
(...skipping 23 matching lines...) Expand all Loading... |
1163 case MONOMORPHIC_PROTOTYPE_FAILURE: | 1159 case MONOMORPHIC_PROTOTYPE_FAILURE: |
1164 UpdateMonomorphicIC(receiver, code, name, strict_mode); | 1160 UpdateMonomorphicIC(receiver, code, name, strict_mode); |
1165 break; | 1161 break; |
1166 case MONOMORPHIC: | 1162 case MONOMORPHIC: |
1167 // Only move to megamorphic if the target changes. | 1163 // Only move to megamorphic if the target changes. |
1168 if (target() != *code) { | 1164 if (target() != *code) { |
1169 if (target()->is_load_stub() || target()->is_store_stub()) { | 1165 if (target()->is_load_stub() || target()->is_store_stub()) { |
1170 bool is_same_handler = false; | 1166 bool is_same_handler = false; |
1171 { | 1167 { |
1172 DisallowHeapAllocation no_allocation; | 1168 DisallowHeapAllocation no_allocation; |
1173 Code* old_handler = target()->FindFirstCode(); | 1169 Code* old_handler = target()->FindFirstHandler(); |
1174 is_same_handler = old_handler == *code; | 1170 is_same_handler = old_handler == *code; |
1175 } | 1171 } |
1176 if (is_same_handler | 1172 if (is_same_handler |
1177 && IsTransitionedMapOfMonomorphicTarget(receiver->map())) { | 1173 && IsTransitionedMapOfMonomorphicTarget(receiver->map())) { |
1178 UpdateMonomorphicIC(receiver, code, name, strict_mode); | 1174 UpdateMonomorphicIC(receiver, code, name, strict_mode); |
1179 break; | 1175 break; |
1180 } | 1176 } |
1181 if (UpdatePolymorphicIC(state, receiver, name, code, strict_mode)) { | 1177 if (UpdatePolymorphicIC(state, receiver, name, code, strict_mode)) { |
1182 break; | 1178 break; |
1183 } | 1179 } |
1184 | 1180 |
1185 if (target()->type() != Code::NORMAL) { | 1181 CopyICToMegamorphicCache(name); |
1186 CopyICToMegamorphicCache(name); | |
1187 } | |
1188 } | 1182 } |
1189 | 1183 |
1190 UpdateMegamorphicCache(receiver->map(), *name, *code); | 1184 UpdateMegamorphicCache(receiver->map(), *name, *code); |
1191 set_target((strict_mode == kStrictMode) | 1185 set_target((strict_mode == kStrictMode) |
1192 ? *megamorphic_stub_strict() | 1186 ? *megamorphic_stub_strict() |
1193 : *megamorphic_stub()); | 1187 : *megamorphic_stub()); |
1194 } | 1188 } |
1195 break; | 1189 break; |
1196 case MEGAMORPHIC: | 1190 case MEGAMORPHIC: |
1197 // Update the stub cache. | 1191 // Update the stub cache. |
(...skipping 1964 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3162 #undef ADDR | 3156 #undef ADDR |
3163 }; | 3157 }; |
3164 | 3158 |
3165 | 3159 |
3166 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 3160 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
3167 return IC_utilities[id]; | 3161 return IC_utilities[id]; |
3168 } | 3162 } |
3169 | 3163 |
3170 | 3164 |
3171 } } // namespace v8::internal | 3165 } } // namespace v8::internal |
OLD | NEW |