1257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Copyright 2011 the V8 project authors. All rights reserved. 2257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Redistribution and use in source and binary forms, with or without 3257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// modification, are permitted provided that the following conditions are 4257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// met: 5257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// 6257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// * Redistributions of source code must retain the above copyright 7257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// notice, this list of conditions and the following disclaimer. 8257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// * Redistributions in binary form must reproduce the above 9257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// copyright notice, this list of conditions and the following 10257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// disclaimer in the documentation and/or other materials provided 11257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// with the distribution. 12257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// * Neither the name of Google Inc. nor the names of its 13257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// contributors may be used to endorse or promote products derived 14257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// from this software without specific prior written permission. 15257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// 16257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 28257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Flags: --allow-natives-syntax 29257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 30257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch/** 31257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch * This class shows how to use %GetOptimizationCount() and 32257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch * %GetOptimizationStatus() to infer information about opts and deopts. 33257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch * Might be nice to put this into mjsunit.js, but that doesn't depend on 34257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch * the --allow-natives-syntax flag so far. 35257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch */ 36257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochfunction OptTracker() { 37257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch this.opt_counts_ = {}; 38257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 39257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 40257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch/** 41257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch * The possible optimization states of a function. Must be in sync with the 42257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch * return values of Runtime_GetOptimizationStatus() in runtime.cc! 43257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch * @enum {int} 44257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch */ 45257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochOptTracker.OptimizationState = { 46257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch YES: 1, 47257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch NO: 2, 48257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ALWAYS: 3, 49257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch NEVER: 4 50257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}; 51257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 52257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch/** 53257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch * Always call this at the beginning of your test, once for each function 54257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch * that you later want to track de/optimizations for. It is necessary because 55257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch * tests are sometimes executed several times in a row, and you want to 56257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch * disregard counts from previous runs. 5769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch */ 58257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochOptTracker.prototype.CheckpointOptCount = function(func) { 59257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch this.opt_counts_[func] = %GetOptimizationCount(func); 60257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}; 61257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 62257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochOptTracker.prototype.AssertOptCount = function(func, optcount) { 63257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (this.DisableAsserts_(func)) { 64257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return; 65257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 66257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch assertEquals(optcount, this.GetOptCount_(func)); 67257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}; 68257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 69257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochOptTracker.prototype.AssertDeoptCount = function(func, deopt_count) { 70257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (this.DisableAsserts_(func)) { 71257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return; 72257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 73257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch assertEquals(deopt_count, this.GetDeoptCount_(func)); 74257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}; 75257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 76257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochOptTracker.prototype.AssertDeoptHappened = function(func, expect_deopt) { 77257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (this.DisableAsserts_(func)) { 78257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return; 79257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 80257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (expect_deopt) { 81257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch assertTrue(this.GetDeoptCount_(func) > 0); 82257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 83257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch assertEquals(0, this.GetDeoptCount_(func)); 84257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 85257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 86257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 87257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochOptTracker.prototype.AssertIsOptimized = function(func, expect_optimized) { 88257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (this.DisableAsserts_(func)) { 89257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return; 90257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 91257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch var raw_optimized = %GetOptimizationStatus(func); 92257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (expect_optimized) { 93257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch assertEquals(OptTracker.OptimizationState.YES, raw_optimized); 94257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 95257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch assertEquals(OptTracker.OptimizationState.NO, raw_optimized); 96257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 97257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 98257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 99257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch/** 100257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch * @private 101257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch */ 102257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochOptTracker.prototype.GetOptCount_ = function(func) { 103257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch var raw_count = %GetOptimizationCount(func); 104257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (func in this.opt_counts_) { 105257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch var checkpointed_count = this.opt_counts_[func]; 106257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return raw_count - checkpointed_count; 107257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 108257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return raw_count; 109257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 110257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 111257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch/** 112257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch * @private 113257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch */ 114257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochOptTracker.prototype.GetDeoptCount_ = function(func) { 115257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch var count = this.GetOptCount_(func); 116257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (%GetOptimizationStatus(func) == OptTracker.OptimizationState.YES) { 117257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch count -= 1; 118257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 119257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return count; 120257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 121257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 122257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch/** 123257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch * @private 124257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch */ 125257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochOptTracker.prototype.DisableAsserts_ = function(func) { 126257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch switch(%GetOptimizationStatus(func)) { 127257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch case OptTracker.OptimizationState.YES: 128257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch case OptTracker.OptimizationState.NO: 129257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return false; 130257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch case OptTracker.OptimizationState.ALWAYS: 131257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch case OptTracker.OptimizationState.NEVER: 132257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return true; 133257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 134257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return false; 135257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 136257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// (End of class OptTracker.) 137257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 138257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Example function used by the test below. 139257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochfunction f(a) { 140257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return a+1; 141257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 142257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 143257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvar tracker = new OptTracker(); 144257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochtracker.CheckpointOptCount(f); 145257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 146257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochtracker.AssertOptCount(f, 0); 147257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochtracker.AssertIsOptimized(f, false); 148257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochtracker.AssertDeoptHappened(f, false); 149257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochtracker.AssertDeoptCount(f, 0); 150257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 15169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochf(1); 152257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 153257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch%OptimizeFunctionOnNextCall(f); 154257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochf(1); 155257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 156257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochtracker.AssertOptCount(f, 1); 157257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochtracker.AssertIsOptimized(f, true); 158257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochtracker.AssertDeoptHappened(f, false); 159257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochtracker.AssertDeoptCount(f, 0); 160257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 161257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch%DeoptimizeFunction(f); 162257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 163257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochtracker.AssertOptCount(f, 1); 164257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochtracker.AssertIsOptimized(f, false); 165257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochtracker.AssertDeoptHappened(f, true); 166257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochtracker.AssertDeoptCount(f, 1); 167257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 168257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Let's trigger optimization for another type. 169257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochfor (var i = 0; i < 5; i++) f("a"); 1703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 171257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch%OptimizeFunctionOnNextCall(f); 172257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochf("b"); 173257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 174257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochtracker.AssertOptCount(f, 2); 175257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochtracker.AssertIsOptimized(f, true); 176257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochtracker.AssertDeoptHappened(f, true); 177257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochtracker.AssertDeoptCount(f, 1); 178