| // Copyright 2012 the V8 project authors. All rights reserved. | 
 | // Redistribution and use in source and binary forms, with or without | 
 | // modification, are permitted provided that the following conditions are | 
 | // met: | 
 | // | 
 | //     * Redistributions of source code must retain the above copyright | 
 | //       notice, this list of conditions and the following disclaimer. | 
 | //     * Redistributions in binary form must reproduce the above | 
 | //       copyright notice, this list of conditions and the following | 
 | //       disclaimer in the documentation and/or other materials provided | 
 | //       with the distribution. | 
 | //     * Neither the name of Google Inc. nor the names of its | 
 | //       contributors may be used to endorse or promote products derived | 
 | //       from this software without specific prior written permission. | 
 | // | 
 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 
 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 
 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 
 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 
 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 
 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 
 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 
 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 
 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 
 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
 |  | 
 | // Flags: --allow-natives-syntax --expose-gc --ignition-osr --no-always-opt | 
 | // Flags: --opt | 
 |  | 
 | // IC and Crankshaft support for smi-only elements in dynamic array literals. | 
 | function get(foo) { return foo; }  // Used to generate dynamic values. | 
 |  | 
 | function array_literal_test() { | 
 |   var a0 = [1, 2, 3]; | 
 |   assertTrue(%HasSmiElements(a0)); | 
 |   var a1 = [get(1), get(2), get(3)]; | 
 |   assertTrue(%HasSmiElements(a1)); | 
 |  | 
 |   var b0 = [1, 2, get("three")]; | 
 |   assertTrue(%HasObjectElements(b0)); | 
 |   var b1 = [get(1), get(2), get("three")]; | 
 |   assertTrue(%HasObjectElements(b1)); | 
 |  | 
 |   var c0 = [1, 2, get(3.5)]; | 
 |   assertTrue(%HasDoubleElements(c0)); | 
 |   assertEquals(3.5, c0[2]); | 
 |   assertEquals(2, c0[1]); | 
 |   assertEquals(1, c0[0]); | 
 |  | 
 |   var c1 = [1, 2, 3.5]; | 
 |   assertTrue(%HasDoubleElements(c1)); | 
 |   assertEquals(3.5, c1[2]); | 
 |   assertEquals(2, c1[1]); | 
 |   assertEquals(1, c1[0]); | 
 |  | 
 |   var c2 = [get(1), get(2), get(3.5)]; | 
 |   assertTrue(%HasDoubleElements(c2)); | 
 |   assertEquals(3.5, c2[2]); | 
 |   assertEquals(2, c2[1]); | 
 |   assertEquals(1, c2[0]); | 
 |  | 
 |   var object = new Object(); | 
 |   var d0 = [1, 2, object]; | 
 |   assertTrue(%HasObjectElements(d0)); | 
 |   assertEquals(object, d0[2]); | 
 |   assertEquals(2, d0[1]); | 
 |   assertEquals(1, d0[0]); | 
 |  | 
 |   var e0 = [1, 2, 3.5]; | 
 |   assertTrue(%HasDoubleElements(e0)); | 
 |   assertEquals(3.5, e0[2]); | 
 |   assertEquals(2, e0[1]); | 
 |   assertEquals(1, e0[0]); | 
 |  | 
 |   var f0 = [1, 2, [1, 2]]; | 
 |   assertTrue(%HasObjectElements(f0)); | 
 |   assertEquals([1,2], f0[2]); | 
 |   assertEquals(2, f0[1]); | 
 |   assertEquals(1, f0[0]); | 
 | } | 
 | %PrepareFunctionForOptimization(array_literal_test); | 
 |  | 
 | %PrepareFunctionForOptimization(array_literal_test); | 
 | for (var i = 0; i < 3; i++) { | 
 |   array_literal_test(); | 
 | } | 
 |   %OptimizeFunctionOnNextCall(array_literal_test); | 
 | array_literal_test(); | 
 |  | 
 | function test_large_literal() { | 
 |  | 
 |   function d() { | 
 |     gc(); | 
 |     return 2.5; | 
 |   } | 
 |  | 
 |   function o() { | 
 |     gc(); | 
 |     return new Object(); | 
 |   } | 
 |  | 
 |   large = | 
 |     [ 0, 1, 2, 3, 4, 5, d(), d(), d(), d(), d(), d(), o(), o(), o(), o() ]; | 
 |   assertFalse(%HasDictionaryElements(large)); | 
 |   assertFalse(%HasSmiElements(large)); | 
 |   assertFalse(%HasDoubleElements(large)); | 
 |   assertTrue(%HasObjectElements(large)); | 
 |   assertEquals(large, | 
 |                [0, 1, 2, 3, 4, 5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, | 
 |                 new Object(), new Object(), new Object(), new Object()]); | 
 | } | 
 | %PrepareFunctionForOptimization(test_large_literal); | 
 |  | 
 | %PrepareFunctionForOptimization(test_large_literal); | 
 | for (var i = 0; i < 3; i++) { | 
 |   test_large_literal(); | 
 | } | 
 |   %OptimizeFunctionOnNextCall(test_large_literal); | 
 | test_large_literal(); | 
 |  | 
 | function deopt_array(use_literal) { | 
 |   if (use_literal) { | 
 |     return [.5, 3, 4]; | 
 |   }  else { | 
 |     return new Array(); | 
 |   } | 
 | } | 
 | %PrepareFunctionForOptimization(deopt_array); | 
 |  | 
 | %PrepareFunctionForOptimization(deopt_array); | 
 | deopt_array(false); | 
 | deopt_array(false); | 
 | deopt_array(false); | 
 |   %OptimizeFunctionOnNextCall(deopt_array); | 
 | var array = deopt_array(false); | 
 | assertOptimized(deopt_array); | 
 | deopt_array(true); | 
 | assertOptimized(deopt_array); | 
 | array = deopt_array(false); | 
 | assertOptimized(deopt_array); | 
 |  | 
 | // Check that unexpected changes in the objects stored into the boilerplate | 
 | // also force a deopt. | 
 | function deopt_array_literal_all_smis(a) { | 
 |   return [0, 1, a]; | 
 | } | 
 | %PrepareFunctionForOptimization(deopt_array_literal_all_smis); | 
 |  | 
 | %PrepareFunctionForOptimization(deopt_array_literal_all_smis); | 
 | deopt_array_literal_all_smis(2); | 
 | deopt_array_literal_all_smis(3); | 
 | deopt_array_literal_all_smis(4); | 
 | array = deopt_array_literal_all_smis(4); | 
 | assertEquals(0, array[0]); | 
 | assertEquals(1, array[1]); | 
 | assertEquals(4, array[2]); | 
 | %OptimizeFunctionOnNextCall(deopt_array_literal_all_smis); | 
 | array = deopt_array_literal_all_smis(5); | 
 | array = deopt_array_literal_all_smis(6); | 
 | assertOptimized(deopt_array_literal_all_smis); | 
 | assertEquals(0, array[0]); | 
 | assertEquals(1, array[1]); | 
 | assertEquals(6, array[2]); | 
 |  | 
 | array = deopt_array_literal_all_smis(.5); | 
 | assertUnoptimized(deopt_array_literal_all_smis); | 
 | assertEquals(0, array[0]); | 
 | assertEquals(1, array[1]); | 
 | assertEquals(.5, array[2]); | 
 |  | 
 | function deopt_array_literal_all_doubles(a) { | 
 |   return [0.5, 1, a]; | 
 | } | 
 | %PrepareFunctionForOptimization(deopt_array_literal_all_doubles); | 
 |  | 
 | %PrepareFunctionForOptimization(deopt_array_literal_all_doubles); | 
 | deopt_array_literal_all_doubles(.5); | 
 | deopt_array_literal_all_doubles(.5); | 
 | deopt_array_literal_all_doubles(.5); | 
 | array = deopt_array_literal_all_doubles(0.5); | 
 | assertEquals(0.5, array[0]); | 
 | assertEquals(1, array[1]); | 
 | assertEquals(0.5, array[2]); | 
 | %OptimizeFunctionOnNextCall(deopt_array_literal_all_doubles); | 
 | array = deopt_array_literal_all_doubles(5); | 
 | array = deopt_array_literal_all_doubles(6); | 
 | assertOptimized(deopt_array_literal_all_doubles); | 
 | assertEquals(0.5, array[0]); | 
 | assertEquals(1, array[1]); | 
 | assertEquals(6, array[2]); | 
 |  | 
 | var foo = new Object(); | 
 | array = deopt_array_literal_all_doubles(foo); | 
 | assertUnoptimized(deopt_array_literal_all_doubles); | 
 | assertEquals(0.5, array[0]); | 
 | assertEquals(1, array[1]); | 
 | assertEquals(foo, array[2]); | 
 |  | 
 | (function literals_after_osr() { | 
 |   var color = [0]; | 
 |   // Trigger OSR. | 
 |   while ((%GetOptimizationStatus(literals_after_osr) & | 
 |     V8OptimizationStatus.kTopmostFrameIsTurboFanned) !== 0) {} | 
 |   return [color[0]]; | 
 | })(); |