Script-getOffsetsCoverage-01.js (13256B)
1 // Currently the Jit integration has a few issues, let's keep this test 2 // case deterministic. 3 // 4 // - Baseline OSR increments the loop header twice. 5 // - Ion is not updating any counter yet. 6 // 7 if (getJitCompilerOptions()["ion.warmup.trigger"] != 30) 8 setJitCompilerOption("ion.warmup.trigger", 30); 9 if (getJitCompilerOptions()["baseline.warmup.trigger"] != 10) 10 setJitCompilerOption("baseline.warmup.trigger", 10); 11 12 /* 13 * These test cases are annotated with the output produced by LCOV [1]. Comment 14 * starting with //<key> without any spaces are used as a reference for the code 15 * coverage output. Any "$" in these line comments are replaced by the current 16 * line number, and any "%" are replaced with the current function name (defined 17 * by the FN key). 18 * 19 * [1] http://ltp.sourceforge.net/coverage/lcov/geninfo.1.php 20 */ 21 function checkGetOffsetsCoverage(fun) { 22 var keys = [ "TN", "SF", "FN", "FNDA", "FNF", "FNH", "BRDA", "BRF", "BRH", "DA", "LF", "LH" ]; 23 function startsWithKey(s) { 24 for (k of keys) { 25 if (s.startsWith(k)) 26 return true; 27 } 28 return false; 29 }; 30 31 // Extract the body of the function, as the code to be executed. 32 var source = fun.toString(); 33 source = source.slice(source.indexOf('{') + 1, source.lastIndexOf('}')); 34 35 // Extract comment starting with the previous keys, as a reference. 36 var lcovRef = []; 37 var currLine = 0; 38 var currFun = [{name: "top-level", braces: 1}]; 39 for (var line of source.split('\n')) { 40 currLine++; 41 42 for (var comment of line.split("//").slice(1)) { 43 if (!startsWithKey(comment)) 44 continue; 45 comment = comment.trim(); 46 if (comment.startsWith("FN:")) 47 currFun.push({ name: comment.split(',')[1], braces: 0 }); 48 var name = currFun[currFun.length - 1].name; 49 if (!comment.startsWith("DA:")) 50 continue; 51 comment = { 52 offset: null, 53 lineNumber: currLine, 54 columnNumber: null, 55 count: comment.split(",")[1] | 0, 56 script: (name == "top-level" ? undefined : name) 57 }; 58 lcovRef.push(comment); 59 } 60 61 var deltaBraces = line.split('{').length - line.split('}').length; 62 currFun[currFun.length - 1].braces += deltaBraces; 63 if (currFun[currFun.length - 1].braces == 0) 64 currFun.pop(); 65 } 66 67 // Create a new global and instrument it with a debugger, to find all scripts, 68 // created in the current global. 69 var g = newGlobal({newCompartment: true}); 70 var dbg = Debugger(g); 71 dbg.collectCoverageInfo = true; 72 73 var topLevel = null; 74 dbg.onNewScript = function (s) { 75 topLevel = s; 76 dbg.onNewScript = function () {}; 77 }; 78 79 // Evaluate the code, and collect the hit counts for each scripts / lines. 80 g.eval(source); 81 82 var coverageRes = []; 83 function collectCoverage(s) { 84 var res = s.getOffsetsCoverage(); 85 if (res == null) 86 res = [{ 87 offset: null, 88 lineNumber: null, 89 columnNumber: null, 90 script: s.displayName, 91 count: 0 92 }]; 93 else { 94 res.map(function (e) { 95 e.script = s.displayName; 96 return e; 97 }); 98 } 99 coverageRes.push(res); 100 s.getChildScripts().forEach(collectCoverage); 101 }; 102 collectCoverage(topLevel); 103 coverageRes = [].concat(...coverageRes); 104 105 // Check that all the lines are present the result. 106 function match(ref) { 107 return function (entry) { 108 return ref.lineNumber == entry.lineNumber && ref.script == entry.script; 109 } 110 } 111 function ppObj(entry) { 112 var str = "{"; 113 for (var k in entry) { 114 if (entry[k] != null) 115 str += " '" + k + "': " + entry[k] + ","; 116 } 117 str += "}"; 118 return str; 119 } 120 for (ref of lcovRef) { 121 var res = coverageRes.find(match(ref)); 122 if (!res) { 123 // getOffsetsCoverage returns null if we have no result for the 124 // script. We added a fake entry with an undefined lineNumber, which is 125 // used to match against the modified reference. 126 var missRef = Object.create(ref); 127 missRef.lineNumber = null; 128 res = coverageRes.find(match(missRef)); 129 } 130 131 if (!res || res.count != ref.count) { 132 print("Cannot find `" + ppObj(ref) + "` in the following results:\n", coverageRes.map(ppObj).join("\n")); 133 print("In the following source:\n", source); 134 assertEq(true, false); 135 } 136 } 137 } 138 139 checkGetOffsetsCoverage(function () { //FN:$,top-level 140 ",".split(','); //DA:$,1 141 }); 142 143 checkGetOffsetsCoverage(function () { //FN:$,top-level 144 function f() { //FN:$,f 145 ",".split(','); //DA:$,0 146 } 147 ",".split(','); //DA:$,1 148 }); 149 150 checkGetOffsetsCoverage(function () { //FN:$,top-level 151 function f() { //FN:$,f 152 ",".split(','); //DA:$,1 153 } 154 f(); //DA:$,1 155 }); 156 157 checkGetOffsetsCoverage(function () { ','.split(','); //FN:$,top-level //DA:$,1 158 }); 159 160 checkGetOffsetsCoverage(function () { function f() { ','.split(','); } //FN:$,top-level //FN:$,f //DA:$,1 161 f(); //DA:$,1 162 }); 163 164 checkGetOffsetsCoverage(function () { //FN:$,top-level //FNDA:1,% 165 var l = ",".split(','); //DA:$,1 166 if (l.length == 3) //DA:$,1 167 l.push(''); //DA:$,0 168 l.pop(); //DA:$,1 169 }); 170 171 checkGetOffsetsCoverage(function () { //FN:$,top-level //FNDA:1,% 172 var l = ",".split(','); //DA:$,1 173 if (l.length == 2) //DA:$,1 174 l.push(''); //DA:$,1 175 l.pop(); //DA:$,1 176 }); 177 178 checkGetOffsetsCoverage(function () { //FN:$,top-level 179 var l = ",".split(','); //DA:$,1 180 if (l.length == 3) //DA:$,1 181 l.push(''); //DA:$,0 182 else 183 l.pop(); //DA:$,1 184 }); 185 186 checkGetOffsetsCoverage(function () { //FN:$,top-level 187 var l = ",".split(','); //DA:$,1 188 if (l.length == 2) //DA:$,1 189 l.push(''); //DA:$,1 190 else 191 l.pop(); //DA:$,0 192 }); 193 194 checkGetOffsetsCoverage(function () { //FN:$,top-level 195 var l = ",".split(','); //DA:$,1 196 if (l.length == 2) //DA:$,1 197 l.push(''); //DA:$,1 198 else { 199 if (l.length == 1) //DA:$,0 200 l.pop(); //DA:$,0 201 } 202 }); 203 204 checkGetOffsetsCoverage(function () { //FN:$,top-level 205 function f(i) { //FN:$,f 206 var x = 0; //DA:$,2 207 while (i--) { // Currently OSR wrongly count the loop header twice. 208 // So instead of DA:$,12 , we have DA:$,13 . 209 x += i; //DA:$,10 210 x = x / 2; //DA:$,10 211 } 212 return x; //DA:$,2 213 } 214 215 f(5); //DA:$,1 216 f(5); //DA:$,1 217 }); 218 219 checkGetOffsetsCoverage(function () { //FN:$,top-level 220 try { //DA:$,1 221 var l = ",".split(','); //DA:$,1 222 if (l.length == 2) { //DA:$,1 223 l.push(''); //DA:$,1 224 throw l; //DA:$,1 225 } 226 l.pop(); //DA:$,0 227 } catch (x) { //DA:$,1 228 x.pop(); //DA:$,1 229 } 230 }); 231 232 checkGetOffsetsCoverage(function () { //FN:$,top-level 233 var l = ",".split(','); //DA:$,1 234 try { //DA:$,1 235 try { //DA:$,1 236 if (l.length == 2) { //DA:$,1 237 l.push(''); //DA:$,1 238 throw l; //DA:$,1 239 } 240 l.pop(); //DA:$,0 241 } finally { //DA:$,1 242 l.pop(); //DA:$,1 243 } 244 } catch (x) { //DA:$,1 245 } 246 }); 247 248 checkGetOffsetsCoverage(function () { //FN:$,top-level 249 function f() { //FN:$,f 250 throw 1; //DA:$,1 251 f(); //DA:$,0 252 } 253 var l = ",".split(','); //DA:$,1 254 try { //DA:$,1 255 f(); //DA:$,1 256 f(); //DA:$,0 257 } catch (x) { //DA:$,1 258 } 259 }); 260 261 262 // Test TableSwitch opcode 263 checkGetOffsetsCoverage(function () { //FN:$,top-level 264 var l = ",".split(','); //DA:$,1 265 switch (l.length) { //DA:$,1 266 case 0: 267 l.push('0'); //DA:$,0 268 break; 269 case 1: 270 l.push('1'); //DA:$,0 271 break; 272 case 2: 273 l.push('2'); //DA:$,1 274 break; 275 case 3: 276 l.push('3'); //DA:$,0 277 break; 278 } 279 l.pop(); //DA:$,1 280 }); 281 282 checkGetOffsetsCoverage(function () { //FN:$,top-level 283 var l = ",".split(','); //DA:$,1 284 switch (l.length) { //DA:$,1 285 case 0: 286 l.push('0'); //DA:$,0 287 case 1: 288 l.push('1'); //DA:$,0 289 case 2: 290 l.push('2'); //DA:$,1 291 case 3: 292 l.push('3'); //DA:$,1 293 } 294 l.pop(); //DA:$,1 295 }); 296 297 checkGetOffsetsCoverage(function () { //FN:$,top-level 298 var l = ",".split(','); //DA:$,1 299 switch (l.length) { //DA:$,1 300 case 5: 301 l.push('5'); //DA:$,0 302 case 4: 303 l.push('4'); //DA:$,0 304 case 3: 305 l.push('3'); //DA:$,0 306 case 2: 307 l.push('2'); //DA:$,1 308 } 309 l.pop(); //DA:$,1 310 }); 311 312 checkGetOffsetsCoverage(function () { //FN:$,top-level 313 var l = ",".split(','); //DA:$,1 314 switch (l.length) { //DA:$,1 315 case 2: 316 l.push('2'); //DA:$,1 317 case 5: 318 l.push('5'); //DA:$,1 319 } 320 l.pop(); //DA:$,1 321 }); 322 323 checkGetOffsetsCoverage(function () { //FN:$,top-level 324 var l = ",".split(','); //DA:$,1 325 switch (l.length) { //DA:$,1 326 case 3: 327 l.push('1'); //DA:$,0 328 case 5: 329 l.push('5'); //DA:$,0 330 } 331 l.pop(); //DA:$,1 332 }); 333 334 // Unfortunately the differences between switch implementations leaks in the 335 // code coverage reports. 336 checkGetOffsetsCoverage(function () { //FN:$,top-level 337 function f(a) { //FN:$,f 338 return a; //DA:$,2 339 } 340 var l = ",".split(','); //DA:$,1 341 switch (l.length) { //DA:$,1 342 case f(-42): //DA:$,1 343 l.push('1'); //DA:$,0 344 case f(51): //DA:$,1 345 l.push('5'); //DA:$,0 346 } 347 l.pop(); //DA:$,1 348 }); 349 350 351 checkGetOffsetsCoverage(function () { //FN:$,top-level //FNDA:1,% 352 var l = ",".split(','); //DA:$,1 353 switch (l.length) { //DA:$,1 //BRDA:$,0,0,0 //BRDA:$,0,1,1 //BRDA:$,0,2,0 //BRDA:$,0,3,0 354 case 0: 355 case 1: 356 l.push('0'); //DA:$,0 357 l.push('1'); //DA:$,0 358 case 2: 359 l.push('2'); //DA:$,1 360 case 3: 361 l.push('3'); //DA:$,1 362 } 363 l.pop(); //DA:$,1 364 //FNF:1 365 //FNH:1 366 //LF:7 367 //LH:5 368 //BRF:4 369 //BRH:1 370 }); 371 372 checkGetOffsetsCoverage(function () { //FN:$,top-level //FNDA:1,% 373 var l = ",".split(','); //DA:$,1 374 switch (l.length) { //DA:$,1 //BRDA:$,0,0,0 //BRDA:$,0,1,0 //BRDA:$,0,2,1 //BRDA:$,0,3,0 375 case 0: 376 l.push('0'); //DA:$,0 377 case 1: 378 l.push('1'); //DA:$,0 379 case 2: 380 case 3: 381 l.push('2'); //DA:$,1 382 l.push('3'); //DA:$,1 383 } 384 l.pop(); //DA:$,1 385 //FNF:1 386 //FNH:1 387 //LF:7 388 //LH:5 389 //BRF:4 390 //BRH:1 391 }); 392 393 checkGetOffsetsCoverage(function () { //FN:$,top-level //FNDA:1,% 394 var l = ",".split(','); //DA:$,1 395 switch (l.length) { //DA:$,1 //BRDA:$,0,0,0 //BRDA:$,0,1,0 //BRDA:$,0,2,1 //BRDA:$,0,3,0 396 case 0: 397 l.push('0'); //DA:$,0 398 case 1: 399 default: 400 l.push('1'); //DA:$,0 401 case 2: 402 l.push('2'); //DA:$,1 403 case 3: 404 l.push('3'); //DA:$,1 405 } 406 l.pop(); //DA:$,1 407 //FNF:1 408 //FNH:1 409 //LF:7 410 //LH:5 411 //BRF:4 412 //BRH:1 413 }); 414 415 checkGetOffsetsCoverage(function () { //FN:$,top-level //FNDA:1,% 416 var l = ",".split(','); //DA:$,1 417 switch (l.length) { //DA:$,1 //BRDA:$,0,0,0 //BRDA:$,0,1,0 //BRDA:$,0,2,1 //BRDA:$,0,3,0 418 case 0: 419 l.push('0'); //DA:$,0 420 case 1: 421 l.push('1'); //DA:$,0 422 default: 423 case 2: 424 l.push('2'); //DA:$,1 425 case 3: 426 l.push('3'); //DA:$,1 427 } 428 l.pop(); //DA:$,1 429 //FNF:1 430 //FNH:1 431 //LF:7 432 //LH:5 433 //BRF:4 434 //BRH:1 435 }); 436 437 checkGetOffsetsCoverage(function () { //FN:$,top-level //FNDA:1,% 438 var l = ",".split(','); //DA:$,1 439 switch (l.length) { //DA:$,1 //BRDA:$,0,0,0 //BRDA:$,0,1,0 //BRDA:$,0,2,1 //BRDA:$,0,3,0 //BRDA:$,0,4,0 440 case 0: 441 l.push('0'); //DA:$,0 442 case 1: 443 l.push('1'); //DA:$,0 444 default: 445 l.push('default'); //DA:$,0 446 case 2: 447 l.push('2'); //DA:$,1 448 case 3: 449 l.push('3'); //DA:$,1 450 } 451 l.pop(); //DA:$,1 452 //FNF:1 453 //FNH:1 454 //LF:8 455 //LH:5 456 //BRF:5 457 //BRH:1 458 }); 459 460 checkGetOffsetsCoverage(function () { //FN:$,top-level //FNDA:1,% 461 var l = ",".split(','); //DA:$,1 462 switch (l.length) { //DA:$,1 //BRDA:$,0,0,0 //BRDA:$,0,1,0 //BRDA:$,0,2,0 //BRDA:$,0,3,1 463 case 0: 464 l.push('0'); //DA:$,0 465 case 1: 466 l.push('1'); //DA:$,0 467 default: 468 l.push('2'); //DA:$,1 469 case 3: 470 l.push('3'); //DA:$,1 471 } 472 l.pop(); //DA:$,1 473 //FNF:1 474 //FNH:1 475 //LF:7 476 //LH:5 477 //BRF:4 478 //BRH:1 479 }); 480 481 checkGetOffsetsCoverage(function () { //FN:$,top-level //FNDA:1,% 482 var l = ','.split(','); //DA:$,1 483 if (l.length === 45) { //DA:$,1 //BRDA:$,0,0,1 //BRDA:$,0,1,0 484 switch (l[0]) { //DA:$,0 //BRDA:$,1,0,- //BRDA:$,1,1,- 485 case ',': 486 l.push('0'); //DA:$,0 487 default: 488 l.push('1'); //DA:$,0 489 } 490 } 491 l.pop(); //DA:$,1 492 //FNF:1 493 //FNH:1 494 //LF:6 495 //LH:3 496 //BRF:4 497 //BRH:1 498 }); 499 500 // If you add a test case here, do the same in 501 // jit-test/tests/coverage/simple.js