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 941 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 AssertNoAllocation no_gc; |
1024 Map* map = target()->FindFirstMap(); | 1036 // We are transitioning from monomorphic to megamorphic case. Place |
1025 if (map != NULL) { | 1037 // the stub compiled for the receiver into stub cache. |
1026 UpdateMegamorphicCache(map, *name, target()); | 1038 Map* map; |
1039 Code* handler; | |
1040 { | |
1041 AssertNoAllocation no_gc; | |
Jakob Kummerow
2013/03/05 17:32:59
This AssertNoAllocation (and its scope) seem unnec
Toon Verwaest
2013/03/05 17:37:14
I removed the one above. The idea was to move that
| |
1042 map = target()->FindFirstMap(); | |
1043 if (map != NULL) { | |
1044 if (target()->is_load_stub()) { | |
1045 handler = target()->FindFirstCode(); | |
1046 } else { | |
1047 handler = target(); | |
1048 } | |
1049 } else { | |
1050 // Avoid compiler warnings. | |
1051 handler = NULL; | |
1052 } | |
1053 } | |
1054 if (handler != NULL) { | |
1055 UpdateMegamorphicCache(map, *name, handler); | |
1056 } | |
1027 } | 1057 } |
1028 UpdateMegamorphicCache(receiver->map(), *name, *code); | 1058 UpdateMegamorphicCache(receiver->map(), *name, *code); |
1029 set_target((strict_mode == kStrictMode) | 1059 set_target((strict_mode == kStrictMode) |
1030 ? *megamorphic_stub_strict() | 1060 ? *megamorphic_stub_strict() |
1031 : *megamorphic_stub()); | 1061 : *megamorphic_stub()); |
1032 } | 1062 } |
1033 break; | 1063 break; |
1034 case MEGAMORPHIC: | 1064 case MEGAMORPHIC: |
1035 // Update the stub cache. | 1065 // Update the stub cache. |
1036 UpdateMegamorphicCache(receiver->map(), *name, *code); | 1066 UpdateMegamorphicCache(receiver->map(), *name, *code); |
1037 break; | 1067 break; |
1038 case POLYMORPHIC: | 1068 case POLYMORPHIC: |
1039 if (target()->is_load_stub()) { | 1069 if (target()->is_load_stub()) { |
1040 if (UpdatePolymorphicIC(state, strict_mode, receiver, name, code)) { | 1070 if (UpdatePolymorphicIC(state, strict_mode, receiver, name, code)) { |
1041 break; | 1071 break; |
1042 } | 1072 } |
1043 MapHandleList receiver_maps; | 1073 MapHandleList receiver_maps; |
1044 CodeHandleList handlers; | 1074 CodeHandleList handlers; |
1045 target()->FindAllMaps(&receiver_maps); | 1075 { |
1046 target()->FindAllCode(&handlers, receiver_maps.length()); | 1076 AssertNoAllocation no_gc; |
1077 target()->FindAllMaps(&receiver_maps); | |
1078 target()->FindAllCode(&handlers, receiver_maps.length()); | |
1079 } | |
1047 for (int i = 0; i < receiver_maps.length(); i++) { | 1080 for (int i = 0; i < receiver_maps.length(); i++) { |
1048 UpdateMegamorphicCache(*receiver_maps.at(i), *name, *handlers.at(i)); | 1081 UpdateMegamorphicCache(*receiver_maps.at(i), *name, *handlers.at(i)); |
1049 } | 1082 } |
1050 UpdateMegamorphicCache(receiver->map(), *name, *code); | 1083 UpdateMegamorphicCache(receiver->map(), *name, *code); |
1051 set_target(*megamorphic_stub()); | 1084 set_target(*megamorphic_stub()); |
1052 } else { | 1085 } else { |
1053 // When trying to patch a polymorphic keyed load/store element stub | 1086 // When trying to patch a polymorphic keyed load/store element stub |
1054 // with anything other than another polymorphic stub, go generic. | 1087 // with anything other than another polymorphic stub, go generic. |
1055 set_target((strict_mode == kStrictMode) | 1088 set_target((strict_mode == kStrictMode) |
1056 ? *generic_stub_strict() | 1089 ? *generic_stub_strict() |
(...skipping 1585 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2642 #undef ADDR | 2675 #undef ADDR |
2643 }; | 2676 }; |
2644 | 2677 |
2645 | 2678 |
2646 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 2679 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
2647 return IC_utilities[id]; | 2680 return IC_utilities[id]; |
2648 } | 2681 } |
2649 | 2682 |
2650 | 2683 |
2651 } } // namespace v8::internal | 2684 } } // namespace v8::internal |
OLD | NEW |