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

Side by Side Diff: src/ic.cc

Issue 12451003: Make IC patching resilient to flushing of the original target() ic. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments Created 7 years, 9 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/ia32/stub-cache-ia32.cc ('k') | src/objects.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 941 matching lines...) Expand 10 before | Expand all | Expand 10 after
952 bool IC::UpdatePolymorphicIC(State state, 952 bool IC::UpdatePolymorphicIC(State state,
953 StrictModeFlag strict_mode, 953 StrictModeFlag strict_mode,
954 Handle<JSObject> receiver, 954 Handle<JSObject> receiver,
955 Handle<String> name, 955 Handle<String> name,
956 Handle<Code> code) { 956 Handle<Code> code) {
957 if (code->type() == Code::NORMAL) return false; 957 if (code->type() == Code::NORMAL) return false;
958 if (target()->ic_state() == MONOMORPHIC && 958 if (target()->ic_state() == MONOMORPHIC &&
959 target()->type() == Code::NORMAL) { 959 target()->type() == Code::NORMAL) {
960 return false; 960 return false;
961 } 961 }
962
962 MapHandleList receiver_maps; 963 MapHandleList receiver_maps;
963 CodeHandleList handlers; 964 CodeHandleList handlers;
964 target()->FindAllMaps(&receiver_maps);
965 int number_of_maps = receiver_maps.length();
966 if (number_of_maps == 0 || number_of_maps >= 4) return false;
967 965
968 target()->FindAllCode(&handlers, receiver_maps.length()); 966 {
967 AssertNoAllocation no_gc;
968 target()->FindAllMaps(&receiver_maps);
969 int number_of_maps = receiver_maps.length();
970 if (number_of_maps >= 4) return false;
971
972 // Only allow 0 maps in case target() was reset to UNINITIALIZED by the GC.
973 // In that case, allow the IC to go back monomorphic.
974 if (number_of_maps == 0 && target()->ic_state() != UNINITIALIZED) {
975 return false;
976 }
977 target()->FindAllCode(&handlers, receiver_maps.length());
978 }
969 979
970 if (!AddOneReceiverMapIfMissing(&receiver_maps, 980 if (!AddOneReceiverMapIfMissing(&receiver_maps,
971 Handle<Map>(receiver->map()))) { 981 Handle<Map>(receiver->map()))) {
972 return false; 982 return false;
973 } 983 }
974 984
975 handlers.Add(code); 985 handlers.Add(code);
976 Handle<Code> ic = isolate()->stub_cache()->ComputePolymorphicIC( 986 Handle<Code> ic = isolate()->stub_cache()->ComputePolymorphicIC(
977 &receiver_maps, &handlers, name); 987 &receiver_maps, &handlers, name);
978 set_target(*ic); 988 set_target(*ic);
(...skipping 14 matching lines...) Expand all
993 void KeyedLoadIC::UpdateMonomorphicIC(Handle<JSObject> receiver, 1003 void KeyedLoadIC::UpdateMonomorphicIC(Handle<JSObject> receiver,
994 Handle<Code> handler, 1004 Handle<Code> handler,
995 Handle<String> name) { 1005 Handle<String> name) {
996 if (handler->type() == Code::NORMAL) return set_target(*handler); 1006 if (handler->type() == Code::NORMAL) return set_target(*handler);
997 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedMonomorphicIC( 1007 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedMonomorphicIC(
998 receiver, handler, name); 1008 receiver, handler, name);
999 set_target(*ic); 1009 set_target(*ic);
1000 } 1010 }
1001 1011
1002 1012
1013 // Since GC may have been invoked, by the time PatchCache is called, |state| is
1014 // not necessarily equal to target()->state().
1003 void IC::PatchCache(State state, 1015 void IC::PatchCache(State state,
1004 StrictModeFlag strict_mode, 1016 StrictModeFlag strict_mode,
1005 Handle<JSObject> receiver, 1017 Handle<JSObject> receiver,
1006 Handle<String> name, 1018 Handle<String> name,
1007 Handle<Code> code) { 1019 Handle<Code> code) {
1008 switch (state) { 1020 switch (state) {
1009 case UNINITIALIZED: 1021 case UNINITIALIZED:
1010 case PREMONOMORPHIC: 1022 case PREMONOMORPHIC:
1011 case MONOMORPHIC_PROTOTYPE_FAILURE: 1023 case MONOMORPHIC_PROTOTYPE_FAILURE:
1012 UpdateMonomorphicIC(receiver, code, name); 1024 UpdateMonomorphicIC(receiver, code, name);
1013 break; 1025 break;
1014 case MONOMORPHIC: 1026 case MONOMORPHIC:
1015 // Only move to megamorphic if the target changes. 1027 // Only move to megamorphic if the target changes.
1016 if (target() != *code) { 1028 if (target() != *code) {
1017 if (target()->is_load_stub()) { 1029 if (target()->is_load_stub()) {
1018 if (UpdatePolymorphicIC(state, strict_mode, receiver, name, code)) { 1030 if (UpdatePolymorphicIC(state, strict_mode, receiver, name, code)) {
1019 break; 1031 break;
1020 } 1032 }
1021 } 1033 }
1022 // We are transitioning from monomorphic to megamorphic case. Place the 1034 if (target()->type() != Code::NORMAL) {
1023 // stub compiled for the receiver into stub cache. 1035 // We are transitioning from monomorphic to megamorphic case. Place
1024 Map* map = target()->FindFirstMap(); 1036 // the stub compiled for the receiver into stub cache.
1025 if (map != NULL) { 1037 Map* map;
1026 UpdateMegamorphicCache(map, *name, target()); 1038 Code* handler;
1039 {
1040 AssertNoAllocation no_gc;
1041 map = target()->FindFirstMap();
1042 if (map != NULL) {
1043 if (target()->is_load_stub()) {
1044 handler = target()->FindFirstCode();
1045 } else {
1046 handler = target();
1047 }
1048 } else {
1049 // Avoid compiler warnings.
1050 handler = NULL;
1051 }
1052 }
1053 if (handler != NULL) {
1054 UpdateMegamorphicCache(map, *name, handler);
1055 }
1027 } 1056 }
1028 UpdateMegamorphicCache(receiver->map(), *name, *code); 1057 UpdateMegamorphicCache(receiver->map(), *name, *code);
1029 set_target((strict_mode == kStrictMode) 1058 set_target((strict_mode == kStrictMode)
1030 ? *megamorphic_stub_strict() 1059 ? *megamorphic_stub_strict()
1031 : *megamorphic_stub()); 1060 : *megamorphic_stub());
1032 } 1061 }
1033 break; 1062 break;
1034 case MEGAMORPHIC: 1063 case MEGAMORPHIC:
1035 // Update the stub cache. 1064 // Update the stub cache.
1036 UpdateMegamorphicCache(receiver->map(), *name, *code); 1065 UpdateMegamorphicCache(receiver->map(), *name, *code);
1037 break; 1066 break;
1038 case POLYMORPHIC: 1067 case POLYMORPHIC:
1039 if (target()->is_load_stub()) { 1068 if (target()->is_load_stub()) {
1040 if (UpdatePolymorphicIC(state, strict_mode, receiver, name, code)) { 1069 if (UpdatePolymorphicIC(state, strict_mode, receiver, name, code)) {
1041 break; 1070 break;
1042 } 1071 }
1043 MapHandleList receiver_maps; 1072 MapHandleList receiver_maps;
1044 CodeHandleList handlers; 1073 CodeHandleList handlers;
1045 target()->FindAllMaps(&receiver_maps); 1074 {
1046 target()->FindAllCode(&handlers, receiver_maps.length()); 1075 AssertNoAllocation no_gc;
1076 target()->FindAllMaps(&receiver_maps);
1077 target()->FindAllCode(&handlers, receiver_maps.length());
1078 }
1047 for (int i = 0; i < receiver_maps.length(); i++) { 1079 for (int i = 0; i < receiver_maps.length(); i++) {
1048 UpdateMegamorphicCache(*receiver_maps.at(i), *name, *handlers.at(i)); 1080 UpdateMegamorphicCache(*receiver_maps.at(i), *name, *handlers.at(i));
1049 } 1081 }
1050 UpdateMegamorphicCache(receiver->map(), *name, *code); 1082 UpdateMegamorphicCache(receiver->map(), *name, *code);
1051 set_target(*megamorphic_stub()); 1083 set_target(*megamorphic_stub());
1052 } else { 1084 } else {
1053 // When trying to patch a polymorphic keyed load/store element stub 1085 // When trying to patch a polymorphic keyed load/store element stub
1054 // with anything other than another polymorphic stub, go generic. 1086 // with anything other than another polymorphic stub, go generic.
1055 set_target((strict_mode == kStrictMode) 1087 set_target((strict_mode == kStrictMode)
1056 ? *generic_stub_strict() 1088 ? *generic_stub_strict()
(...skipping 1585 matching lines...) Expand 10 before | Expand all | Expand 10 after
2642 #undef ADDR 2674 #undef ADDR
2643 }; 2675 };
2644 2676
2645 2677
2646 Address IC::AddressFromUtilityId(IC::UtilityId id) { 2678 Address IC::AddressFromUtilityId(IC::UtilityId id) {
2647 return IC_utilities[id]; 2679 return IC_utilities[id];
2648 } 2680 }
2649 2681
2650 2682
2651 } } // namespace v8::internal 2683 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/stub-cache-ia32.cc ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698