OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/code-stubs.h" | 5 #include "src/code-stubs.h" |
6 | 6 |
7 #include <sstream> | 7 #include <sstream> |
8 | 8 |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
(...skipping 1017 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1028 Node* rhs_value = var_fsub_rhs.value(); | 1028 Node* rhs_value = var_fsub_rhs.value(); |
1029 Node* value = assembler->Float64Sub(lhs_value, rhs_value); | 1029 Node* value = assembler->Float64Sub(lhs_value, rhs_value); |
1030 // TODO(bmeurer): Introduce a ChangeFloat64ToTagged. | 1030 // TODO(bmeurer): Introduce a ChangeFloat64ToTagged. |
1031 Node* result = assembler->AllocateHeapNumberWithValue(value); | 1031 Node* result = assembler->AllocateHeapNumberWithValue(value); |
1032 assembler->Return(result); | 1032 assembler->Return(result); |
1033 } | 1033 } |
1034 } | 1034 } |
1035 | 1035 |
1036 namespace { | 1036 namespace { |
1037 | 1037 |
1038 void GenerateBitwiseOperation( | |
1039 compiler::CodeStubAssembler* assembler, | |
1040 compiler::Node* (compiler::CodeStubAssembler::*bitop)(compiler::Node*, | |
1041 compiler::Node*)) { | |
1042 typedef compiler::CodeStubAssembler::Label Label; | |
1043 typedef compiler::Node Node; | |
1044 typedef compiler::CodeStubAssembler::Variable Variable; | |
1045 | |
1046 Node* context = assembler->Parameter(2); | |
1047 | |
1048 // Shared entry for word32 bitwise operation. | |
1049 Label do_bitop(assembler); | |
1050 Variable var_bitop_lhs(assembler, MachineRepresentation::kWord32), | |
1051 var_bitop_rhs(assembler, MachineRepresentation::kWord32); | |
1052 | |
1053 // We might need to loop several times due to ToNumber conversions. | |
1054 Variable var_lhs(assembler, MachineRepresentation::kTagged), | |
1055 var_rhs(assembler, MachineRepresentation::kTagged); | |
1056 Variable* loop_vars[2] = {&var_lhs, &var_rhs}; | |
1057 Label loop(assembler, 2, loop_vars); | |
1058 var_lhs.Bind(assembler->Parameter(0)); | |
1059 var_rhs.Bind(assembler->Parameter(1)); | |
1060 assembler->Goto(&loop); | |
epertoso
2016/03/23 13:15:39
Wouldn't an 'ObjectToInt32' or similar-named metho
Benedikt Meurer
2016/03/23 13:23:03
Well, you'd still need to distinguish HeapNumber a
epertoso
2016/03/23 13:41:39
As discussed offline, let's leave it like this for
| |
1061 assembler->Bind(&loop); | |
1062 { | |
1063 // Load the current {lhs} and {rhs} values. | |
1064 Node* lhs = var_lhs.value(); | |
1065 Node* rhs = var_rhs.value(); | |
1066 | |
1067 // Check if the {lhs} is a Smi or a HeapObject. | |
1068 Label if_lhsissmi(assembler), if_lhsisnotsmi(assembler); | |
1069 assembler->Branch(assembler->WordIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi); | |
1070 | |
1071 assembler->Bind(&if_lhsissmi); | |
1072 { | |
1073 // Check if the {rhs} is also a Smi. | |
1074 Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler); | |
1075 assembler->Branch(assembler->WordIsSmi(rhs), &if_rhsissmi, | |
1076 &if_rhsisnotsmi); | |
1077 | |
1078 assembler->Bind(&if_rhsissmi); | |
1079 { | |
1080 // Perform the word32 bitwise operation. | |
1081 var_bitop_lhs.Bind(assembler->SmiToInt32(lhs)); | |
1082 var_bitop_rhs.Bind(assembler->SmiToInt32(rhs)); | |
1083 assembler->Goto(&do_bitop); | |
1084 } | |
1085 | |
1086 assembler->Bind(&if_rhsisnotsmi); | |
1087 { | |
1088 // Load the map of the {rhs}. | |
1089 Node* rhs_map = assembler->LoadMap(rhs); | |
1090 | |
1091 // Check if {rhs} is a HeapNumber. | |
1092 Label if_rhsisnumber(assembler), | |
1093 if_rhsisnotnumber(assembler, Label::kDeferred); | |
1094 Node* number_map = assembler->HeapNumberMapConstant(); | |
1095 assembler->Branch(assembler->WordEqual(rhs_map, number_map), | |
1096 &if_rhsisnumber, &if_rhsisnotnumber); | |
1097 | |
1098 assembler->Bind(&if_rhsisnumber); | |
1099 { | |
1100 // Perform the word32 bitwise operation. | |
1101 var_bitop_lhs.Bind(assembler->SmiToInt32(lhs)); | |
1102 var_bitop_rhs.Bind(assembler->TruncateHeapNumberValueToInt32(rhs)); | |
1103 assembler->Goto(&do_bitop); | |
1104 } | |
1105 | |
1106 assembler->Bind(&if_rhsisnotnumber); | |
1107 { | |
1108 // Convert the {rhs} to a Number first. | |
1109 Callable callable = | |
1110 CodeFactory::NonNumberToNumber(assembler->isolate()); | |
1111 var_rhs.Bind(assembler->CallStub(callable, context, rhs)); | |
1112 assembler->Goto(&loop); | |
1113 } | |
1114 } | |
1115 } | |
1116 | |
1117 assembler->Bind(&if_lhsisnotsmi); | |
1118 { | |
1119 // Load the map of the {lhs}. | |
1120 Node* lhs_map = assembler->LoadMap(lhs); | |
1121 | |
1122 // Check if the {lhs} is a HeapNumber. | |
1123 Label if_lhsisnumber(assembler), | |
1124 if_lhsisnotnumber(assembler, Label::kDeferred); | |
1125 Node* number_map = assembler->HeapNumberMapConstant(); | |
1126 assembler->Branch(assembler->WordEqual(lhs_map, number_map), | |
1127 &if_lhsisnumber, &if_lhsisnotnumber); | |
1128 | |
1129 assembler->Bind(&if_lhsisnumber); | |
1130 { | |
1131 // Check if the {rhs} is a Smi. | |
1132 Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler); | |
1133 assembler->Branch(assembler->WordIsSmi(rhs), &if_rhsissmi, | |
1134 &if_rhsisnotsmi); | |
1135 | |
1136 assembler->Bind(&if_rhsissmi); | |
1137 { | |
1138 // Perform the word32 bitwise operation. | |
1139 var_bitop_lhs.Bind(assembler->TruncateHeapNumberValueToInt32(lhs)); | |
1140 var_bitop_rhs.Bind(assembler->SmiToInt32(rhs)); | |
1141 assembler->Goto(&do_bitop); | |
1142 } | |
1143 | |
1144 assembler->Bind(&if_rhsisnotsmi); | |
1145 { | |
1146 // Load the map of the {rhs}. | |
1147 Node* rhs_map = assembler->LoadMap(rhs); | |
1148 | |
1149 // Check if the {rhs} is a HeapNumber. | |
1150 Label if_rhsisnumber(assembler), | |
1151 if_rhsisnotnumber(assembler, Label::kDeferred); | |
1152 assembler->Branch(assembler->WordEqual(rhs_map, number_map), | |
1153 &if_rhsisnumber, &if_rhsisnotnumber); | |
1154 | |
1155 assembler->Bind(&if_rhsisnumber); | |
1156 { | |
1157 // Perform the word32 bitwise operation. | |
1158 var_bitop_lhs.Bind(assembler->TruncateHeapNumberValueToInt32(lhs)); | |
1159 var_bitop_rhs.Bind(assembler->TruncateHeapNumberValueToInt32(rhs)); | |
1160 assembler->Goto(&do_bitop); | |
1161 } | |
1162 | |
1163 assembler->Bind(&if_rhsisnotnumber); | |
1164 { | |
1165 // Convert the {rhs} to a Number first. | |
1166 Callable callable = | |
1167 CodeFactory::NonNumberToNumber(assembler->isolate()); | |
1168 var_rhs.Bind(assembler->CallStub(callable, context, rhs)); | |
1169 assembler->Goto(&loop); | |
1170 } | |
1171 } | |
1172 } | |
1173 | |
1174 assembler->Bind(&if_lhsisnotnumber); | |
1175 { | |
1176 // Convert the {lhs} to a Number first. | |
1177 Callable callable = | |
1178 CodeFactory::NonNumberToNumber(assembler->isolate()); | |
1179 var_lhs.Bind(assembler->CallStub(callable, context, lhs)); | |
1180 assembler->Goto(&loop); | |
1181 } | |
1182 } | |
1183 } | |
1184 | |
1185 assembler->Bind(&do_bitop); | |
1186 { | |
1187 Node* lhs_value = var_bitop_lhs.value(); | |
1188 Node* rhs_value = var_bitop_rhs.value(); | |
1189 Node* value = (assembler->*bitop)(lhs_value, rhs_value); | |
1190 Node* result = assembler->ChangeInt32ToTagged(value); | |
1191 assembler->Return(result); | |
1192 } | |
1193 } | |
1194 | |
1195 } // namespace | |
1196 | |
1197 void BitwiseAndStub::GenerateAssembly( | |
1198 compiler::CodeStubAssembler* assembler) const { | |
1199 GenerateBitwiseOperation(assembler, &compiler::CodeStubAssembler::Word32And); | |
1200 } | |
1201 | |
1202 void BitwiseOrStub::GenerateAssembly( | |
1203 compiler::CodeStubAssembler* assembler) const { | |
1204 GenerateBitwiseOperation(assembler, &compiler::CodeStubAssembler::Word32Or); | |
1205 } | |
1206 | |
1207 void BitwiseXorStub::GenerateAssembly( | |
1208 compiler::CodeStubAssembler* assembler) const { | |
1209 GenerateBitwiseOperation(assembler, &compiler::CodeStubAssembler::Word32Xor); | |
1210 } | |
1211 | |
1212 namespace { | |
1213 | |
1038 enum RelationalComparisonMode { | 1214 enum RelationalComparisonMode { |
1039 kLessThan, | 1215 kLessThan, |
1040 kLessThanOrEqual, | 1216 kLessThanOrEqual, |
1041 kGreaterThan, | 1217 kGreaterThan, |
1042 kGreaterThanOrEqual | 1218 kGreaterThanOrEqual |
1043 }; | 1219 }; |
1044 | 1220 |
1045 void GenerateAbstractRelationalComparison( | 1221 void GenerateAbstractRelationalComparison( |
1046 compiler::CodeStubAssembler* assembler, RelationalComparisonMode mode) { | 1222 compiler::CodeStubAssembler* assembler, RelationalComparisonMode mode) { |
1047 typedef compiler::CodeStubAssembler::Label Label; | 1223 typedef compiler::CodeStubAssembler::Label Label; |
(...skipping 2287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3335 if (type->Is(Type::UntaggedPointer())) { | 3511 if (type->Is(Type::UntaggedPointer())) { |
3336 return Representation::External(); | 3512 return Representation::External(); |
3337 } | 3513 } |
3338 | 3514 |
3339 DCHECK(!type->Is(Type::Untagged())); | 3515 DCHECK(!type->Is(Type::Untagged())); |
3340 return Representation::Tagged(); | 3516 return Representation::Tagged(); |
3341 } | 3517 } |
3342 | 3518 |
3343 } // namespace internal | 3519 } // namespace internal |
3344 } // namespace v8 | 3520 } // namespace v8 |
OLD | NEW |