178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org// Copyright 2012 the V8 project authors. All rights reserved.
278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org// Redistribution and use in source and binary forms, with or without
378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org// modification, are permitted provided that the following conditions are
478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org// met:
578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org//
678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org//     * Redistributions of source code must retain the above copyright
778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org//       notice, this list of conditions and the following disclaimer.
878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org//     * Redistributions in binary form must reproduce the above
978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org//       copyright notice, this list of conditions and the following
1078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org//       disclaimer in the documentation and/or other materials provided
1178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org//       with the distribution.
1278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org//     * Neither the name of Google Inc. nor the names of its
1378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org//       contributors may be used to endorse or promote products derived
1478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org//       from this software without specific prior written permission.
1578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org//
1678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
2837be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org// Flags: --max-new-space-size=128 --allow-natives-syntax
2978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
3078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org// Test inlining of Math.floor when assigned to a local.
3178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.orgvar test_id = 0;
3278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
3378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.orgfunction testFloor(expect, input) {
3478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  var test = new Function('n',
3578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org                          '"' + (test_id++) +
3678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org                          '";var f = Math.floor; return f(n)');
3778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  assertEquals(expect, test(input));
3878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  assertEquals(expect, test(input));
3978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  assertEquals(expect, test(input));
4078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  %OptimizeFunctionOnNextCall(test);
4178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  assertEquals(expect, test(input));
4278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org}
4378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
4478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.orgfunction zero() {
4578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  var x = 0.5;
4678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  return (function() { return x - 0.5; })();
4778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org}
4878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
4978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.orgfunction test() {
5078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(0, 0);
5178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(0, zero());
5278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(-0, -0);
5378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(Infinity, Infinity);
5478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(-Infinity, -Infinity);
5578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(NaN, NaN);
5678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
5778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  // Ensure that a negative zero coming from Math.floor is properly handled
5878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  // by other operations.
5978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  function ifloor(x) {
6078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    return 1 / Math.floor(x);
6178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  }
6278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  assertEquals(-Infinity, ifloor(-0));
6378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  assertEquals(-Infinity, ifloor(-0));
6478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  assertEquals(-Infinity, ifloor(-0));
6578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  %OptimizeFunctionOnNextCall(ifloor);
6678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  assertEquals(-Infinity, ifloor(-0));
6778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
6878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(0, 0.1);
6978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(0, 0.49999999999999994);
7078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(0, 0.5);
7178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(0, 0.7);
7278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(-1, -0.1);
7378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(-1, -0.49999999999999994);
7478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(-1, -0.5);
7578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(-1, -0.7);
7678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(1, 1);
7778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(1, 1.1);
7878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(1, 1.5);
7978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(1, 1.7);
8078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(-1, -1);
8178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(-2, -1.1);
8278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(-2, -1.5);
8378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(-2, -1.7);
8478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
8578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(0, Number.MIN_VALUE);
8678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(-1, -Number.MIN_VALUE);
8778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(Number.MAX_VALUE, Number.MAX_VALUE);
8878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(-Number.MAX_VALUE, -Number.MAX_VALUE);
8978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(Infinity, Infinity);
9078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(-Infinity, -Infinity);
9178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
9278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  // 2^30 is a smi boundary.
9378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  var two_30 = 1 << 30;
9478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
9578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(two_30, two_30);
9678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(two_30, two_30 + 0.1);
9778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(two_30, two_30 + 0.5);
9878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(two_30, two_30 + 0.7);
9978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
10078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(two_30 - 1, two_30 - 1);
10178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(two_30 - 1, two_30 - 1 + 0.1);
10278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(two_30 - 1, two_30 - 1 + 0.5);
10378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(two_30 - 1, two_30 - 1 + 0.7);
10478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
10578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(-two_30, -two_30);
10678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(-two_30, -two_30 + 0.1);
10778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(-two_30, -two_30 + 0.5);
10878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(-two_30, -two_30 + 0.7);
10978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
11078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(-two_30 + 1, -two_30 + 1);
11178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(-two_30 + 1, -two_30 + 1 + 0.1);
11278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(-two_30 + 1, -two_30 + 1 + 0.5);
11378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(-two_30 + 1, -two_30 + 1 + 0.7);
11478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
11578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  // 2^52 is a precision boundary.
11678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  var two_52 = (1 << 30) * (1 << 22);
11778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
11878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(two_52, two_52);
11978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(two_52, two_52 + 0.1);
12078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  assertEquals(two_52, two_52 + 0.5);
12178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(two_52, two_52 + 0.5);
12278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  assertEquals(two_52 + 1, two_52 + 0.7);
12378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(two_52 + 1, two_52 + 0.7);
12478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
12578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(two_52 - 1, two_52 - 1);
12678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(two_52 - 1, two_52 - 1 + 0.1);
12778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(two_52 - 1, two_52 - 1 + 0.5);
12878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(two_52 - 1, two_52 - 1 + 0.7);
12978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
13078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(-two_52, -two_52);
13178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(-two_52, -two_52 + 0.1);
13278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(-two_52, -two_52 + 0.5);
13378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(-two_52, -two_52 + 0.7);
13478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
13578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(-two_52 + 1, -two_52 + 1);
13678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(-two_52 + 1, -two_52 + 1 + 0.1);
13778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(-two_52 + 1, -two_52 + 1 + 0.5);
13878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  testFloor(-two_52 + 1, -two_52 + 1 + 0.7);
13978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org}
14078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
14178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
14278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org// Test in a loop to cover the custom IC and GC-related issues.
14337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.orgfor (var i = 0; i < 10; i++) {
14478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  test();
14537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  new Array(i * 10000);
14678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org}
14778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
14878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
14978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org// Regression test for a bug where a negative zero coming from Math.floor
15078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org// was not properly handled by other operations.
15178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.orgfunction floorsum(i, n) {
15278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  var ret = Math.floor(n);
15378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  while (--i > 0) {
15478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    ret += Math.floor(n);
15578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  }
15678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  return ret;
15778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org}
15878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.orgassertEquals(-0, floorsum(1, -0));
15978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org%OptimizeFunctionOnNextCall(floorsum);
16078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org// The optimized function will deopt.  Run it with enough iterations to try
16178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org// to optimize via OSR (triggering the bug).
16278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.orgassertEquals(-0, floorsum(100000, -0));
163