| function sumOfArithSeries(limit) { |
| return limit * (limit + 1) / 2; |
| } |
| |
| var n = 10000000; |
| |
| function bar() { } |
| |
| function verify(q, i) { |
| if (q.f == q.g) |
| throw "Error: q.f == q.g"; |
| if (q.f.f != q.g.f) |
| throw "Error: q.f.f != q.g.f"; |
| if (q.f.f.f != i) |
| throw "Error: q.f.f.f != i"; |
| } |
| |
| function foo() { |
| var result = 0; |
| for (var i = 0; i < n; ++i) { |
| var leaf = {f:i}; |
| var o = {f:leaf}; |
| var p = {f:leaf}; |
| var q = {f:o, g:p}; |
| result += q.f.f.f; |
| if (i >= n - 100) { |
| // We want the materialization to happen in the exit. So, before calling the thing that |
| // causes the materialization, we call bar(). We've never profiled this call at the time |
| // of FTL compilation, so this should be an exit. |
| bar(); |
| verify(q, i); |
| } |
| } |
| return result; |
| } |
| |
| noInline(foo); |
| noInline(verify); |
| noInline(bar); |
| |
| var result = foo(); |
| if (result != sumOfArithSeries(n - 1)) |
| throw "Error: bad result: " + result; |