1e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org// Copyright 2011 the V8 project authors. All rights reserved. 2e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org// Redistribution and use in source and binary forms, with or without 3e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org// modification, are permitted provided that the following conditions are 4e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org// met: 5e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org// 6e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org// * Redistributions of source code must retain the above copyright 7e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org// notice, this list of conditions and the following disclaimer. 8e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org// * Redistributions in binary form must reproduce the above 9e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org// copyright notice, this list of conditions and the following 10e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org// disclaimer in the documentation and/or other materials provided 11e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org// with the distribution. 12e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org// * Neither the name of Google Inc. nor the names of its 13e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org// contributors may be used to endorse or promote products derived 14e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org// from this software without specific prior written permission. 15e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org// 16e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 28e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org// Flags: --allow-natives-syntax --max-opt-count=100 --noalways-opt 29e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 30e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org// We specify max-opt-count because we opt/deopt the same function many 31e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org// times. 32e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 33e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org// It's nice to run this in other browsers too. 34e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.orgvar standalone = false; 35e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.orgif (standalone) { 36e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org assertTrue = function(val) { 37e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org if (val != true) { 38e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org print("FAILURE"); 39e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 40e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 41e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 42e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org assertFalse = function(val) { 43e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org if (val != false) { 44e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org print("FAILURE"); 45e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 46e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 47e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 48e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org assertEquals = function(expected, val) { 49e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org if (expected !== val) { 50e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org print("FAILURE"); 51e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 52e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 53e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 54e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org empty_func = function(name) { } 55e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org assertUnoptimized = empty_func; 56e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org assertOptimized = empty_func; 57e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 58e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org optimize = empty_func; 59e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org clearFunctionTypeFeedback = empty_func; 60e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org deoptimizeFunction = empty_func; 61e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org} else { 62e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org optimize = function(name) { 63e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org %OptimizeFunctionOnNextCall(name); 64e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 65e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org clearFunctionTypeFeedback = function(name) { 66e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org %ClearFunctionTypeFeedback(name); 67e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 68e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org deoptimizeFunction = function(name) { 69e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org %DeoptimizeFunction(name); 70e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 71e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org} 72e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 73e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.orgfunction base_setter_test(create_func, index, store_value) { 74e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org var calls = 0; 75e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 76e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org // Testcase: setter in prototype chain 77e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org foo = function(a) { a[index] = store_value; } 78e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org var a = create_func(); 79e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org var ap = []; 80e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org ap.__defineSetter__(index, function() { calls++; }); 81e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 82e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org foo(a); 83e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org foo(a); 84e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org foo(a); 85e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org delete a[index]; 86e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 87e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org assertEquals(0, calls); 88e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org a.__proto__ = ap; 89e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org foo(a); 90e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org assertEquals(1, calls); 91e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org optimize(foo); 92e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org foo(a); 93e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org assertEquals(2, calls); 94e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org assertOptimized(foo); 95e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 96e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org // Testcase: setter added on prototype chain object already in place. 97e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org clearFunctionTypeFeedback(foo); 98e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org deoptimizeFunction(foo); 99e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org clearFunctionTypeFeedback(foo); 100e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org calls = 0; 101e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org a = create_func(); 102e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org var apap = []; 103e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org a.__proto__ = apap; 104e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org foo(a); 105e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org foo(a); 106e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org foo(a); 107e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org delete a[index]; 108e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org apap.__defineSetter__(index, function() { calls++; }); 109e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org foo(a); 110e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org foo(a); 111e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org foo(a); 112e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org assertEquals(3, calls); 113e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 114e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org // Testcase: setter "deep" in prototype chain. 115e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org clearFunctionTypeFeedback(foo); 116e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org deoptimizeFunction(foo); 117e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org clearFunctionTypeFeedback(foo); 118e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org calls = 0; 119e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 120e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org a = create_func(); 121e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org var ap2 = []; 122e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org a.__proto__ = ap2; 123e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org foo(a); 124e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org foo(a); 125e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org foo(a); 126e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org delete a[index]; 127e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 128e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org assertEquals(0, calls); 129e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 130e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org ap2.__proto__ = ap; // "sneak" in a callback. 131e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org // The sneak case should be caught by unoptimized code too. 132e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org assertUnoptimized(foo); 133e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org foo(a); 134e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org foo(a); 135e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org foo(a); 136e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org assertEquals(3, calls); 137e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 138e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org // Testcase: setter added after optimization (feedback is monomorphic) 139e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org clearFunctionTypeFeedback(foo); 140e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org deoptimizeFunction(foo); 141e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org clearFunctionTypeFeedback(foo); 142e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org calls = 0; 143e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 144e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org a = create_func(); 145e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org ap2 = []; 146e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org a.__proto__ = ap2; 147e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org foo(a); 148e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org foo(a); 149e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org foo(a); 150e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org optimize(foo); 151e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org foo(a); 152e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org assertOptimized(foo); 153e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org delete a[index]; 154e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org ap2.__proto__ = ap; 155e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org foo(a); 156e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org assertUnoptimized(foo); // map shape change should deopt foo. 157e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org assertEquals(1, calls); 158e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 159e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org // Testcase: adding additional setters to a prototype chain that already has 160e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org // one shouldn't deopt anything. (ie, we aren't changing the map shape). 161e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org clearFunctionTypeFeedback(foo); 162e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org calls = 0; 163e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 164e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org a = create_func(); 165e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org a.__proto__ = ap2; 166e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org bar = function(a) { a[index+1] = store_value; } 167e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org bar(a); 168e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org bar(a); 169e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org bar(a); // store should be generic 170e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org optimize(bar); 171e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org bar(a); 172e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org assertOptimized(bar); 173e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org assertEquals(0, calls); 174e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org delete a[index+1]; 175e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org ap2.__defineSetter__(index+1, function() { calls++; }); 176e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org bar(a); 177e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org assertOptimized(bar); 178e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org assertEquals(1, calls); 179e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org} 180e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 181e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org// Verify that map transitions don't confuse us. 182e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.orgcreate_func_smi = function() { return [,,,,,,5]; } 183e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.orgcreate_func_double = function() { return [0,,3.2,,,,5.5]; } 184e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.orgcreate_func_fast = function() { return [,,,,,,true]; } 185e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.orgcreate_func_dictionary = function() { var a = []; a.length = 100000; return a; } 186e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 187e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.orgvar cf = [create_func_smi, 188e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org create_func_double, 189e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org create_func_fast, 190e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org create_func_dictionary]; 191e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 192e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.orgvar values = [3, 3.5, true]; 193e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 194e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.orgfor(var c = 0; c < 3; c++) { 195e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org for(var s = 0; s < 3; s++) { 196e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org base_setter_test(cf[c], 0, values[s]); 197e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org base_setter_test(cf[c], 1, values[s]); 198e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 199e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org} 200