Chromium Code Reviews| 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 |