1 /* 2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #include "precompiled.hpp" 26 #include "interpreter/invocationCounter.hpp" 27 #include "runtime/frame.hpp" 28 #include "runtime/handles.inline.hpp" 29 30 31 // Implementation of InvocationCounter 32 33 void InvocationCounter::init() { 34 _counter = 0; // reset all the bits, including the sticky carry 35 } 36 37 void InvocationCounter::reset() { 38 uint counter = raw_counter(); 39 int init = 0; 40 // prevent from going to zero, to distinguish from never-executed methods 41 if (count(counter) > 0) { 42 init = 1; 43 } 44 counter = (init << number_of_noncount_bits) | (counter & carry_mask); 45 set_raw(counter); 46 } 47 48 void InvocationCounter::set_carry_and_reduce() { 49 // single read 50 uint counter = raw_counter(); 51 52 //update 53 set_carry_flag(&counter); 54 int old_count = count(counter); 55 int new_count = MIN2(old_count, (int) (CompileThreshold / 2)); 56 // prevent from going to zero, to distinguish from never-executed methods 57 if (new_count == 0) { 58 new_count = 1; 59 } 60 if (old_count != new_count) { 61 set_count(&counter, new_count); 62 } 63 64 // single write 65 set_raw(counter); 66 } 67 68 void InvocationCounter::set_carry_if_necessary() { 69 // single read 70 uint counter = raw_counter(); 71 72 //update 73 if (!carry(counter) && count(counter) > count_limit / 2) { 74 set_carry_flag(&counter); 75 set_raw(counter); 76 } 77 } 78 79 void InvocationCounter::print() { 80 tty->print_cr("invocation count: up = %d, carry = %s", 81 count(), carry() ? "true" : "false"); 82 } 83 84 void InvocationCounter::print_short() { 85 tty->print(" [%d%s]", count(), carry()?"+carry":""); 86 } 87 88 // Initialization 89 int InvocationCounter::InterpreterInvocationLimit; 90 int InvocationCounter::InterpreterBackwardBranchLimit; 91 int InvocationCounter::InterpreterProfileLimit; 92 93 void InvocationCounter::reinitialize(bool delay_overflow) { 94 InterpreterInvocationLimit = CompileThreshold << number_of_noncount_bits; 95 InterpreterProfileLimit = ((CompileThreshold * InterpreterProfilePercentage) / 100)<< number_of_noncount_bits; 96 97 // When methodData is collected, the backward branch limit is compared against a 98 // methodData counter, rather than an InvocationCounter. In the former case, we 99 // don't need the shift by number_of_noncount_bits, but we do need to adjust 100 // the factor by which we scale the threshold. 101 if (ProfileInterpreter) { 102 InterpreterBackwardBranchLimit = (CompileThreshold * (OnStackReplacePercentage - InterpreterProfilePercentage)) / 100; 103 } else { 104 InterpreterBackwardBranchLimit = ((CompileThreshold * OnStackReplacePercentage) / 100) << number_of_noncount_bits; 105 } 106 107 assert(0 <= InterpreterBackwardBranchLimit, 108 "OSR threshold should be non-negative"); 109 assert(0 <= InterpreterProfileLimit && 110 InterpreterProfileLimit <= InterpreterInvocationLimit, 111 "profile threshold should be less than the compilation threshold " 112 "and non-negative"); 113 } 114 115 void invocationCounter_init() { 116 InvocationCounter::reinitialize(DelayCompilationDuringStartup); 117 }