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

Side by Side Diff: src/x64/ic-x64.cc

Issue 148223002: Remove CallICs (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Update test262 status file Created 6 years, 10 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/x64/full-codegen-x64.cc ('k') | src/x64/lithium-codegen-x64.cc » ('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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 810 matching lines...) Expand 10 before | Expand all | Expand 10 after
821 __ SmiCompareInteger32(FieldOperand(rdx, JSArray::kLengthOffset), rcx); 821 __ SmiCompareInteger32(FieldOperand(rdx, JSArray::kLengthOffset), rcx);
822 __ j(below_equal, &extra); 822 __ j(below_equal, &extra);
823 823
824 KeyedStoreGenerateGenericHelper(masm, &fast_object, &fast_double, 824 KeyedStoreGenerateGenericHelper(masm, &fast_object, &fast_double,
825 &slow, kCheckMap, kDontIncrementLength); 825 &slow, kCheckMap, kDontIncrementLength);
826 KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow, 826 KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow,
827 &slow, kDontCheckMap, kIncrementLength); 827 &slow, kDontCheckMap, kIncrementLength);
828 } 828 }
829 829
830 830
831 // The generated code does not accept smi keys.
832 // The generated code falls through if both probes miss.
833 void CallICBase::GenerateMonomorphicCacheProbe(MacroAssembler* masm,
834 int argc,
835 Code::Kind kind,
836 ExtraICState extra_state) {
837 // ----------- S t a t e -------------
838 // rcx : function name
839 // rdx : receiver
840 // -----------------------------------
841 Label number, non_number, non_string, boolean, probe, miss;
842
843 // Probe the stub cache.
844 Code::Flags flags = Code::ComputeFlags(kind,
845 MONOMORPHIC,
846 extra_state,
847 Code::NORMAL,
848 argc);
849 masm->isolate()->stub_cache()->GenerateProbe(
850 masm, flags, rdx, rcx, rbx, rax);
851
852 // If the stub cache probing failed, the receiver might be a value.
853 // For value objects, we use the map of the prototype objects for
854 // the corresponding JSValue for the cache and that is what we need
855 // to probe.
856 //
857 // Check for number.
858 __ JumpIfSmi(rdx, &number);
859 __ CmpObjectType(rdx, HEAP_NUMBER_TYPE, rbx);
860 __ j(not_equal, &non_number);
861 __ bind(&number);
862 StubCompiler::GenerateLoadGlobalFunctionPrototype(
863 masm, Context::NUMBER_FUNCTION_INDEX, rdx);
864 __ jmp(&probe);
865
866 // Check for string.
867 __ bind(&non_number);
868 __ CmpInstanceType(rbx, FIRST_NONSTRING_TYPE);
869 __ j(above_equal, &non_string);
870 StubCompiler::GenerateLoadGlobalFunctionPrototype(
871 masm, Context::STRING_FUNCTION_INDEX, rdx);
872 __ jmp(&probe);
873
874 // Check for boolean.
875 __ bind(&non_string);
876 __ CompareRoot(rdx, Heap::kTrueValueRootIndex);
877 __ j(equal, &boolean);
878 __ CompareRoot(rdx, Heap::kFalseValueRootIndex);
879 __ j(not_equal, &miss);
880 __ bind(&boolean);
881 StubCompiler::GenerateLoadGlobalFunctionPrototype(
882 masm, Context::BOOLEAN_FUNCTION_INDEX, rdx);
883
884 // Probe the stub cache for the value object.
885 __ bind(&probe);
886 masm->isolate()->stub_cache()->GenerateProbe(
887 masm, flags, rdx, rcx, rbx, no_reg);
888
889 __ bind(&miss);
890 }
891
892
893 static void GenerateFunctionTailCall(MacroAssembler* masm,
894 int argc,
895 Label* miss) {
896 // ----------- S t a t e -------------
897 // rcx : function name
898 // rdi : function
899 // rsp[0] : return address
900 // rsp[8] : argument argc
901 // rsp[16] : argument argc - 1
902 // ...
903 // rsp[argc * 8] : argument 1
904 // rsp[(argc + 1) * 8] : argument 0 = receiver
905 // -----------------------------------
906 __ JumpIfSmi(rdi, miss);
907 // Check that the value is a JavaScript function.
908 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rdx);
909 __ j(not_equal, miss);
910
911 // Invoke the function.
912 ParameterCount actual(argc);
913 __ InvokeFunction(rdi, actual, JUMP_FUNCTION, NullCallWrapper());
914 }
915
916
917 // The generated code falls through if the call should be handled by runtime.
918 void CallICBase::GenerateNormal(MacroAssembler* masm, int argc) {
919 // ----------- S t a t e -------------
920 // rcx : function name
921 // rsp[0] : return address
922 // rsp[8] : argument argc
923 // rsp[16] : argument argc - 1
924 // ...
925 // rsp[argc * 8] : argument 1
926 // rsp[(argc + 1) * 8] : argument 0 = receiver
927 // -----------------------------------
928 Label miss;
929
930 StackArgumentsAccessor args(rsp, argc);
931 __ movp(rdx, args.GetReceiverOperand());
932
933 GenerateNameDictionaryReceiverCheck(masm, rdx, rax, rbx, &miss);
934
935 // rax: elements
936 // Search the dictionary placing the result in rdi.
937 GenerateDictionaryLoad(masm, &miss, rax, rcx, rbx, rdi, rdi);
938
939 GenerateFunctionTailCall(masm, argc, &miss);
940
941 __ bind(&miss);
942 }
943
944
945 void CallICBase::GenerateMiss(MacroAssembler* masm,
946 int argc,
947 IC::UtilityId id,
948 ExtraICState extra_state) {
949 // ----------- S t a t e -------------
950 // rcx : function name
951 // rsp[0] : return address
952 // rsp[8] : argument argc
953 // rsp[16] : argument argc - 1
954 // ...
955 // rsp[argc * 8] : argument 1
956 // rsp[(argc + 1) * 8] : argument 0 = receiver
957 // -----------------------------------
958
959 Counters* counters = masm->isolate()->counters();
960 if (id == IC::kCallIC_Miss) {
961 __ IncrementCounter(counters->call_miss(), 1);
962 } else {
963 __ IncrementCounter(counters->keyed_call_miss(), 1);
964 }
965
966 StackArgumentsAccessor args(rsp, argc);
967 __ movp(rdx, args.GetReceiverOperand());
968
969 // Enter an internal frame.
970 {
971 FrameScope scope(masm, StackFrame::INTERNAL);
972
973 // Push the receiver and the name of the function.
974 __ push(rdx);
975 __ push(rcx);
976
977 // Call the entry.
978 CEntryStub stub(1);
979 __ Set(rax, 2);
980 __ LoadAddress(rbx, ExternalReference(IC_Utility(id), masm->isolate()));
981 __ CallStub(&stub);
982
983 // Move result to rdi and exit the internal frame.
984 __ movp(rdi, rax);
985 }
986
987 // Check if the receiver is a global object of some sort.
988 // This can happen only for regular CallIC but not KeyedCallIC.
989 if (id == IC::kCallIC_Miss) {
990 Label invoke, global;
991 __ movp(rdx, args.GetReceiverOperand());
992 __ JumpIfSmi(rdx, &invoke);
993 __ CmpObjectType(rdx, JS_GLOBAL_OBJECT_TYPE, rcx);
994 __ j(equal, &global);
995 __ CmpInstanceType(rcx, JS_BUILTINS_OBJECT_TYPE);
996 __ j(not_equal, &invoke);
997
998 // Patch the receiver on the stack.
999 __ bind(&global);
1000 __ LoadRoot(rdx, Heap::kUndefinedValueRootIndex);
1001 __ movp(args.GetReceiverOperand(), rdx);
1002 __ bind(&invoke);
1003 }
1004
1005 // Invoke the function.
1006 ParameterCount actual(argc);
1007 __ InvokeFunction(rdi, actual, JUMP_FUNCTION, NullCallWrapper());
1008 }
1009
1010
1011 void CallIC::GenerateMegamorphic(MacroAssembler* masm,
1012 int argc,
1013 ExtraICState extra_ic_state) {
1014 // ----------- S t a t e -------------
1015 // rcx : function name
1016 // rsp[0] : return address
1017 // rsp[8] : argument argc
1018 // rsp[16] : argument argc - 1
1019 // ...
1020 // rsp[argc * 8] : argument 1
1021 // rsp[(argc + 1) * 8] : argument 0 = receiver
1022 // -----------------------------------
1023
1024 StackArgumentsAccessor args(rsp, argc);
1025 __ movp(rdx, args.GetReceiverOperand());
1026 GenerateMonomorphicCacheProbe(masm, argc, Code::CALL_IC, extra_ic_state);
1027 GenerateMiss(masm, argc, extra_ic_state);
1028 }
1029
1030
1031 void KeyedCallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) {
1032 // ----------- S t a t e -------------
1033 // rcx : function name
1034 // rsp[0] : return address
1035 // rsp[8] : argument argc
1036 // rsp[16] : argument argc - 1
1037 // ...
1038 // rsp[argc * 8] : argument 1
1039 // rsp[(argc + 1) * 8] : argument 0 = receiver
1040 // -----------------------------------
1041
1042 StackArgumentsAccessor args(rsp, argc);
1043 __ movp(rdx, args.GetReceiverOperand());
1044
1045 Label do_call, slow_call, slow_load;
1046 Label check_number_dictionary, check_name, lookup_monomorphic_cache;
1047 Label index_smi, index_name;
1048
1049 // Check that the key is a smi.
1050 __ JumpIfNotSmi(rcx, &check_name);
1051
1052 __ bind(&index_smi);
1053 // Now the key is known to be a smi. This place is also jumped to from below
1054 // where a numeric string is converted to a smi.
1055
1056 GenerateKeyedLoadReceiverCheck(
1057 masm, rdx, rax, Map::kHasIndexedInterceptor, &slow_call);
1058
1059 GenerateFastArrayLoad(
1060 masm, rdx, rcx, rax, rbx, rdi, &check_number_dictionary, &slow_load);
1061 Counters* counters = masm->isolate()->counters();
1062 __ IncrementCounter(counters->keyed_call_generic_smi_fast(), 1);
1063
1064 __ bind(&do_call);
1065 // receiver in rdx is not used after this point.
1066 // rcx: key
1067 // rdi: function
1068 GenerateFunctionTailCall(masm, argc, &slow_call);
1069
1070 __ bind(&check_number_dictionary);
1071 // rax: elements
1072 // rcx: smi key
1073 // Check whether the elements is a number dictionary.
1074 __ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset),
1075 Heap::kHashTableMapRootIndex);
1076 __ j(not_equal, &slow_load);
1077 __ SmiToInteger32(rbx, rcx);
1078 // ebx: untagged index
1079 __ LoadFromNumberDictionary(&slow_load, rax, rcx, rbx, r9, rdi, rdi);
1080 __ IncrementCounter(counters->keyed_call_generic_smi_dict(), 1);
1081 __ jmp(&do_call);
1082
1083 __ bind(&slow_load);
1084 // This branch is taken when calling KeyedCallIC_Miss is neither required
1085 // nor beneficial.
1086 __ IncrementCounter(counters->keyed_call_generic_slow_load(), 1);
1087 {
1088 FrameScope scope(masm, StackFrame::INTERNAL);
1089 __ push(rcx); // save the key
1090 __ push(rdx); // pass the receiver
1091 __ push(rcx); // pass the key
1092 __ CallRuntime(Runtime::kKeyedGetProperty, 2);
1093 __ pop(rcx); // restore the key
1094 }
1095 __ movp(rdi, rax);
1096 __ jmp(&do_call);
1097
1098 __ bind(&check_name);
1099 GenerateKeyNameCheck(masm, rcx, rax, rbx, &index_name, &slow_call);
1100
1101 // The key is known to be a unique name.
1102 // If the receiver is a regular JS object with slow properties then do
1103 // a quick inline probe of the receiver's dictionary.
1104 // Otherwise do the monomorphic cache probe.
1105 GenerateKeyedLoadReceiverCheck(
1106 masm, rdx, rax, Map::kHasNamedInterceptor, &lookup_monomorphic_cache);
1107
1108 __ movp(rbx, FieldOperand(rdx, JSObject::kPropertiesOffset));
1109 __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset),
1110 Heap::kHashTableMapRootIndex);
1111 __ j(not_equal, &lookup_monomorphic_cache);
1112
1113 GenerateDictionaryLoad(masm, &slow_load, rbx, rcx, rax, rdi, rdi);
1114 __ IncrementCounter(counters->keyed_call_generic_lookup_dict(), 1);
1115 __ jmp(&do_call);
1116
1117 __ bind(&lookup_monomorphic_cache);
1118 __ IncrementCounter(counters->keyed_call_generic_lookup_cache(), 1);
1119 GenerateMonomorphicCacheProbe(masm,
1120 argc,
1121 Code::KEYED_CALL_IC,
1122 kNoExtraICState);
1123 // Fall through on miss.
1124
1125 __ bind(&slow_call);
1126 // This branch is taken if:
1127 // - the receiver requires boxing or access check,
1128 // - the key is neither smi nor a unique name,
1129 // - the value loaded is not a function,
1130 // - there is hope that the runtime will create a monomorphic call stub
1131 // that will get fetched next time.
1132 __ IncrementCounter(counters->keyed_call_generic_slow(), 1);
1133 GenerateMiss(masm, argc);
1134
1135 __ bind(&index_name);
1136 __ IndexFromHash(rbx, rcx);
1137 // Now jump to the place where smi keys are handled.
1138 __ jmp(&index_smi);
1139 }
1140
1141
1142 void KeyedCallIC::GenerateNormal(MacroAssembler* masm, int argc) {
1143 // ----------- S t a t e -------------
1144 // rcx : function name
1145 // rsp[0] : return address
1146 // rsp[8] : argument argc
1147 // rsp[16] : argument argc - 1
1148 // ...
1149 // rsp[argc * 8] : argument 1
1150 // rsp[(argc + 1) * 8] : argument 0 = receiver
1151 // -----------------------------------
1152
1153 // Check if the name is really a name.
1154 Label miss;
1155 __ JumpIfSmi(rcx, &miss);
1156 Condition cond = masm->IsObjectNameType(rcx, rax, rax);
1157 __ j(NegateCondition(cond), &miss);
1158 CallICBase::GenerateNormal(masm, argc);
1159 __ bind(&miss);
1160 GenerateMiss(masm, argc);
1161 }
1162
1163
1164 static Operand GenerateMappedArgumentsLookup(MacroAssembler* masm, 831 static Operand GenerateMappedArgumentsLookup(MacroAssembler* masm,
1165 Register object, 832 Register object,
1166 Register key, 833 Register key,
1167 Register scratch1, 834 Register scratch1,
1168 Register scratch2, 835 Register scratch2,
1169 Register scratch3, 836 Register scratch3,
1170 Label* unmapped_case, 837 Label* unmapped_case,
1171 Label* slow_case) { 838 Label* slow_case) {
1172 Heap* heap = masm->isolate()->heap(); 839 Heap* heap = masm->isolate()->heap();
1173 840
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1299 r8, 966 r8,
1300 kDontSaveFPRegs, 967 kDontSaveFPRegs,
1301 EMIT_REMEMBERED_SET, 968 EMIT_REMEMBERED_SET,
1302 INLINE_SMI_CHECK); 969 INLINE_SMI_CHECK);
1303 __ Ret(); 970 __ Ret();
1304 __ bind(&slow); 971 __ bind(&slow);
1305 GenerateMiss(masm); 972 GenerateMiss(masm);
1306 } 973 }
1307 974
1308 975
1309 void KeyedCallIC::GenerateNonStrictArguments(MacroAssembler* masm, 976 void LoadIC::GenerateMegamorphic(MacroAssembler* masm,
1310 int argc) { 977 ExtraICState extra_state) {
1311 // ----------- S t a t e -------------
1312 // rcx : function name
1313 // rsp[0] : return address
1314 // rsp[8] : argument argc
1315 // rsp[16] : argument argc - 1
1316 // ...
1317 // rsp[argc * 8] : argument 1
1318 // rsp[(argc + 1) * 8] : argument 0 = receiver
1319 // -----------------------------------
1320 Label slow, notin;
1321 StackArgumentsAccessor args(rsp, argc);
1322 __ movp(rdx, args.GetReceiverOperand());
1323 Operand mapped_location = GenerateMappedArgumentsLookup(
1324 masm, rdx, rcx, rbx, rax, r8, &notin, &slow);
1325 __ movp(rdi, mapped_location);
1326 GenerateFunctionTailCall(masm, argc, &slow);
1327 __ bind(&notin);
1328 // The unmapped lookup expects that the parameter map is in rbx.
1329 Operand unmapped_location =
1330 GenerateUnmappedArgumentsLookup(masm, rcx, rbx, rax, &slow);
1331 __ CompareRoot(unmapped_location, Heap::kTheHoleValueRootIndex);
1332 __ j(equal, &slow);
1333 __ movp(rdi, unmapped_location);
1334 GenerateFunctionTailCall(masm, argc, &slow);
1335 __ bind(&slow);
1336 GenerateMiss(masm, argc);
1337 }
1338
1339
1340 void LoadIC::GenerateMegamorphic(MacroAssembler* masm, ContextualMode mode) {
1341 // ----------- S t a t e ------------- 978 // ----------- S t a t e -------------
1342 // -- rax : receiver 979 // -- rax : receiver
1343 // -- rcx : name 980 // -- rcx : name
1344 // -- rsp[0] : return address 981 // -- rsp[0] : return address
1345 // ----------------------------------- 982 // -----------------------------------
1346 983
1347 // Probe the stub cache. 984 // Probe the stub cache.
1348 ExtraICState extra_ic_state = LoadIC::ComputeExtraICState(mode);
1349 Code::Flags flags = Code::ComputeFlags( 985 Code::Flags flags = Code::ComputeFlags(
1350 Code::HANDLER, MONOMORPHIC, extra_ic_state, 986 Code::HANDLER, MONOMORPHIC, extra_state,
1351 Code::NORMAL, Code::LOAD_IC); 987 Code::NORMAL, Code::LOAD_IC);
1352 masm->isolate()->stub_cache()->GenerateProbe( 988 masm->isolate()->stub_cache()->GenerateProbe(
1353 masm, flags, rax, rcx, rbx, rdx); 989 masm, flags, rax, rcx, rbx, rdx);
1354 990
1355 GenerateMiss(masm); 991 GenerateMiss(masm);
1356 } 992 }
1357 993
1358 994
1359 void LoadIC::GenerateNormal(MacroAssembler* masm) { 995 void LoadIC::GenerateNormal(MacroAssembler* masm) {
1360 // ----------- S t a t e ------------- 996 // ----------- S t a t e -------------
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
1691 Condition cc = (check == ENABLE_INLINED_SMI_CHECK) 1327 Condition cc = (check == ENABLE_INLINED_SMI_CHECK)
1692 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) 1328 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero)
1693 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); 1329 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry);
1694 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); 1330 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc);
1695 } 1331 }
1696 1332
1697 1333
1698 } } // namespace v8::internal 1334 } } // namespace v8::internal
1699 1335
1700 #endif // V8_TARGET_ARCH_X64 1336 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/full-codegen-x64.cc ('k') | src/x64/lithium-codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698