OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 |
11 // with the distribution. | 11 // with the distribution. |
(...skipping 825 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
837 if (!maybe_result->ToObject(&result)) return maybe_result; | 837 if (!maybe_result->ToObject(&result)) return maybe_result; |
838 } | 838 } |
839 } | 839 } |
840 return code; | 840 return code; |
841 } | 841 } |
842 | 842 |
843 | 843 |
844 MaybeObject* StubCache::ComputeCallField(int argc, | 844 MaybeObject* StubCache::ComputeCallField(int argc, |
845 InLoopFlag in_loop, | 845 InLoopFlag in_loop, |
846 Code::Kind kind, | 846 Code::Kind kind, |
| 847 Code::ExtraICState extra_ic_state, |
847 String* name, | 848 String* name, |
848 Object* object, | 849 Object* object, |
849 JSObject* holder, | 850 JSObject* holder, |
850 int index) { | 851 int index) { |
851 // Compute the check type and the map. | 852 // Compute the check type and the map. |
852 InlineCacheHolderFlag cache_holder = | 853 InlineCacheHolderFlag cache_holder = |
853 IC::GetCodeCacheForObject(object, holder); | 854 IC::GetCodeCacheForObject(object, holder); |
854 JSObject* map_holder = IC::GetCodeCacheHolder(object, cache_holder); | 855 JSObject* map_holder = IC::GetCodeCacheHolder(object, cache_holder); |
855 | 856 |
856 // TODO(1233596): We cannot do receiver map check for non-JS objects | 857 // TODO(1233596): We cannot do receiver map check for non-JS objects |
857 // because they may be represented as immediates without a | 858 // because they may be represented as immediates without a |
858 // map. Instead, we check against the map in the holder. | 859 // map. Instead, we check against the map in the holder. |
859 if (object->IsNumber() || object->IsBoolean() || object->IsString()) { | 860 if (object->IsNumber() || object->IsBoolean() || object->IsString()) { |
860 object = holder; | 861 object = holder; |
861 } | 862 } |
862 | 863 |
863 Code::Flags flags = Code::ComputeMonomorphicFlags(kind, | 864 Code::Flags flags = Code::ComputeMonomorphicFlags(kind, |
864 FIELD, | 865 FIELD, |
865 Code::kNoExtraICState, | 866 extra_ic_state, |
866 cache_holder, | 867 cache_holder, |
867 in_loop, | 868 in_loop, |
868 argc); | 869 argc); |
869 Object* code = map_holder->map()->FindInCodeCache(name, flags); | 870 Object* code = map_holder->map()->FindInCodeCache(name, flags); |
870 if (code->IsUndefined()) { | 871 if (code->IsUndefined()) { |
871 CallStubCompiler compiler( | 872 CallStubCompiler compiler( |
872 argc, in_loop, kind, Code::kNoExtraICState, cache_holder); | 873 argc, in_loop, kind, extra_ic_state, cache_holder); |
873 { MaybeObject* maybe_code = | 874 { MaybeObject* maybe_code = |
874 compiler.CompileCallField(JSObject::cast(object), | 875 compiler.CompileCallField(JSObject::cast(object), |
875 holder, | 876 holder, |
876 index, | 877 index, |
877 name); | 878 name); |
878 if (!maybe_code->ToObject(&code)) return maybe_code; | 879 if (!maybe_code->ToObject(&code)) return maybe_code; |
879 } | 880 } |
880 ASSERT_EQ(flags, Code::cast(code)->flags()); | 881 ASSERT_EQ(flags, Code::cast(code)->flags()); |
881 PROFILE(isolate_, | 882 PROFILE(isolate_, |
882 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), | 883 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), |
883 Code::cast(code), name)); | 884 Code::cast(code), name)); |
884 GDBJIT(AddCode(GDBJITInterface::CALL_IC, name, Code::cast(code))); | 885 GDBJIT(AddCode(GDBJITInterface::CALL_IC, name, Code::cast(code))); |
885 Object* result; | 886 Object* result; |
886 { MaybeObject* maybe_result = | 887 { MaybeObject* maybe_result = |
887 map_holder->UpdateMapCodeCache(name, Code::cast(code)); | 888 map_holder->UpdateMapCodeCache(name, Code::cast(code)); |
888 if (!maybe_result->ToObject(&result)) return maybe_result; | 889 if (!maybe_result->ToObject(&result)) return maybe_result; |
889 } | 890 } |
890 } | 891 } |
891 return code; | 892 return code; |
892 } | 893 } |
893 | 894 |
894 | 895 |
895 MaybeObject* StubCache::ComputeCallInterceptor(int argc, | 896 MaybeObject* StubCache::ComputeCallInterceptor( |
896 Code::Kind kind, | 897 int argc, |
897 String* name, | 898 Code::Kind kind, |
898 Object* object, | 899 Code::ExtraICState extra_ic_state, |
899 JSObject* holder) { | 900 String* name, |
| 901 Object* object, |
| 902 JSObject* holder) { |
900 // Compute the check type and the map. | 903 // Compute the check type and the map. |
901 InlineCacheHolderFlag cache_holder = | 904 InlineCacheHolderFlag cache_holder = |
902 IC::GetCodeCacheForObject(object, holder); | 905 IC::GetCodeCacheForObject(object, holder); |
903 JSObject* map_holder = IC::GetCodeCacheHolder(object, cache_holder); | 906 JSObject* map_holder = IC::GetCodeCacheHolder(object, cache_holder); |
904 | 907 |
905 // TODO(1233596): We cannot do receiver map check for non-JS objects | 908 // TODO(1233596): We cannot do receiver map check for non-JS objects |
906 // because they may be represented as immediates without a | 909 // because they may be represented as immediates without a |
907 // map. Instead, we check against the map in the holder. | 910 // map. Instead, we check against the map in the holder. |
908 if (object->IsNumber() || object->IsBoolean() || object->IsString()) { | 911 if (object->IsNumber() || object->IsBoolean() || object->IsString()) { |
909 object = holder; | 912 object = holder; |
910 } | 913 } |
911 | 914 |
912 Code::Flags flags = Code::ComputeMonomorphicFlags(kind, | 915 Code::Flags flags = Code::ComputeMonomorphicFlags(kind, |
913 INTERCEPTOR, | 916 INTERCEPTOR, |
914 Code::kNoExtraICState, | 917 extra_ic_state, |
915 cache_holder, | 918 cache_holder, |
916 NOT_IN_LOOP, | 919 NOT_IN_LOOP, |
917 argc); | 920 argc); |
918 Object* code = map_holder->map()->FindInCodeCache(name, flags); | 921 Object* code = map_holder->map()->FindInCodeCache(name, flags); |
919 if (code->IsUndefined()) { | 922 if (code->IsUndefined()) { |
920 CallStubCompiler compiler( | 923 CallStubCompiler compiler( |
921 argc, NOT_IN_LOOP, kind, Code::kNoExtraICState, cache_holder); | 924 argc, NOT_IN_LOOP, kind, extra_ic_state, cache_holder); |
922 { MaybeObject* maybe_code = | 925 { MaybeObject* maybe_code = |
923 compiler.CompileCallInterceptor(JSObject::cast(object), holder, name); | 926 compiler.CompileCallInterceptor(JSObject::cast(object), holder, name); |
924 if (!maybe_code->ToObject(&code)) return maybe_code; | 927 if (!maybe_code->ToObject(&code)) return maybe_code; |
925 } | 928 } |
926 ASSERT_EQ(flags, Code::cast(code)->flags()); | 929 ASSERT_EQ(flags, Code::cast(code)->flags()); |
927 PROFILE(isolate(), | 930 PROFILE(isolate(), |
928 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), | 931 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), |
929 Code::cast(code), name)); | 932 Code::cast(code), name)); |
930 GDBJIT(AddCode(GDBJITInterface::CALL_IC, name, Code::cast(code))); | 933 GDBJIT(AddCode(GDBJITInterface::CALL_IC, name, Code::cast(code))); |
931 Object* result; | 934 Object* result; |
932 { MaybeObject* maybe_result = | 935 { MaybeObject* maybe_result = |
933 map_holder->UpdateMapCodeCache(name, Code::cast(code)); | 936 map_holder->UpdateMapCodeCache(name, Code::cast(code)); |
934 if (!maybe_result->ToObject(&result)) return maybe_result; | 937 if (!maybe_result->ToObject(&result)) return maybe_result; |
935 } | 938 } |
936 } | 939 } |
937 return code; | 940 return code; |
938 } | 941 } |
939 | 942 |
940 | 943 |
941 MaybeObject* StubCache::ComputeCallNormal(int argc, | 944 MaybeObject* StubCache::ComputeCallNormal(int argc, |
942 InLoopFlag in_loop, | 945 InLoopFlag in_loop, |
943 Code::Kind kind, | 946 Code::Kind kind, |
| 947 Code::ExtraICState extra_ic_state, |
944 String* name, | 948 String* name, |
945 JSObject* receiver) { | 949 JSObject* receiver) { |
946 Object* code; | 950 Object* code; |
947 { MaybeObject* maybe_code = ComputeCallNormal(argc, in_loop, kind); | 951 { MaybeObject* maybe_code = |
| 952 ComputeCallNormal(argc, in_loop, kind, extra_ic_state); |
948 if (!maybe_code->ToObject(&code)) return maybe_code; | 953 if (!maybe_code->ToObject(&code)) return maybe_code; |
949 } | 954 } |
950 return code; | 955 return code; |
951 } | 956 } |
952 | 957 |
953 | 958 |
954 MaybeObject* StubCache::ComputeCallGlobal(int argc, | 959 MaybeObject* StubCache::ComputeCallGlobal(int argc, |
955 InLoopFlag in_loop, | 960 InLoopFlag in_loop, |
956 Code::Kind kind, | 961 Code::Kind kind, |
| 962 Code::ExtraICState extra_ic_state, |
957 String* name, | 963 String* name, |
958 JSObject* receiver, | 964 JSObject* receiver, |
959 GlobalObject* holder, | 965 GlobalObject* holder, |
960 JSGlobalPropertyCell* cell, | 966 JSGlobalPropertyCell* cell, |
961 JSFunction* function) { | 967 JSFunction* function) { |
962 InlineCacheHolderFlag cache_holder = | 968 InlineCacheHolderFlag cache_holder = |
963 IC::GetCodeCacheForObject(receiver, holder); | 969 IC::GetCodeCacheForObject(receiver, holder); |
964 JSObject* map_holder = IC::GetCodeCacheHolder(receiver, cache_holder); | 970 JSObject* map_holder = IC::GetCodeCacheHolder(receiver, cache_holder); |
965 Code::Flags flags = Code::ComputeMonomorphicFlags(kind, | 971 Code::Flags flags = Code::ComputeMonomorphicFlags(kind, |
966 NORMAL, | 972 NORMAL, |
967 Code::kNoExtraICState, | 973 extra_ic_state, |
968 cache_holder, | 974 cache_holder, |
969 in_loop, | 975 in_loop, |
970 argc); | 976 argc); |
971 Object* code = map_holder->map()->FindInCodeCache(name, flags); | 977 Object* code = map_holder->map()->FindInCodeCache(name, flags); |
972 if (code->IsUndefined()) { | 978 if (code->IsUndefined()) { |
973 // If the function hasn't been compiled yet, we cannot do it now | 979 // If the function hasn't been compiled yet, we cannot do it now |
974 // because it may cause GC. To avoid this issue, we return an | 980 // because it may cause GC. To avoid this issue, we return an |
975 // internal error which will make sure we do not update any | 981 // internal error which will make sure we do not update any |
976 // caches. | 982 // caches. |
977 if (!function->is_compiled()) return Failure::InternalError(); | 983 if (!function->is_compiled()) return Failure::InternalError(); |
978 CallStubCompiler compiler( | 984 CallStubCompiler compiler( |
979 argc, in_loop, kind, Code::kNoExtraICState, cache_holder); | 985 argc, in_loop, kind, extra_ic_state, cache_holder); |
980 { MaybeObject* maybe_code = | 986 { MaybeObject* maybe_code = |
981 compiler.CompileCallGlobal(receiver, holder, cell, function, name); | 987 compiler.CompileCallGlobal(receiver, |
| 988 holder, |
| 989 cell, |
| 990 function, |
| 991 name, |
| 992 extra_ic_state); |
982 if (!maybe_code->ToObject(&code)) return maybe_code; | 993 if (!maybe_code->ToObject(&code)) return maybe_code; |
983 } | 994 } |
984 ASSERT_EQ(flags, Code::cast(code)->flags()); | 995 ASSERT_EQ(flags, Code::cast(code)->flags()); |
985 PROFILE(isolate(), | 996 PROFILE(isolate(), |
986 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), | 997 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), |
987 Code::cast(code), name)); | 998 Code::cast(code), name)); |
988 GDBJIT(AddCode(GDBJITInterface::CALL_IC, name, Code::cast(code))); | 999 GDBJIT(AddCode(GDBJITInterface::CALL_IC, name, Code::cast(code))); |
989 Object* result; | 1000 Object* result; |
990 { MaybeObject* maybe_result = | 1001 { MaybeObject* maybe_result = |
991 map_holder->UpdateMapCodeCache(name, Code::cast(code)); | 1002 map_holder->UpdateMapCodeCache(name, Code::cast(code)); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1039 heap->non_monomorphic_cache()->ValueAtPut(entry, code); | 1050 heap->non_monomorphic_cache()->ValueAtPut(entry, code); |
1040 CHECK(GetProbeValue(isolate, Code::cast(code)->flags()) == code); | 1051 CHECK(GetProbeValue(isolate, Code::cast(code)->flags()) == code); |
1041 } | 1052 } |
1042 } | 1053 } |
1043 return maybe_code; | 1054 return maybe_code; |
1044 } | 1055 } |
1045 | 1056 |
1046 | 1057 |
1047 Code* StubCache::FindCallInitialize(int argc, | 1058 Code* StubCache::FindCallInitialize(int argc, |
1048 InLoopFlag in_loop, | 1059 InLoopFlag in_loop, |
| 1060 RelocInfo::Mode mode, |
1049 Code::Kind kind) { | 1061 Code::Kind kind) { |
| 1062 Code::ExtraICState extra_state = |
| 1063 CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) | |
| 1064 CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT); |
1050 Code::Flags flags = Code::ComputeFlags(kind, | 1065 Code::Flags flags = Code::ComputeFlags(kind, |
1051 in_loop, | 1066 in_loop, |
1052 UNINITIALIZED, | 1067 UNINITIALIZED, |
1053 Code::kNoExtraICState, | 1068 extra_state, |
1054 NORMAL, | 1069 NORMAL, |
1055 argc); | 1070 argc); |
1056 Object* result = ProbeCache(isolate(), flags)->ToObjectUnchecked(); | 1071 Object* result = ProbeCache(isolate(), flags)->ToObjectUnchecked(); |
1057 ASSERT(result != heap()->undefined_value()); | 1072 ASSERT(result != heap()->undefined_value()); |
1058 // This might be called during the marking phase of the collector | 1073 // This might be called during the marking phase of the collector |
1059 // hence the unchecked cast. | 1074 // hence the unchecked cast. |
1060 return reinterpret_cast<Code*>(result); | 1075 return reinterpret_cast<Code*>(result); |
1061 } | 1076 } |
1062 | 1077 |
1063 | 1078 |
1064 MaybeObject* StubCache::ComputeCallInitialize(int argc, | 1079 MaybeObject* StubCache::ComputeCallInitialize(int argc, |
1065 InLoopFlag in_loop, | 1080 InLoopFlag in_loop, |
| 1081 RelocInfo::Mode mode, |
1066 Code::Kind kind) { | 1082 Code::Kind kind) { |
| 1083 Code::ExtraICState extra_state = |
| 1084 CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) | |
| 1085 CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT); |
1067 Code::Flags flags = Code::ComputeFlags(kind, | 1086 Code::Flags flags = Code::ComputeFlags(kind, |
1068 in_loop, | 1087 in_loop, |
1069 UNINITIALIZED, | 1088 UNINITIALIZED, |
1070 Code::kNoExtraICState, | 1089 extra_state, |
1071 NORMAL, | 1090 NORMAL, |
1072 argc); | 1091 argc); |
1073 Object* probe; | 1092 Object* probe; |
1074 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); | 1093 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); |
1075 if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 1094 if (!maybe_probe->ToObject(&probe)) return maybe_probe; |
1076 } | 1095 } |
1077 if (!probe->IsUndefined()) return probe; | 1096 if (!probe->IsUndefined()) return probe; |
1078 StubCompiler compiler; | 1097 StubCompiler compiler; |
1079 return FillCache(isolate_, compiler.CompileCallInitialize(flags)); | 1098 return FillCache(isolate_, compiler.CompileCallInitialize(flags)); |
1080 } | 1099 } |
1081 | 1100 |
1082 | 1101 |
1083 Handle<Code> StubCache::ComputeCallInitialize(int argc, InLoopFlag in_loop) { | 1102 Handle<Code> StubCache::ComputeCallInitialize(int argc, |
| 1103 InLoopFlag in_loop, |
| 1104 RelocInfo::Mode mode) { |
1084 if (in_loop == IN_LOOP) { | 1105 if (in_loop == IN_LOOP) { |
1085 // Force the creation of the corresponding stub outside loops, | 1106 // Force the creation of the corresponding stub outside loops, |
1086 // because it may be used when clearing the ICs later - it is | 1107 // because it may be used when clearing the ICs later - it is |
1087 // possible for a series of IC transitions to lose the in-loop | 1108 // possible for a series of IC transitions to lose the in-loop |
1088 // information, and the IC clearing code can't generate a stub | 1109 // information, and the IC clearing code can't generate a stub |
1089 // that it needs so we need to ensure it is generated already. | 1110 // that it needs so we need to ensure it is generated already. |
1090 ComputeCallInitialize(argc, NOT_IN_LOOP); | 1111 ComputeCallInitialize(argc, NOT_IN_LOOP, mode); |
1091 } | 1112 } |
1092 CALL_HEAP_FUNCTION(isolate_, | 1113 CALL_HEAP_FUNCTION(isolate_, |
1093 ComputeCallInitialize(argc, in_loop, Code::CALL_IC), Code); | 1114 ComputeCallInitialize(argc, in_loop, mode, Code::CALL_IC), |
| 1115 Code); |
1094 } | 1116 } |
1095 | 1117 |
1096 | 1118 |
1097 Handle<Code> StubCache::ComputeKeyedCallInitialize(int argc, | 1119 Handle<Code> StubCache::ComputeKeyedCallInitialize(int argc, |
1098 InLoopFlag in_loop) { | 1120 InLoopFlag in_loop) { |
1099 if (in_loop == IN_LOOP) { | 1121 if (in_loop == IN_LOOP) { |
1100 // Force the creation of the corresponding stub outside loops, | 1122 // Force the creation of the corresponding stub outside loops, |
1101 // because it may be used when clearing the ICs later - it is | 1123 // because it may be used when clearing the ICs later - it is |
1102 // possible for a series of IC transitions to lose the in-loop | 1124 // possible for a series of IC transitions to lose the in-loop |
1103 // information, and the IC clearing code can't generate a stub | 1125 // information, and the IC clearing code can't generate a stub |
1104 // that it needs so we need to ensure it is generated already. | 1126 // that it needs so we need to ensure it is generated already. |
1105 ComputeKeyedCallInitialize(argc, NOT_IN_LOOP); | 1127 ComputeKeyedCallInitialize(argc, NOT_IN_LOOP); |
1106 } | 1128 } |
1107 CALL_HEAP_FUNCTION( | 1129 CALL_HEAP_FUNCTION( |
1108 isolate_, | 1130 isolate_, |
1109 ComputeCallInitialize(argc, in_loop, Code::KEYED_CALL_IC), Code); | 1131 ComputeCallInitialize(argc, |
| 1132 in_loop, |
| 1133 RelocInfo::CODE_TARGET, |
| 1134 Code::KEYED_CALL_IC), |
| 1135 Code); |
1110 } | 1136 } |
1111 | 1137 |
1112 | 1138 |
1113 MaybeObject* StubCache::ComputeCallPreMonomorphic(int argc, | 1139 MaybeObject* StubCache::ComputeCallPreMonomorphic( |
1114 InLoopFlag in_loop, | 1140 int argc, |
1115 Code::Kind kind) { | 1141 InLoopFlag in_loop, |
| 1142 Code::Kind kind, |
| 1143 Code::ExtraICState extra_ic_state) { |
1116 Code::Flags flags = Code::ComputeFlags(kind, | 1144 Code::Flags flags = Code::ComputeFlags(kind, |
1117 in_loop, | 1145 in_loop, |
1118 PREMONOMORPHIC, | 1146 PREMONOMORPHIC, |
1119 Code::kNoExtraICState, | 1147 extra_ic_state, |
1120 NORMAL, | 1148 NORMAL, |
1121 argc); | 1149 argc); |
1122 Object* probe; | 1150 Object* probe; |
1123 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); | 1151 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); |
1124 if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 1152 if (!maybe_probe->ToObject(&probe)) return maybe_probe; |
1125 } | 1153 } |
1126 if (!probe->IsUndefined()) return probe; | 1154 if (!probe->IsUndefined()) return probe; |
1127 StubCompiler compiler; | 1155 StubCompiler compiler; |
1128 return FillCache(isolate_, compiler.CompileCallPreMonomorphic(flags)); | 1156 return FillCache(isolate_, compiler.CompileCallPreMonomorphic(flags)); |
1129 } | 1157 } |
1130 | 1158 |
1131 | 1159 |
1132 MaybeObject* StubCache::ComputeCallNormal(int argc, | 1160 MaybeObject* StubCache::ComputeCallNormal(int argc, |
1133 InLoopFlag in_loop, | 1161 InLoopFlag in_loop, |
1134 Code::Kind kind) { | 1162 Code::Kind kind, |
| 1163 Code::ExtraICState extra_ic_state) { |
1135 Code::Flags flags = Code::ComputeFlags(kind, | 1164 Code::Flags flags = Code::ComputeFlags(kind, |
1136 in_loop, | 1165 in_loop, |
1137 MONOMORPHIC, | 1166 MONOMORPHIC, |
1138 Code::kNoExtraICState, | 1167 extra_ic_state, |
1139 NORMAL, | 1168 NORMAL, |
1140 argc); | 1169 argc); |
1141 Object* probe; | 1170 Object* probe; |
1142 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); | 1171 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); |
1143 if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 1172 if (!maybe_probe->ToObject(&probe)) return maybe_probe; |
1144 } | 1173 } |
1145 if (!probe->IsUndefined()) return probe; | 1174 if (!probe->IsUndefined()) return probe; |
1146 StubCompiler compiler; | 1175 StubCompiler compiler; |
1147 return FillCache(isolate_, compiler.CompileCallNormal(flags)); | 1176 return FillCache(isolate_, compiler.CompileCallNormal(flags)); |
1148 } | 1177 } |
1149 | 1178 |
1150 | 1179 |
1151 MaybeObject* StubCache::ComputeCallMegamorphic(int argc, | 1180 MaybeObject* StubCache::ComputeCallMegamorphic( |
1152 InLoopFlag in_loop, | 1181 int argc, |
1153 Code::Kind kind) { | 1182 InLoopFlag in_loop, |
| 1183 Code::Kind kind, |
| 1184 Code::ExtraICState extra_ic_state) { |
1154 Code::Flags flags = Code::ComputeFlags(kind, | 1185 Code::Flags flags = Code::ComputeFlags(kind, |
1155 in_loop, | 1186 in_loop, |
1156 MEGAMORPHIC, | 1187 MEGAMORPHIC, |
1157 Code::kNoExtraICState, | 1188 extra_ic_state, |
1158 NORMAL, | 1189 NORMAL, |
1159 argc); | 1190 argc); |
1160 Object* probe; | 1191 Object* probe; |
1161 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); | 1192 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); |
1162 if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 1193 if (!maybe_probe->ToObject(&probe)) return maybe_probe; |
1163 } | 1194 } |
1164 if (!probe->IsUndefined()) return probe; | 1195 if (!probe->IsUndefined()) return probe; |
1165 StubCompiler compiler; | 1196 StubCompiler compiler; |
1166 return FillCache(isolate_, compiler.CompileCallMegamorphic(flags)); | 1197 return FillCache(isolate_, compiler.CompileCallMegamorphic(flags)); |
1167 } | 1198 } |
1168 | 1199 |
1169 | 1200 |
1170 MaybeObject* StubCache::ComputeCallMiss(int argc, Code::Kind kind) { | 1201 MaybeObject* StubCache::ComputeCallMiss(int argc, |
| 1202 Code::Kind kind, |
| 1203 Code::ExtraICState extra_ic_state) { |
1171 // MONOMORPHIC_PROTOTYPE_FAILURE state is used to make sure that miss stubs | 1204 // MONOMORPHIC_PROTOTYPE_FAILURE state is used to make sure that miss stubs |
1172 // and monomorphic stubs are not mixed up together in the stub cache. | 1205 // and monomorphic stubs are not mixed up together in the stub cache. |
1173 Code::Flags flags = Code::ComputeFlags(kind, | 1206 Code::Flags flags = Code::ComputeFlags(kind, |
1174 NOT_IN_LOOP, | 1207 NOT_IN_LOOP, |
1175 MONOMORPHIC_PROTOTYPE_FAILURE, | 1208 MONOMORPHIC_PROTOTYPE_FAILURE, |
1176 Code::kNoExtraICState, | 1209 extra_ic_state, |
1177 NORMAL, | 1210 NORMAL, |
1178 argc, | 1211 argc, |
1179 OWN_MAP); | 1212 OWN_MAP); |
1180 Object* probe; | 1213 Object* probe; |
1181 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); | 1214 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); |
1182 if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 1215 if (!maybe_probe->ToObject(&probe)) return maybe_probe; |
1183 } | 1216 } |
1184 if (!probe->IsUndefined()) return probe; | 1217 if (!probe->IsUndefined()) return probe; |
1185 StubCompiler compiler; | 1218 StubCompiler compiler; |
1186 return FillCache(isolate_, compiler.CompileCallMiss(flags)); | 1219 return FillCache(isolate_, compiler.CompileCallMiss(flags)); |
1187 } | 1220 } |
1188 | 1221 |
1189 | 1222 |
1190 #ifdef ENABLE_DEBUGGER_SUPPORT | 1223 #ifdef ENABLE_DEBUGGER_SUPPORT |
1191 MaybeObject* StubCache::ComputeCallDebugBreak(int argc, Code::Kind kind) { | 1224 MaybeObject* StubCache::ComputeCallDebugBreak( |
| 1225 int argc, |
| 1226 Code::Kind kind) { |
| 1227 // Extra IC state is irrelevant for debug break ICs. They jump to |
| 1228 // the actual call ic to carry out the work. |
1192 Code::Flags flags = Code::ComputeFlags(kind, | 1229 Code::Flags flags = Code::ComputeFlags(kind, |
1193 NOT_IN_LOOP, | 1230 NOT_IN_LOOP, |
1194 DEBUG_BREAK, | 1231 DEBUG_BREAK, |
1195 Code::kNoExtraICState, | 1232 Code::kNoExtraICState, |
1196 NORMAL, | 1233 NORMAL, |
1197 argc); | 1234 argc); |
1198 Object* probe; | 1235 Object* probe; |
1199 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); | 1236 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); |
1200 if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 1237 if (!maybe_probe->ToObject(&probe)) return maybe_probe; |
1201 } | 1238 } |
1202 if (!probe->IsUndefined()) return probe; | 1239 if (!probe->IsUndefined()) return probe; |
1203 StubCompiler compiler; | 1240 StubCompiler compiler; |
1204 return FillCache(isolate_, compiler.CompileCallDebugBreak(flags)); | 1241 return FillCache(isolate_, compiler.CompileCallDebugBreak(flags)); |
1205 } | 1242 } |
1206 | 1243 |
1207 | 1244 |
1208 MaybeObject* StubCache::ComputeCallDebugPrepareStepIn(int argc, | 1245 MaybeObject* StubCache::ComputeCallDebugPrepareStepIn( |
1209 Code::Kind kind) { | 1246 int argc, |
| 1247 Code::Kind kind) { |
| 1248 // Extra IC state is irrelevant for debug break ICs. They jump to |
| 1249 // the actual call ic to carry out the work. |
1210 Code::Flags flags = Code::ComputeFlags(kind, | 1250 Code::Flags flags = Code::ComputeFlags(kind, |
1211 NOT_IN_LOOP, | 1251 NOT_IN_LOOP, |
1212 DEBUG_PREPARE_STEP_IN, | 1252 DEBUG_PREPARE_STEP_IN, |
1213 Code::kNoExtraICState, | 1253 Code::kNoExtraICState, |
1214 NORMAL, | 1254 NORMAL, |
1215 argc); | 1255 argc); |
1216 Object* probe; | 1256 Object* probe; |
1217 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); | 1257 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); |
1218 if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 1258 if (!maybe_probe->ToObject(&probe)) return maybe_probe; |
1219 } | 1259 } |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1483 ASSERT(Smi::cast(args[1])->value() >= 0); | 1523 ASSERT(Smi::cast(args[1])->value() >= 0); |
1484 uint32_t index = Smi::cast(args[1])->value(); | 1524 uint32_t index = Smi::cast(args[1])->value(); |
1485 return receiver->GetElementWithInterceptor(receiver, index); | 1525 return receiver->GetElementWithInterceptor(receiver, index); |
1486 } | 1526 } |
1487 | 1527 |
1488 | 1528 |
1489 MaybeObject* StubCompiler::CompileCallInitialize(Code::Flags flags) { | 1529 MaybeObject* StubCompiler::CompileCallInitialize(Code::Flags flags) { |
1490 HandleScope scope(isolate()); | 1530 HandleScope scope(isolate()); |
1491 int argc = Code::ExtractArgumentsCountFromFlags(flags); | 1531 int argc = Code::ExtractArgumentsCountFromFlags(flags); |
1492 Code::Kind kind = Code::ExtractKindFromFlags(flags); | 1532 Code::Kind kind = Code::ExtractKindFromFlags(flags); |
| 1533 Code::ExtraICState extra_ic_state = Code::ExtractExtraICStateFromFlags(flags); |
1493 if (kind == Code::CALL_IC) { | 1534 if (kind == Code::CALL_IC) { |
1494 CallIC::GenerateInitialize(masm(), argc); | 1535 CallIC::GenerateInitialize(masm(), argc, extra_ic_state); |
1495 } else { | 1536 } else { |
1496 KeyedCallIC::GenerateInitialize(masm(), argc); | 1537 KeyedCallIC::GenerateInitialize(masm(), argc); |
1497 } | 1538 } |
1498 Object* result; | 1539 Object* result; |
1499 { MaybeObject* maybe_result = | 1540 { MaybeObject* maybe_result = |
1500 GetCodeWithFlags(flags, "CompileCallInitialize"); | 1541 GetCodeWithFlags(flags, "CompileCallInitialize"); |
1501 if (!maybe_result->ToObject(&result)) return maybe_result; | 1542 if (!maybe_result->ToObject(&result)) return maybe_result; |
1502 } | 1543 } |
1503 isolate()->counters()->call_initialize_stubs()->Increment(); | 1544 isolate()->counters()->call_initialize_stubs()->Increment(); |
1504 Code* code = Code::cast(result); | 1545 Code* code = Code::cast(result); |
1505 USE(code); | 1546 USE(code); |
1506 PROFILE(isolate(), | 1547 PROFILE(isolate(), |
1507 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_INITIALIZE_TAG), | 1548 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_INITIALIZE_TAG), |
1508 code, code->arguments_count())); | 1549 code, code->arguments_count())); |
1509 GDBJIT(AddCode(GDBJITInterface::CALL_INITIALIZE, Code::cast(code))); | 1550 GDBJIT(AddCode(GDBJITInterface::CALL_INITIALIZE, Code::cast(code))); |
1510 return result; | 1551 return result; |
1511 } | 1552 } |
1512 | 1553 |
1513 | 1554 |
1514 MaybeObject* StubCompiler::CompileCallPreMonomorphic(Code::Flags flags) { | 1555 MaybeObject* StubCompiler::CompileCallPreMonomorphic(Code::Flags flags) { |
1515 HandleScope scope(isolate()); | 1556 HandleScope scope(isolate()); |
1516 int argc = Code::ExtractArgumentsCountFromFlags(flags); | 1557 int argc = Code::ExtractArgumentsCountFromFlags(flags); |
1517 // The code of the PreMonomorphic stub is the same as the code | 1558 // The code of the PreMonomorphic stub is the same as the code |
1518 // of the Initialized stub. They just differ on the code object flags. | 1559 // of the Initialized stub. They just differ on the code object flags. |
1519 Code::Kind kind = Code::ExtractKindFromFlags(flags); | 1560 Code::Kind kind = Code::ExtractKindFromFlags(flags); |
| 1561 Code::ExtraICState extra_ic_state = Code::ExtractExtraICStateFromFlags(flags); |
1520 if (kind == Code::CALL_IC) { | 1562 if (kind == Code::CALL_IC) { |
1521 CallIC::GenerateInitialize(masm(), argc); | 1563 CallIC::GenerateInitialize(masm(), argc, extra_ic_state); |
1522 } else { | 1564 } else { |
1523 KeyedCallIC::GenerateInitialize(masm(), argc); | 1565 KeyedCallIC::GenerateInitialize(masm(), argc); |
1524 } | 1566 } |
1525 Object* result; | 1567 Object* result; |
1526 { MaybeObject* maybe_result = | 1568 { MaybeObject* maybe_result = |
1527 GetCodeWithFlags(flags, "CompileCallPreMonomorphic"); | 1569 GetCodeWithFlags(flags, "CompileCallPreMonomorphic"); |
1528 if (!maybe_result->ToObject(&result)) return maybe_result; | 1570 if (!maybe_result->ToObject(&result)) return maybe_result; |
1529 } | 1571 } |
1530 isolate()->counters()->call_premonomorphic_stubs()->Increment(); | 1572 isolate()->counters()->call_premonomorphic_stubs()->Increment(); |
1531 Code* code = Code::cast(result); | 1573 Code* code = Code::cast(result); |
1532 USE(code); | 1574 USE(code); |
1533 PROFILE(isolate(), | 1575 PROFILE(isolate(), |
1534 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_PRE_MONOMORPHIC_TAG), | 1576 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_PRE_MONOMORPHIC_TAG), |
1535 code, code->arguments_count())); | 1577 code, code->arguments_count())); |
1536 GDBJIT(AddCode(GDBJITInterface::CALL_PRE_MONOMORPHIC, Code::cast(code))); | 1578 GDBJIT(AddCode(GDBJITInterface::CALL_PRE_MONOMORPHIC, Code::cast(code))); |
1537 return result; | 1579 return result; |
1538 } | 1580 } |
1539 | 1581 |
1540 | 1582 |
1541 MaybeObject* StubCompiler::CompileCallNormal(Code::Flags flags) { | 1583 MaybeObject* StubCompiler::CompileCallNormal(Code::Flags flags) { |
1542 HandleScope scope(isolate()); | 1584 HandleScope scope(isolate()); |
1543 int argc = Code::ExtractArgumentsCountFromFlags(flags); | 1585 int argc = Code::ExtractArgumentsCountFromFlags(flags); |
1544 Code::Kind kind = Code::ExtractKindFromFlags(flags); | 1586 Code::Kind kind = Code::ExtractKindFromFlags(flags); |
1545 if (kind == Code::CALL_IC) { | 1587 if (kind == Code::CALL_IC) { |
| 1588 // Call normal is always with a explict receiver. |
| 1589 ASSERT(!CallIC::Contextual::decode( |
| 1590 Code::ExtractExtraICStateFromFlags(flags))); |
1546 CallIC::GenerateNormal(masm(), argc); | 1591 CallIC::GenerateNormal(masm(), argc); |
1547 } else { | 1592 } else { |
1548 KeyedCallIC::GenerateNormal(masm(), argc); | 1593 KeyedCallIC::GenerateNormal(masm(), argc); |
1549 } | 1594 } |
1550 Object* result; | 1595 Object* result; |
1551 { MaybeObject* maybe_result = GetCodeWithFlags(flags, "CompileCallNormal"); | 1596 { MaybeObject* maybe_result = GetCodeWithFlags(flags, "CompileCallNormal"); |
1552 if (!maybe_result->ToObject(&result)) return maybe_result; | 1597 if (!maybe_result->ToObject(&result)) return maybe_result; |
1553 } | 1598 } |
1554 isolate()->counters()->call_normal_stubs()->Increment(); | 1599 isolate()->counters()->call_normal_stubs()->Increment(); |
1555 Code* code = Code::cast(result); | 1600 Code* code = Code::cast(result); |
1556 USE(code); | 1601 USE(code); |
1557 PROFILE(isolate(), | 1602 PROFILE(isolate(), |
1558 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_NORMAL_TAG), | 1603 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_NORMAL_TAG), |
1559 code, code->arguments_count())); | 1604 code, code->arguments_count())); |
1560 GDBJIT(AddCode(GDBJITInterface::CALL_NORMAL, Code::cast(code))); | 1605 GDBJIT(AddCode(GDBJITInterface::CALL_NORMAL, Code::cast(code))); |
1561 return result; | 1606 return result; |
1562 } | 1607 } |
1563 | 1608 |
1564 | 1609 |
1565 MaybeObject* StubCompiler::CompileCallMegamorphic(Code::Flags flags) { | 1610 MaybeObject* StubCompiler::CompileCallMegamorphic(Code::Flags flags) { |
1566 HandleScope scope(isolate()); | 1611 HandleScope scope(isolate()); |
1567 int argc = Code::ExtractArgumentsCountFromFlags(flags); | 1612 int argc = Code::ExtractArgumentsCountFromFlags(flags); |
1568 Code::Kind kind = Code::ExtractKindFromFlags(flags); | 1613 Code::Kind kind = Code::ExtractKindFromFlags(flags); |
| 1614 Code::ExtraICState extra_ic_state = Code::ExtractExtraICStateFromFlags(flags); |
1569 if (kind == Code::CALL_IC) { | 1615 if (kind == Code::CALL_IC) { |
1570 CallIC::GenerateMegamorphic(masm(), argc); | 1616 CallIC::GenerateMegamorphic(masm(), argc, extra_ic_state); |
1571 } else { | 1617 } else { |
1572 KeyedCallIC::GenerateMegamorphic(masm(), argc); | 1618 KeyedCallIC::GenerateMegamorphic(masm(), argc); |
1573 } | 1619 } |
1574 Object* result; | 1620 Object* result; |
1575 { MaybeObject* maybe_result = | 1621 { MaybeObject* maybe_result = |
1576 GetCodeWithFlags(flags, "CompileCallMegamorphic"); | 1622 GetCodeWithFlags(flags, "CompileCallMegamorphic"); |
1577 if (!maybe_result->ToObject(&result)) return maybe_result; | 1623 if (!maybe_result->ToObject(&result)) return maybe_result; |
1578 } | 1624 } |
1579 isolate()->counters()->call_megamorphic_stubs()->Increment(); | 1625 isolate()->counters()->call_megamorphic_stubs()->Increment(); |
1580 Code* code = Code::cast(result); | 1626 Code* code = Code::cast(result); |
1581 USE(code); | 1627 USE(code); |
1582 PROFILE(isolate(), | 1628 PROFILE(isolate(), |
1583 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MEGAMORPHIC_TAG), | 1629 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MEGAMORPHIC_TAG), |
1584 code, code->arguments_count())); | 1630 code, code->arguments_count())); |
1585 GDBJIT(AddCode(GDBJITInterface::CALL_MEGAMORPHIC, Code::cast(code))); | 1631 GDBJIT(AddCode(GDBJITInterface::CALL_MEGAMORPHIC, Code::cast(code))); |
1586 return result; | 1632 return result; |
1587 } | 1633 } |
1588 | 1634 |
1589 | 1635 |
1590 MaybeObject* StubCompiler::CompileCallMiss(Code::Flags flags) { | 1636 MaybeObject* StubCompiler::CompileCallMiss(Code::Flags flags) { |
1591 HandleScope scope(isolate()); | 1637 HandleScope scope(isolate()); |
1592 int argc = Code::ExtractArgumentsCountFromFlags(flags); | 1638 int argc = Code::ExtractArgumentsCountFromFlags(flags); |
1593 Code::Kind kind = Code::ExtractKindFromFlags(flags); | 1639 Code::Kind kind = Code::ExtractKindFromFlags(flags); |
| 1640 Code::ExtraICState extra_ic_state = Code::ExtractExtraICStateFromFlags(flags); |
1594 if (kind == Code::CALL_IC) { | 1641 if (kind == Code::CALL_IC) { |
1595 CallIC::GenerateMiss(masm(), argc); | 1642 CallIC::GenerateMiss(masm(), argc, extra_ic_state); |
1596 } else { | 1643 } else { |
1597 KeyedCallIC::GenerateMiss(masm(), argc); | 1644 KeyedCallIC::GenerateMiss(masm(), argc); |
1598 } | 1645 } |
1599 Object* result; | 1646 Object* result; |
1600 { MaybeObject* maybe_result = GetCodeWithFlags(flags, "CompileCallMiss"); | 1647 { MaybeObject* maybe_result = GetCodeWithFlags(flags, "CompileCallMiss"); |
1601 if (!maybe_result->ToObject(&result)) return maybe_result; | 1648 if (!maybe_result->ToObject(&result)) return maybe_result; |
1602 } | 1649 } |
1603 isolate()->counters()->call_megamorphic_stubs()->Increment(); | 1650 isolate()->counters()->call_megamorphic_stubs()->Increment(); |
1604 Code* code = Code::cast(result); | 1651 Code* code = Code::cast(result); |
1605 USE(code); | 1652 USE(code); |
(...skipping 25 matching lines...) Expand all Loading... |
1631 } | 1678 } |
1632 | 1679 |
1633 | 1680 |
1634 MaybeObject* StubCompiler::CompileCallDebugPrepareStepIn(Code::Flags flags) { | 1681 MaybeObject* StubCompiler::CompileCallDebugPrepareStepIn(Code::Flags flags) { |
1635 HandleScope scope(isolate()); | 1682 HandleScope scope(isolate()); |
1636 // Use the same code for the the step in preparations as we do for | 1683 // Use the same code for the the step in preparations as we do for |
1637 // the miss case. | 1684 // the miss case. |
1638 int argc = Code::ExtractArgumentsCountFromFlags(flags); | 1685 int argc = Code::ExtractArgumentsCountFromFlags(flags); |
1639 Code::Kind kind = Code::ExtractKindFromFlags(flags); | 1686 Code::Kind kind = Code::ExtractKindFromFlags(flags); |
1640 if (kind == Code::CALL_IC) { | 1687 if (kind == Code::CALL_IC) { |
1641 CallIC::GenerateMiss(masm(), argc); | 1688 // For the debugger extra ic state is irrelevant. |
| 1689 CallIC::GenerateMiss(masm(), argc, Code::kNoExtraICState); |
1642 } else { | 1690 } else { |
1643 KeyedCallIC::GenerateMiss(masm(), argc); | 1691 KeyedCallIC::GenerateMiss(masm(), argc); |
1644 } | 1692 } |
1645 Object* result; | 1693 Object* result; |
1646 { MaybeObject* maybe_result = | 1694 { MaybeObject* maybe_result = |
1647 GetCodeWithFlags(flags, "CompileCallDebugPrepareStepIn"); | 1695 GetCodeWithFlags(flags, "CompileCallDebugPrepareStepIn"); |
1648 if (!maybe_result->ToObject(&result)) return maybe_result; | 1696 if (!maybe_result->ToObject(&result)) return maybe_result; |
1649 } | 1697 } |
1650 Code* code = Code::cast(result); | 1698 Code* code = Code::cast(result); |
1651 USE(code); | 1699 USE(code); |
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1937 } | 1985 } |
1938 Code* code = Code::cast(result); | 1986 Code* code = Code::cast(result); |
1939 USE(code); | 1987 USE(code); |
1940 PROFILE(isolate(), | 1988 PROFILE(isolate(), |
1941 CodeCreateEvent(Logger::STUB_TAG, code, "ExternalArrayStub")); | 1989 CodeCreateEvent(Logger::STUB_TAG, code, "ExternalArrayStub")); |
1942 return result; | 1990 return result; |
1943 } | 1991 } |
1944 | 1992 |
1945 | 1993 |
1946 } } // namespace v8::internal | 1994 } } // namespace v8::internal |
OLD | NEW |