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

Side by Side Diff: src/ic.cc

Issue 61773004: Remove DisallowHeapAllocation requirement now that the target() is cached on the IC. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 1 month 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 | « no previous file | no next file » | 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 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 break; 263 break;
264 default: 264 default:
265 return false; 265 return false;
266 } 266 }
267 return false; 267 return false;
268 } 268 }
269 269
270 270
271 bool IC::TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver, 271 bool IC::TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver,
272 Handle<String> name) { 272 Handle<String> name) {
273 DisallowHeapAllocation no_gc;
274
275 if (target()->is_call_stub()) { 273 if (target()->is_call_stub()) {
276 LookupResult lookup(isolate()); 274 LookupResult lookup(isolate());
277 LookupForRead(receiver, name, &lookup); 275 LookupForRead(receiver, name, &lookup);
278 if (static_cast<CallIC*>(this)->TryUpdateExtraICState(&lookup, receiver)) { 276 if (static_cast<CallIC*>(this)->TryUpdateExtraICState(&lookup, receiver)) {
279 return true; 277 return true;
280 } 278 }
281 } 279 }
282 280
283 if (target()->is_keyed_stub()) { 281 if (target()->is_keyed_stub()) {
284 // Determine whether the failure is due to a name failure. 282 // Determine whether the failure is due to a name failure.
(...skipping 669 matching lines...) Expand 10 before | Expand all | Expand 10 after
954 Handle<String> name, 952 Handle<String> name,
955 Handle<Code> code) { 953 Handle<Code> code) {
956 if (!code->is_handler()) return false; 954 if (!code->is_handler()) return false;
957 955
958 MapHandleList receiver_maps; 956 MapHandleList receiver_maps;
959 CodeHandleList handlers; 957 CodeHandleList handlers;
960 958
961 int number_of_valid_maps; 959 int number_of_valid_maps;
962 int handler_to_overwrite = -1; 960 int handler_to_overwrite = -1;
963 Handle<Map> new_receiver_map(receiver->map()); 961 Handle<Map> new_receiver_map(receiver->map());
964 {
965 DisallowHeapAllocation no_gc;
966 target()->FindAllMaps(&receiver_maps);
967 int number_of_maps = receiver_maps.length();
968 number_of_valid_maps = number_of_maps;
969 962
970 for (int i = 0; i < number_of_maps; i++) { 963 target()->FindAllMaps(&receiver_maps);
971 Handle<Map> map = receiver_maps.at(i); 964 int number_of_maps = receiver_maps.length();
972 // Filter out deprecated maps to ensure its instances get migrated. 965 number_of_valid_maps = number_of_maps;
973 if (map->is_deprecated()) {
974 number_of_valid_maps--;
975 // If the receiver map is already in the polymorphic IC, this indicates
976 // there was a prototoype chain failure. In that case, just overwrite the
977 // handler.
978 } else if (map.is_identical_to(new_receiver_map)) {
979 number_of_valid_maps--;
980 handler_to_overwrite = i;
981 }
982 }
983 966
984 if (number_of_valid_maps >= 4) return false; 967 for (int i = 0; i < number_of_maps; i++) {
985 if (number_of_maps == 0) return false; 968 Handle<Map> map = receiver_maps.at(i);
986 969 // Filter out deprecated maps to ensure its instances get migrated.
987 if (!target()->FindHandlers(&handlers, receiver_maps.length())) { 970 if (map->is_deprecated()) {
988 return false; 971 number_of_valid_maps--;
972 // If the receiver map is already in the polymorphic IC, this indicates
973 // there was a prototoype chain failure. In that case, just overwrite the
974 // handler.
975 } else if (map.is_identical_to(new_receiver_map)) {
976 number_of_valid_maps--;
977 handler_to_overwrite = i;
989 } 978 }
990 } 979 }
991 980
981 if (number_of_valid_maps >= 4) return false;
982 if (number_of_maps == 0) return false;
983
984 if (!target()->FindHandlers(&handlers, receiver_maps.length())) {
985 return false;
986 }
987
992 number_of_valid_maps++; 988 number_of_valid_maps++;
993 if (handler_to_overwrite >= 0) { 989 if (handler_to_overwrite >= 0) {
994 handlers.Set(handler_to_overwrite, code); 990 handlers.Set(handler_to_overwrite, code);
995 } else { 991 } else {
996 receiver_maps.Add(new_receiver_map); 992 receiver_maps.Add(new_receiver_map);
997 handlers.Add(code); 993 handlers.Add(code);
998 } 994 }
999 995
1000 Handle<Code> ic = isolate()->stub_cache()->ComputePolymorphicIC( 996 Handle<Code> ic = isolate()->stub_cache()->ComputePolymorphicIC(
1001 &receiver_maps, &handlers, number_of_valid_maps, name, strict_mode()); 997 &receiver_maps, &handlers, number_of_valid_maps, name, strict_mode());
1002 set_target(*ic); 998 set_target(*ic);
1003 return true; 999 return true;
1004 } 1000 }
1005 1001
1006 1002
1007 void IC::UpdateMonomorphicIC(Handle<HeapObject> receiver, 1003 void IC::UpdateMonomorphicIC(Handle<HeapObject> receiver,
1008 Handle<Code> handler, 1004 Handle<Code> handler,
1009 Handle<String> name) { 1005 Handle<String> name) {
1010 if (!handler->is_handler()) return set_target(*handler); 1006 if (!handler->is_handler()) return set_target(*handler);
1011 Handle<Code> ic = isolate()->stub_cache()->ComputeMonomorphicIC( 1007 Handle<Code> ic = isolate()->stub_cache()->ComputeMonomorphicIC(
1012 receiver, handler, name, strict_mode()); 1008 receiver, handler, name, strict_mode());
1013 set_target(*ic); 1009 set_target(*ic);
1014 } 1010 }
1015 1011
1016 1012
1017 void IC::CopyICToMegamorphicCache(Handle<String> name) { 1013 void IC::CopyICToMegamorphicCache(Handle<String> name) {
1018 MapHandleList receiver_maps; 1014 MapHandleList receiver_maps;
1019 CodeHandleList handlers; 1015 CodeHandleList handlers;
1020 { 1016 target()->FindAllMaps(&receiver_maps);
1021 DisallowHeapAllocation no_gc; 1017 if (!target()->FindHandlers(&handlers, receiver_maps.length())) return;
1022 target()->FindAllMaps(&receiver_maps);
1023 if (!target()->FindHandlers(&handlers, receiver_maps.length())) return;
1024 }
1025 for (int i = 0; i < receiver_maps.length(); i++) { 1018 for (int i = 0; i < receiver_maps.length(); i++) {
1026 UpdateMegamorphicCache(*receiver_maps.at(i), *name, *handlers.at(i)); 1019 UpdateMegamorphicCache(*receiver_maps.at(i), *name, *handlers.at(i));
1027 } 1020 }
1028 } 1021 }
1029 1022
1030 1023
1031 bool IC::IsTransitionedMapOfMonomorphicTarget(Map* receiver_map) { 1024 bool IC::IsTransitionedMapOfMonomorphicTarget(Map* receiver_map) {
1032 DisallowHeapAllocation no_allocation;
1033
1034 Map* current_map = target()->FindFirstMap(); 1025 Map* current_map = target()->FindFirstMap();
1035 ElementsKind receiver_elements_kind = receiver_map->elements_kind(); 1026 ElementsKind receiver_elements_kind = receiver_map->elements_kind();
1036 bool more_general_transition = 1027 bool more_general_transition =
1037 IsMoreGeneralElementsKindTransition( 1028 IsMoreGeneralElementsKindTransition(
1038 current_map->elements_kind(), receiver_elements_kind); 1029 current_map->elements_kind(), receiver_elements_kind);
1039 Map* transitioned_map = more_general_transition 1030 Map* transitioned_map = more_general_transition
1040 ? current_map->LookupElementsTransitionMap(receiver_elements_kind) 1031 ? current_map->LookupElementsTransitionMap(receiver_elements_kind)
1041 : NULL; 1032 : NULL;
1042 1033
1043 return transitioned_map == receiver_map; 1034 return transitioned_map == receiver_map;
(...skipping 10 matching lines...) Expand all
1054 UpdateMonomorphicIC(receiver, code, name); 1045 UpdateMonomorphicIC(receiver, code, name);
1055 break; 1046 break;
1056 case MONOMORPHIC: 1047 case MONOMORPHIC:
1057 // For now, call stubs are allowed to rewrite to the same stub. This 1048 // For now, call stubs are allowed to rewrite to the same stub. This
1058 // happens e.g., when the field does not contain a function. 1049 // happens e.g., when the field does not contain a function.
1059 ASSERT(target()->is_call_stub() || 1050 ASSERT(target()->is_call_stub() ||
1060 target()->is_keyed_call_stub() || 1051 target()->is_keyed_call_stub() ||
1061 !target().is_identical_to(code)); 1052 !target().is_identical_to(code));
1062 if (!target()->is_keyed_stub()) { 1053 if (!target()->is_keyed_stub()) {
1063 bool is_same_handler = false; 1054 bool is_same_handler = false;
1064 { 1055 Code* old_handler = target()->FindFirstHandler();
1065 DisallowHeapAllocation no_allocation; 1056 is_same_handler = old_handler == *code;
1066 Code* old_handler = target()->FindFirstHandler(); 1057
1067 is_same_handler = old_handler == *code; 1058 if (is_same_handler &&
1068 } 1059 IsTransitionedMapOfMonomorphicTarget(receiver->map())) {
1069 if (is_same_handler
1070 && IsTransitionedMapOfMonomorphicTarget(receiver->map())) {
1071 UpdateMonomorphicIC(receiver, code, name); 1060 UpdateMonomorphicIC(receiver, code, name);
1072 break; 1061 break;
1073 } 1062 }
1074 if (UpdatePolymorphicIC(receiver, name, code)) { 1063 }
1075 break; 1064 // Fall through.
1076 } 1065 case POLYMORPHIC:
1077 1066 if (!target()->is_keyed_stub()) {
1067 if (UpdatePolymorphicIC(receiver, name, code)) break;
1078 CopyICToMegamorphicCache(name); 1068 CopyICToMegamorphicCache(name);
1079 } 1069 }
1080
1081 UpdateMegamorphicCache(receiver->map(), *name, *code);
1082 set_target(*megamorphic_stub()); 1070 set_target(*megamorphic_stub());
1083 break; 1071 // Fall through.
1084 case MEGAMORPHIC: 1072 case MEGAMORPHIC:
1085 UpdateMegamorphicCache(receiver->map(), *name, *code); 1073 UpdateMegamorphicCache(receiver->map(), *name, *code);
1086 break; 1074 break;
1087 case POLYMORPHIC:
1088 if (target()->is_keyed_stub()) {
1089 // When trying to patch a polymorphic keyed stub with anything other
1090 // than another polymorphic stub, go generic.
1091 set_target(*generic_stub());
1092 } else {
1093 if (UpdatePolymorphicIC(receiver, name, code)) {
1094 break;
1095 }
1096 CopyICToMegamorphicCache(name);
1097 UpdateMegamorphicCache(receiver->map(), *name, *code);
1098 set_target(*megamorphic_stub());
1099 }
1100 break;
1101 case DEBUG_STUB: 1075 case DEBUG_STUB:
1102 break; 1076 break;
1103 case GENERIC: 1077 case GENERIC:
1104 UNREACHABLE(); 1078 UNREACHABLE();
1105 break; 1079 break;
1106 } 1080 }
1107 } 1081 }
1108 1082
1109 1083
1110 Handle<Code> LoadIC::SimpleFieldLoad(int offset, 1084 Handle<Code> LoadIC::SimpleFieldLoad(int offset,
(...skipping 1626 matching lines...) Expand 10 before | Expand all | Expand 10 after
2737 #undef ADDR 2711 #undef ADDR
2738 }; 2712 };
2739 2713
2740 2714
2741 Address IC::AddressFromUtilityId(IC::UtilityId id) { 2715 Address IC::AddressFromUtilityId(IC::UtilityId id) {
2742 return IC_utilities[id]; 2716 return IC_utilities[id];
2743 } 2717 }
2744 2718
2745 2719
2746 } } // namespace v8::internal 2720 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698