Changeset 191290 in webkit
- Timestamp:
- Oct 19, 2015, 9:13:59 AM (10 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r191286 r191290 1 2015-10-19 Mark Lam <mark.lam@apple.com> 2 3 DoubleRep fails to convert SpecBoolean values. 4 https://bugs.webkit.org/show_bug.cgi?id=150313 5 6 Reviewed by Geoffrey Garen. 7 8 This was uncovered by the op_sub stress test on 32-bit builds. On 32-bit builds, 9 DoubleRep will erroneously convert 'true' to a 'NaN' instead of a double 1. 10 On 64-bit, the same issue exists but is masked by another bug in DoubleRep where 11 boolean values will always erroneously trigger a BadType OSR exit. 12 13 The erroneous conversion of 'true' to 'NaN' is because the 'true' case in 14 compileDoubleRep() is missing a jump to the "done" destination. Instead, it 15 fall through to the "isUndefined" case where it produces a NaN. 16 17 The 64-bit erroneous BadType OSR exit is due to the boolean type check being 18 implemented incorrectly. It was checking if any bits other than bit 0 were set. 19 However, boolean JS values always have TagBitBool (the 3rd bit) set. Hence, the 20 check will always fail if we have a boolean value. 21 22 This patch fixes both of these issues. 23 24 No new test is needed because these issues are already covered by scenarios in 25 the op_sub.js stress test. This patch also fixes the op_sub.js test to throw an 26 exception if any failures are encountered (as expected by the stress test 27 harness). This patch also re-worked the test code to provide more accurate 28 descriptions of each test scenario for error reporting. 29 30 * dfg/DFGSpeculativeJIT.cpp: 31 (JSC::DFG::SpeculativeJIT::compileDoubleRep): 32 33 * tests/stress/op_sub.js: 34 (generateScenarios): 35 (func): 36 (initializeTestCases): 37 (runTest): 38 (stringify): Deleted. 39 1 40 2015-10-19 Yusuke Suzuki <utatane.tea@gmail.com> 2 41 -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r191224 r191290 2197 2197 2198 2198 DFG_TYPE_CHECK(JSValueRegs(op1GPR), node->child1(), ~SpecCell, 2199 m_jit.branchTest64(JITCompiler:: NonZero, op1GPR, TrustedImm32(static_cast<int32_t>(~1))));2199 m_jit.branchTest64(JITCompiler::Zero, op1GPR, TrustedImm32(static_cast<int32_t>(TagBitBool)))); 2200 2200 2201 2201 JITCompiler::Jump isFalse = m_jit.branch64(JITCompiler::Equal, op1GPR, TrustedImm64(ValueFalse)); 2202 2202 static const double one = 1; 2203 2203 m_jit.loadDouble(MacroAssembler::TrustedImmPtr(&one), resultFPR); 2204 done.append(m_jit.jump()); 2204 2205 done.append(isFalse); 2205 2206 … … 2250 2251 static const double one = 1; 2251 2252 m_jit.loadDouble(MacroAssembler::TrustedImmPtr(&one), resultFPR); 2253 done.append(m_jit.jump()); 2252 2254 done.append(isFalse); 2253 2255 -
trunk/Source/JavaScriptCore/tests/stress/op_sub.js
r191224 r191290 25 25 26 26 var set1 = [ 27 o1,28 null,29 undefined,30 NaN,31 "abc",27 'o1', 28 'null', 29 'undefined', 30 'NaN', 31 '"abc"', 32 32 ]; 33 33 34 34 var set2 = [ 35 10, -10, 36 2147483647, -2147483647, 37 4294967296, -4294967296, 38 100.2, -100.2, 39 true, false 35 '10', 36 '-10', 37 '2147483647', 38 '-2147483647', 39 '4294967296', 40 '-4294967296', 41 '100.2', 42 '-100.2', 43 'true', 44 'false', 40 45 ]; 41 46 … … 47 52 values.push(set2[i]); 48 53 for (var i = 0; i < set2.length; i++) 49 values.push("" + set2[i]); 50 51 function stringify(value) { 52 if (typeof value == "string") 53 return '"' + value + '"'; 54 return "" + value; 55 } 54 values.push('"' + set2[i] + '"'); 56 55 57 56 function generateScenarios(xvalues, yvalues) { … … 59 58 for (var i = 0; i < xvalues.length; i++) { 60 59 for (var j = 0; j < yvalues.length; j++) { 61 var name = "(" + xvalues[i] + " - " + yvalues[j] + ")"; 62 var x = xvalues[i]; 63 var y = yvalues[j]; 64 var expected = eval(stringify(x) + " - " + stringify(y)); 60 var xStr = xvalues[i]; 61 var yStr = yvalues[j]; 62 var x = eval(xStr); 63 var y = eval(yStr); 64 var name = "(" + xStr + " - " + yStr + ")"; 65 var expected = eval("" + xStr + " - " + yStr); 65 66 var scenario = { name: name, x: x, y: y, expected: expected }; 66 67 … … 88 89 name: "subI32V", 89 90 func: function(x, y) { return 10 - y; }, 90 xvalues: [ 10],91 xvalues: [ '10' ], 91 92 yvalues: values 92 93 }, … … 95 96 func: function(x, y) { return x - 10; }, 96 97 xvalues: values, 97 yvalues: [ 10]98 yvalues: [ '10' ] 98 99 }, 99 100 { 100 101 name: "subI32oV", 101 102 func: function(x, y) { return -2147483647 - y; }, 102 xvalues: [ -2147483647],103 xvalues: [ '-2147483647' ], 103 104 yvalues: values 104 105 }, … … 107 108 func: function(x, y) { return x - 2147483647; }, 108 109 xvalues: values, 109 yvalues: [ 2147483647]110 yvalues: [ '2147483647' ] 110 111 }, 111 112 { 112 113 name: "subI52V", 113 114 func: function(x, y) { return 4294967296 - y; }, 114 xvalues: [ 4294967296],115 xvalues: [ '4294967296' ], 115 116 yvalues: values 116 117 }, … … 119 120 func: function(x, y) { return x - 4294967296; }, 120 121 xvalues: values, 121 yvalues: [ 4294967296]122 yvalues: [ '4294967296' ] 122 123 }, 123 124 { 124 125 name: "subDV", 125 126 func: function(x, y) { return 100.2 - y; }, 126 xvalues: [ 100.2],127 xvalues: [ '100.2' ], 127 128 yvalues: values 128 129 }, … … 131 132 func: function(x, y) { return x - 100.2; }, 132 133 xvalues: values, 133 yvalues: [ 100.2]134 yvalues: [ '100.2' ] 134 135 }, 135 136 { 136 137 name: "subBV", 137 138 func: function(x, y) { return true - y; }, 138 xvalues: [ true],139 xvalues: [ 'true' ], 139 140 yvalues: values 140 141 }, … … 143 144 func: function(x, y) { return x - true; }, 144 145 xvalues: values, 145 yvalues: [ true]146 yvalues: [ 'true' ] 146 147 }, 147 148 { 148 149 name: "subSi32V", 149 150 func: function(x, y) { return "10" - y; }, 150 xvalues: [ "10"],151 xvalues: [ '"10"' ], 151 152 yvalues: values 152 153 }, … … 155 156 func: function(x, y) { return x - "10"; }, 156 157 xvalues: values, 157 yvalues: [ "10"]158 yvalues: [ '"10"' ] 158 159 }, 159 160 … … 161 162 name: "subSi32oV", 162 163 func: function(x, y) { return "-2147483647" - y; }, 163 xvalues: [ "-2147483647"],164 xvalues: [ '"-2147483647"' ], 164 165 yvalues: values 165 166 }, … … 168 169 func: function(x, y) { return x - "2147483647"; }, 169 170 xvalues: values, 170 yvalues: [ "2147483647"]171 yvalues: [ '"2147483647"' ] 171 172 }, 172 173 { 173 174 name: "subSi52V", 174 175 func: function(x, y) { return "4294967296" - y; }, 175 xvalues: [ "4294967296"],176 xvalues: [ '"4294967296"' ], 176 177 yvalues: values 177 178 }, … … 180 181 func: function(x, y) { return x - "4294967296"; }, 181 182 xvalues: values, 182 yvalues: [ "4294967296"]183 yvalues: [ '"4294967296"' ] 183 184 }, 184 185 { 185 186 name: "subSdV", 186 187 func: function(x, y) { return "100.2" - y; }, 187 xvalues: [ "100.2"],188 xvalues: [ '"100.2"' ], 188 189 yvalues: values 189 190 }, … … 192 193 func: function(x, y) { return x - "100.2"; }, 193 194 xvalues: values, 194 yvalues: [ "100.2"]195 yvalues: [ '"100.2"' ] 195 196 }, 196 197 { 197 198 name: "subSbV", 198 199 func: function(x, y) { return "true" - y; }, 199 xvalues: [ "true"],200 xvalues: [ '"true"' ], 200 201 yvalues: values 201 202 }, … … 204 205 func: function(x, y) { return x - "true"; }, 205 206 xvalues: values, 206 yvalues: [ "true"]207 yvalues: [ '"true"' ] 207 208 }, 208 209 … … 210 211 name: "subSV", 211 212 func: function(x, y) { return "abc" - y; }, 212 xvalues: [ "abc"],213 xvalues: [ '"abc"' ], 213 214 yvalues: values 214 215 }, … … 217 218 func: function(x, y) { return x - "abc"; }, 218 219 xvalues: values, 219 yvalues: [ "abc"]220 yvalues: [ '"abc"' ] 220 221 }, 221 222 { 222 223 name: "subNV", 223 224 func: function(x, y) { return null - y; }, 224 xvalues: [ null],225 xvalues: [ 'null' ], 225 226 yvalues: values 226 227 }, … … 229 230 func: function(x, y) { return x - null; }, 230 231 xvalues: values, 231 yvalues: [ null]232 yvalues: [ 'null' ] 232 233 }, 233 234 { 234 235 name: "subOV", 235 236 func: function(x, y) { return o1 - y; }, 236 xvalues: [ o1],237 xvalues: [ 'o1' ], 237 238 yvalues: values 238 239 }, … … 241 242 func: function(x, y) { return x - o1; }, 242 243 xvalues: values, 243 yvalues: [ o1]244 yvalues: [ 'o1' ] 244 245 }, 245 246 { 246 247 name: "subNaNV", 247 248 func: function(x, y) { return NaN - y; }, 248 xvalues: [ NaN],249 xvalues: [ 'NaN' ], 249 250 yvalues: values 250 251 }, … … 253 254 func: function(x, y) { return x - NaN; }, 254 255 xvalues: values, 255 yvalues: [ NaN]256 yvalues: [ 'NaN' ] 256 257 }, 257 258 ]; … … 264 265 } 265 266 initializeTestCases(); 267 268 var errorReport = ""; 266 269 267 270 function runTest(test) { … … 279 282 continue; 280 283 if (!failedScenario[scenarioID]) { 281 print("FAIL: " + test.name + ":" + scenario.name + " started failing on iteration " + i + ": expected " + scenario.expected + ", actual " + result);284 errorReport += "FAIL: " + test.name + ":" + scenario.name + " started failing on iteration " + i + ": expected " + scenario.expected + ", actual " + result + "\n"; 282 285 failedScenario[scenarioID] = scenario; 283 286 } … … 285 288 } 286 289 } catch(e) { 287 print("Unexpected exception: " + e);290 errorReport += "Unexpected exception: " + e + "\n"; 288 291 } 289 292 } … … 292 295 runTest(test); 293 296 297 if (errorReport !== "") 298 throw "Error: bad result:\n" + errorReport;
Note:
See TracChangeset
for help on using the changeset viewer.