Changeset 156029 in webkit for trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
- Timestamp:
- Sep 18, 2013, 12:25:52 AM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r156019 r156029 41 41 #if USE(JSVALUE64) 42 42 43 void SpeculativeJIT::boxInt52(GPRReg sourceGPR, GPRReg targetGPR, DataFormat format)44 {45 GPRReg tempGPR;46 if (sourceGPR == targetGPR)47 tempGPR = allocate();48 else49 tempGPR = targetGPR;50 51 FPRReg fpr = fprAllocate();52 53 if (format == DataFormatInt52)54 m_jit.rshift64(TrustedImm32(JSValue::int52ShiftAmount), sourceGPR);55 else56 ASSERT(format == DataFormatStrictInt52);57 58 m_jit.boxInt52(sourceGPR, targetGPR, tempGPR, fpr);59 60 if (tempGPR != targetGPR)61 unlock(tempGPR);62 63 unlock(fpr);64 }65 66 43 GPRReg SpeculativeJIT::fillJSValue(Edge edge) 67 44 { … … 93 70 DataFormat spillFormat = info.spillFormat(); 94 71 m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled); 95 switch (spillFormat) { 96 case DataFormatInt32: { 72 if (spillFormat == DataFormatInt32) { 97 73 m_jit.load32(JITCompiler::addressFor(virtualRegister), gpr); 98 74 m_jit.or64(GPRInfo::tagTypeNumberRegister, gpr); 99 75 spillFormat = DataFormatJSInt32; 100 break; 101 } 102 103 case DataFormatInt52: 104 case DataFormatStrictInt52: { 105 m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr); 106 boxInt52(gpr, gpr, spillFormat); 107 return gpr; 108 } 109 110 default: 76 } else { 111 77 m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr); 112 78 if (spillFormat == DataFormatDouble) { … … 116 82 } else 117 83 RELEASE_ASSERT(spillFormat & DataFormatJS); 118 break;119 84 } 120 85 info.fillJSValue(*m_stream, gpr, spillFormat); … … 148 113 149 114 return gpr; 150 }151 152 case DataFormatInt52:153 case DataFormatStrictInt52: {154 GPRReg gpr = info.gpr();155 lock(gpr);156 GPRReg resultGPR = allocate();157 boxInt52(gpr, resultGPR, info.registerFormat());158 unlock(gpr);159 return resultGPR;160 115 } 161 116 … … 814 769 DataFormat spillFormat = info.spillFormat(); 815 770 816 RELEASE_ASSERT((spillFormat & DataFormatJS) || spillFormat == DataFormatInt32 || spillFormat == DataFormatInt52 || spillFormat == DataFormatStrictInt52);771 RELEASE_ASSERT((spillFormat & DataFormatJS) || spillFormat == DataFormatInt32); 817 772 818 773 m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled); … … 835 790 return gpr; 836 791 } 837 if (spillFormat == DataFormatInt52 || spillFormat == DataFormatStrictInt52) {838 // Generally, this can only happen if we've already proved that the839 // value is an int32. That's because if a value originated as a JSValue840 // then we would speculate that it's an int32 before representing it as841 // an int52. Otherwise, if we knowingly produced an int52, then we would842 // be boxing it into a value using Int52ToValue. This assertion is valid843 // only because Int52 is something that we introduce at prediction time.844 // However: we may have an int32-producing node replaced by an845 // int52-producing node due to CSE. So we must do a check.846 RELEASE_ASSERT(!(type & ~SpecMachineInt));847 if (type & SpecInt52) {848 GPRReg temp = allocate();849 m_jit.signExtend32ToPtr(gpr, temp);850 // Currently, we can't supply value profiling information here. :-/851 speculationCheck(852 BadType, JSValueRegs(), 0,853 m_jit.branch64(MacroAssembler::NotEqual, gpr, temp));854 unlock(temp);855 }856 if (spillFormat == DataFormatStrictInt52)857 m_jit.load32(JITCompiler::addressFor(virtualRegister), gpr);858 else {859 m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr);860 m_jit.rshift64(TrustedImm32(JSValue::int52ShiftAmount), gpr);861 m_jit.zeroExtend32ToPtr(gpr, gpr);862 }863 info.fillInt32(*m_stream, gpr);864 returnFormat = DataFormatInt32;865 return gpr;866 }867 792 m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr); 868 793 … … 873 798 874 799 case DataFormatJS: { 875 RELEASE_ASSERT(!(type & SpecInt52));876 800 // Check the value is an integer. 877 801 GPRReg gpr = info.gpr(); … … 920 844 return gpr; 921 845 } 922 923 case DataFormatStrictInt52:924 case DataFormatInt52: {925 GPRReg gpr = info.gpr();926 GPRReg result;927 if (m_gprs.isLocked(gpr)) {928 result = allocate();929 m_jit.move(gpr, result);930 } else {931 lock(gpr);932 info.fillInt32(*m_stream, gpr);933 result = gpr;934 }935 RELEASE_ASSERT(!(type & ~SpecMachineInt));936 if (info.registerFormat() == DataFormatInt52)937 m_jit.rshift64(TrustedImm32(JSValue::int52ShiftAmount), result);938 if (type & SpecInt52) {939 GPRReg temp = allocate();940 m_jit.signExtend32ToPtr(result, temp);941 // Currently, we can't supply value profiling information here. :-/942 speculationCheck(943 BadType, JSValueRegs(), 0,944 m_jit.branch64(MacroAssembler::NotEqual, result, temp));945 unlock(temp);946 }947 m_jit.zeroExtend32ToPtr(result, result);948 returnFormat = DataFormatInt32;949 return gpr;950 }951 846 952 847 case DataFormatDouble: … … 991 886 } 992 887 993 GPRReg SpeculativeJIT::fillSpeculateInt52(Edge edge, DataFormat desiredFormat)994 {995 ASSERT(desiredFormat == DataFormatInt52 || desiredFormat == DataFormatStrictInt52);996 AbstractValue& value = m_state.forNode(edge);997 SpeculatedType type = value.m_type;998 m_interpreter.filter(value, SpecMachineInt);999 VirtualRegister virtualRegister = edge->virtualRegister();1000 GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);1001 1002 switch (info.registerFormat()) {1003 case DataFormatNone: {1004 if ((edge->hasConstant() && !valueOfJSConstant(edge.node()).isMachineInt()) || info.spillFormat() == DataFormatDouble) {1005 terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);1006 return allocate();1007 }1008 1009 GPRReg gpr = allocate();1010 1011 if (edge->hasConstant()) {1012 JSValue jsValue = valueOfJSConstant(edge.node());1013 ASSERT(jsValue.isMachineInt());1014 m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);1015 int64_t value = jsValue.asMachineInt();1016 if (desiredFormat == DataFormatInt52)1017 value = value << JSValue::int52ShiftAmount;1018 m_jit.move(MacroAssembler::Imm64(value), gpr);1019 info.fillGPR(*m_stream, gpr, desiredFormat);1020 return gpr;1021 }1022 1023 DataFormat spillFormat = info.spillFormat();1024 1025 RELEASE_ASSERT((spillFormat & DataFormatJS) || spillFormat == DataFormatInt32 || spillFormat == DataFormatInt52 || spillFormat == DataFormatStrictInt52);1026 1027 m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);1028 1029 if (spillFormat == DataFormatJSInt32 || spillFormat == DataFormatInt32) {1030 // If we know this was spilled as an integer we can fill without checking.1031 m_jit.load32(JITCompiler::addressFor(virtualRegister), gpr);1032 m_jit.signExtend32ToPtr(gpr, gpr);1033 if (desiredFormat == DataFormatStrictInt52) {1034 info.fillStrictInt52(*m_stream, gpr);1035 return gpr;1036 }1037 m_jit.lshift64(TrustedImm32(JSValue::int52ShiftAmount), gpr);1038 info.fillInt52(*m_stream, gpr);1039 return gpr;1040 }1041 if (spillFormat == DataFormatInt52 || spillFormat == DataFormatStrictInt52) {1042 m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr);1043 if (desiredFormat == DataFormatStrictInt52) {1044 if (spillFormat == DataFormatInt52)1045 m_jit.rshift64(TrustedImm32(JSValue::int52ShiftAmount), gpr);1046 info.fillStrictInt52(*m_stream, gpr);1047 return gpr;1048 }1049 if (spillFormat == DataFormatStrictInt52)1050 m_jit.lshift64(TrustedImm32(JSValue::int52ShiftAmount), gpr);1051 info.fillInt52(*m_stream, gpr);1052 return gpr;1053 }1054 m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr);1055 1056 // Fill as JSValue, and fall through.1057 info.fillJSValue(*m_stream, gpr, DataFormatJSInt32);1058 m_gprs.unlock(gpr);1059 }1060 1061 case DataFormatJS: {1062 // Check the value is an integer. Note that we would *like* to unbox an Int521063 // at this point but this is too costly. We only *prove* that this is an Int521064 // even though we check if it's an int32.1065 GPRReg gpr = info.gpr();1066 GPRReg result;1067 if (m_gprs.isLocked(gpr)) {1068 result = allocate();1069 m_jit.move(gpr, result);1070 } else {1071 m_gprs.lock(gpr);1072 result = gpr;1073 }1074 if (type & ~SpecInt32)1075 speculationCheck(BadType, JSValueRegs(result), edge, m_jit.branch64(MacroAssembler::Below, result, GPRInfo::tagTypeNumberRegister));1076 if (result == gpr) // The not-already-locked, so fill in-place, case.1077 info.fillInt52(*m_stream, gpr, desiredFormat);1078 m_jit.signExtend32ToPtr(result, result);1079 if (desiredFormat == DataFormatInt52)1080 m_jit.lshift64(TrustedImm32(JSValue::int52ShiftAmount), result);1081 return result;1082 }1083 1084 case DataFormatInt32:1085 case DataFormatJSInt32: {1086 GPRReg gpr = info.gpr();1087 GPRReg result;1088 if (m_gprs.isLocked(gpr)) {1089 result = allocate();1090 m_jit.move(gpr, result);1091 } else {1092 m_gprs.lock(gpr);1093 info.fillInt52(*m_stream, gpr, desiredFormat);1094 result = gpr;1095 }1096 m_jit.signExtend32ToPtr(result, result);1097 if (desiredFormat == DataFormatInt52)1098 m_jit.lshift64(TrustedImm32(JSValue::int52ShiftAmount), result);1099 return result;1100 }1101 1102 case DataFormatStrictInt52: {1103 GPRReg gpr = info.gpr();1104 bool wasLocked = m_gprs.isLocked(gpr);1105 lock(gpr);1106 if (desiredFormat == DataFormatStrictInt52)1107 return gpr;1108 if (wasLocked) {1109 GPRReg result = allocate();1110 m_jit.move(gpr, result);1111 unlock(gpr);1112 gpr = result;1113 } else1114 info.fillStrictInt52(*m_stream, gpr);1115 m_jit.lshift64(TrustedImm32(JSValue::int52ShiftAmount), gpr);1116 return gpr;1117 }1118 1119 case DataFormatInt52: {1120 GPRReg gpr = info.gpr();1121 bool wasLocked = m_gprs.isLocked(gpr);1122 lock(gpr);1123 if (desiredFormat == DataFormatInt52)1124 return gpr;1125 if (wasLocked) {1126 GPRReg result = allocate();1127 m_jit.move(gpr, result);1128 unlock(gpr);1129 gpr = result;1130 } else1131 info.fillInt52(*m_stream, gpr);1132 m_jit.rshift64(TrustedImm32(JSValue::int52ShiftAmount), gpr);1133 return gpr;1134 }1135 1136 case DataFormatDouble:1137 case DataFormatJSDouble:1138 if (edge->hasConstant()) {1139 JSValue jsValue = valueOfJSConstant(edge.node());1140 if (jsValue.isMachineInt()) {1141 int64_t value = jsValue.asMachineInt();1142 if (desiredFormat == DataFormatInt52)1143 value = value << JSValue::int52ShiftAmount;1144 GPRReg gpr = allocate();1145 m_jit.move(MacroAssembler::Imm64(value), gpr);1146 return gpr;1147 }1148 }1149 1150 case DataFormatCell:1151 case DataFormatBoolean:1152 case DataFormatJSCell:1153 case DataFormatJSBoolean: {1154 terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);1155 return allocate();1156 }1157 1158 case DataFormatStorage:1159 RELEASE_ASSERT_NOT_REACHED();1160 1161 default:1162 RELEASE_ASSERT_NOT_REACHED();1163 return InvalidGPRReg;1164 }1165 }1166 1167 888 FPRReg SpeculativeJIT::fillSpeculateDouble(Edge edge) 1168 889 { … … 1172 893 AbstractValue& value = m_state.forNode(edge); 1173 894 SpeculatedType type = value.m_type; 1174 ASSERT(edge.useKind() != KnownNumberUse || !(value.m_type & ~Spec FullNumber));1175 m_interpreter.filter(value, Spec FullNumber);895 ASSERT(edge.useKind() != KnownNumberUse || !(value.m_type & ~SpecNumber)); 896 m_interpreter.filter(value, SpecNumber); 1176 897 VirtualRegister virtualRegister = edge->virtualRegister(); 1177 898 GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister); … … 1225 946 break; 1226 947 } 1227 1228 case DataFormatInt52: {1229 GPRReg gpr = allocate();1230 m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);1231 m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr);1232 info.fillInt52(*m_stream, gpr);1233 unlock(gpr);1234 break;1235 }1236 1237 case DataFormatStrictInt52: {1238 GPRReg gpr = allocate();1239 m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);1240 m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr);1241 info.fillStrictInt52(*m_stream, gpr);1242 unlock(gpr);1243 break;1244 }1245 948 1246 949 default: … … 1276 979 JITCompiler::Jump isInteger = m_jit.branch64(MacroAssembler::AboveOrEqual, jsValueGpr, GPRInfo::tagTypeNumberRegister); 1277 980 1278 if (type & ~Spec FullNumber)981 if (type & ~SpecNumber) 1279 982 speculationCheck(BadType, JSValueRegs(jsValueGpr), edge, m_jit.branchTest64(MacroAssembler::Zero, jsValueGpr, GPRInfo::tagTypeNumberRegister)); 1280 983 … … 1304 1007 m_gprs.lock(gpr); 1305 1008 m_jit.convertInt32ToDouble(gpr, fpr); 1306 m_gprs.unlock(gpr);1307 return fpr;1308 }1309 1310 case DataFormatInt52: {1311 FPRReg fpr = fprAllocate();1312 GPRReg gpr = info.gpr();1313 m_gprs.lock(gpr);1314 GPRReg temp = allocate();1315 m_jit.move(gpr, temp);1316 m_jit.rshift64(TrustedImm32(JSValue::int52ShiftAmount), temp);1317 m_jit.convertInt64ToDouble(temp, fpr);1318 unlock(temp);1319 m_gprs.unlock(gpr);1320 return fpr;1321 }1322 1323 case DataFormatStrictInt52: {1324 FPRReg fpr = fprAllocate();1325 GPRReg gpr = info.gpr();1326 m_gprs.lock(gpr);1327 m_jit.convertInt64ToDouble(gpr, fpr);1328 1009 m_gprs.unlock(gpr); 1329 1010 return fpr; … … 1431 1112 case DataFormatDouble: 1432 1113 case DataFormatJSBoolean: 1433 case DataFormatBoolean: 1434 case DataFormatInt52: 1435 case DataFormatStrictInt52: { 1114 case DataFormatBoolean: { 1436 1115 terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0); 1437 1116 return allocate(); … … 1516 1195 case DataFormatDouble: 1517 1196 case DataFormatJSCell: 1518 case DataFormatCell: 1519 case DataFormatInt52: 1520 case DataFormatStrictInt52: { 1197 case DataFormatCell: { 1521 1198 terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0); 1522 1199 return allocate(); … … 1825 1502 m_jit.or32(TrustedImm32(ValueFalse), result.gpr()); 1826 1503 jsValueResult(result.gpr(), m_currentNode, DataFormatJSBoolean); 1827 }1828 1829 void SpeculativeJIT::compileInt52Compare(Node* node, MacroAssembler::RelationalCondition condition)1830 {1831 SpeculateWhicheverInt52Operand op1(this, node->child1());1832 SpeculateWhicheverInt52Operand op2(this, node->child2(), op1);1833 GPRTemporary result(this, Reuse, op1, op2);1834 1835 m_jit.compare64(condition, op1.gpr(), op2.gpr(), result.gpr());1836 1837 // If we add a DataFormatBool, we should use it here.1838 m_jit.or32(TrustedImm32(ValueFalse), result.gpr());1839 jsValueResult(result.gpr(), m_currentNode, DataFormatJSBoolean);1840 }1841 1842 void SpeculativeJIT::compilePeepHoleInt52Branch(Node* node, Node* branchNode, JITCompiler::RelationalCondition condition)1843 {1844 BasicBlock* taken = branchNode->takenBlock();1845 BasicBlock* notTaken = branchNode->notTakenBlock();1846 1847 // The branch instruction will branch to the taken block.1848 // If taken is next, switch taken with notTaken & invert the branch condition so we can fall through.1849 if (taken == nextBlock()) {1850 condition = JITCompiler::invert(condition);1851 BasicBlock* tmp = taken;1852 taken = notTaken;1853 notTaken = tmp;1854 }1855 1856 SpeculateWhicheverInt52Operand op1(this, node->child1());1857 SpeculateWhicheverInt52Operand op2(this, node->child2(), op1);1858 1859 branch64(condition, op1.gpr(), op2.gpr(), taken);1860 jump(notTaken);1861 1504 } 1862 1505 … … 2264 1907 } 2265 1908 2266 case FlushedInt52: {2267 GPRTemporary result(this);2268 m_jit.load64(JITCompiler::addressFor(node->local()), result.gpr());2269 2270 VirtualRegister virtualRegister = node->virtualRegister();2271 m_gprs.retain(result.gpr(), virtualRegister, SpillOrderJS);2272 generationInfoFromVirtualRegister(virtualRegister).initInt52(node, node->refCount(), result.gpr());2273 break;2274 }2275 2276 1909 default: 2277 1910 GPRTemporary result(this); … … 2349 1982 } 2350 1983 2351 case FlushedInt52: {2352 SpeculateInt52Operand value(this, node->child1());2353 m_jit.store64(value.gpr(), JITCompiler::addressFor(node->local()));2354 noResult(node);2355 recordSetLocal(node->local(), ValueSource(Int52InJSStack));2356 break;2357 }2358 2359 1984 case FlushedCell: { 2360 1985 SpeculateCellOperand cell(this, node->child1()); … … 2477 2102 case Int32ToDouble: { 2478 2103 compileInt32ToDouble(node); 2479 break;2480 }2481 2482 case Int52ToValue: {2483 JSValueOperand operand(this, node->child1());2484 GPRTemporary result(this, Reuse, operand);2485 m_jit.move(operand.gpr(), result.gpr());2486 jsValueResult(result.gpr(), node);2487 break;2488 }2489 2490 case Int52ToDouble: {2491 SpeculateDoubleOperand operand(this, node->child1());2492 FPRTemporary result(this, operand);2493 m_jit.moveDouble(operand.fpr(), result.fpr());2494 doubleResult(result.fpr(), node);2495 2104 break; 2496 2105 } … … 3281 2890 3282 2891 DFG_TYPE_CHECK( 3283 JSValueRegs(), node->child2(), Spec FullRealNumber,2892 JSValueRegs(), node->child2(), SpecRealNumber, 3284 2893 m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, valueFPR, valueFPR)); 3285 2894 … … 3497 3106 op1.use(); 3498 3107 3499 if (!(m_state.forNode(node->child1()).m_type & ~(Spec FullNumber | SpecBoolean)))3108 if (!(m_state.forNode(node->child1()).m_type & ~(SpecNumber | SpecBoolean))) 3500 3109 m_jit.move(op1GPR, resultGPR); 3501 3110 else { … … 3594 3203 FPRReg opFPR = operand.fpr(); 3595 3204 DFG_TYPE_CHECK( 3596 JSValueRegs(), use, Spec FullRealNumber,3205 JSValueRegs(), use, SpecRealNumber, 3597 3206 m_jit.branchDouble( 3598 3207 MacroAssembler::DoubleNotEqualOrUnordered, opFPR, opFPR)); … … 3659 3268 GPRReg scratchGPR = scratch.gpr(); 3660 3269 DFG_TYPE_CHECK( 3661 JSValueRegs(), use, Spec FullRealNumber,3270 JSValueRegs(), use, SpecRealNumber, 3662 3271 m_jit.branchDouble( 3663 3272 MacroAssembler::DoubleNotEqualOrUnordered, opFPR, opFPR));
Note:
See TracChangeset
for help on using the changeset viewer.