Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(688)

Side by Side Diff: src/ic.cc

Issue 14142005: Implement Polymorphic Store ICs (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ic.h ('k') | src/stub-cache.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/ic.h ('k') | src/stub-cache.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698