[JSC] Clean up Object.entries implementation
[WebKit-https.git] / JSTests / microbenchmarks / rest-parameter-allocation-elimination.js
1 function assert(b, m = "") {
2     if (!b)
3         throw new Error("Bad assertion: " + m);
4 }
5 noInline(assert);
6
7 const iterations = 20000;
8
9 function test1() {
10     function bar(a, b, ...args) {
11         return args.length;
12     }
13     noInline(bar);
14     for (let i = 0; i < iterations; i++) {
15         assert(bar() === 0, bar());
16         assert(bar(i) === 0);
17         assert(bar(i, i) === 0);
18         assert(bar(i, i, i) === 1);
19         assert(bar(i, i, i, i, i) === 3);
20     }
21 }
22
23 function shallowEq(a, b) {
24     if (a.length !== b.length)
25         return false;
26     for (let i = 0; i < a.length; i++) {
27         if (a.length !== b.length)
28             return false;
29     }
30     return true;
31 }
32 noInline(shallowEq);
33
34 function test2() {
35     function jaz(a, b, ...args) {
36         let result = [];
37         for (let i = 0; i < args.length; i++) {
38             result.push(args[i]);
39         }
40         return result;
41     }
42     noInline(jaz);
43
44     function jaz2(...args) {
45         function kaz(a, b, ...args) {
46             let result = [];
47             for (let i = 0; i < args.length; i++) {
48                 result.push(args[i]);
49             }
50             return result;
51         }
52         return kaz.apply(null, args);
53     }
54     noInline(jaz2);
55
56     for (let f of [jaz, jaz2]) {
57         for (let i = 0; i < iterations; i++) {
58             let r = f();
59             assert(!r.length);
60
61             r = f(i);
62             assert(!r.length);
63
64             r = f(i, i)
65             assert(!r.length);
66
67             r = f(i, i, i)
68             assert(r.length === 1);
69             assert(shallowEq(r, [i]));
70
71             r = f(i, i, i)
72             assert(r.length === 1);
73             assert(shallowEq(r, [i]));
74
75             r = f(i, i, i, i*2, i*4)
76             assert(r.length === 3);
77             assert(shallowEq(r, [i, i*2, i*4]));
78         }
79     }
80 }
81
82 function test3() {
83     function foo(...args) {
84         return args;
85     }
86     function baz(a, b, c, ...args) {
87         return foo.apply(null, args);
88     }
89     function jaz(a, b, c, d, e, f) {
90         return baz(a, b, c, d, e, f);
91     }
92     noInline(jaz);
93
94     for (let i = 0; i < iterations; i++) {
95         let r = jaz();
96         assert(r.length === 3);
97         assert(shallowEq(r, [undefined, undefined, undefined]));
98
99         r = jaz(i, i);
100         assert(r.length === 3);
101         assert(shallowEq(r, [undefined, undefined, undefined]));
102
103         r = jaz(i, i, i);
104         assert(r.length === 3);
105         assert(shallowEq(r, [undefined, undefined, undefined]));
106
107         r = jaz(i, i, i, i);
108         assert(r.length === 3);
109         assert(shallowEq(r, [i, undefined, undefined]));
110
111         r = jaz(i, i, i, i, i, i);
112         assert(r.length === 3);
113         assert(shallowEq(r, [i, i, i]));
114     }
115 }
116
117 function test4() {
118     function baz(...args) {
119         return args;
120     }
121     function jaz(a, b, ...args) {
122         return baz.apply(null, args);
123     }
124     noInline(jaz);
125
126     for (let i = 0; i < iterations; i++) {
127         let r = jaz();
128         assert(r.length === 0);
129
130         r = jaz(i);
131         assert(r.length === 0);
132
133         r = jaz(i, i);
134         assert(r.length === 0);
135
136         r = jaz(i, i, i);
137         assert(r.length === 1);
138         assert(shallowEq(r, [i]));
139
140         r = jaz(i, i, i, i*10);
141         assert(r.length === 2);
142         assert(shallowEq(r, [i, i*10]));
143
144         let o = {};
145         r = jaz(i, i, i, i*10, o);
146         assert(r.length === 3);
147         assert(shallowEq(r, [i, i*10, o]));
148     }
149 }
150
151 function test5() {
152     function baz(...args) {
153         return args;
154     }
155     noInline(baz);
156     function jaz(a, b, ...args) {
157         return baz.apply(null, args);
158     }
159     noInline(jaz);
160
161     for (let i = 0; i < iterations; i++) {
162         let r = jaz();
163         assert(r.length === 0);
164
165         r = jaz(i);
166         assert(r.length === 0);
167
168         r = jaz(i, i);
169         assert(r.length === 0);
170
171         r = jaz(i, i, i);
172         assert(r.length === 1);
173         assert(shallowEq(r, [i]));
174
175         r = jaz(i, i, i, i*10);
176         assert(r.length === 2);
177         assert(shallowEq(r, [i, i*10]));
178
179         let o = {};
180         r = jaz(i, i, i, i*10, o);
181         assert(r.length === 3);
182         assert(shallowEq(r, [i, i*10, o]));
183     }
184 }
185
186 function test6() {
187     "use strict";
188     function baz(...args) {
189         return args;
190     }
191     noInline(baz);
192     function jaz(a, b, ...args) {
193         return baz.apply(null, args);
194     }
195     noInline(jaz);
196
197     for (let i = 0; i < iterations; i++) {
198         let r = jaz();
199         assert(r.length === 0);
200
201         r = jaz(i);
202         assert(r.length === 0);
203
204         r = jaz(i, i);
205         assert(r.length === 0);
206
207         r = jaz(i, i, i);
208         assert(r.length === 1);
209         assert(shallowEq(r, [i]));
210
211         r = jaz(i, i, i, i*10);
212         assert(r.length === 2);
213         assert(shallowEq(r, [i, i*10]));
214
215         let o = {};
216         r = jaz(i, i, i, i*10, o);
217         assert(r.length === 3);
218         assert(shallowEq(r, [i, i*10, o]));
219     }
220 }
221
222 function test7() {
223     let shouldExit = false;
224     function baz(...args) {
225         if (shouldExit) {
226             OSRExit();
227             return [args.length, args[0], args[1], args[2]];
228         }
229         return [args.length, args[0], args[1], args[2]];
230     }
231     function jaz(a, b, ...args) {
232         return baz.apply(null, args);
233     }
234     noInline(jaz);
235
236     function check(i) {
237         let [length, a, b, c] = jaz();
238         assert(length === 0);
239         assert(a === undefined);
240         assert(b === undefined);
241         assert(c === undefined);
242
243         [length, a, b, c] = jaz(i);
244         assert(length === 0);
245         assert(a === undefined);
246         assert(b === undefined);
247         assert(c === undefined);
248
249         [length, a, b, c] = jaz(i, i);
250         assert(length === 0);
251         assert(a === undefined);
252         assert(b === undefined);
253         assert(c === undefined);
254
255         [length, a, b, c] = jaz(i, i, i);
256         assert(length === 1);
257         assert(a === i, JSON.stringify(a));
258         assert(b === undefined);
259         assert(c === undefined);
260
261         [length, a, b, c] = jaz(i, i, i, i*10);
262         assert(length === 2);
263         assert(a === i);
264         assert(b === i*10);
265         assert(c === undefined);
266
267         let o = {oooo:20};
268         [length, a, b, c] = jaz(i, i, i, i*10, o);
269         assert(length === 3);
270         assert(a === i);
271         assert(b === i*10);
272         assert(c === o);
273     }
274
275     shouldExit = true;
276     for (let i = 0; i < 400; i++) {
277         check(i);
278     }
279
280     shouldExit = false;
281     for (let i = 0; i < iterations; i++) {
282         check(i);
283     }
284
285     shouldExit = false;
286     check(10);
287 }
288
289 function test8() {
290     let shouldExit = false;
291     function baz(...args) {
292         if (shouldExit) {
293             OSRExit();
294             return args;
295         }
296         return args;
297     }
298     function jaz(a, b, ...args) {
299         return baz.apply(null, args);
300     }
301     noInline(jaz);
302
303     function check(i) {
304         let args = jaz();
305         assert(args.length === 0);
306
307         args = jaz(i);
308         assert(args.length === 0);
309
310         args = jaz(i, i);
311         assert(args.length === 0);
312
313         args = jaz(i, i, i);
314         assert(args.length === 1);
315         assert(args[0] === i);
316
317         args = jaz(i, i, i, i*10);
318         assert(args.length === 2);
319         assert(args[0] === i);
320         assert(args[1] === i*10);
321
322         let o = {oooo:20};
323         args = jaz(i, i, i, i*10, o);
324         assert(args.length === 3);
325         assert(args[0] === i);
326         assert(args[1] === i*10);
327         assert(args[2] === o);
328     }
329
330     shouldExit = true;
331     for (let i = 0; i < 400; i++) {
332         check(i);
333     }
334
335     shouldExit = false;
336     for (let i = 0; i < iterations; i++) {
337         check(i);
338     }
339
340     shouldExit = false;
341     check(10);
342 }
343
344 function test9() {
345     let shouldExit = false;
346     function baz(a, ...args) {
347         if (shouldExit) {
348             OSRExit();
349             return [args.length, args[0], args[1]];
350         }
351         return [args.length, args[0], args[1]];
352     }
353     function jaz(...args) {
354         return baz.apply(null, args);
355     }
356     noInline(jaz);
357
358     function check(i) {
359         let [length, a, b] = jaz();
360         assert(length === 0);
361
362         [length, a, b] = jaz(i);
363         assert(length === 0);
364         assert(a === undefined);
365         assert(b === undefined);
366
367         [length, a, b] = jaz(i, i + 1);
368         assert(length === 1);
369         assert(a === i+1);
370         assert(b === undefined);
371
372         [length, a, b] = jaz(i, i+1, i+2);
373         assert(length === 2);
374         assert(a === i+1);
375         assert(b === i+2);
376
377         let o = {oooo:20};
378         [length, a, b] = jaz(i, i+1, o);
379         assert(length === 2);
380         assert(a === i+1);
381         assert(b === o);
382     }
383
384     shouldExit = true;
385     for (let i = 0; i < 400; i++) {
386         check(i);
387     }
388
389     shouldExit = false;
390     for (let i = 0; i < iterations; i++) {
391         check(i);
392     }
393
394     shouldExit = false;
395     check(10);
396 }
397
398 function test10() {
399     function baz(a, b, c, ...args) {
400         return [args.length, args[0], args[1], args[2], args[3]];
401     }
402     function jaz(a, b, c, d, e, f) {
403         return baz(a, b, c, d, e, f);
404     }
405     noInline(jaz);
406
407     for (let i = 0; i < iterations; i++) {
408         let [length, a, b, c, d] = jaz(1, 2, 3, 4, 5, 6);
409         assert(length === 3);
410         assert(a === 4);
411         assert(b === 5);
412         assert(c === 6);
413         assert(d === undefined);
414     }
415 }
416
417 function test11() {
418     function bar(...args) {
419         return args;
420     }
421     noInline(bar);
422
423     function foo(a, b, c, d, ...args) {
424         return bar.apply(null, args);
425     }
426     noInline(foo);
427
428     function makeArguments(args) {
429         return [1,2,3,4, ...args];
430     }
431     for (let i = 0; i < iterations; i++) {
432         function test() { assert(shallowEq(a, foo.apply(null, makeArguments(a)))); }
433         let a = [{}, 25, 50];
434         test();
435
436         a = [];
437         test();
438
439         a = [{foo: 20}];
440         test();
441
442         a = [10, 20, 30, 40, 50, 60, 70, 80];
443         test();
444     }
445 }
446
447 function test12() {
448     "use strict";
449     let thisValue = {};
450     function getThisValue() { return thisValue; }
451     noInline(getThisValue);
452
453     function bar(...args) {
454         assert(this === thisValue);
455         return args;
456     }
457     noInline(bar);
458
459     function foo(a, b, c, d, ...args) {
460         return bar.apply(getThisValue(), args);
461     }
462     noInline(foo);
463
464     function makeArguments(args) {
465         return [1,2,3,4, ...args];
466     }
467     for (let i = 0; i < iterations; i++) {
468         function test() { assert(shallowEq(a, foo.apply(null, makeArguments(a)))); }
469         let a = [{}, 25, 50];
470         test();
471
472         a = [];
473         test();
474
475         a = [{foo: 20}];
476         test();
477
478         a = [10, 20, 30, 40, 50, 60, 70, 80];
479         test();
480     }
481 }
482
483 function test13() {
484     "use strict";
485     function bar(...args) {
486         return args;
487     }
488     noInline(bar);
489
490     function top(a, b, c, d, ...args) {
491         return bar.apply(null, args);
492     }
493     function foo(...args) {
494         let r = top.apply(null, args);
495         return r;
496     }
497     noInline(foo);
498
499     function makeArguments(args) {
500         return [1,2,3,4, ...args];
501     }
502     for (let i = 0; i < iterations; i++) {
503         function test() { assert(shallowEq(a, foo.apply(null, makeArguments(a)))); }
504         let a = [{}, 25, 50];
505         test();
506
507         a = [];
508         test();
509
510         a = [10, 20, 30, 40, 50, 60, 70, 80];
511         test();
512     }
513 }
514
515 function test14() {
516     "use strict";
517     function bar(...args) {
518         return args;
519     }
520     noInline(bar);
521
522     function top(a, b, c, d, ...args) {
523         return bar.apply(null, args);
524     }
525     function foo(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17) {
526         return top(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17);
527     }
528     noInline(foo);
529
530     function makeArguments(args) {
531         let r = [1,2,3,4, ...args];
532         while (r.length < foo.length)
533             r.push(undefined);
534         return r;
535     }
536     for (let i = 0; i < iterations; i++) {
537         function test()
538         {
539             let args = makeArguments(a);
540             assert(shallowEq(args.slice(4), foo.apply(null, args)));
541         }
542
543         let a = [{}, 25, 50];
544         test();
545
546         a = [];
547         test();
548
549         a = [10, 20, 30, 40, 50, 60, 70, 80];
550         test();
551     }
552 }
553
554 function test15() {
555     "use strict";
556     function bar(...args) {
557         return args;
558     }
559     noInline(bar);
560
561     function top(a, b, c, d, ...args) {
562         return bar.apply(null, args);
563     }
564     function foo(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17) {
565         let r = top(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17);
566         return r;
567     }
568     noInline(foo);
569
570     function makeArguments(args) {
571         let r = [1,2,3,4, ...args];
572         while (r.length < foo.length)
573             r.push(undefined);
574         return r;
575     }
576     for (let i = 0; i < iterations; i++) {
577         function test()
578         {
579             let args = makeArguments(a);
580             assert(shallowEq(args.slice(4), foo.apply(null, args)));
581         }
582
583         let a = [{}, 25, 50];
584         test();
585
586         a = [];
587         test();
588
589         a = [10, 20, 30, 40, 50, 60, 70, 80];
590         test();
591     }
592 }
593
594 let start = Date.now();
595 test1();
596 test2();
597 test3();
598 test4();
599 test5();
600 test6();
601 test7();
602 test8();
603 test9();
604 test10();
605 test11();
606 test12();
607 test13();
608 test14();
609 test15();
610 const verbose = false;
611 if (verbose)
612     print(Date.now() - start);
613