OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 970 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
981 | 981 |
982 Handle<Code> GetBinaryOpStub(int key, BinaryOpIC::TypeInfo type_info) { | 982 Handle<Code> GetBinaryOpStub(int key, BinaryOpIC::TypeInfo type_info) { |
983 GenericBinaryOpStub stub(key, type_info); | 983 GenericBinaryOpStub stub(key, type_info); |
984 return stub.GetCode(); | 984 return stub.GetCode(); |
985 } | 985 } |
986 | 986 |
987 | 987 |
988 Handle<Code> GetTypeRecordingBinaryOpStub(int key, | 988 Handle<Code> GetTypeRecordingBinaryOpStub(int key, |
989 TRBinaryOpIC::TypeInfo type_info, | 989 TRBinaryOpIC::TypeInfo type_info, |
990 TRBinaryOpIC::TypeInfo result_type_info) { | 990 TRBinaryOpIC::TypeInfo result_type_info) { |
| 991 TypeRecordingBinaryOpStub stub(key, type_info, result_type_info); |
| 992 return stub.GetCode(); |
| 993 } |
| 994 |
| 995 |
| 996 void TypeRecordingBinaryOpStub::GenerateTypeTransition(MacroAssembler* masm) { |
| 997 __ pop(rcx); // Save return address. |
| 998 __ push(rdx); |
| 999 __ push(rax); |
| 1000 // Left and right arguments are now on top. |
| 1001 // Push this stub's key. Although the operation and the type info are |
| 1002 // encoded into the key, the encoding is opaque, so push them too. |
| 1003 __ Push(Smi::FromInt(MinorKey())); |
| 1004 __ Push(Smi::FromInt(op_)); |
| 1005 __ Push(Smi::FromInt(operands_type_)); |
| 1006 |
| 1007 __ push(rcx); // Push return address. |
| 1008 |
| 1009 // Patch the caller to an appropriate specialized stub and return the |
| 1010 // operation result to the caller of the stub. |
| 1011 __ TailCallExternalReference( |
| 1012 ExternalReference(IC_Utility(IC::kTypeRecordingBinaryOp_Patch)), |
| 1013 5, |
| 1014 1); |
| 1015 } |
| 1016 |
| 1017 |
| 1018 // Prepare for a type transition runtime call when the args are already on |
| 1019 // the stack, under the return address. |
| 1020 void TypeRecordingBinaryOpStub::GenerateTypeTransitionWithSavedArgs( |
| 1021 MacroAssembler* masm) { |
| 1022 __ pop(rcx); // Save return address. |
| 1023 // Left and right arguments are already on top of the stack. |
| 1024 // Push this stub's key. Although the operation and the type info are |
| 1025 // encoded into the key, the encoding is opaque, so push them too. |
| 1026 __ Push(Smi::FromInt(MinorKey())); |
| 1027 __ Push(Smi::FromInt(op_)); |
| 1028 __ Push(Smi::FromInt(operands_type_)); |
| 1029 |
| 1030 __ push(rcx); // Push return address. |
| 1031 |
| 1032 // Patch the caller to an appropriate specialized stub and return the |
| 1033 // operation result to the caller of the stub. |
| 1034 __ TailCallExternalReference( |
| 1035 ExternalReference(IC_Utility(IC::kTypeRecordingBinaryOp_Patch)), |
| 1036 5, |
| 1037 1); |
| 1038 } |
| 1039 |
| 1040 |
| 1041 void TypeRecordingBinaryOpStub::Generate(MacroAssembler* masm) { |
| 1042 switch (operands_type_) { |
| 1043 case TRBinaryOpIC::UNINITIALIZED: |
| 1044 GenerateTypeTransition(masm); |
| 1045 break; |
| 1046 case TRBinaryOpIC::SMI: |
| 1047 GenerateSmiStub(masm); |
| 1048 break; |
| 1049 case TRBinaryOpIC::INT32: |
| 1050 GenerateInt32Stub(masm); |
| 1051 break; |
| 1052 case TRBinaryOpIC::HEAP_NUMBER: |
| 1053 GenerateHeapNumberStub(masm); |
| 1054 break; |
| 1055 case TRBinaryOpIC::STRING: |
| 1056 GenerateStringStub(masm); |
| 1057 break; |
| 1058 case TRBinaryOpIC::GENERIC: |
| 1059 GenerateGeneric(masm); |
| 1060 break; |
| 1061 default: |
| 1062 UNREACHABLE(); |
| 1063 } |
| 1064 } |
| 1065 |
| 1066 |
| 1067 const char* TypeRecordingBinaryOpStub::GetName() { |
| 1068 if (name_ != NULL) return name_; |
| 1069 const int kMaxNameLength = 100; |
| 1070 name_ = Bootstrapper::AllocateAutoDeletedArray(kMaxNameLength); |
| 1071 if (name_ == NULL) return "OOM"; |
| 1072 const char* op_name = Token::Name(op_); |
| 1073 const char* overwrite_name; |
| 1074 switch (mode_) { |
| 1075 case NO_OVERWRITE: overwrite_name = "Alloc"; break; |
| 1076 case OVERWRITE_RIGHT: overwrite_name = "OverwriteRight"; break; |
| 1077 case OVERWRITE_LEFT: overwrite_name = "OverwriteLeft"; break; |
| 1078 default: overwrite_name = "UnknownOverwrite"; break; |
| 1079 } |
| 1080 |
| 1081 OS::SNPrintF(Vector<char>(name_, kMaxNameLength), |
| 1082 "TypeRecordingBinaryOpStub_%s_%s_%s", |
| 1083 op_name, |
| 1084 overwrite_name, |
| 1085 TRBinaryOpIC::GetName(operands_type_)); |
| 1086 return name_; |
| 1087 } |
| 1088 |
| 1089 |
| 1090 void TypeRecordingBinaryOpStub::GenerateSmiCode(MacroAssembler* masm, |
| 1091 Label* slow, |
| 1092 SmiCodeGenerateHeapNumberResults allow_heapnumber_results) { |
991 UNIMPLEMENTED(); | 1093 UNIMPLEMENTED(); |
992 return Handle<Code>::null(); | 1094 } |
| 1095 |
| 1096 |
| 1097 void TypeRecordingBinaryOpStub::GenerateSmiStub(MacroAssembler* masm) { |
| 1098 Label call_runtime; |
| 1099 |
| 1100 switch (op_) { |
| 1101 case Token::ADD: |
| 1102 case Token::SUB: |
| 1103 case Token::MUL: |
| 1104 case Token::DIV: |
| 1105 break; |
| 1106 case Token::MOD: |
| 1107 case Token::BIT_OR: |
| 1108 case Token::BIT_AND: |
| 1109 case Token::BIT_XOR: |
| 1110 case Token::SAR: |
| 1111 case Token::SHL: |
| 1112 case Token::SHR: |
| 1113 GenerateRegisterArgsPush(masm); |
| 1114 break; |
| 1115 default: |
| 1116 UNREACHABLE(); |
| 1117 } |
| 1118 |
| 1119 if (result_type_ == TRBinaryOpIC::UNINITIALIZED || |
| 1120 result_type_ == TRBinaryOpIC::SMI) { |
| 1121 GenerateSmiCode(masm, &call_runtime, NO_HEAPNUMBER_RESULTS); |
| 1122 } else { |
| 1123 GenerateSmiCode(masm, &call_runtime, ALLOW_HEAPNUMBER_RESULTS); |
| 1124 } |
| 1125 __ bind(&call_runtime); |
| 1126 switch (op_) { |
| 1127 case Token::ADD: |
| 1128 case Token::SUB: |
| 1129 case Token::MUL: |
| 1130 case Token::DIV: |
| 1131 GenerateTypeTransition(masm); |
| 1132 break; |
| 1133 case Token::MOD: |
| 1134 case Token::BIT_OR: |
| 1135 case Token::BIT_AND: |
| 1136 case Token::BIT_XOR: |
| 1137 case Token::SAR: |
| 1138 case Token::SHL: |
| 1139 case Token::SHR: |
| 1140 GenerateTypeTransitionWithSavedArgs(masm); |
| 1141 break; |
| 1142 default: |
| 1143 UNREACHABLE(); |
| 1144 } |
| 1145 } |
| 1146 |
| 1147 |
| 1148 void TypeRecordingBinaryOpStub::GenerateStringStub(MacroAssembler* masm) { |
| 1149 UNIMPLEMENTED(); |
| 1150 } |
| 1151 |
| 1152 |
| 1153 void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { |
| 1154 UNIMPLEMENTED(); |
| 1155 } |
| 1156 |
| 1157 |
| 1158 void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) { |
| 1159 UNIMPLEMENTED(); |
| 1160 } |
| 1161 |
| 1162 |
| 1163 void TypeRecordingBinaryOpStub::GenerateGeneric(MacroAssembler* masm) { |
| 1164 UNIMPLEMENTED(); |
| 1165 } |
| 1166 |
| 1167 |
| 1168 void TypeRecordingBinaryOpStub::GenerateHeapResultAllocation( |
| 1169 MacroAssembler* masm, |
| 1170 Label* alloc_failure) { |
| 1171 UNIMPLEMENTED(); |
| 1172 } |
| 1173 |
| 1174 |
| 1175 void TypeRecordingBinaryOpStub::GenerateRegisterArgsPush(MacroAssembler* masm) { |
| 1176 __ pop(rcx); |
| 1177 __ push(rdx); |
| 1178 __ push(rax); |
| 1179 __ push(rcx); |
993 } | 1180 } |
994 | 1181 |
995 | 1182 |
996 void TranscendentalCacheStub::Generate(MacroAssembler* masm) { | 1183 void TranscendentalCacheStub::Generate(MacroAssembler* masm) { |
997 // Input on stack: | 1184 // Input on stack: |
998 // rsp[8]: argument (should be number). | 1185 // rsp[8]: argument (should be number). |
999 // rsp[0]: return address. | 1186 // rsp[0]: return address. |
1000 Label runtime_call; | 1187 Label runtime_call; |
1001 Label runtime_call_clear_stack; | 1188 Label runtime_call_clear_stack; |
1002 Label input_not_smi; | 1189 Label input_not_smi; |
(...skipping 3098 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4101 | 4288 |
4102 void ICCompareStub::GenerateMiss(MacroAssembler* masm) { | 4289 void ICCompareStub::GenerateMiss(MacroAssembler* masm) { |
4103 UNIMPLEMENTED(); | 4290 UNIMPLEMENTED(); |
4104 } | 4291 } |
4105 | 4292 |
4106 #undef __ | 4293 #undef __ |
4107 | 4294 |
4108 } } // namespace v8::internal | 4295 } } // namespace v8::internal |
4109 | 4296 |
4110 #endif // V8_TARGET_ARCH_X64 | 4297 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |