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 778 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
789 __ mov(edx, Operand(eax)); | 789 __ mov(edx, Operand(eax)); |
790 __ RecordWrite(edi, 0, edx, ecx); | 790 __ RecordWrite(edi, 0, edx, ecx); |
791 __ ret(0); | 791 __ ret(0); |
792 } | 792 } |
793 | 793 |
794 | 794 |
795 // The generated code does not accept smi keys. | 795 // The generated code does not accept smi keys. |
796 // The generated code falls through if both probes miss. | 796 // The generated code falls through if both probes miss. |
797 static void GenerateMonomorphicCacheProbe(MacroAssembler* masm, | 797 static void GenerateMonomorphicCacheProbe(MacroAssembler* masm, |
798 int argc, | 798 int argc, |
799 Code::Kind kind) { | 799 Code::Kind kind, |
| 800 Code::ExtraICState extra_ic_state) { |
800 // ----------- S t a t e ------------- | 801 // ----------- S t a t e ------------- |
801 // -- ecx : name | 802 // -- ecx : name |
802 // -- edx : receiver | 803 // -- edx : receiver |
803 // ----------------------------------- | 804 // ----------------------------------- |
804 Label number, non_number, non_string, boolean, probe, miss; | 805 Label number, non_number, non_string, boolean, probe, miss; |
805 | 806 |
806 // Probe the stub cache. | 807 // Probe the stub cache. |
807 Code::Flags flags = Code::ComputeFlags(kind, | 808 Code::Flags flags = Code::ComputeFlags(kind, |
808 NOT_IN_LOOP, | 809 NOT_IN_LOOP, |
809 MONOMORPHIC, | 810 MONOMORPHIC, |
810 Code::kNoExtraICState, | 811 extra_ic_state, |
811 NORMAL, | 812 NORMAL, |
812 argc); | 813 argc); |
813 Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, edx, ecx, ebx, | 814 Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, edx, ecx, ebx, |
814 eax); | 815 eax); |
815 | 816 |
816 // If the stub cache probing failed, the receiver might be a value. | 817 // If the stub cache probing failed, the receiver might be a value. |
817 // For value objects, we use the map of the prototype objects for | 818 // For value objects, we use the map of the prototype objects for |
818 // the corresponding JSValue for the cache and that is what we need | 819 // the corresponding JSValue for the cache and that is what we need |
819 // to probe. | 820 // to probe. |
820 // | 821 // |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
899 // Search the dictionary placing the result in edi. | 900 // Search the dictionary placing the result in edi. |
900 GenerateDictionaryLoad(masm, &miss, eax, ecx, edi, ebx, edi); | 901 GenerateDictionaryLoad(masm, &miss, eax, ecx, edi, ebx, edi); |
901 GenerateFunctionTailCall(masm, argc, &miss); | 902 GenerateFunctionTailCall(masm, argc, &miss); |
902 | 903 |
903 __ bind(&miss); | 904 __ bind(&miss); |
904 } | 905 } |
905 | 906 |
906 | 907 |
907 static void GenerateCallMiss(MacroAssembler* masm, | 908 static void GenerateCallMiss(MacroAssembler* masm, |
908 int argc, | 909 int argc, |
909 IC::UtilityId id) { | 910 IC::UtilityId id, |
| 911 Code::ExtraICState extra_ic_state) { |
910 // ----------- S t a t e ------------- | 912 // ----------- S t a t e ------------- |
911 // -- ecx : name | 913 // -- ecx : name |
912 // -- esp[0] : return address | 914 // -- esp[0] : return address |
913 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 915 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
914 // -- ... | 916 // -- ... |
915 // -- esp[(argc + 1) * 4] : receiver | 917 // -- esp[(argc + 1) * 4] : receiver |
916 // ----------------------------------- | 918 // ----------------------------------- |
917 | 919 |
918 Counters* counters = masm->isolate()->counters(); | 920 Counters* counters = masm->isolate()->counters(); |
919 if (id == IC::kCallIC_Miss) { | 921 if (id == IC::kCallIC_Miss) { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
957 __ j(not_equal, &invoke, Label::kNear); | 959 __ j(not_equal, &invoke, Label::kNear); |
958 | 960 |
959 // Patch the receiver on the stack. | 961 // Patch the receiver on the stack. |
960 __ bind(&global); | 962 __ bind(&global); |
961 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); | 963 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); |
962 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); | 964 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); |
963 __ bind(&invoke); | 965 __ bind(&invoke); |
964 } | 966 } |
965 | 967 |
966 // Invoke the function. | 968 // Invoke the function. |
| 969 ReceiverType receiver_type = CallICBase::Contextual::decode(extra_ic_state) |
| 970 ? IMPLICIT_RECEIVER |
| 971 : EXPLICIT_RECEIVER; |
967 ParameterCount actual(argc); | 972 ParameterCount actual(argc); |
968 __ InvokeFunction(edi, actual, JUMP_FUNCTION); | 973 __ InvokeFunction(edi, |
| 974 actual, |
| 975 JUMP_FUNCTION, |
| 976 NullCallWrapper(), |
| 977 receiver_type); |
969 } | 978 } |
970 | 979 |
971 | 980 |
972 void CallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) { | 981 void CallIC::GenerateMegamorphic(MacroAssembler* masm, |
| 982 int argc, |
| 983 Code::ExtraICState extra_ic_state) { |
973 // ----------- S t a t e ------------- | 984 // ----------- S t a t e ------------- |
974 // -- ecx : name | 985 // -- ecx : name |
975 // -- esp[0] : return address | 986 // -- esp[0] : return address |
976 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 987 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
977 // -- ... | 988 // -- ... |
978 // -- esp[(argc + 1) * 4] : receiver | 989 // -- esp[(argc + 1) * 4] : receiver |
979 // ----------------------------------- | 990 // ----------------------------------- |
980 | 991 |
981 // Get the receiver of the function from the stack; 1 ~ return address. | 992 // Get the receiver of the function from the stack; 1 ~ return address. |
982 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 993 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
983 GenerateMonomorphicCacheProbe(masm, argc, Code::CALL_IC); | 994 GenerateMonomorphicCacheProbe(masm, argc, Code::CALL_IC, extra_ic_state); |
984 GenerateMiss(masm, argc); | 995 |
| 996 GenerateMiss(masm, argc, extra_ic_state); |
985 } | 997 } |
986 | 998 |
987 | 999 |
988 void CallIC::GenerateNormal(MacroAssembler* masm, int argc) { | 1000 void CallIC::GenerateNormal(MacroAssembler* masm, int argc) { |
989 // ----------- S t a t e ------------- | 1001 // ----------- S t a t e ------------- |
990 // -- ecx : name | 1002 // -- ecx : name |
991 // -- esp[0] : return address | 1003 // -- esp[0] : return address |
992 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1004 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
993 // -- ... | 1005 // -- ... |
994 // -- esp[(argc + 1) * 4] : receiver | 1006 // -- esp[(argc + 1) * 4] : receiver |
995 // ----------------------------------- | 1007 // ----------------------------------- |
996 | 1008 |
997 GenerateCallNormal(masm, argc); | 1009 GenerateCallNormal(masm, argc); |
998 GenerateMiss(masm, argc); | 1010 GenerateMiss(masm, argc, Code::kNoExtraICState); |
999 } | 1011 } |
1000 | 1012 |
1001 | 1013 |
1002 void CallIC::GenerateMiss(MacroAssembler* masm, int argc) { | 1014 void CallIC::GenerateMiss(MacroAssembler* masm, |
| 1015 int argc, |
| 1016 Code::ExtraICState extra_ic_state) { |
1003 // ----------- S t a t e ------------- | 1017 // ----------- S t a t e ------------- |
1004 // -- ecx : name | 1018 // -- ecx : name |
1005 // -- esp[0] : return address | 1019 // -- esp[0] : return address |
1006 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1020 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1007 // -- ... | 1021 // -- ... |
1008 // -- esp[(argc + 1) * 4] : receiver | 1022 // -- esp[(argc + 1) * 4] : receiver |
1009 // ----------------------------------- | 1023 // ----------------------------------- |
1010 | 1024 |
1011 GenerateCallMiss(masm, argc, IC::kCallIC_Miss); | 1025 GenerateCallMiss(masm, argc, IC::kCallIC_Miss, extra_ic_state); |
1012 } | 1026 } |
1013 | 1027 |
1014 | 1028 |
1015 void KeyedCallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) { | 1029 void KeyedCallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) { |
1016 // ----------- S t a t e ------------- | 1030 // ----------- S t a t e ------------- |
1017 // -- ecx : name | 1031 // -- ecx : name |
1018 // -- esp[0] : return address | 1032 // -- esp[0] : return address |
1019 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1033 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1020 // -- ... | 1034 // -- ... |
1021 // -- esp[(argc + 1) * 4] : receiver | 1035 // -- esp[(argc + 1) * 4] : receiver |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1100 isolate->factory()->hash_table_map(), | 1114 isolate->factory()->hash_table_map(), |
1101 &lookup_monomorphic_cache, | 1115 &lookup_monomorphic_cache, |
1102 DONT_DO_SMI_CHECK); | 1116 DONT_DO_SMI_CHECK); |
1103 | 1117 |
1104 GenerateDictionaryLoad(masm, &slow_load, ebx, ecx, eax, edi, edi); | 1118 GenerateDictionaryLoad(masm, &slow_load, ebx, ecx, eax, edi, edi); |
1105 __ IncrementCounter(counters->keyed_call_generic_lookup_dict(), 1); | 1119 __ IncrementCounter(counters->keyed_call_generic_lookup_dict(), 1); |
1106 __ jmp(&do_call); | 1120 __ jmp(&do_call); |
1107 | 1121 |
1108 __ bind(&lookup_monomorphic_cache); | 1122 __ bind(&lookup_monomorphic_cache); |
1109 __ IncrementCounter(counters->keyed_call_generic_lookup_cache(), 1); | 1123 __ IncrementCounter(counters->keyed_call_generic_lookup_cache(), 1); |
1110 GenerateMonomorphicCacheProbe(masm, argc, Code::KEYED_CALL_IC); | 1124 GenerateMonomorphicCacheProbe(masm, |
| 1125 argc, |
| 1126 Code::KEYED_CALL_IC, |
| 1127 Code::kNoExtraICState); |
1111 // Fall through on miss. | 1128 // Fall through on miss. |
1112 | 1129 |
1113 __ bind(&slow_call); | 1130 __ bind(&slow_call); |
1114 // This branch is taken if: | 1131 // This branch is taken if: |
1115 // - the receiver requires boxing or access check, | 1132 // - the receiver requires boxing or access check, |
1116 // - the key is neither smi nor symbol, | 1133 // - the key is neither smi nor symbol, |
1117 // - the value loaded is not a function, | 1134 // - the value loaded is not a function, |
1118 // - there is hope that the runtime will create a monomorphic call stub | 1135 // - there is hope that the runtime will create a monomorphic call stub |
1119 // that will get fetched next time. | 1136 // that will get fetched next time. |
1120 __ IncrementCounter(counters->keyed_call_generic_slow(), 1); | 1137 __ IncrementCounter(counters->keyed_call_generic_slow(), 1); |
(...skipping 29 matching lines...) Expand all Loading... |
1150 | 1167 |
1151 void KeyedCallIC::GenerateMiss(MacroAssembler* masm, int argc) { | 1168 void KeyedCallIC::GenerateMiss(MacroAssembler* masm, int argc) { |
1152 // ----------- S t a t e ------------- | 1169 // ----------- S t a t e ------------- |
1153 // -- ecx : name | 1170 // -- ecx : name |
1154 // -- esp[0] : return address | 1171 // -- esp[0] : return address |
1155 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1172 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1156 // -- ... | 1173 // -- ... |
1157 // -- esp[(argc + 1) * 4] : receiver | 1174 // -- esp[(argc + 1) * 4] : receiver |
1158 // ----------------------------------- | 1175 // ----------------------------------- |
1159 | 1176 |
1160 GenerateCallMiss(masm, argc, IC::kKeyedCallIC_Miss); | 1177 GenerateCallMiss(masm, argc, IC::kKeyedCallIC_Miss, Code::kNoExtraICState); |
1161 } | 1178 } |
1162 | 1179 |
1163 | 1180 |
1164 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { | 1181 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { |
1165 // ----------- S t a t e ------------- | 1182 // ----------- S t a t e ------------- |
1166 // -- eax : receiver | 1183 // -- eax : receiver |
1167 // -- ecx : name | 1184 // -- ecx : name |
1168 // -- esp[0] : return address | 1185 // -- esp[0] : return address |
1169 // ----------------------------------- | 1186 // ----------------------------------- |
1170 | 1187 |
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1547 Condition cc = *jmp_address == Assembler::kJncShortOpcode | 1564 Condition cc = *jmp_address == Assembler::kJncShortOpcode |
1548 ? not_zero | 1565 ? not_zero |
1549 : zero; | 1566 : zero; |
1550 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); | 1567 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); |
1551 } | 1568 } |
1552 | 1569 |
1553 | 1570 |
1554 } } // namespace v8::internal | 1571 } } // namespace v8::internal |
1555 | 1572 |
1556 #endif // V8_TARGET_ARCH_IA32 | 1573 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |