Added test case for bug 456667.
[mozilla-central.git] / js / src / trace-test.js
blob5856442b8db786a0fd1ff12e0834223615ae58ce
1 /**
2  * A number of the tests in this file depend on the setting of
3  * HOTLOOP.  Define some constants up front, so they're easy to grep
4  * for.
5  */
6 // The HOTLOOP constant we depend on; only readable from our stats
7 // object in debug builds.
8 const haveTracemonkey = !!(this.tracemonkey)
9 const HOTLOOP = haveTracemonkey ? tracemonkey.HOTLOOP : 2;
10 // The loop count at which we trace
11 const RECORDLOOP = HOTLOOP;
12 // The loop count at which we run the trace
13 const RUNLOOP = HOTLOOP + 1;
15 var testName = null;
16 if ("arguments" in this && arguments.length > 0)
17   testName = arguments[0];
18 var fails = [], passes=[];
20 function jitstatHandler(f)
22     if (!haveTracemonkey) {
23         return;
24     }
25     // XXXbz this is a nasty hack, but I can't figure out a way to
26     // just use jitstats.tbl here
27     f("recorderStarted");
28     f("recorderAborted");
29     f("traceCompleted");
30     f("sideExitIntoInterpreter");
31     f("typeMapMismatchAtEntry");
32     f("returnToDifferentLoopHeader");
33     f("traceTriggered");
34     f("globalShapeMismatchAtEntry");
35     f("treesTrashed");
36     f("slotPromoted");
37     f("unstableLoopVariable");
38     f("breakLoopExits");
39     f("returnLoopExits");
42 function test(f)
44   if (!testName || testName == f.name) {
45     // Collect our jit stats
46     var localJITstats = {};
47     jitstatHandler(function(prop, local, global) {
48                      localJITstats[prop] = tracemonkey[prop];
49                    });
50     check(f.name, f(), f.expected, localJITstats, f.jitstats);
51   }
54 function check(desc, actual, expected, oldJITstats, expectedJITstats)
56   if (expected == actual) {
57     var pass = true;
58     jitstatHandler(function(prop) {
59                      if (expectedJITstats && prop in expectedJITstats &&
60                          expectedJITstats[prop] !=
61                            tracemonkey[prop] - oldJITstats[prop]) {
62                        pass = false;
63                      }
64                    });
65     if (pass) {
66       passes.push(desc);
67       return print(desc, ": passed");
68     }
69   }
70   fails.push(desc);
71   var expectedStats = "";
72   if (expectedJITstats) {
73       jitstatHandler(function(prop) {
74                        if (prop in expectedJITstats) {
75                          if (expectedStats)
76                            expectedStats += " ";
77                          expectedStats +=
78                            prop + ": " + expectedJITstats[prop];
79                        }
80                      });
81   }
82   var actualStats = "";
83   if (expectedJITstats) {
84       jitstatHandler(function(prop) {
85                        if (prop in expectedJITstats) {
86                          if (actualStats)
87                            actualStats += " ";
88                          actualStats += prop + ": " + (tracemonkey[prop]-oldJITstats[prop]);
89                        }
90                      });
91   }
92   print(desc, ": FAILED: expected", typeof(expected), "(", expected, ")",
93         (expectedStats ? " [" + expectedStats + "] " : ""),
94         "!= actual",
95         typeof(actual), "(", actual, ")",
96         (actualStats ? " [" + actualStats + "] " : ""));
99 function ifInsideLoop()
101   var cond = true, intCond = 5, count = 0;
102   for (var i = 0; i < 100; i++) {
103     if (cond)
104       count++;
105     if (intCond)
106       count++;
107   }
108   return count;
110 ifInsideLoop.expected = 200;
111 test(ifInsideLoop);
113 function bitwiseAnd_inner(bitwiseAndValue) {
114   for (var i = 0; i < 60000; i++)
115     bitwiseAndValue = bitwiseAndValue & i;
116   return bitwiseAndValue;
118 function bitwiseAnd()
120   return bitwiseAnd_inner(12341234);
122 bitwiseAnd.expected = 0;
123 test(bitwiseAnd);
125 if (!testName || testName == "bitwiseGlobal") {
126   bitwiseAndValue = Math.pow(2,32);
127   for (var i = 0; i < 60000; i++)
128     bitwiseAndValue = bitwiseAndValue & i;
129   check("bitwiseGlobal", bitwiseAndValue, 0);
133 function equalInt()
135   var i1 = 55, one = 1, zero = 0, undef;
136   var o1 = { }, o2 = { };
137   var s = "5";
138   var hits = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
139   for (var i = 0; i < 5000; i++) {
140     if (i1 == 55) hits[0]++;
141     if (i1 != 56) hits[1]++;
142     if (i1 < 56)  hits[2]++;
143     if (i1 > 50)  hits[3]++;
144     if (i1 <= 60) hits[4]++;
145     if (i1 >= 30) hits[5]++;
146     if (i1 == 7)  hits[6]++;
147     if (i1 != 55) hits[7]++;
148     if (i1 < 30)  hits[8]++;
149     if (i1 > 90)  hits[9]++;
150     if (i1 <= 40) hits[10]++;
151     if (i1 >= 70) hits[11]++;
152     if (o1 == o2) hits[12]++;
153     if (o2 != null) hits[13]++;
154     if (s < 10) hits[14]++;
155     if (true < zero) hits[15]++;
156     if (undef > one) hits[16]++;
157     if (undef < zero) hits[17]++;
158   }
159   return hits.toString();
161 equalInt.expected = "5000,5000,5000,5000,5000,5000,0,0,0,0,0,0,0,5000,5000,0,0,0";
162 test(equalInt);
164 var a;
165 function setelem()
167   a = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
168   a = a.concat(a, a, a);
169   var l = a.length;
170   for (var i = 0; i < l; i++) {
171     a[i] = i;
172   }
173   return a.toString();
175 setelem.expected = "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83";
176 test(setelem);
178 function getelem_inner(a)
180   var accum = 0;
181   var l = a.length;
182   for (var i = 0; i < l; i++) {
183     accum += a[i];
184   }
185   return accum;
187 function getelem()
189   return getelem_inner(a);
191 getelem.expected = 3486;
192 test(getelem);
194 globalName = 907;
195 function name()
197   var a = 0;
198   for (var i = 0; i < 100; i++)
199     a = globalName;
200   return a;
202 name.expected = 907;
203 test(name);
205 var globalInt = 0;
206 if (!testName || testName == "globalGet") {
207   for (var i = 0; i < 500; i++)
208     globalInt = globalName + i;
209   check("globalGet", globalInt, globalName + 499);
212 if (!testName || testName == "globalSet") {
213   for (var i = 0; i < 500; i++)
214     globalInt = i;
215   check("globalSet", globalInt, 499);
218 function arith()
220   var accum = 0;
221   for (var i = 0; i < 100; i++) {
222     accum += (i * 2) - 1;
223   }
224   return accum;
226 arith.expected = 9800;
227 test(arith);
229 function lsh_inner(n)
231   var r;
232   for (var i = 0; i < 35; i++)
233     r = 0x1 << n;
234   return r;
236 function lsh()
238   return [lsh_inner(15),lsh_inner(55),lsh_inner(1),lsh_inner(0)];
240 lsh.expected = "32768,8388608,2,1";
241 test(lsh);
243 function rsh_inner(n)
245   var r;
246   for (var i = 0; i < 35; i++)
247     r = 0x11010101 >> n;
248   return r;
250 function rsh()
252   return [rsh_inner(8),rsh_inner(5),rsh_inner(35),rsh_inner(-1)];
254 rsh.expected = "1114369,8914952,35659808,0";
255 test(rsh);
257 function ursh_inner(n)
259   var r;
260   for (var i = 0; i < 35; i++)
261     r = -55 >>> n;
262   return r;
264 function ursh() {
265   return [ursh_inner(8),ursh_inner(33),ursh_inner(0),ursh_inner(1)];
267 ursh.expected = "16777215,2147483620,4294967241,2147483620";
268 test(ursh);
270 function doMath_inner(cos)
272     var s = 0;
273     var sin = Math.sin;
274     for (var i = 0; i < 200; i++)
275         s = -Math.pow(sin(i) + cos(i * 0.75), 4);
276     return s;
278 function doMath() {
279   return doMath_inner(Math.cos);
281 doMath.expected = -0.5405549555611059;
282 test(doMath);
284 function fannkuch() {
285    var count = Array(8);
286    var r = 8;
287    var done = 0;
288    while (done < 40) {
289       // write-out the first 30 permutations
290       done += r;
291       while (r != 1) { count[r - 1] = r; r--; }
292       while (true) {
293          count[r] = count[r] - 1;
294          if (count[r] > 0) break;
295          r++;
296       }
297    }
298    return done;
300 fannkuch.expected = 41;
301 test(fannkuch);
303 function xprop()
305   a = 0;
306   for (var i = 0; i < 20; i++)
307     a += 7;
308   return a;
310 xprop.expected = 140;
311 test(xprop);
313 var a = 2;
314 function getprop_inner(o2)
316   var o = {a:5};
317   var t = this;
318   var x = 0;
319   for (var i = 0; i < 20; i++) {
320     t = this;
321     x += o.a + o2.a + this.a + t.a;
322   }
323   return x;
325 function getprop() {
326   return getprop_inner({a:9});
328 getprop.expected = 360;
329 test(getprop);
331 function mod()
333   var mods = [-1,-1,-1,-1];
334   var a = 9.5, b = -5, c = 42, d = (1/0);
335   for (var i = 0; i < 20; i++) {
336     mods[0] = a % b;
337     mods[1] = b % 1;
338     mods[2] = c % d;
339     mods[3] = c % a;
340     mods[4] = b % 0;
341   }
342   return mods.toString();
344 mod.expected = "4.5,0,42,4,NaN";
345 test(mod);
347 function glob_f1() {
348   return 1;
350 function glob_f2() {
351   return glob_f1();
353 function call()
355   var q1 = 0, q2 = 0, q3 = 0, q4 = 0, q5 = 0;
356   var o = {};
357   function f1() {
358       return 1;
359   }
360   function f2(f) {
361       return f();
362   }
363   o.f = f1;
364   for (var i = 0; i < 100; ++i) {
365       q1 += f1();
366       q2 += f2(f1);
367       q3 += glob_f1();
368       q4 += o.f();
369       q5 += glob_f2();
370   }
371   var ret = [q1, q2, q3, q4, q5];
372   return ret;
374 call.expected =  "100,100,100,100,100";
375 test(call);
377 function setprop()
379   var obj = { a:-1 };
380   var obj2 = { b:-1, a:-1 };
381   for (var i = 0; i < 20; i++) {
382     obj2.b = obj.a = i;
383   }
384   return [obj.a, obj2.a, obj2.b].toString();
386 setprop.expected =  "19,-1,19";
387 test(setprop);
389 function testif() {
390         var q = 0;
391         for (var i = 0; i < 100; i++) {
392                 if ((i & 1) == 0)
393                         q++;
394                 else
395                         q--;
396         }
397     return q;
399 testif.expected = "0";
400 test(testif);
402 var globalinc = 0;
403 function testincops(n) {
404   var i = 0, o = {p:0}, a = [0];
405   n = 100;
407   for (i = 0; i < n; i++);
408   while (i-- > 0);
409   for (i = 0; i < n; ++i);
410   while (--i >= 0);
412   for (o.p = 0; o.p < n; o.p++) globalinc++;
413   while (o.p-- > 0) --globalinc;
414   for (o.p = 0; o.p < n; ++o.p) ++globalinc;
415   while (--o.p >= 0) globalinc--;
417   ++i; // set to 0
418   for (a[i] = 0; a[i] < n; a[i]++);
419   while (a[i]-- > 0);
420   for (a[i] = 0; a[i] < n; ++a[i]);
421   while (--a[i] >= 0);
423   return [++o.p, ++a[i], globalinc].toString();
425 testincops.expected = "0,0,0";
426 test(testincops);
428 function trees() {
429   var i = 0, o = [0,0,0];
430   for (i = 0; i < 100; ++i) {
431     if ((i & 1) == 0) o[0]++;
432     else if ((i & 2) == 0) o[1]++;
433     else o[2]++;
434   }
435   return o;
437 trees.expected = "50,25,25";
438 test(trees);
440 function unboxint() {
441     var q = 0;
442     var o = [4];
443     for (var i = 0; i < 100; ++i)
444         q = o[0] << 1;
445     return q;
447 unboxint.expected = "8";
448 test(unboxint);
450 function strings()
452   var a = [], b = -1;
453   var s = "abcdefghij", s2 = "a";
454   var f = "f";
455   var c = 0, d = 0, e = 0, g = 0;
456   for (var i = 0; i < 10; i++) {
457     a[i] = (s.substring(i, i+1) + s[i] + String.fromCharCode(s2.charCodeAt(0) + i)).concat(i) + i;
458     if (s[i] == f)
459       c++;
460     if (s[i] != 'b')
461       d++;
462     if ("B" > s2)
463       g++; // f already used
464     if (s2 < "b")
465       e++;
466     b = s.length;
467   }
468   return a.toString() + b + c + d + e + g;
470 strings.expected = "aaa00,bbb11,ccc22,ddd33,eee44,fff55,ggg66,hhh77,iii88,jjj991019100";
471 test(strings);
473 function dependentStrings()
475   var a = [];
476   var t = "abcdefghijklmnopqrst";
477   for (var i = 0; i < 10; i++) {
478     var s = t.substring(2*i, 2*i + 2);
479     a[i] = s + s.length;
480   }
481   return a.join("");
483 dependentStrings.expected = "ab2cd2ef2gh2ij2kl2mn2op2qr2st2";
484 test(dependentStrings);
486 function stringConvert()
488   var a = [];
489   var s1 = "F", s2 = "1.3", s3 = "5";
490   for (var i = 0; i < 10; i++) {
491     a[0] = 1 >> s1;
492     a[1] = 10 - s2;
493     a[2] = 15 * s3;
494     a[3] = s3 | 32;
495     a[4] = s2 + 60;
496     // a[5] = 9 + s3;
497     // a[6] = -s3;
498     a[7] = s3 & "7";
499     // a[8] = ~s3;
500   }
501   return a.toString();
503 stringConvert.expected = "1,8.7,75,37,1.360,,,5";
504 test(stringConvert);
506 function orTestHelper(a, b, n)
508   var k = 0;
509   for (var i = 0; i < n; i++) {
510     if (a || b)
511       k += i;
512   }
513   return k;
516 var orNaNTest1, orNaNTest2;
518 orNaNTest1 = new Function("return orTestHelper(NaN, NaN, 10);");
519 orNaNTest1.name = 'orNaNTest1';
520 orNaNTest1.expected = '0';
521 orNaNTest2 = new Function("return orTestHelper(NaN, 1, 10);");
522 orNaNTest2.name = 'orNaNTest2';
523 orNaNTest2.expected = '45';
524 test(orNaNTest1);
525 test(orNaNTest2);
527 function andTestHelper(a, b, n)
529   var k = 0;
530   for (var i = 0; i < n; i++) {
531     if (a && b)
532       k += i;
533   }
534   return k;
537 if (!testName || testName == "truthies") {
538   (function () {
539      var opsies   = ["||", "&&"];
540      var falsies  = [null, undefined, false, NaN, 0, ""];
541      var truthies = [{}, true, 1, 42, 1/0, -1/0, "blah"];
542      var boolies  = [falsies, truthies];
544      // The for each here should abort tracing, so that this test framework
545      // relies only on the interpreter while the orTestHelper and andTestHelper
546      //  functions get trace-JITed.
547      for each (var op in opsies) {
548        for (var i in boolies) {
549          for (var j in boolies[i]) {
550            var x = uneval(boolies[i][j]);
551            for (var k in boolies) {
552              for (var l in boolies[k]) {
553                var y = uneval(boolies[k][l]);
554                var prefix = (op == "||") ? "or" : "and";
555                var f = new Function("return " + prefix + "TestHelper(" + x + "," + y + ",10)");
556                f.name = prefix + "Test(" + x + "," + y + ")";
557                f.expected = eval(x + op + y) ? 45 : 0;
558                test(f);
559              }
560            }
561          }
562        }
563      }
564    })();
567 function nonEmptyStack1Helper(o, farble) {
568     var a = [];
569     var j = 0;
570     for (var i in o)
571         a[j++] = i;
572     return a.join("");
575 function nonEmptyStack1() {
576     return nonEmptyStack1Helper({a:1,b:2,c:3,d:4,e:5,f:6,g:7,h:8}, "hi");
579 nonEmptyStack1.expected = "abcdefgh";
580 test(nonEmptyStack1);
582 function nonEmptyStack2()
584   var a = 0;
585   for (var c in {a:1, b:2, c:3}) {
586     for (var i = 0; i < 10; i++)
587       a += i;
588   }
589   return String(a);
591 nonEmptyStack2.expected = "135";
592 test(nonEmptyStack2);
594 function arityMismatchMissingArg(arg)
596   for (var a = 0, i = 1; i < 10000; i *= 2) {
597     a += i;
598   }
599   return a;
601 arityMismatchMissingArg.expected = 16383;
602 test(arityMismatchMissingArg);
604 function arityMismatchExtraArg()
606   return arityMismatchMissingArg(1, 2);
608 arityMismatchExtraArg.expected = 16383;
609 test(arityMismatchExtraArg);
611 function MyConstructor(i)
613   this.i = i;
615 MyConstructor.prototype.toString = function() {return this.i + ""};
617 function newTest()
619   var a = [];
620   for (var i = 0; i < 10; i++)
621     a[i] = new MyConstructor(i);
622   return a.join("");
624 newTest.expected = "0123456789";
625 test(newTest);
627 // The following functions use a delay line of length 2 to change the value
628 // of the callee without exiting the traced loop. This is obviously tuned to
629 // match the current HOTLOOP setting of 2.
630 function shapelessArgCalleeLoop(f, g, h, a)
632   for (var i = 0; i < 10; i++) {
633     f(i, a);
634     f = g;
635     g = h;
636   }
639 function shapelessVarCalleeLoop(f0, g, h, a)
641   var f = f0;
642   for (var i = 0; i < 10; i++) {
643     f(i, a);
644     f = g;
645     g = h;
646   }
649 function shapelessLetCalleeLoop(f0, g, h, a)
651   for (var i = 0; i < 10; i++) {
652     let f = f0;
653     f(i, a);
654     f = g;
655     g = h;
656   }
659 function shapelessUnknownCalleeLoop(n, f, g, h, a)
661   for (var i = 0; i < 10; i++) {
662     (n || f)(i, a);
663     f = g;
664     g = h;
665   }
668 function shapelessCalleeTest()
670   var a = [];
672   var helper = function (i, a) a[i] = i;
673   shapelessArgCalleeLoop(helper, helper, function (i, a) a[i] = -i, a);
675   helper = function (i, a) a[10 + i] = i;
676   shapelessVarCalleeLoop(helper, helper, function (i, a) a[10 + i] = -i, a);
678   helper = function (i, a) a[20 + i] = i;
679   shapelessLetCalleeLoop(helper, helper, function (i, a) a[20 + i] = -i, a);
681   helper = function (i, a) a[30 + i] = i;
682   shapelessUnknownCalleeLoop(null, helper, helper, function (i, a) a[30 + i] = -i, a);
684   try {
685     helper = {hack: 42};
686     shapelessUnknownCalleeLoop(null, helper, helper, helper, a);
687   } catch (e) {
688     if (e + "" != "TypeError: f is not a function")
689       print("shapelessUnknownCalleeLoop: unexpected exception " + e);
690   }
691   return a.join("");
693 shapelessCalleeTest.expected = "01-2-3-4-5-6-7-8-901-2-3-4-5-6-7-8-9012345678901-2-3-4-5-6-7-8-9";
694 test(shapelessCalleeTest);
696 function typeofTest()
698   var values = ["hi", "hi", "hi", null, 5, 5.1, true, undefined, /foo/, typeofTest, [], {}], types = [];
699   for (var i = 0; i < values.length; i++)
700     types[i] = typeof values[i];
701   return types.toString();
703 typeofTest.expected = "string,string,string,object,number,number,boolean,undefined,object,function,object,object";
704 test(typeofTest);
706 function joinTest()
708   var s = "";
709   var a = [];
710   for (var i = 0; i < 8; i++)
711     a[i] = [String.fromCharCode(97 + i)];
712   for (i = 0; i < 8; i++) {
713     for (var j = 0; j < 8; j++)
714       a[i][1 + j] = j;
715   }
716   for (i = 0; i < 8; i++)
717     s += a[i].join(",");
718   return s;
720 joinTest.expected = "a,0,1,2,3,4,5,6,7b,0,1,2,3,4,5,6,7c,0,1,2,3,4,5,6,7d,0,1,2,3,4,5,6,7e,0,1,2,3,4,5,6,7f,0,1,2,3,4,5,6,7g,0,1,2,3,4,5,6,7h,0,1,2,3,4,5,6,7";
721 test(joinTest);
723 function arity1(x)
725   return (x == undefined) ? 1 : 0;
727 function missingArgTest() {
728   var q;
729   for (var i = 0; i < 10; i++) {
730     q = arity1();
731   }
732   return q;
734 missingArgTest.expected = "1"
735 test(missingArgTest);
737 JSON = function () {
738     return {
739         stringify: function stringify(value, whitelist) {
740             switch (typeof(value)) {
741               case "object":
742                 return value.constructor.name;
743             }
744         }
745     };
746 }();
748 function missingArgTest2() {
749   var testPairs = [
750     ["{}", {}],
751     ["[]", []],
752     ['{"foo":"bar"}', {"foo":"bar"}],
753   ]
755   var a = [];
756   for (var i=0; i < testPairs.length; i++) {
757     var s = JSON.stringify(testPairs[i][1])
758     a[i] = s;
759   }
760   return a.join(",");
762 missingArgTest2.expected = "Object,Array,Object";
763 test(missingArgTest2);
765 function deepForInLoop() {
766   // NB: the number of props set in C is arefully tuned to match HOTLOOP = 2.
767   function C(){this.p = 1, this.q = 2}
768   C.prototype = {p:1, q:2, r:3, s:4, t:5};
769   var o = new C;
770   var j = 0;
771   var a = [];
772   for (var i in o)
773     a[j++] = i;
774   return a.join("");
776 deepForInLoop.expected = "pqrst";
777 test(deepForInLoop);
779 function nestedExit(x) {
780     var q = 0;
781     for (var i = 0; i < 10; ++i)
782         if (x)
783             ++q;
785 function nestedExitLoop() {
786     for (var j = 0; j < 10; ++j)
787         nestedExit(j < 7);
788     return "ok";
790 nestedExitLoop.expected = "ok";
791 test(nestedExitLoop);
793 function bitsinbyte(b) {
794     var m = 1, c = 0;
795     while(m<0x100) {
796         if(b & m) c++;
797         m <<= 1;
798     }
799     return 1;
801 function TimeFunc(func) {
802     var x,y;
803     for(var y=0; y<256; y++) func(y);
805 function nestedExit2() {
806     TimeFunc(bitsinbyte);
807     return "ok";
809 nestedExit2.expected = "ok";
810 test(nestedExit2);
812 function parsingNumbers() {
813     var s1 = "123";
814     var s1z = "123zzz";
815     var s2 = "123.456";
816     var s2z = "123.456zzz";
818     var e1 = 123;
819     var e2 = 123.456;
821     var r1, r1z, r2, r2z;
823     for (var i = 0; i < 10; i++) {
824         r1 = parseInt(s1);
825         r1z = parseInt(s1z);
826         r2 = parseFloat(s2);
827         r2z = parseFloat(s2z);
828     }
830     if (r1 == e1 && r1z == e1 && r2 == e2 && r2z == e2)
831         return "ok";
832     return "fail";
834 parsingNumbers.expected = "ok";
835 test(parsingNumbers);
837 function matchInLoop() {
838     var k = "hi";
839     for (var i = 0; i < 10; i++) {
840         var result = k.match(/hi/) != null;
841     }
842     return result;
844 matchInLoop.expected = true;
845 test(matchInLoop);
847 function deep1(x) {
848     if (x > 90)
849         return 1;
850     return 2;
852 function deep2() {
853     for (var i = 0; i < 100; ++i)
854         deep1(i);
855     return "ok";
857 deep2.expected = "ok";
858 test(deep2);
860 var merge_type_maps_x = 0, merge_type_maps_y = 0;
861 function merge_type_maps() {
862     for (merge_type_maps_x = 0; merge_type_maps_x < 50; ++merge_type_maps_x)
863         if ((merge_type_maps_x & 1) == 1)
864             ++merge_type_maps_y;
865     return [merge_type_maps_x,merge_type_maps_y].join(",");
867 merge_type_maps.expected = "50,25";
868 test(merge_type_maps)
870 function inner_double_outer_int() {
871     function f(i) {
872         for (var m = 0; m < 20; ++m)
873             for (var n = 0; n < 100; n += i)
874                 ;
875         return n;
876     }
877     return f(.5);
879 inner_double_outer_int.expected = "100";
880 test(inner_double_outer_int);
882 function newArrayTest()
884   var a = [];
885   for (var i = 0; i < 10; i++)
886     a[i] = new Array();
887   return a.map(function(x) x.length).toString();
889 newArrayTest.expected="0,0,0,0,0,0,0,0,0,0";
890 test(newArrayTest);
892 function stringSplitTest()
894   var s = "a,b"
895   var a = null;
896   for (var i = 0; i < 10; ++i)
897     a = s.split(",");
898   return a.join();
900 stringSplitTest.expected="a,b";
901 test(stringSplitTest);
903 function stringSplitIntoArrayTest()
905   var s = "a,b"
906   var a = [];
907   for (var i = 0; i < 10; ++i)
908     a[i] = s.split(",");
909   return a.join();
911 stringSplitIntoArrayTest.expected="a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b";
912 test(stringSplitIntoArrayTest);
914 function forVarInWith() {
915     function foo() ({notk:42});
916     function bar() ({p:1, q:2, r:3, s:4, t:5});
917     var o = foo();
918     var a = [];
919     with (o) {
920         for (var k in bar())
921             a[a.length] = k;
922     }
923     return a.join("");
925 forVarInWith.expected = "pqrst";
926 test(forVarInWith);
928 function inObjectTest() {
929     var o = {p: 1, q: 2, r: 3, s: 4, t: 5};
930     var r = 0;
931     for (var i in o) {
932         if (!(i in o))
933             break;
934         if ((i + i) in o)
935             break;
936         ++r;
937     }
938     return r;
940 inObjectTest.expected = 5;
941 test(inObjectTest);
943 function inArrayTest() {
944     var a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
945     for (var i = 0; i < a.length; i++) {
946         if (!(i in a))
947             break;
948     }
949     return i;
951 inArrayTest.expected = 10;
952 test(inArrayTest);
954 function innerLoopIntOuterDouble() {
955     var n = 10000, i=0, j=0, count=0, limit=0;
956     for (i = 1; i <= n; ++i) {
957         limit = i * 1;
958         for (j = 0; j < limit; ++j) {
959             ++count;
960         }
961     }
962     return "" + count;
964 innerLoopIntOuterDouble.expected="50005000";
965 test(innerLoopIntOuterDouble);
967 function outerline(){
968     var i=0;
969     var j=0;
971     for (i = 3; i<= 100000; i+=2)
972         for (j = 3; j < 1000; j+=2)
973             if ((i & 1) == 1)
974                 break;
975     return "ok";
977 outerline.expected="ok";
978 test(outerline);
980 function addAccumulations(f) {
981   var a = f();
982   var b = f();
983   return a() + b();
986 function loopingAccumulator() {
987   var x = 0;
988   return function () {
989     for (var i = 0; i < 10; ++i) {
990       ++x;
991     }
992     return x;
993   }
996 function testLoopingAccumulator() {
997         var x = addAccumulations(loopingAccumulator);
998         return x;
1000 testLoopingAccumulator.expected = 20;
1001 test(testLoopingAccumulator);
1003 function testBranchingLoop() {
1004   var x = 0;
1005   for (var i=0; i < 100; ++i) {
1006     if (i == 51) {
1007       x += 10;
1008     }
1009     x++;
1010   }
1011   return x;
1013 testBranchingLoop.expected = 110;
1014 test(testBranchingLoop);
1016 function testBranchingUnstableLoop() {
1017   var x = 0;
1018   for (var i=0; i < 100; ++i) {
1019     if (i == 51) {
1020       x += 10.1;
1021     }
1022     x++;
1023   }
1024   return x;
1026 testBranchingUnstableLoop.expected = 110.1;
1027 test(testBranchingUnstableLoop);
1029 function testBranchingUnstableLoopCounter() {
1030   var x = 0;
1031   for (var i=0; i < 100; ++i) {
1032     if (i == 51) {
1033       i += 1.1;
1034     }
1035     x++;    
1036   }
1037   return x;
1039 testBranchingUnstableLoopCounter.expected = 99;
1040 test(testBranchingUnstableLoopCounter);
1043 function testBranchingUnstableObject() {
1044   var x = {s: "a"};
1045   var t = "";
1046   for (var i=0; i < 100; ++i) {
1047       if (i == 51)
1048       {
1049         x.s = 5;
1050       }
1051       t += x.s;
1052   }
1053   return t.length;
1055 testBranchingUnstableObject.expected = 100;
1056 test(testBranchingUnstableObject);
1058 function testArrayDensityChange() {
1059   var x = [];
1060   var count = 0;
1061   for (var i=0; i < 100; ++i) {
1062     x[i] = "asdf";
1063   }
1064   for (var i=0; i < x.length; ++i) {
1065       if (i == 51)
1066       {
1067         x[199] = "asdf";
1068       }
1069       if (x[i])
1070         count += x[i].length;
1071   }
1072   return count;
1074 testArrayDensityChange.expected = 404;
1075 test(testArrayDensityChange);
1077 function testDoubleToStr() {
1078     var x = 0.0;
1079     var y = 5.5;
1080     for (var i = 0; i < 200; i++) {
1081        x += parseFloat(y.toString());
1082     }
1083     return x;
1085 testDoubleToStr.expected = 5.5*200;
1086 test(testDoubleToStr);
1088 function testDecayingInnerLoop() {
1089     var i, j, k = 10;
1090     for (i = 0; i < 5000; ++i) {
1091         for (j = 0; j < k; ++j);
1092         --k;
1093     }
1094     return i;
1096 testDecayingInnerLoop.expected = 5000;
1097 test(testDecayingInnerLoop);
1099 function testContinue() {
1100     var i;
1101     var total = 0;
1102     for (i = 0; i < 20; ++i) {
1103         if (i == 11)
1104             continue;
1105         total++;
1106     }
1107     return total;
1109 testContinue.expected = 19;
1110 test(testContinue);
1112 function testContinueWithLabel() {
1113     var i = 0;
1114     var j = 20;
1115     checkiandj :
1116     while (i<10) {
1117         i+=1;
1118         checkj :
1119         while (j>10) {
1120             j-=1;
1121             if ((j%2)==0)
1122                 continue checkj;
1123         }   
1124     }
1125     return i + j;
1127 testContinueWithLabel.expected = 20;
1128 test(testContinueWithLabel);
1130 function testDivision() {
1131     var a = 32768;
1132     var b;
1133     while (b !== 1) {
1134         b = a / 2;
1135         a = b;
1136     }
1137     return a;
1139 testDivision.expected = 1;
1140 test(testDivision);
1142 function testDivisionFloat() {
1143     var a = 32768.0;
1144     var b;
1145     while (b !== 1) {
1146         b = a / 2.0;
1147         a = b;
1148     }
1149     return a === 1.0;
1151 testDivisionFloat.expected = true;
1152 test(testDivisionFloat);
1154 function testToUpperToLower() {
1155     var s = "Hello", s1, s2;
1156     for (i = 0; i < 100; ++i) {
1157         s1 = s.toLowerCase();
1158         s2 = s.toUpperCase();
1159     }
1160     return s1 + s2;
1162 testToUpperToLower.expected = "helloHELLO";
1163 test(testToUpperToLower);
1165 function testReplace2() {
1166     var s = "H e l l o", s1;
1167     for (i = 0; i < 100; ++i) {
1168         s1 = s.replace(" ", "");
1169     }
1170     return s1;
1172 testReplace2.expected = "He l l o";
1173 test(testReplace2);
1175 function testBitwise() {
1176     var x = 10000;
1177     var y = 123456;
1178     var z = 987234;
1179     for (var i = 0; i < 50; i++) {
1180         x = x ^ y;
1181         y = y | z;
1182         z = ~x;
1183     }
1184     return x + y + z;
1186 testBitwise.expected = -1298;
1187 test(testBitwise);
1189 function testSwitch() {
1190     var x = 0;
1191     var ret = 0;
1192     for (var i = 0; i < 100; ++i) {
1193         switch (x) {
1194             case 0:
1195                 ret += 1;
1196                 break;
1197             case 1:
1198                 ret += 2;
1199                 break;
1200             case 2:
1201                 ret += 3;
1202                 break;
1203             case 3:
1204                 ret += 4;
1205                 break;
1206             default:
1207                 x = 0;
1208         }
1209         x++;
1210     }
1211     return ret;
1213 testSwitch.expected = 226;
1214 test(testSwitch);
1216 function testSwitchString() {
1217     var x = "asdf";
1218     var ret = 0;
1219     for (var i = 0; i < 100; ++i) {
1220         switch (x) {
1221         case "asdf":
1222             x = "asd";
1223             ret += 1;
1224             break;
1225         case "asd":
1226             x = "as";
1227             ret += 2;
1228             break;
1229         case "as":
1230             x = "a";
1231             ret += 3;
1232             break;
1233         case "a":
1234             x = "foo";
1235             ret += 4;
1236             break;
1237         default:
1238             x = "asdf";
1239         }
1240     }
1241     return ret;
1243 testSwitchString.expected = 200;
1244 test(testSwitchString);
1246 function testNegZero1Helper(z) {
1247     for (let j = 0; j < 5; ++j) { z = -z; }
1248     return Math.atan2(0, -0) == Math.atan2(0, z);
1251 var testNegZero1 = function() { return testNegZero1Helper(0); }
1252 testNegZero1.expected = true;
1253 testNegZero1.name = 'testNegZero1';
1254 testNegZero1Helper(1);
1255 test(testNegZero1);
1257 // No test case, just make sure this doesn't assert. 
1258 function testNegZero2() {
1259     var z = 0;
1260     for (let j = 0; j < 5; ++j) { ({p: (-z)}); }
1262 testNegZero2();
1264 function testConstSwitch() {
1265     var x;
1266     for (var j=0;j<5;++j) { switch(1.1) { case NaN: case 2: } x = 2; }
1267     return x;
1269 testConstSwitch.expected = 2;
1270 test(testConstSwitch);
1272 function testConstSwitch2() {
1273     var x;
1274     for (var j = 0; j < 4; ++j) { switch(0/0) { } }
1275     return "ok";
1277 testConstSwitch2.expected = "ok";
1278 test(testConstSwitch2);
1280 function testConstIf() {
1281     var x;
1282     for (var j=0;j<5;++j) { if (1.1 || 5) { } x = 2;}
1283     return x;
1285 testConstIf.expected = 2;
1286 test(testConstIf);
1288 function testTypeofHole() {
1289   var a = new Array(6);
1290   a[5] = 3;
1291   for (var i = 0; i < 6; ++i)
1292     a[i] = typeof a[i];
1293   return a.join(",");
1295 testTypeofHole.expected = "undefined,undefined,undefined,undefined,undefined,number"
1296 test(testTypeofHole);
1298 function testNativeLog() {
1299   var a = new Array(5);
1300   for (var i = 0; i < 5; i++) {
1301     a[i] = Math.log(Math.pow(Math.E, 10));
1302   }
1303   return a.join(",");
1305 testNativeLog.expected = "10,10,10,10,10";
1306 test(testNativeLog);
1308 function test_JSOP_ARGSUB() {
1309     function f0() { return arguments[0]; }
1310     function f1() { return arguments[1]; }
1311     function f2() { return arguments[2]; }
1312     function f3() { return arguments[3]; }
1313     function f4() { return arguments[4]; }
1314     function f5() { return arguments[5]; }
1315     function f6() { return arguments[6]; }
1316     function f7() { return arguments[7]; }
1317     function f8() { return arguments[8]; }
1318     function f9() { return arguments[9]; }
1319     var a = [];
1320     for (var i = 0; i < 10; i++) {
1321         a[0] = f0('a');
1322         a[1] = f1('a','b');
1323         a[2] = f2('a','b','c');
1324         a[3] = f3('a','b','c','d');
1325         a[4] = f4('a','b','c','d','e');
1326         a[5] = f5('a','b','c','d','e','f');
1327         a[6] = f6('a','b','c','d','e','f','g');
1328         a[7] = f7('a','b','c','d','e','f','g','h');
1329         a[8] = f8('a','b','c','d','e','f','g','h','i');
1330         a[9] = f9('a','b','c','d','e','f','g','h','i','j');
1331     }
1332     return a.join("");
1334 test_JSOP_ARGSUB.expected = "abcdefghij";
1335 test(test_JSOP_ARGSUB);
1337 function test_JSOP_ARGCNT() {
1338     function f0() { return arguments.length; }
1339     function f1() { return arguments.length; }
1340     function f2() { return arguments.length; }
1341     function f3() { return arguments.length; }
1342     function f4() { return arguments.length; }
1343     function f5() { return arguments.length; }
1344     function f6() { return arguments.length; }
1345     function f7() { return arguments.length; }
1346     function f8() { return arguments.length; }
1347     function f9() { return arguments.length; }
1348     var a = [];
1349     for (var i = 0; i < 10; i++) {
1350         a[0] = f0('a');
1351         a[1] = f1('a','b');
1352         a[2] = f2('a','b','c');
1353         a[3] = f3('a','b','c','d');
1354         a[4] = f4('a','b','c','d','e');
1355         a[5] = f5('a','b','c','d','e','f');
1356         a[6] = f6('a','b','c','d','e','f','g');
1357         a[7] = f7('a','b','c','d','e','f','g','h');
1358         a[8] = f8('a','b','c','d','e','f','g','h','i');
1359         a[9] = f9('a','b','c','d','e','f','g','h','i','j');
1360     }
1361     return a.join(",");
1363 test_JSOP_ARGCNT.expected = "1,2,3,4,5,6,7,8,9,10";
1364 test(test_JSOP_ARGCNT);
1366 function testNativeMax() {
1367     var out = [], k;
1368     for (var i = 0; i < 5; ++i) {
1369         k = Math.max(k, i);
1370     }
1371     out.push(k);
1373     k = 0;
1374     for (var i = 0; i < 5; ++i) {
1375         k = Math.max(k, i);
1376     }
1377     out.push(k);
1379     for (var i = 0; i < 5; ++i) {
1380         k = Math.max(0, -0);
1381     }
1382     out.push((1 / k) < 0);
1383     return out.join(",");
1385 testNativeMax.expected = "NaN,4,false";
1386 test(testNativeMax);
1388 function testFloatArrayIndex() {
1389     var a = [];
1390     for (var i = 0; i < 10; ++i) {
1391         a[3] = 5;
1392         a[3.5] = 7;
1393     }
1394     return a[3] + "," + a[3.5];
1396 testFloatArrayIndex.expected = "5,7";
1397 test(testFloatArrayIndex);
1399 function testStrict() {
1400     var n = 10, a = [];
1401     for (var i = 0; i < 10; ++i) {
1402         a[0] = (n === 10);
1403         a[1] = (n !== 10);
1404         a[2] = (n === null);
1405         a[3] = (n == null);
1406     }
1407     return a.join(",");
1409 testStrict.expected = "true,false,false,false";
1410 test(testStrict);
1412 function testSetPropNeitherMissNorHit() {
1413     for (var j = 0; j < 5; ++j) { if (({}).__proto__ = 1) { } }
1414     return "ok";
1416 testSetPropNeitherMissNorHit.expected = "ok";
1417 test(testSetPropNeitherMissNorHit);
1419 function testPrimitiveConstructorPrototype() {
1420     var f = function(){};
1421     f.prototype = false;
1422     for (let j=0;j<5;++j) { new f; }
1423     return "ok";
1424 }    
1425 testPrimitiveConstructorPrototype.expected = "ok";
1426 test(testPrimitiveConstructorPrototype);
1428 function testSideExitInConstructor() {
1429     var FCKConfig = {};
1430     FCKConfig.CoreStyles =
1431         {
1432             'Bold': { },
1433             'Italic': { },
1434             'FontFace': { },
1435             'Size' :
1436             {
1437                 Overrides: [ ]
1438             },
1440             'Color' :
1441             {
1442                 Element: '',
1443                 Styles: {  },
1444                 Overrides: [  ]
1445             },
1446             'BackColor': {
1447                 Element : '',
1448                 Styles : { 'background-color' : '' }
1449             },
1450             
1451         };
1452     var FCKStyle = function(A) {
1453         A.Element;
1454     };
1455     
1456     var pass = true;
1457     for (var s in FCKConfig.CoreStyles) {
1458         var x = new FCKStyle(FCKConfig.CoreStyles[s]);
1459         if (!x) pass = false;
1460     }
1461     return pass;
1463 testSideExitInConstructor.expected = true;
1464 test(testSideExitInConstructor);
1466 function testNot() {
1467     var a = new Object(), b = null, c = "foo", d = "", e = 5, f = 0, g = 5.5, h = -0, i = true, j = false, k = undefined;
1468     var r;
1469     for (var i = 0; i < 10; ++i) {
1470         r = [!a, !b, !c, !d, !e, !f, !g, !h, !i, !j, !k];
1471     }
1472     return r.join(",");
1474 testNot.expected = "false,true,false,true,false,true,false,true,false,true,true";
1475 test(testNot);
1477 function doTestDifferingArgc(a, b)
1479     var k = 0;
1480     for (var i = 0; i < 10; i++)
1481     {
1482         k += i;
1483     }
1484     return k;
1486 function testDifferingArgc()
1488     var x = 0;
1489     x += doTestDifferingArgc(1, 2);
1490     x += doTestDifferingArgc(1);
1491     x += doTestDifferingArgc(1, 2, 3);
1492     return x;
1494 testDifferingArgc.expected = 45*3;
1495 test(testDifferingArgc);
1497 function doTestMoreArgcThanNargs()
1499     var x = 0;
1500     for (var i = 0; i < 10; i++)
1501     {
1502         x = x + arguments[3];
1503     }
1504     return x;
1506 function testMoreArgcThanNargs()
1508     return doTestMoreArgcThanNargs(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
1510 testMoreArgcThanNargs.expected = 4*10;
1511 test(testMoreArgcThanNargs);
1513 // Test stack reconstruction after a nested exit
1514 function testNestedExitStackInner(j, counter) {
1515   ++counter;
1516   var b = 0;
1517   for (var i = 1; i <= RUNLOOP; i++) {
1518     ++b;
1519     var a;
1520     // Make sure that once everything has been traced we suddenly switch to
1521     // a different control flow the first time we run the outermost tree,
1522     // triggering a side exit.
1523     if (j < RUNLOOP)
1524       a = 1;
1525     else
1526       a = 0;
1527     ++b;
1528     b += a;
1529   }
1530   return counter + b;
1532 function testNestedExitStackOuter() {
1533   var counter = 0;
1534   for (var j = 1; j <= RUNLOOP; ++j) {
1535     for (var k = 1; k <= RUNLOOP; ++k) {
1536       counter = testNestedExitStackInner(j, counter);
1537     }
1538   }
1539   return counter;
1541 testNestedExitStackOuter.expected = 81;
1542 testNestedExitStackOuter.jitstats = {
1543     recorderStarted: 4,
1544     recorderAborted: 0,
1545     traceTriggered: 9
1547 test(testNestedExitStackOuter);
1549 function testHOTLOOPSize() {
1550     return HOTLOOP > 1;
1552 testHOTLOOPSize.expected = true;
1553 test(testHOTLOOPSize);
1555 function testGlobalProtoAccess() {
1556     return "ok";
1558 this.__proto__.a = 3; for (var j = 0; j < 4; ++j) { [a]; }
1559 testGlobalProtoAccess.expected = "ok";
1560 test(testGlobalProtoAccess);
1562 function testMatchStringObject() {
1563     var a = new String("foo");
1564     var b;
1565     for (i = 0; i < 300; i++) {
1566         b = a.match(/bar/);
1567     }
1568     return b;
1570 testMatchStringObject.expected = null;
1571 test(testMatchStringObject);
1573 function innerSwitch(k)
1575     var m = 0;
1577     switch (k)
1578     {
1579     case 0:
1580         m = 1;
1581         break;
1582     }
1584     return m;
1586 function testInnerSwitchBreak()
1588     var r = new Array(5);
1589     for (var i = 0; i < 5; i++)
1590     {
1591         r[i] = innerSwitch(0);
1592     }
1594     return r.join(",");
1596 testInnerSwitchBreak.expected = "1,1,1,1,1";
1597 test(testInnerSwitchBreak);
1599 function testArrayNaNIndex() 
1601     for (var j = 0; j < 4; ++j) { [this[NaN]]; }
1602     for (var j = 0; j < 5; ++j) { if([1][-0]) { } }
1603     return "ok";
1605 testArrayNaNIndex.expected = "ok";
1606 test(testArrayNaNIndex);
1608 function innerTestInnerMissingArgs(a,b,c,d)
1610         if (a) {
1611         } else {
1612         }
1614 function doTestInnerMissingArgs(k)
1616     for (i = 0; i < 10; i++) {
1617         innerTestInnerMissingArgs(k);
1618     }
1620 function testInnerMissingArgs()
1622     doTestInnerMissingArgs(1);
1623     doTestInnerMissingArgs(0);
1624     return 1;
1626 testInnerMissingArgs.expected = 1;  //Expected: that we don't crash.
1627 test(testInnerMissingArgs);
1629 /* Keep these at the end so that we can see the summary after the trace-debug spew. */
1630 print("\npassed:", passes.length && passes.join(","));
1631 print("\nFAILED:", fails.length && fails.join(","));