Changeset 156019 in webkit for trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
- Timestamp:
- Sep 17, 2013, 6:31:04 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r155783 r156019 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 else 49 tempGPR = targetGPR; 50 51 FPRReg fpr = fprAllocate(); 52 53 if (format == DataFormatInt52) 54 m_jit.rshift64(TrustedImm32(JSValue::int52ShiftAmount), sourceGPR); 55 else 56 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 43 66 GPRReg SpeculativeJIT::fillJSValue(Edge edge) 44 67 { … … 70 93 DataFormat spillFormat = info.spillFormat(); 71 94 m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled); 72 if (spillFormat == DataFormatInt32) { 95 switch (spillFormat) { 96 case DataFormatInt32: { 73 97 m_jit.load32(JITCompiler::addressFor(virtualRegister), gpr); 74 98 m_jit.or64(GPRInfo::tagTypeNumberRegister, gpr); 75 99 spillFormat = DataFormatJSInt32; 76 } else { 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: 77 111 m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr); 78 112 if (spillFormat == DataFormatDouble) { … … 82 116 } else 83 117 RELEASE_ASSERT(spillFormat & DataFormatJS); 118 break; 84 119 } 85 120 info.fillJSValue(*m_stream, gpr, spillFormat); … … 113 148 114 149 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; 115 160 } 116 161 … … 769 814 DataFormat spillFormat = info.spillFormat(); 770 815 771 RELEASE_ASSERT((spillFormat & DataFormatJS) || spillFormat == DataFormatInt32 );816 RELEASE_ASSERT((spillFormat & DataFormatJS) || spillFormat == DataFormatInt32 || spillFormat == DataFormatInt52 || spillFormat == DataFormatStrictInt52); 772 817 773 818 m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled); … … 790 835 return gpr; 791 836 } 837 if (spillFormat == DataFormatInt52 || spillFormat == DataFormatStrictInt52) { 838 // Generally, this can only happen if we've already proved that the 839 // value is an int32. That's because if a value originated as a JSValue 840 // then we would speculate that it's an int32 before representing it as 841 // an int52. Otherwise, if we knowingly produced an int52, then we would 842 // be boxing it into a value using Int52ToValue. This assertion is valid 843 // only because Int52 is something that we introduce at prediction time. 844 // However: we may have an int32-producing node replaced by an 845 // 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 } 792 867 m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr); 793 868 … … 798 873 799 874 case DataFormatJS: { 875 RELEASE_ASSERT(!(type & SpecInt52)); 800 876 // Check the value is an integer. 801 877 GPRReg gpr = info.gpr(); … … 844 920 return gpr; 845 921 } 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 } 846 951 847 952 case DataFormatDouble: … … 886 991 } 887 992 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 Int52 1063 // at this point but this is too costly. We only *prove* that this is an Int52 1064 // 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 } else 1114 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 } else 1131 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 888 1167 FPRReg SpeculativeJIT::fillSpeculateDouble(Edge edge) 889 1168 { … … 893 1172 AbstractValue& value = m_state.forNode(edge); 894 1173 SpeculatedType type = value.m_type; 895 ASSERT(edge.useKind() != KnownNumberUse || !(value.m_type & ~Spec Number));896 m_interpreter.filter(value, Spec Number);1174 ASSERT(edge.useKind() != KnownNumberUse || !(value.m_type & ~SpecFullNumber)); 1175 m_interpreter.filter(value, SpecFullNumber); 897 1176 VirtualRegister virtualRegister = edge->virtualRegister(); 898 1177 GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister); … … 946 1225 break; 947 1226 } 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 } 948 1245 949 1246 default: … … 979 1276 JITCompiler::Jump isInteger = m_jit.branch64(MacroAssembler::AboveOrEqual, jsValueGpr, GPRInfo::tagTypeNumberRegister); 980 1277 981 if (type & ~Spec Number)1278 if (type & ~SpecFullNumber) 982 1279 speculationCheck(BadType, JSValueRegs(jsValueGpr), edge, m_jit.branchTest64(MacroAssembler::Zero, jsValueGpr, GPRInfo::tagTypeNumberRegister)); 983 1280 … … 1007 1304 m_gprs.lock(gpr); 1008 1305 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); 1009 1328 m_gprs.unlock(gpr); 1010 1329 return fpr; … … 1112 1431 case DataFormatDouble: 1113 1432 case DataFormatJSBoolean: 1114 case DataFormatBoolean: { 1433 case DataFormatBoolean: 1434 case DataFormatInt52: 1435 case DataFormatStrictInt52: { 1115 1436 terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0); 1116 1437 return allocate(); … … 1195 1516 case DataFormatDouble: 1196 1517 case DataFormatJSCell: 1197 case DataFormatCell: { 1518 case DataFormatCell: 1519 case DataFormatInt52: 1520 case DataFormatStrictInt52: { 1198 1521 terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0); 1199 1522 return allocate(); … … 1502 1825 m_jit.or32(TrustedImm32(ValueFalse), result.gpr()); 1503 1826 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); 1504 1861 } 1505 1862 … … 1907 2264 } 1908 2265 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 1909 2276 default: 1910 2277 GPRTemporary result(this); … … 1982 2349 } 1983 2350 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 1984 2359 case FlushedCell: { 1985 2360 SpeculateCellOperand cell(this, node->child1()); … … 2102 2477 case Int32ToDouble: { 2103 2478 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); 2104 2495 break; 2105 2496 } … … 2890 3281 2891 3282 DFG_TYPE_CHECK( 2892 JSValueRegs(), node->child2(), Spec RealNumber,3283 JSValueRegs(), node->child2(), SpecFullRealNumber, 2893 3284 m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, valueFPR, valueFPR)); 2894 3285 … … 3106 3497 op1.use(); 3107 3498 3108 if (!(m_state.forNode(node->child1()).m_type & ~(Spec Number | SpecBoolean)))3499 if (!(m_state.forNode(node->child1()).m_type & ~(SpecFullNumber | SpecBoolean))) 3109 3500 m_jit.move(op1GPR, resultGPR); 3110 3501 else { … … 3203 3594 FPRReg opFPR = operand.fpr(); 3204 3595 DFG_TYPE_CHECK( 3205 JSValueRegs(), use, Spec RealNumber,3596 JSValueRegs(), use, SpecFullRealNumber, 3206 3597 m_jit.branchDouble( 3207 3598 MacroAssembler::DoubleNotEqualOrUnordered, opFPR, opFPR)); … … 3268 3659 GPRReg scratchGPR = scratch.gpr(); 3269 3660 DFG_TYPE_CHECK( 3270 JSValueRegs(), use, Spec RealNumber,3661 JSValueRegs(), use, SpecFullRealNumber, 3271 3662 m_jit.branchDouble( 3272 3663 MacroAssembler::DoubleNotEqualOrUnordered, opFPR, opFPR));
Note:
See TracChangeset
for help on using the changeset viewer.