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 960 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
971 receiver_maps->Add(new_receiver_map); | 971 receiver_maps->Add(new_receiver_map); |
972 return true; | 972 return true; |
973 } | 973 } |
974 | 974 |
975 | 975 |
976 bool IC::UpdatePolymorphicIC(State state, | 976 bool IC::UpdatePolymorphicIC(State state, |
977 Handle<JSObject> receiver, | 977 Handle<JSObject> receiver, |
978 Handle<String> name, | 978 Handle<String> name, |
979 Handle<Code> code, | 979 Handle<Code> code, |
980 StrictModeFlag strict_mode) { | 980 StrictModeFlag strict_mode) { |
| 981 if (code->type() == Code::NORMAL) return false; |
| 982 if (target()->ic_state() == MONOMORPHIC && |
| 983 target()->type() == Code::NORMAL) { |
| 984 return false; |
| 985 } |
| 986 |
981 MapHandleList receiver_maps; | 987 MapHandleList receiver_maps; |
982 CodeHandleList handlers; | 988 CodeHandleList handlers; |
983 | 989 |
984 int number_of_valid_maps; | 990 int number_of_valid_maps; |
985 int handler_to_overwrite = -1; | 991 int handler_to_overwrite = -1; |
986 Handle<Map> new_receiver_map(receiver->map()); | 992 Handle<Map> new_receiver_map(receiver->map()); |
987 { | 993 { |
988 DisallowHeapAllocation no_gc; | 994 DisallowHeapAllocation no_gc; |
989 if (target()->ic_state() == POLYMORPHIC || | 995 target()->FindAllMaps(&receiver_maps); |
990 (target()->ic_state() == MONOMORPHIC && | |
991 target()->type() != Code::NORMAL)) { | |
992 target()->FindAllMaps(&receiver_maps); | |
993 } | |
994 | |
995 int number_of_maps = receiver_maps.length(); | 996 int number_of_maps = receiver_maps.length(); |
996 number_of_valid_maps = number_of_maps; | 997 number_of_valid_maps = number_of_maps; |
997 | 998 |
998 for (int i = 0; i < number_of_maps; i++) { | 999 for (int i = 0; i < number_of_maps; i++) { |
999 Handle<Map> map = receiver_maps.at(i); | 1000 Handle<Map> map = receiver_maps.at(i); |
1000 // Filter out deprecated maps to ensure its instances get migrated. | 1001 // Filter out deprecated maps to ensure its instances get migrated. |
1001 if (map->is_deprecated()) { | 1002 if (map->is_deprecated()) { |
1002 number_of_valid_maps--; | 1003 number_of_valid_maps--; |
1003 // If the receiver map is already in the polymorphic IC, this indicates | 1004 // If the receiver map is already in the polymorphic IC, this indicates |
1004 // there was a prototoype chain failure. In that case, just overwrite the | 1005 // there was a prototoype chain failure. In that case, just overwrite the |
1005 // handler. | 1006 // handler. |
1006 } else if (map.is_identical_to(new_receiver_map)) { | 1007 } else if (map.is_identical_to(new_receiver_map)) { |
1007 number_of_valid_maps--; | 1008 number_of_valid_maps--; |
1008 handler_to_overwrite = i; | 1009 handler_to_overwrite = i; |
1009 } | 1010 } |
1010 } | 1011 } |
1011 | 1012 |
1012 if (number_of_valid_maps >= 4) return false; | 1013 if (number_of_valid_maps >= 4) return false; |
1013 | 1014 |
1014 if (number_of_maps > 0) { | 1015 // Only allow 0 maps in case target() was reset to UNINITIALIZED by the GC. |
1015 target()->FindAllCode(&handlers, receiver_maps.length()); | 1016 // In that case, allow the IC to go back monomorphic. |
| 1017 if (number_of_maps == 0 && target()->ic_state() != UNINITIALIZED) { |
| 1018 return false; |
1016 } | 1019 } |
| 1020 target()->FindAllCode(&handlers, receiver_maps.length()); |
1017 } | 1021 } |
1018 | 1022 |
1019 number_of_valid_maps++; | 1023 number_of_valid_maps++; |
1020 if (handler_to_overwrite >= 0) { | 1024 if (handler_to_overwrite >= 0) { |
1021 handlers.Set(handler_to_overwrite, code); | 1025 handlers.Set(handler_to_overwrite, code); |
1022 } else { | 1026 } else { |
1023 receiver_maps.Add(new_receiver_map); | 1027 receiver_maps.Add(new_receiver_map); |
1024 handlers.Add(code); | 1028 handlers.Add(code); |
1025 } | 1029 } |
1026 | 1030 |
(...skipping 2050 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3077 #undef ADDR | 3081 #undef ADDR |
3078 }; | 3082 }; |
3079 | 3083 |
3080 | 3084 |
3081 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 3085 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
3082 return IC_utilities[id]; | 3086 return IC_utilities[id]; |
3083 } | 3087 } |
3084 | 3088 |
3085 | 3089 |
3086 } } // namespace v8::internal | 3090 } } // namespace v8::internal |
OLD | NEW |