OLD | NEW |
1 // Copyright 2011 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 |
(...skipping 771 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
782 if (!maybe_result->ToObject(&result)) return maybe_result; | 782 if (!maybe_result->ToObject(&result)) return maybe_result; |
783 } | 783 } |
784 } | 784 } |
785 return code; | 785 return code; |
786 } | 786 } |
787 | 787 |
788 | 788 |
789 MaybeObject* StubCache::ComputeCallField(int argc, | 789 MaybeObject* StubCache::ComputeCallField(int argc, |
790 InLoopFlag in_loop, | 790 InLoopFlag in_loop, |
791 Code::Kind kind, | 791 Code::Kind kind, |
| 792 Code::ExtraICState extra_ic_state, |
792 String* name, | 793 String* name, |
793 Object* object, | 794 Object* object, |
794 JSObject* holder, | 795 JSObject* holder, |
795 int index) { | 796 int index) { |
796 // Compute the check type and the map. | 797 // Compute the check type and the map. |
797 InlineCacheHolderFlag cache_holder = | 798 InlineCacheHolderFlag cache_holder = |
798 IC::GetCodeCacheForObject(object, holder); | 799 IC::GetCodeCacheForObject(object, holder); |
799 JSObject* map_holder = IC::GetCodeCacheHolder(object, cache_holder); | 800 JSObject* map_holder = IC::GetCodeCacheHolder(object, cache_holder); |
800 | 801 |
801 // TODO(1233596): We cannot do receiver map check for non-JS objects | 802 // TODO(1233596): We cannot do receiver map check for non-JS objects |
802 // because they may be represented as immediates without a | 803 // because they may be represented as immediates without a |
803 // map. Instead, we check against the map in the holder. | 804 // map. Instead, we check against the map in the holder. |
804 if (object->IsNumber() || object->IsBoolean() || object->IsString()) { | 805 if (object->IsNumber() || object->IsBoolean() || object->IsString()) { |
805 object = holder; | 806 object = holder; |
806 } | 807 } |
807 | 808 |
808 Code::Flags flags = Code::ComputeMonomorphicFlags(kind, | 809 Code::Flags flags = Code::ComputeMonomorphicFlags(kind, |
809 FIELD, | 810 FIELD, |
810 Code::kNoExtraICState, | 811 extra_ic_state, |
811 cache_holder, | 812 cache_holder, |
812 in_loop, | 813 in_loop, |
813 argc); | 814 argc); |
814 Object* code = map_holder->map()->FindInCodeCache(name, flags); | 815 Object* code = map_holder->map()->FindInCodeCache(name, flags); |
815 if (code->IsUndefined()) { | 816 if (code->IsUndefined()) { |
816 CallStubCompiler compiler( | 817 CallStubCompiler compiler( |
817 argc, in_loop, kind, Code::kNoExtraICState, cache_holder); | 818 argc, in_loop, kind, extra_ic_state, cache_holder); |
818 { MaybeObject* maybe_code = | 819 { MaybeObject* maybe_code = |
819 compiler.CompileCallField(JSObject::cast(object), | 820 compiler.CompileCallField(JSObject::cast(object), |
820 holder, | 821 holder, |
821 index, | 822 index, |
822 name); | 823 name); |
823 if (!maybe_code->ToObject(&code)) return maybe_code; | 824 if (!maybe_code->ToObject(&code)) return maybe_code; |
824 } | 825 } |
825 ASSERT_EQ(flags, Code::cast(code)->flags()); | 826 ASSERT_EQ(flags, Code::cast(code)->flags()); |
826 PROFILE(isolate_, | 827 PROFILE(isolate_, |
827 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), | 828 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), |
828 Code::cast(code), name)); | 829 Code::cast(code), name)); |
829 GDBJIT(AddCode(GDBJITInterface::CALL_IC, name, Code::cast(code))); | 830 GDBJIT(AddCode(GDBJITInterface::CALL_IC, name, Code::cast(code))); |
830 Object* result; | 831 Object* result; |
831 { MaybeObject* maybe_result = | 832 { MaybeObject* maybe_result = |
832 map_holder->UpdateMapCodeCache(name, Code::cast(code)); | 833 map_holder->UpdateMapCodeCache(name, Code::cast(code)); |
833 if (!maybe_result->ToObject(&result)) return maybe_result; | 834 if (!maybe_result->ToObject(&result)) return maybe_result; |
834 } | 835 } |
835 } | 836 } |
836 return code; | 837 return code; |
837 } | 838 } |
838 | 839 |
839 | 840 |
840 MaybeObject* StubCache::ComputeCallInterceptor(int argc, | 841 MaybeObject* StubCache::ComputeCallInterceptor( |
841 Code::Kind kind, | 842 int argc, |
842 String* name, | 843 Code::Kind kind, |
843 Object* object, | 844 Code::ExtraICState extra_ic_state, |
844 JSObject* holder) { | 845 String* name, |
| 846 Object* object, |
| 847 JSObject* holder) { |
845 // Compute the check type and the map. | 848 // Compute the check type and the map. |
846 InlineCacheHolderFlag cache_holder = | 849 InlineCacheHolderFlag cache_holder = |
847 IC::GetCodeCacheForObject(object, holder); | 850 IC::GetCodeCacheForObject(object, holder); |
848 JSObject* map_holder = IC::GetCodeCacheHolder(object, cache_holder); | 851 JSObject* map_holder = IC::GetCodeCacheHolder(object, cache_holder); |
849 | 852 |
850 // TODO(1233596): We cannot do receiver map check for non-JS objects | 853 // TODO(1233596): We cannot do receiver map check for non-JS objects |
851 // because they may be represented as immediates without a | 854 // because they may be represented as immediates without a |
852 // map. Instead, we check against the map in the holder. | 855 // map. Instead, we check against the map in the holder. |
853 if (object->IsNumber() || object->IsBoolean() || object->IsString()) { | 856 if (object->IsNumber() || object->IsBoolean() || object->IsString()) { |
854 object = holder; | 857 object = holder; |
855 } | 858 } |
856 | 859 |
857 Code::Flags flags = Code::ComputeMonomorphicFlags(kind, | 860 Code::Flags flags = Code::ComputeMonomorphicFlags(kind, |
858 INTERCEPTOR, | 861 INTERCEPTOR, |
859 Code::kNoExtraICState, | 862 extra_ic_state, |
860 cache_holder, | 863 cache_holder, |
861 NOT_IN_LOOP, | 864 NOT_IN_LOOP, |
862 argc); | 865 argc); |
863 Object* code = map_holder->map()->FindInCodeCache(name, flags); | 866 Object* code = map_holder->map()->FindInCodeCache(name, flags); |
864 if (code->IsUndefined()) { | 867 if (code->IsUndefined()) { |
865 CallStubCompiler compiler( | 868 CallStubCompiler compiler( |
866 argc, NOT_IN_LOOP, kind, Code::kNoExtraICState, cache_holder); | 869 argc, NOT_IN_LOOP, kind, extra_ic_state, cache_holder); |
867 { MaybeObject* maybe_code = | 870 { MaybeObject* maybe_code = |
868 compiler.CompileCallInterceptor(JSObject::cast(object), holder, name); | 871 compiler.CompileCallInterceptor(JSObject::cast(object), holder, name); |
869 if (!maybe_code->ToObject(&code)) return maybe_code; | 872 if (!maybe_code->ToObject(&code)) return maybe_code; |
870 } | 873 } |
871 ASSERT_EQ(flags, Code::cast(code)->flags()); | 874 ASSERT_EQ(flags, Code::cast(code)->flags()); |
872 PROFILE(isolate(), | 875 PROFILE(isolate(), |
873 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), | 876 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), |
874 Code::cast(code), name)); | 877 Code::cast(code), name)); |
875 GDBJIT(AddCode(GDBJITInterface::CALL_IC, name, Code::cast(code))); | 878 GDBJIT(AddCode(GDBJITInterface::CALL_IC, name, Code::cast(code))); |
876 Object* result; | 879 Object* result; |
877 { MaybeObject* maybe_result = | 880 { MaybeObject* maybe_result = |
878 map_holder->UpdateMapCodeCache(name, Code::cast(code)); | 881 map_holder->UpdateMapCodeCache(name, Code::cast(code)); |
879 if (!maybe_result->ToObject(&result)) return maybe_result; | 882 if (!maybe_result->ToObject(&result)) return maybe_result; |
880 } | 883 } |
881 } | 884 } |
882 return code; | 885 return code; |
883 } | 886 } |
884 | 887 |
885 | 888 |
886 MaybeObject* StubCache::ComputeCallNormal(int argc, | 889 MaybeObject* StubCache::ComputeCallNormal(int argc, |
887 InLoopFlag in_loop, | 890 InLoopFlag in_loop, |
888 Code::Kind kind, | 891 Code::Kind kind, |
| 892 Code::ExtraICState extra_ic_state, |
889 String* name, | 893 String* name, |
890 JSObject* receiver) { | 894 JSObject* receiver) { |
891 Object* code; | 895 Object* code; |
892 { MaybeObject* maybe_code = ComputeCallNormal(argc, in_loop, kind); | 896 { MaybeObject* maybe_code = |
| 897 ComputeCallNormal(argc, in_loop, kind, extra_ic_state); |
893 if (!maybe_code->ToObject(&code)) return maybe_code; | 898 if (!maybe_code->ToObject(&code)) return maybe_code; |
894 } | 899 } |
895 return code; | 900 return code; |
896 } | 901 } |
897 | 902 |
898 | 903 |
899 MaybeObject* StubCache::ComputeCallGlobal(int argc, | 904 MaybeObject* StubCache::ComputeCallGlobal(int argc, |
900 InLoopFlag in_loop, | 905 InLoopFlag in_loop, |
901 Code::Kind kind, | 906 Code::Kind kind, |
| 907 Code::ExtraICState extra_ic_state, |
902 String* name, | 908 String* name, |
903 JSObject* receiver, | 909 JSObject* receiver, |
904 GlobalObject* holder, | 910 GlobalObject* holder, |
905 JSGlobalPropertyCell* cell, | 911 JSGlobalPropertyCell* cell, |
906 JSFunction* function) { | 912 JSFunction* function) { |
907 InlineCacheHolderFlag cache_holder = | 913 InlineCacheHolderFlag cache_holder = |
908 IC::GetCodeCacheForObject(receiver, holder); | 914 IC::GetCodeCacheForObject(receiver, holder); |
909 JSObject* map_holder = IC::GetCodeCacheHolder(receiver, cache_holder); | 915 JSObject* map_holder = IC::GetCodeCacheHolder(receiver, cache_holder); |
910 Code::Flags flags = Code::ComputeMonomorphicFlags(kind, | 916 Code::Flags flags = Code::ComputeMonomorphicFlags(kind, |
911 NORMAL, | 917 NORMAL, |
912 Code::kNoExtraICState, | 918 extra_ic_state, |
913 cache_holder, | 919 cache_holder, |
914 in_loop, | 920 in_loop, |
915 argc); | 921 argc); |
916 Object* code = map_holder->map()->FindInCodeCache(name, flags); | 922 Object* code = map_holder->map()->FindInCodeCache(name, flags); |
917 if (code->IsUndefined()) { | 923 if (code->IsUndefined()) { |
918 // If the function hasn't been compiled yet, we cannot do it now | 924 // If the function hasn't been compiled yet, we cannot do it now |
919 // because it may cause GC. To avoid this issue, we return an | 925 // because it may cause GC. To avoid this issue, we return an |
920 // internal error which will make sure we do not update any | 926 // internal error which will make sure we do not update any |
921 // caches. | 927 // caches. |
922 if (!function->is_compiled()) return Failure::InternalError(); | 928 if (!function->is_compiled()) return Failure::InternalError(); |
923 CallStubCompiler compiler( | 929 CallStubCompiler compiler( |
924 argc, in_loop, kind, Code::kNoExtraICState, cache_holder); | 930 argc, in_loop, kind, extra_ic_state, cache_holder); |
925 { MaybeObject* maybe_code = | 931 { MaybeObject* maybe_code = |
926 compiler.CompileCallGlobal(receiver, holder, cell, function, name); | 932 compiler.CompileCallGlobal(receiver, |
| 933 holder, |
| 934 cell, |
| 935 function, |
| 936 name, |
| 937 extra_ic_state); |
927 if (!maybe_code->ToObject(&code)) return maybe_code; | 938 if (!maybe_code->ToObject(&code)) return maybe_code; |
928 } | 939 } |
929 ASSERT_EQ(flags, Code::cast(code)->flags()); | 940 ASSERT_EQ(flags, Code::cast(code)->flags()); |
930 PROFILE(isolate(), | 941 PROFILE(isolate(), |
931 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), | 942 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), |
932 Code::cast(code), name)); | 943 Code::cast(code), name)); |
933 GDBJIT(AddCode(GDBJITInterface::CALL_IC, name, Code::cast(code))); | 944 GDBJIT(AddCode(GDBJITInterface::CALL_IC, name, Code::cast(code))); |
934 Object* result; | 945 Object* result; |
935 { MaybeObject* maybe_result = | 946 { MaybeObject* maybe_result = |
936 map_holder->UpdateMapCodeCache(name, Code::cast(code)); | 947 map_holder->UpdateMapCodeCache(name, Code::cast(code)); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
984 heap->non_monomorphic_cache()->ValueAtPut(entry, code); | 995 heap->non_monomorphic_cache()->ValueAtPut(entry, code); |
985 CHECK(GetProbeValue(isolate, Code::cast(code)->flags()) == code); | 996 CHECK(GetProbeValue(isolate, Code::cast(code)->flags()) == code); |
986 } | 997 } |
987 } | 998 } |
988 return maybe_code; | 999 return maybe_code; |
989 } | 1000 } |
990 | 1001 |
991 | 1002 |
992 Code* StubCache::FindCallInitialize(int argc, | 1003 Code* StubCache::FindCallInitialize(int argc, |
993 InLoopFlag in_loop, | 1004 InLoopFlag in_loop, |
| 1005 RelocInfo::Mode mode, |
994 Code::Kind kind) { | 1006 Code::Kind kind) { |
| 1007 Code::ExtraICState extra_state = |
| 1008 CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) | |
| 1009 CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT); |
995 Code::Flags flags = Code::ComputeFlags(kind, | 1010 Code::Flags flags = Code::ComputeFlags(kind, |
996 in_loop, | 1011 in_loop, |
997 UNINITIALIZED, | 1012 UNINITIALIZED, |
998 Code::kNoExtraICState, | 1013 extra_state, |
999 NORMAL, | 1014 NORMAL, |
1000 argc); | 1015 argc); |
1001 Object* result = ProbeCache(isolate(), flags)->ToObjectUnchecked(); | 1016 Object* result = ProbeCache(isolate(), flags)->ToObjectUnchecked(); |
1002 ASSERT(result != heap()->undefined_value()); | 1017 ASSERT(result != heap()->undefined_value()); |
1003 // This might be called during the marking phase of the collector | 1018 // This might be called during the marking phase of the collector |
1004 // hence the unchecked cast. | 1019 // hence the unchecked cast. |
1005 return reinterpret_cast<Code*>(result); | 1020 return reinterpret_cast<Code*>(result); |
1006 } | 1021 } |
1007 | 1022 |
1008 | 1023 |
1009 MaybeObject* StubCache::ComputeCallInitialize(int argc, | 1024 MaybeObject* StubCache::ComputeCallInitialize(int argc, |
1010 InLoopFlag in_loop, | 1025 InLoopFlag in_loop, |
| 1026 RelocInfo::Mode mode, |
1011 Code::Kind kind) { | 1027 Code::Kind kind) { |
| 1028 Code::ExtraICState extra_state = |
| 1029 CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) | |
| 1030 CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT); |
1012 Code::Flags flags = Code::ComputeFlags(kind, | 1031 Code::Flags flags = Code::ComputeFlags(kind, |
1013 in_loop, | 1032 in_loop, |
1014 UNINITIALIZED, | 1033 UNINITIALIZED, |
1015 Code::kNoExtraICState, | 1034 extra_state, |
1016 NORMAL, | 1035 NORMAL, |
1017 argc); | 1036 argc); |
1018 Object* probe; | 1037 Object* probe; |
1019 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); | 1038 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); |
1020 if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 1039 if (!maybe_probe->ToObject(&probe)) return maybe_probe; |
1021 } | 1040 } |
1022 if (!probe->IsUndefined()) return probe; | 1041 if (!probe->IsUndefined()) return probe; |
1023 StubCompiler compiler; | 1042 StubCompiler compiler; |
1024 return FillCache(isolate_, compiler.CompileCallInitialize(flags)); | 1043 return FillCache(isolate_, compiler.CompileCallInitialize(flags)); |
1025 } | 1044 } |
1026 | 1045 |
1027 | 1046 |
1028 Handle<Code> StubCache::ComputeCallInitialize(int argc, InLoopFlag in_loop) { | 1047 Handle<Code> StubCache::ComputeCallInitialize(int argc, |
| 1048 InLoopFlag in_loop, |
| 1049 RelocInfo::Mode mode) { |
1029 if (in_loop == IN_LOOP) { | 1050 if (in_loop == IN_LOOP) { |
1030 // Force the creation of the corresponding stub outside loops, | 1051 // Force the creation of the corresponding stub outside loops, |
1031 // because it may be used when clearing the ICs later - it is | 1052 // because it may be used when clearing the ICs later - it is |
1032 // possible for a series of IC transitions to lose the in-loop | 1053 // possible for a series of IC transitions to lose the in-loop |
1033 // information, and the IC clearing code can't generate a stub | 1054 // information, and the IC clearing code can't generate a stub |
1034 // that it needs so we need to ensure it is generated already. | 1055 // that it needs so we need to ensure it is generated already. |
1035 ComputeCallInitialize(argc, NOT_IN_LOOP); | 1056 ComputeCallInitialize(argc, NOT_IN_LOOP, mode); |
1036 } | 1057 } |
1037 CALL_HEAP_FUNCTION(isolate_, | 1058 CALL_HEAP_FUNCTION(isolate_, |
1038 ComputeCallInitialize(argc, in_loop, Code::CALL_IC), Code); | 1059 ComputeCallInitialize(argc, in_loop, mode, Code::CALL_IC), |
| 1060 Code); |
1039 } | 1061 } |
1040 | 1062 |
1041 | 1063 |
1042 Handle<Code> StubCache::ComputeKeyedCallInitialize(int argc, | 1064 Handle<Code> StubCache::ComputeKeyedCallInitialize(int argc, |
1043 InLoopFlag in_loop) { | 1065 InLoopFlag in_loop) { |
1044 if (in_loop == IN_LOOP) { | 1066 if (in_loop == IN_LOOP) { |
1045 // Force the creation of the corresponding stub outside loops, | 1067 // Force the creation of the corresponding stub outside loops, |
1046 // because it may be used when clearing the ICs later - it is | 1068 // because it may be used when clearing the ICs later - it is |
1047 // possible for a series of IC transitions to lose the in-loop | 1069 // possible for a series of IC transitions to lose the in-loop |
1048 // information, and the IC clearing code can't generate a stub | 1070 // information, and the IC clearing code can't generate a stub |
1049 // that it needs so we need to ensure it is generated already. | 1071 // that it needs so we need to ensure it is generated already. |
1050 ComputeKeyedCallInitialize(argc, NOT_IN_LOOP); | 1072 ComputeKeyedCallInitialize(argc, NOT_IN_LOOP); |
1051 } | 1073 } |
1052 CALL_HEAP_FUNCTION( | 1074 CALL_HEAP_FUNCTION( |
1053 isolate_, | 1075 isolate_, |
1054 ComputeCallInitialize(argc, in_loop, Code::KEYED_CALL_IC), Code); | 1076 ComputeCallInitialize(argc, |
| 1077 in_loop, |
| 1078 RelocInfo::CODE_TARGET, |
| 1079 Code::KEYED_CALL_IC), |
| 1080 Code); |
1055 } | 1081 } |
1056 | 1082 |
1057 | 1083 |
1058 MaybeObject* StubCache::ComputeCallPreMonomorphic(int argc, | 1084 MaybeObject* StubCache::ComputeCallPreMonomorphic( |
1059 InLoopFlag in_loop, | 1085 int argc, |
1060 Code::Kind kind) { | 1086 InLoopFlag in_loop, |
| 1087 Code::Kind kind, |
| 1088 Code::ExtraICState extra_ic_state) { |
1061 Code::Flags flags = Code::ComputeFlags(kind, | 1089 Code::Flags flags = Code::ComputeFlags(kind, |
1062 in_loop, | 1090 in_loop, |
1063 PREMONOMORPHIC, | 1091 PREMONOMORPHIC, |
1064 Code::kNoExtraICState, | 1092 extra_ic_state, |
1065 NORMAL, | 1093 NORMAL, |
1066 argc); | 1094 argc); |
1067 Object* probe; | 1095 Object* probe; |
1068 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); | 1096 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); |
1069 if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 1097 if (!maybe_probe->ToObject(&probe)) return maybe_probe; |
1070 } | 1098 } |
1071 if (!probe->IsUndefined()) return probe; | 1099 if (!probe->IsUndefined()) return probe; |
1072 StubCompiler compiler; | 1100 StubCompiler compiler; |
1073 return FillCache(isolate_, compiler.CompileCallPreMonomorphic(flags)); | 1101 return FillCache(isolate_, compiler.CompileCallPreMonomorphic(flags)); |
1074 } | 1102 } |
1075 | 1103 |
1076 | 1104 |
1077 MaybeObject* StubCache::ComputeCallNormal(int argc, | 1105 MaybeObject* StubCache::ComputeCallNormal(int argc, |
1078 InLoopFlag in_loop, | 1106 InLoopFlag in_loop, |
1079 Code::Kind kind) { | 1107 Code::Kind kind, |
| 1108 Code::ExtraICState extra_ic_state) { |
1080 Code::Flags flags = Code::ComputeFlags(kind, | 1109 Code::Flags flags = Code::ComputeFlags(kind, |
1081 in_loop, | 1110 in_loop, |
1082 MONOMORPHIC, | 1111 MONOMORPHIC, |
1083 Code::kNoExtraICState, | 1112 extra_ic_state, |
1084 NORMAL, | 1113 NORMAL, |
1085 argc); | 1114 argc); |
1086 Object* probe; | 1115 Object* probe; |
1087 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); | 1116 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); |
1088 if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 1117 if (!maybe_probe->ToObject(&probe)) return maybe_probe; |
1089 } | 1118 } |
1090 if (!probe->IsUndefined()) return probe; | 1119 if (!probe->IsUndefined()) return probe; |
1091 StubCompiler compiler; | 1120 StubCompiler compiler; |
1092 return FillCache(isolate_, compiler.CompileCallNormal(flags)); | 1121 return FillCache(isolate_, compiler.CompileCallNormal(flags)); |
1093 } | 1122 } |
1094 | 1123 |
1095 | 1124 |
1096 MaybeObject* StubCache::ComputeCallMegamorphic(int argc, | 1125 MaybeObject* StubCache::ComputeCallMegamorphic( |
1097 InLoopFlag in_loop, | 1126 int argc, |
1098 Code::Kind kind) { | 1127 InLoopFlag in_loop, |
| 1128 Code::Kind kind, |
| 1129 Code::ExtraICState extra_ic_state) { |
1099 Code::Flags flags = Code::ComputeFlags(kind, | 1130 Code::Flags flags = Code::ComputeFlags(kind, |
1100 in_loop, | 1131 in_loop, |
1101 MEGAMORPHIC, | 1132 MEGAMORPHIC, |
1102 Code::kNoExtraICState, | 1133 extra_ic_state, |
1103 NORMAL, | 1134 NORMAL, |
1104 argc); | 1135 argc); |
1105 Object* probe; | 1136 Object* probe; |
1106 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); | 1137 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); |
1107 if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 1138 if (!maybe_probe->ToObject(&probe)) return maybe_probe; |
1108 } | 1139 } |
1109 if (!probe->IsUndefined()) return probe; | 1140 if (!probe->IsUndefined()) return probe; |
1110 StubCompiler compiler; | 1141 StubCompiler compiler; |
1111 return FillCache(isolate_, compiler.CompileCallMegamorphic(flags)); | 1142 return FillCache(isolate_, compiler.CompileCallMegamorphic(flags)); |
1112 } | 1143 } |
1113 | 1144 |
1114 | 1145 |
1115 MaybeObject* StubCache::ComputeCallMiss(int argc, Code::Kind kind) { | 1146 MaybeObject* StubCache::ComputeCallMiss(int argc, |
| 1147 Code::Kind kind, |
| 1148 Code::ExtraICState extra_ic_state) { |
1116 // MONOMORPHIC_PROTOTYPE_FAILURE state is used to make sure that miss stubs | 1149 // MONOMORPHIC_PROTOTYPE_FAILURE state is used to make sure that miss stubs |
1117 // and monomorphic stubs are not mixed up together in the stub cache. | 1150 // and monomorphic stubs are not mixed up together in the stub cache. |
1118 Code::Flags flags = Code::ComputeFlags(kind, | 1151 Code::Flags flags = Code::ComputeFlags(kind, |
1119 NOT_IN_LOOP, | 1152 NOT_IN_LOOP, |
1120 MONOMORPHIC_PROTOTYPE_FAILURE, | 1153 MONOMORPHIC_PROTOTYPE_FAILURE, |
1121 Code::kNoExtraICState, | 1154 extra_ic_state, |
1122 NORMAL, | 1155 NORMAL, |
1123 argc, | 1156 argc, |
1124 OWN_MAP); | 1157 OWN_MAP); |
1125 Object* probe; | 1158 Object* probe; |
1126 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); | 1159 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); |
1127 if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 1160 if (!maybe_probe->ToObject(&probe)) return maybe_probe; |
1128 } | 1161 } |
1129 if (!probe->IsUndefined()) return probe; | 1162 if (!probe->IsUndefined()) return probe; |
1130 StubCompiler compiler; | 1163 StubCompiler compiler; |
1131 return FillCache(isolate_, compiler.CompileCallMiss(flags)); | 1164 return FillCache(isolate_, compiler.CompileCallMiss(flags)); |
1132 } | 1165 } |
1133 | 1166 |
1134 | 1167 |
1135 #ifdef ENABLE_DEBUGGER_SUPPORT | 1168 #ifdef ENABLE_DEBUGGER_SUPPORT |
1136 MaybeObject* StubCache::ComputeCallDebugBreak(int argc, Code::Kind kind) { | 1169 MaybeObject* StubCache::ComputeCallDebugBreak( |
| 1170 int argc, |
| 1171 Code::Kind kind) { |
| 1172 // Extra IC state is irrelevant for debug break ICs. They jump to |
| 1173 // the actual call ic to carry out the work. |
1137 Code::Flags flags = Code::ComputeFlags(kind, | 1174 Code::Flags flags = Code::ComputeFlags(kind, |
1138 NOT_IN_LOOP, | 1175 NOT_IN_LOOP, |
1139 DEBUG_BREAK, | 1176 DEBUG_BREAK, |
1140 Code::kNoExtraICState, | 1177 Code::kNoExtraICState, |
1141 NORMAL, | 1178 NORMAL, |
1142 argc); | 1179 argc); |
1143 Object* probe; | 1180 Object* probe; |
1144 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); | 1181 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); |
1145 if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 1182 if (!maybe_probe->ToObject(&probe)) return maybe_probe; |
1146 } | 1183 } |
1147 if (!probe->IsUndefined()) return probe; | 1184 if (!probe->IsUndefined()) return probe; |
1148 StubCompiler compiler; | 1185 StubCompiler compiler; |
1149 return FillCache(isolate_, compiler.CompileCallDebugBreak(flags)); | 1186 return FillCache(isolate_, compiler.CompileCallDebugBreak(flags)); |
1150 } | 1187 } |
1151 | 1188 |
1152 | 1189 |
1153 MaybeObject* StubCache::ComputeCallDebugPrepareStepIn(int argc, | 1190 MaybeObject* StubCache::ComputeCallDebugPrepareStepIn( |
1154 Code::Kind kind) { | 1191 int argc, |
| 1192 Code::Kind kind) { |
| 1193 // Extra IC state is irrelevant for debug break ICs. They jump to |
| 1194 // the actual call ic to carry out the work. |
1155 Code::Flags flags = Code::ComputeFlags(kind, | 1195 Code::Flags flags = Code::ComputeFlags(kind, |
1156 NOT_IN_LOOP, | 1196 NOT_IN_LOOP, |
1157 DEBUG_PREPARE_STEP_IN, | 1197 DEBUG_PREPARE_STEP_IN, |
1158 Code::kNoExtraICState, | 1198 Code::kNoExtraICState, |
1159 NORMAL, | 1199 NORMAL, |
1160 argc); | 1200 argc); |
1161 Object* probe; | 1201 Object* probe; |
1162 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); | 1202 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); |
1163 if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 1203 if (!maybe_probe->ToObject(&probe)) return maybe_probe; |
1164 } | 1204 } |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1428 ASSERT(Smi::cast(args[1])->value() >= 0); | 1468 ASSERT(Smi::cast(args[1])->value() >= 0); |
1429 uint32_t index = Smi::cast(args[1])->value(); | 1469 uint32_t index = Smi::cast(args[1])->value(); |
1430 return receiver->GetElementWithInterceptor(receiver, index); | 1470 return receiver->GetElementWithInterceptor(receiver, index); |
1431 } | 1471 } |
1432 | 1472 |
1433 | 1473 |
1434 MaybeObject* StubCompiler::CompileCallInitialize(Code::Flags flags) { | 1474 MaybeObject* StubCompiler::CompileCallInitialize(Code::Flags flags) { |
1435 HandleScope scope(isolate()); | 1475 HandleScope scope(isolate()); |
1436 int argc = Code::ExtractArgumentsCountFromFlags(flags); | 1476 int argc = Code::ExtractArgumentsCountFromFlags(flags); |
1437 Code::Kind kind = Code::ExtractKindFromFlags(flags); | 1477 Code::Kind kind = Code::ExtractKindFromFlags(flags); |
| 1478 Code::ExtraICState extra_ic_state = Code::ExtractExtraICStateFromFlags(flags); |
1438 if (kind == Code::CALL_IC) { | 1479 if (kind == Code::CALL_IC) { |
1439 CallIC::GenerateInitialize(masm(), argc); | 1480 CallIC::GenerateInitialize(masm(), argc, extra_ic_state); |
1440 } else { | 1481 } else { |
1441 KeyedCallIC::GenerateInitialize(masm(), argc); | 1482 KeyedCallIC::GenerateInitialize(masm(), argc); |
1442 } | 1483 } |
1443 Object* result; | 1484 Object* result; |
1444 { MaybeObject* maybe_result = | 1485 { MaybeObject* maybe_result = |
1445 GetCodeWithFlags(flags, "CompileCallInitialize"); | 1486 GetCodeWithFlags(flags, "CompileCallInitialize"); |
1446 if (!maybe_result->ToObject(&result)) return maybe_result; | 1487 if (!maybe_result->ToObject(&result)) return maybe_result; |
1447 } | 1488 } |
1448 isolate()->counters()->call_initialize_stubs()->Increment(); | 1489 isolate()->counters()->call_initialize_stubs()->Increment(); |
1449 Code* code = Code::cast(result); | 1490 Code* code = Code::cast(result); |
1450 USE(code); | 1491 USE(code); |
1451 PROFILE(isolate(), | 1492 PROFILE(isolate(), |
1452 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_INITIALIZE_TAG), | 1493 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_INITIALIZE_TAG), |
1453 code, code->arguments_count())); | 1494 code, code->arguments_count())); |
1454 GDBJIT(AddCode(GDBJITInterface::CALL_INITIALIZE, Code::cast(code))); | 1495 GDBJIT(AddCode(GDBJITInterface::CALL_INITIALIZE, Code::cast(code))); |
1455 return result; | 1496 return result; |
1456 } | 1497 } |
1457 | 1498 |
1458 | 1499 |
1459 MaybeObject* StubCompiler::CompileCallPreMonomorphic(Code::Flags flags) { | 1500 MaybeObject* StubCompiler::CompileCallPreMonomorphic(Code::Flags flags) { |
1460 HandleScope scope(isolate()); | 1501 HandleScope scope(isolate()); |
1461 int argc = Code::ExtractArgumentsCountFromFlags(flags); | 1502 int argc = Code::ExtractArgumentsCountFromFlags(flags); |
1462 // The code of the PreMonomorphic stub is the same as the code | 1503 // The code of the PreMonomorphic stub is the same as the code |
1463 // of the Initialized stub. They just differ on the code object flags. | 1504 // of the Initialized stub. They just differ on the code object flags. |
1464 Code::Kind kind = Code::ExtractKindFromFlags(flags); | 1505 Code::Kind kind = Code::ExtractKindFromFlags(flags); |
| 1506 Code::ExtraICState extra_ic_state = Code::ExtractExtraICStateFromFlags(flags); |
1465 if (kind == Code::CALL_IC) { | 1507 if (kind == Code::CALL_IC) { |
1466 CallIC::GenerateInitialize(masm(), argc); | 1508 CallIC::GenerateInitialize(masm(), argc, extra_ic_state); |
1467 } else { | 1509 } else { |
1468 KeyedCallIC::GenerateInitialize(masm(), argc); | 1510 KeyedCallIC::GenerateInitialize(masm(), argc); |
1469 } | 1511 } |
1470 Object* result; | 1512 Object* result; |
1471 { MaybeObject* maybe_result = | 1513 { MaybeObject* maybe_result = |
1472 GetCodeWithFlags(flags, "CompileCallPreMonomorphic"); | 1514 GetCodeWithFlags(flags, "CompileCallPreMonomorphic"); |
1473 if (!maybe_result->ToObject(&result)) return maybe_result; | 1515 if (!maybe_result->ToObject(&result)) return maybe_result; |
1474 } | 1516 } |
1475 isolate()->counters()->call_premonomorphic_stubs()->Increment(); | 1517 isolate()->counters()->call_premonomorphic_stubs()->Increment(); |
1476 Code* code = Code::cast(result); | 1518 Code* code = Code::cast(result); |
1477 USE(code); | 1519 USE(code); |
1478 PROFILE(isolate(), | 1520 PROFILE(isolate(), |
1479 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_PRE_MONOMORPHIC_TAG), | 1521 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_PRE_MONOMORPHIC_TAG), |
1480 code, code->arguments_count())); | 1522 code, code->arguments_count())); |
1481 GDBJIT(AddCode(GDBJITInterface::CALL_PRE_MONOMORPHIC, Code::cast(code))); | 1523 GDBJIT(AddCode(GDBJITInterface::CALL_PRE_MONOMORPHIC, Code::cast(code))); |
1482 return result; | 1524 return result; |
1483 } | 1525 } |
1484 | 1526 |
1485 | 1527 |
1486 MaybeObject* StubCompiler::CompileCallNormal(Code::Flags flags) { | 1528 MaybeObject* StubCompiler::CompileCallNormal(Code::Flags flags) { |
1487 HandleScope scope(isolate()); | 1529 HandleScope scope(isolate()); |
1488 int argc = Code::ExtractArgumentsCountFromFlags(flags); | 1530 int argc = Code::ExtractArgumentsCountFromFlags(flags); |
1489 Code::Kind kind = Code::ExtractKindFromFlags(flags); | 1531 Code::Kind kind = Code::ExtractKindFromFlags(flags); |
1490 if (kind == Code::CALL_IC) { | 1532 if (kind == Code::CALL_IC) { |
| 1533 // Call normal is always with a explict receiver. |
| 1534 ASSERT(!CallIC::Contextual::decode( |
| 1535 Code::ExtractExtraICStateFromFlags(flags))); |
1491 CallIC::GenerateNormal(masm(), argc); | 1536 CallIC::GenerateNormal(masm(), argc); |
1492 } else { | 1537 } else { |
1493 KeyedCallIC::GenerateNormal(masm(), argc); | 1538 KeyedCallIC::GenerateNormal(masm(), argc); |
1494 } | 1539 } |
1495 Object* result; | 1540 Object* result; |
1496 { MaybeObject* maybe_result = GetCodeWithFlags(flags, "CompileCallNormal"); | 1541 { MaybeObject* maybe_result = GetCodeWithFlags(flags, "CompileCallNormal"); |
1497 if (!maybe_result->ToObject(&result)) return maybe_result; | 1542 if (!maybe_result->ToObject(&result)) return maybe_result; |
1498 } | 1543 } |
1499 isolate()->counters()->call_normal_stubs()->Increment(); | 1544 isolate()->counters()->call_normal_stubs()->Increment(); |
1500 Code* code = Code::cast(result); | 1545 Code* code = Code::cast(result); |
1501 USE(code); | 1546 USE(code); |
1502 PROFILE(isolate(), | 1547 PROFILE(isolate(), |
1503 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_NORMAL_TAG), | 1548 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_NORMAL_TAG), |
1504 code, code->arguments_count())); | 1549 code, code->arguments_count())); |
1505 GDBJIT(AddCode(GDBJITInterface::CALL_NORMAL, Code::cast(code))); | 1550 GDBJIT(AddCode(GDBJITInterface::CALL_NORMAL, Code::cast(code))); |
1506 return result; | 1551 return result; |
1507 } | 1552 } |
1508 | 1553 |
1509 | 1554 |
1510 MaybeObject* StubCompiler::CompileCallMegamorphic(Code::Flags flags) { | 1555 MaybeObject* StubCompiler::CompileCallMegamorphic(Code::Flags flags) { |
1511 HandleScope scope(isolate()); | 1556 HandleScope scope(isolate()); |
1512 int argc = Code::ExtractArgumentsCountFromFlags(flags); | 1557 int argc = Code::ExtractArgumentsCountFromFlags(flags); |
1513 Code::Kind kind = Code::ExtractKindFromFlags(flags); | 1558 Code::Kind kind = Code::ExtractKindFromFlags(flags); |
| 1559 Code::ExtraICState extra_ic_state = Code::ExtractExtraICStateFromFlags(flags); |
1514 if (kind == Code::CALL_IC) { | 1560 if (kind == Code::CALL_IC) { |
1515 CallIC::GenerateMegamorphic(masm(), argc); | 1561 CallIC::GenerateMegamorphic(masm(), argc, extra_ic_state); |
1516 } else { | 1562 } else { |
1517 KeyedCallIC::GenerateMegamorphic(masm(), argc); | 1563 KeyedCallIC::GenerateMegamorphic(masm(), argc); |
1518 } | 1564 } |
1519 Object* result; | 1565 Object* result; |
1520 { MaybeObject* maybe_result = | 1566 { MaybeObject* maybe_result = |
1521 GetCodeWithFlags(flags, "CompileCallMegamorphic"); | 1567 GetCodeWithFlags(flags, "CompileCallMegamorphic"); |
1522 if (!maybe_result->ToObject(&result)) return maybe_result; | 1568 if (!maybe_result->ToObject(&result)) return maybe_result; |
1523 } | 1569 } |
1524 isolate()->counters()->call_megamorphic_stubs()->Increment(); | 1570 isolate()->counters()->call_megamorphic_stubs()->Increment(); |
1525 Code* code = Code::cast(result); | 1571 Code* code = Code::cast(result); |
1526 USE(code); | 1572 USE(code); |
1527 PROFILE(isolate(), | 1573 PROFILE(isolate(), |
1528 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MEGAMORPHIC_TAG), | 1574 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MEGAMORPHIC_TAG), |
1529 code, code->arguments_count())); | 1575 code, code->arguments_count())); |
1530 GDBJIT(AddCode(GDBJITInterface::CALL_MEGAMORPHIC, Code::cast(code))); | 1576 GDBJIT(AddCode(GDBJITInterface::CALL_MEGAMORPHIC, Code::cast(code))); |
1531 return result; | 1577 return result; |
1532 } | 1578 } |
1533 | 1579 |
1534 | 1580 |
1535 MaybeObject* StubCompiler::CompileCallMiss(Code::Flags flags) { | 1581 MaybeObject* StubCompiler::CompileCallMiss(Code::Flags flags) { |
1536 HandleScope scope(isolate()); | 1582 HandleScope scope(isolate()); |
1537 int argc = Code::ExtractArgumentsCountFromFlags(flags); | 1583 int argc = Code::ExtractArgumentsCountFromFlags(flags); |
1538 Code::Kind kind = Code::ExtractKindFromFlags(flags); | 1584 Code::Kind kind = Code::ExtractKindFromFlags(flags); |
| 1585 Code::ExtraICState extra_ic_state = Code::ExtractExtraICStateFromFlags(flags); |
1539 if (kind == Code::CALL_IC) { | 1586 if (kind == Code::CALL_IC) { |
1540 CallIC::GenerateMiss(masm(), argc); | 1587 CallIC::GenerateMiss(masm(), argc, extra_ic_state); |
1541 } else { | 1588 } else { |
1542 KeyedCallIC::GenerateMiss(masm(), argc); | 1589 KeyedCallIC::GenerateMiss(masm(), argc); |
1543 } | 1590 } |
1544 Object* result; | 1591 Object* result; |
1545 { MaybeObject* maybe_result = GetCodeWithFlags(flags, "CompileCallMiss"); | 1592 { MaybeObject* maybe_result = GetCodeWithFlags(flags, "CompileCallMiss"); |
1546 if (!maybe_result->ToObject(&result)) return maybe_result; | 1593 if (!maybe_result->ToObject(&result)) return maybe_result; |
1547 } | 1594 } |
1548 isolate()->counters()->call_megamorphic_stubs()->Increment(); | 1595 isolate()->counters()->call_megamorphic_stubs()->Increment(); |
1549 Code* code = Code::cast(result); | 1596 Code* code = Code::cast(result); |
1550 USE(code); | 1597 USE(code); |
(...skipping 25 matching lines...) Expand all Loading... |
1576 } | 1623 } |
1577 | 1624 |
1578 | 1625 |
1579 MaybeObject* StubCompiler::CompileCallDebugPrepareStepIn(Code::Flags flags) { | 1626 MaybeObject* StubCompiler::CompileCallDebugPrepareStepIn(Code::Flags flags) { |
1580 HandleScope scope(isolate()); | 1627 HandleScope scope(isolate()); |
1581 // Use the same code for the the step in preparations as we do for | 1628 // Use the same code for the the step in preparations as we do for |
1582 // the miss case. | 1629 // the miss case. |
1583 int argc = Code::ExtractArgumentsCountFromFlags(flags); | 1630 int argc = Code::ExtractArgumentsCountFromFlags(flags); |
1584 Code::Kind kind = Code::ExtractKindFromFlags(flags); | 1631 Code::Kind kind = Code::ExtractKindFromFlags(flags); |
1585 if (kind == Code::CALL_IC) { | 1632 if (kind == Code::CALL_IC) { |
1586 CallIC::GenerateMiss(masm(), argc); | 1633 // For the debugger extra ic state is irrelevant. |
| 1634 CallIC::GenerateMiss(masm(), argc, Code::kNoExtraICState); |
1587 } else { | 1635 } else { |
1588 KeyedCallIC::GenerateMiss(masm(), argc); | 1636 KeyedCallIC::GenerateMiss(masm(), argc); |
1589 } | 1637 } |
1590 Object* result; | 1638 Object* result; |
1591 { MaybeObject* maybe_result = | 1639 { MaybeObject* maybe_result = |
1592 GetCodeWithFlags(flags, "CompileCallDebugPrepareStepIn"); | 1640 GetCodeWithFlags(flags, "CompileCallDebugPrepareStepIn"); |
1593 if (!maybe_result->ToObject(&result)) return maybe_result; | 1641 if (!maybe_result->ToObject(&result)) return maybe_result; |
1594 } | 1642 } |
1595 Code* code = Code::cast(result); | 1643 Code* code = Code::cast(result); |
1596 USE(code); | 1644 USE(code); |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1908 } | 1956 } |
1909 Code* code = Code::cast(result); | 1957 Code* code = Code::cast(result); |
1910 USE(code); | 1958 USE(code); |
1911 PROFILE(isolate(), | 1959 PROFILE(isolate(), |
1912 CodeCreateEvent(Logger::STUB_TAG, code, "ExternalArrayStoreStub")); | 1960 CodeCreateEvent(Logger::STUB_TAG, code, "ExternalArrayStoreStub")); |
1913 return result; | 1961 return result; |
1914 } | 1962 } |
1915 | 1963 |
1916 | 1964 |
1917 } } // namespace v8::internal | 1965 } } // namespace v8::internal |
OLD | NEW |