| 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 900 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 911 | 911 |
| 912 // Probe the stub cache for the value object. | 912 // Probe the stub cache for the value object. |
| 913 __ bind(&probe); | 913 __ bind(&probe); |
| 914 isolate->stub_cache()->GenerateProbe(masm, flags, edx, ecx, ebx, no_reg); | 914 isolate->stub_cache()->GenerateProbe(masm, flags, edx, ecx, ebx, no_reg); |
| 915 __ bind(&miss); | 915 __ bind(&miss); |
| 916 } | 916 } |
| 917 | 917 |
| 918 | 918 |
| 919 static void GenerateFunctionTailCall(MacroAssembler* masm, | 919 static void GenerateFunctionTailCall(MacroAssembler* masm, |
| 920 int argc, | 920 int argc, |
| 921 Code::ExtraICState extra_state, |
| 921 Label* miss) { | 922 Label* miss) { |
| 922 // ----------- S t a t e ------------- | 923 // ----------- S t a t e ------------- |
| 923 // -- ecx : name | 924 // -- ecx : name |
| 924 // -- edi : function | 925 // -- edi : function |
| 925 // -- esp[0] : return address | 926 // -- esp[0] : return address |
| 926 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 927 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
| 927 // -- ... | 928 // -- ... |
| 928 // -- esp[(argc + 1) * 4] : receiver | 929 // -- esp[(argc + 1) * 4] : receiver |
| 929 // ----------------------------------- | 930 // ----------------------------------- |
| 930 | 931 |
| 931 // Check that the result is not a smi. | 932 // Check that the result is not a smi. |
| 932 __ JumpIfSmi(edi, miss); | 933 __ JumpIfSmi(edi, miss); |
| 933 | 934 |
| 934 // Check that the value is a JavaScript function, fetching its map into eax. | 935 // Check that the value is a JavaScript function, fetching its map into eax. |
| 935 __ CmpObjectType(edi, JS_FUNCTION_TYPE, eax); | 936 __ CmpObjectType(edi, JS_FUNCTION_TYPE, eax); |
| 936 __ j(not_equal, miss); | 937 __ j(not_equal, miss); |
| 937 | 938 |
| 938 // Invoke the function. | 939 // Invoke the function. |
| 939 ParameterCount actual(argc); | 940 if (CallICBase::ConstructCall::decode(extra_state)) { |
| 940 __ InvokeFunction(edi, actual, JUMP_FUNCTION, | 941 ParameterCount actual(argc); |
| 941 NullCallWrapper(), CALL_AS_METHOD); | 942 __ InvokeConstruct(edi, actual); |
| 943 } else { |
| 944 ParameterCount actual(argc); |
| 945 __ InvokeFunction(edi, actual, JUMP_FUNCTION, |
| 946 NullCallWrapper(), CALL_AS_METHOD); |
| 947 } |
| 942 } | 948 } |
| 943 | 949 |
| 944 | 950 |
| 945 // The generated code falls through if the call should be handled by runtime. | 951 // The generated code falls through if the call should be handled by runtime. |
| 946 void CallICBase::GenerateNormal(MacroAssembler* masm, int argc) { | 952 void CallICBase::GenerateNormal(MacroAssembler* masm, |
| 953 int argc, |
| 954 Code::ExtraICState extra_state) { |
| 947 // ----------- S t a t e ------------- | 955 // ----------- S t a t e ------------- |
| 948 // -- ecx : name | 956 // -- ecx : name |
| 949 // -- esp[0] : return address | 957 // -- esp[0] : return address |
| 950 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 958 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
| 951 // -- ... | 959 // -- ... |
| 952 // -- esp[(argc + 1) * 4] : receiver | 960 // -- esp[(argc + 1) * 4] : receiver |
| 953 // ----------------------------------- | 961 // ----------------------------------- |
| 954 Label miss; | 962 Label miss; |
| 955 | 963 |
| 956 // Get the receiver of the function from the stack; 1 ~ return address. | 964 // Get the receiver of the function from the stack; 1 ~ return address. |
| 957 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 965 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
| 958 | 966 |
| 959 GenerateStringDictionaryReceiverCheck(masm, edx, eax, ebx, &miss); | 967 GenerateStringDictionaryReceiverCheck(masm, edx, eax, ebx, &miss); |
| 960 | 968 |
| 961 // eax: elements | 969 // eax: elements |
| 962 // Search the dictionary placing the result in edi. | 970 // Search the dictionary placing the result in edi. |
| 963 GenerateDictionaryLoad(masm, &miss, eax, ecx, edi, ebx, edi); | 971 GenerateDictionaryLoad(masm, &miss, eax, ecx, edi, ebx, edi); |
| 964 GenerateFunctionTailCall(masm, argc, &miss); | 972 GenerateFunctionTailCall(masm, argc, extra_state, &miss); |
| 965 | 973 |
| 966 __ bind(&miss); | 974 __ bind(&miss); |
| 967 } | 975 } |
| 968 | 976 |
| 969 | 977 |
| 970 void CallICBase::GenerateMiss(MacroAssembler* masm, | 978 void CallICBase::GenerateMiss(MacroAssembler* masm, |
| 971 int argc, | 979 int argc, |
| 972 IC::UtilityId id, | 980 IC::UtilityId id, |
| 973 Code::ExtraICState extra_state) { | 981 Code::ExtraICState extra_state) { |
| 974 // ----------- S t a t e ------------- | 982 // ----------- S t a t e ------------- |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1020 __ j(not_equal, &invoke, Label::kNear); | 1028 __ j(not_equal, &invoke, Label::kNear); |
| 1021 | 1029 |
| 1022 // Patch the receiver on the stack. | 1030 // Patch the receiver on the stack. |
| 1023 __ bind(&global); | 1031 __ bind(&global); |
| 1024 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); | 1032 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); |
| 1025 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); | 1033 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); |
| 1026 __ bind(&invoke); | 1034 __ bind(&invoke); |
| 1027 } | 1035 } |
| 1028 | 1036 |
| 1029 // Invoke the function. | 1037 // Invoke the function. |
| 1030 CallKind call_kind = CallICBase::Contextual::decode(extra_state) | 1038 if (CallICBase::ConstructCall::decode(extra_state)) { |
| 1031 ? CALL_AS_FUNCTION | 1039 ParameterCount actual(argc); |
| 1032 : CALL_AS_METHOD; | 1040 __ InvokeConstruct(edi, actual); |
| 1033 ParameterCount actual(argc); | 1041 } else { |
| 1034 __ InvokeFunction(edi, | 1042 CallKind call_kind = CallICBase::Contextual::decode(extra_state) |
| 1035 actual, | 1043 ? CALL_AS_FUNCTION |
| 1036 JUMP_FUNCTION, | 1044 : CALL_AS_METHOD; |
| 1037 NullCallWrapper(), | 1045 ParameterCount actual(argc); |
| 1038 call_kind); | 1046 __ InvokeFunction(edi, |
| 1047 actual, |
| 1048 JUMP_FUNCTION, |
| 1049 NullCallWrapper(), |
| 1050 call_kind); |
| 1051 } |
| 1039 } | 1052 } |
| 1040 | 1053 |
| 1041 | 1054 |
| 1042 void CallIC::GenerateMegamorphic(MacroAssembler* masm, | 1055 void CallIC::GenerateMegamorphic(MacroAssembler* masm, |
| 1043 int argc, | 1056 int argc, |
| 1044 Code::ExtraICState extra_state) { | 1057 Code::ExtraICState extra_state) { |
| 1045 // ----------- S t a t e ------------- | 1058 // ----------- S t a t e ------------- |
| 1046 // -- ecx : name | 1059 // -- ecx : name |
| 1047 // -- esp[0] : return address | 1060 // -- esp[0] : return address |
| 1048 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1061 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
| 1049 // -- ... | 1062 // -- ... |
| 1050 // -- esp[(argc + 1) * 4] : receiver | 1063 // -- esp[(argc + 1) * 4] : receiver |
| 1051 // ----------------------------------- | 1064 // ----------------------------------- |
| 1052 | 1065 |
| 1053 // Get the receiver of the function from the stack; 1 ~ return address. | 1066 // Get the receiver of the function from the stack; 1 ~ return address. |
| 1054 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 1067 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
| 1055 CallICBase::GenerateMonomorphicCacheProbe(masm, argc, Code::CALL_IC, | 1068 CallICBase::GenerateMonomorphicCacheProbe(masm, argc, Code::CALL_IC, |
| 1056 extra_state); | 1069 extra_state); |
| 1057 | 1070 |
| 1058 GenerateMiss(masm, argc, extra_state); | 1071 GenerateMiss(masm, argc, extra_state); |
| 1059 } | 1072 } |
| 1060 | 1073 |
| 1061 | 1074 |
| 1062 void KeyedCallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) { | 1075 void KeyedCallIC::GenerateMegamorphic(MacroAssembler* masm, |
| 1076 int argc, |
| 1077 Code::ExtraICState extra_state) { |
| 1063 // ----------- S t a t e ------------- | 1078 // ----------- S t a t e ------------- |
| 1064 // -- ecx : name | 1079 // -- ecx : name |
| 1065 // -- esp[0] : return address | 1080 // -- esp[0] : return address |
| 1066 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1081 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
| 1067 // -- ... | 1082 // -- ... |
| 1068 // -- esp[(argc + 1) * 4] : receiver | 1083 // -- esp[(argc + 1) * 4] : receiver |
| 1069 // ----------------------------------- | 1084 // ----------------------------------- |
| 1070 | 1085 |
| 1071 // Get the receiver of the function from the stack; 1 ~ return address. | 1086 // Get the receiver of the function from the stack; 1 ~ return address. |
| 1072 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 1087 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1088 GenerateFastArrayLoad( | 1103 GenerateFastArrayLoad( |
| 1089 masm, edx, ecx, eax, edi, &check_number_dictionary, &slow_load); | 1104 masm, edx, ecx, eax, edi, &check_number_dictionary, &slow_load); |
| 1090 Isolate* isolate = masm->isolate(); | 1105 Isolate* isolate = masm->isolate(); |
| 1091 Counters* counters = isolate->counters(); | 1106 Counters* counters = isolate->counters(); |
| 1092 __ IncrementCounter(counters->keyed_call_generic_smi_fast(), 1); | 1107 __ IncrementCounter(counters->keyed_call_generic_smi_fast(), 1); |
| 1093 | 1108 |
| 1094 __ bind(&do_call); | 1109 __ bind(&do_call); |
| 1095 // receiver in edx is not used after this point. | 1110 // receiver in edx is not used after this point. |
| 1096 // ecx: key | 1111 // ecx: key |
| 1097 // edi: function | 1112 // edi: function |
| 1098 GenerateFunctionTailCall(masm, argc, &slow_call); | 1113 GenerateFunctionTailCall(masm, argc, extra_state, &slow_call); |
| 1099 | 1114 |
| 1100 __ bind(&check_number_dictionary); | 1115 __ bind(&check_number_dictionary); |
| 1101 // eax: elements | 1116 // eax: elements |
| 1102 // ecx: smi key | 1117 // ecx: smi key |
| 1103 // Check whether the elements is a number dictionary. | 1118 // Check whether the elements is a number dictionary. |
| 1104 __ CheckMap(eax, | 1119 __ CheckMap(eax, |
| 1105 isolate->factory()->hash_table_map(), | 1120 isolate->factory()->hash_table_map(), |
| 1106 &slow_load, | 1121 &slow_load, |
| 1107 DONT_DO_SMI_CHECK); | 1122 DONT_DO_SMI_CHECK); |
| 1108 __ mov(ebx, ecx); | 1123 __ mov(ebx, ecx); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1151 &lookup_monomorphic_cache, | 1166 &lookup_monomorphic_cache, |
| 1152 DONT_DO_SMI_CHECK); | 1167 DONT_DO_SMI_CHECK); |
| 1153 | 1168 |
| 1154 GenerateDictionaryLoad(masm, &slow_load, ebx, ecx, eax, edi, edi); | 1169 GenerateDictionaryLoad(masm, &slow_load, ebx, ecx, eax, edi, edi); |
| 1155 __ IncrementCounter(counters->keyed_call_generic_lookup_dict(), 1); | 1170 __ IncrementCounter(counters->keyed_call_generic_lookup_dict(), 1); |
| 1156 __ jmp(&do_call); | 1171 __ jmp(&do_call); |
| 1157 | 1172 |
| 1158 __ bind(&lookup_monomorphic_cache); | 1173 __ bind(&lookup_monomorphic_cache); |
| 1159 __ IncrementCounter(counters->keyed_call_generic_lookup_cache(), 1); | 1174 __ IncrementCounter(counters->keyed_call_generic_lookup_cache(), 1); |
| 1160 CallICBase::GenerateMonomorphicCacheProbe(masm, argc, Code::KEYED_CALL_IC, | 1175 CallICBase::GenerateMonomorphicCacheProbe(masm, argc, Code::KEYED_CALL_IC, |
| 1161 Code::kNoExtraICState); | 1176 extra_state); |
| 1162 // Fall through on miss. | 1177 // Fall through on miss. |
| 1163 | 1178 |
| 1164 __ bind(&slow_call); | 1179 __ bind(&slow_call); |
| 1165 // This branch is taken if: | 1180 // This branch is taken if: |
| 1166 // - the receiver requires boxing or access check, | 1181 // - the receiver requires boxing or access check, |
| 1167 // - the key is neither smi nor symbol, | 1182 // - the key is neither smi nor symbol, |
| 1168 // - the value loaded is not a function, | 1183 // - the value loaded is not a function, |
| 1169 // - there is hope that the runtime will create a monomorphic call stub | 1184 // - there is hope that the runtime will create a monomorphic call stub |
| 1170 // that will get fetched next time. | 1185 // that will get fetched next time. |
| 1171 __ IncrementCounter(counters->keyed_call_generic_slow(), 1); | 1186 __ IncrementCounter(counters->keyed_call_generic_slow(), 1); |
| 1172 GenerateMiss(masm, argc); | 1187 GenerateMiss(masm, argc, extra_state); |
| 1173 | 1188 |
| 1174 __ bind(&index_string); | 1189 __ bind(&index_string); |
| 1175 __ IndexFromHash(ebx, ecx); | 1190 __ IndexFromHash(ebx, ecx); |
| 1176 // Now jump to the place where smi keys are handled. | 1191 // Now jump to the place where smi keys are handled. |
| 1177 __ jmp(&index_smi); | 1192 __ jmp(&index_smi); |
| 1178 } | 1193 } |
| 1179 | 1194 |
| 1180 | 1195 |
| 1181 void KeyedCallIC::GenerateNonStrictArguments(MacroAssembler* masm, | 1196 void KeyedCallIC::GenerateNonStrictArguments(MacroAssembler* masm, |
| 1182 int argc) { | 1197 int argc, |
| 1198 Code::ExtraICState extra_state) { |
| 1183 // ----------- S t a t e ------------- | 1199 // ----------- S t a t e ------------- |
| 1184 // -- ecx : name | 1200 // -- ecx : name |
| 1185 // -- esp[0] : return address | 1201 // -- esp[0] : return address |
| 1186 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1202 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
| 1187 // -- ... | 1203 // -- ... |
| 1188 // -- esp[(argc + 1) * 4] : receiver | 1204 // -- esp[(argc + 1) * 4] : receiver |
| 1189 // ----------------------------------- | 1205 // ----------------------------------- |
| 1190 Label slow, notin; | 1206 Label slow, notin; |
| 1191 Factory* factory = masm->isolate()->factory(); | 1207 Factory* factory = masm->isolate()->factory(); |
| 1192 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 1208 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
| 1193 Operand mapped_location = | 1209 Operand mapped_location = |
| 1194 GenerateMappedArgumentsLookup(masm, edx, ecx, ebx, eax, ¬in, &slow); | 1210 GenerateMappedArgumentsLookup(masm, edx, ecx, ebx, eax, ¬in, &slow); |
| 1195 __ mov(edi, mapped_location); | 1211 __ mov(edi, mapped_location); |
| 1196 GenerateFunctionTailCall(masm, argc, &slow); | 1212 GenerateFunctionTailCall(masm, argc, extra_state, &slow); |
| 1197 __ bind(¬in); | 1213 __ bind(¬in); |
| 1198 // The unmapped lookup expects that the parameter map is in ebx. | 1214 // The unmapped lookup expects that the parameter map is in ebx. |
| 1199 Operand unmapped_location = | 1215 Operand unmapped_location = |
| 1200 GenerateUnmappedArgumentsLookup(masm, ecx, ebx, eax, &slow); | 1216 GenerateUnmappedArgumentsLookup(masm, ecx, ebx, eax, &slow); |
| 1201 __ cmp(unmapped_location, factory->the_hole_value()); | 1217 __ cmp(unmapped_location, factory->the_hole_value()); |
| 1202 __ j(equal, &slow); | 1218 __ j(equal, &slow); |
| 1203 __ mov(edi, unmapped_location); | 1219 __ mov(edi, unmapped_location); |
| 1204 GenerateFunctionTailCall(masm, argc, &slow); | 1220 GenerateFunctionTailCall(masm, argc, extra_state, &slow); |
| 1205 __ bind(&slow); | 1221 __ bind(&slow); |
| 1206 GenerateMiss(masm, argc); | 1222 GenerateMiss(masm, argc, extra_state); |
| 1207 } | 1223 } |
| 1208 | 1224 |
| 1209 | 1225 |
| 1210 void KeyedCallIC::GenerateNormal(MacroAssembler* masm, int argc) { | 1226 void KeyedCallIC::GenerateNormal(MacroAssembler* masm, |
| 1227 int argc, |
| 1228 Code::ExtraICState extra_state) { |
| 1211 // ----------- S t a t e ------------- | 1229 // ----------- S t a t e ------------- |
| 1212 // -- ecx : name | 1230 // -- ecx : name |
| 1213 // -- esp[0] : return address | 1231 // -- esp[0] : return address |
| 1214 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1232 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
| 1215 // -- ... | 1233 // -- ... |
| 1216 // -- esp[(argc + 1) * 4] : receiver | 1234 // -- esp[(argc + 1) * 4] : receiver |
| 1217 // ----------------------------------- | 1235 // ----------------------------------- |
| 1218 | 1236 |
| 1219 // Check if the name is a string. | 1237 // Check if the name is a string. |
| 1220 Label miss; | 1238 Label miss; |
| 1221 __ JumpIfSmi(ecx, &miss); | 1239 __ JumpIfSmi(ecx, &miss); |
| 1222 Condition cond = masm->IsObjectStringType(ecx, eax, eax); | 1240 Condition cond = masm->IsObjectStringType(ecx, eax, eax); |
| 1223 __ j(NegateCondition(cond), &miss); | 1241 __ j(NegateCondition(cond), &miss); |
| 1224 CallICBase::GenerateNormal(masm, argc); | 1242 CallICBase::GenerateNormal(masm, argc, extra_state); |
| 1225 __ bind(&miss); | 1243 __ bind(&miss); |
| 1226 GenerateMiss(masm, argc); | 1244 GenerateMiss(masm, argc, extra_state); |
| 1227 } | 1245 } |
| 1228 | 1246 |
| 1229 | 1247 |
| 1230 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { | 1248 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { |
| 1231 // ----------- S t a t e ------------- | 1249 // ----------- S t a t e ------------- |
| 1232 // -- eax : receiver | 1250 // -- eax : receiver |
| 1233 // -- ecx : name | 1251 // -- ecx : name |
| 1234 // -- esp[0] : return address | 1252 // -- esp[0] : return address |
| 1235 // ----------------------------------- | 1253 // ----------------------------------- |
| 1236 | 1254 |
| (...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1674 Condition cc = *jmp_address == Assembler::kJncShortOpcode | 1692 Condition cc = *jmp_address == Assembler::kJncShortOpcode |
| 1675 ? not_zero | 1693 ? not_zero |
| 1676 : zero; | 1694 : zero; |
| 1677 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); | 1695 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); |
| 1678 } | 1696 } |
| 1679 | 1697 |
| 1680 | 1698 |
| 1681 } } // namespace v8::internal | 1699 } } // namespace v8::internal |
| 1682 | 1700 |
| 1683 #endif // V8_TARGET_ARCH_IA32 | 1701 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |