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