Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(189)

Side by Side Diff: src/stub-cache.cc

Issue 7039036: Fix calls of strict mode function with an implicit receiver. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Address comments. Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/stub-cache.h ('k') | src/type-info.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/stub-cache.h ('k') | src/type-info.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698