invocationCounter.hpp revision 1472:c18cbe5936b8
1215911Sjfv/* 2215911Sjfv * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. 3315333Serj * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4215911Sjfv * 5315333Serj * This code is free software; you can redistribute it and/or modify it 6315333Serj * under the terms of the GNU General Public License version 2 only, as 7215911Sjfv * published by the Free Software Foundation. 8315333Serj * 9315333Serj * This code is distributed in the hope that it will be useful, but WITHOUT 10215911Sjfv * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11315333Serj * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12315333Serj * version 2 for more details (a copy is included in the LICENSE file that 13315333Serj * accompanied this code). 14215911Sjfv * 15315333Serj * You should have received a copy of the GNU General Public License version 16315333Serj * 2 along with this work; if not, write to the Free Software Foundation, 17315333Serj * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18215911Sjfv * 19315333Serj * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20215911Sjfv * or visit www.oracle.com if you need additional information or have any 21315333Serj * questions. 22315333Serj * 23315333Serj */ 24315333Serj 25315333Serj// InvocationCounters are used to trigger actions when a limit (threshold) is reached. 26315333Serj// For different states, different limits and actions can be defined in the initialization 27315333Serj// routine of InvocationCounters. 28315333Serj// 29215911Sjfv// Implementation notes: For space reasons, state & counter are both encoded in one word, 30215911Sjfv// The state is encoded using some of the least significant bits, the counter is using the 31215911Sjfv// more significant bits. The counter is incremented before a method is activated and an 32215911Sjfv// action is triggered when when count() > limit(). 33215911Sjfv 34215911Sjfvclass InvocationCounter VALUE_OBJ_CLASS_SPEC { 35215911Sjfv friend class VMStructs; 36215911Sjfv private: // bit no: |31 3| 2 | 1 0 | 37215911Sjfv unsigned int _counter; // format: [count|carry|state] 38215911Sjfv 39215911Sjfv enum PrivateConstants { 40215911Sjfv number_of_state_bits = 2, 41215911Sjfv number_of_carry_bits = 1, 42215911Sjfv number_of_noncount_bits = number_of_state_bits + number_of_carry_bits, 43215911Sjfv number_of_count_bits = BitsPerInt - number_of_noncount_bits, 44215911Sjfv state_limit = nth_bit(number_of_state_bits), 45215911Sjfv count_grain = nth_bit(number_of_state_bits + number_of_carry_bits), 46215911Sjfv count_limit = nth_bit(number_of_count_bits - 1), 47215911Sjfv carry_mask = right_n_bits(number_of_carry_bits) << number_of_state_bits, 48215911Sjfv state_mask = right_n_bits(number_of_state_bits), 49215911Sjfv status_mask = right_n_bits(number_of_state_bits + number_of_carry_bits), 50215911Sjfv count_mask = ((int)(-1) ^ status_mask) 51215911Sjfv }; 52215911Sjfv 53215911Sjfv public: 54215911Sjfv static int InterpreterInvocationLimit; // CompileThreshold scaled for interpreter use 55215911Sjfv static int Tier1InvocationLimit; // CompileThreshold scaled for tier1 use 56215911Sjfv static int Tier1BackEdgeLimit; // BackEdgeThreshold scaled for tier1 use 57215911Sjfv 58215911Sjfv static int InterpreterBackwardBranchLimit; // A separate threshold for on stack replacement 59215911Sjfv 60215911Sjfv static int InterpreterProfileLimit; // Profiling threshold scaled for interpreter use 61215911Sjfv 62215911Sjfv typedef address (*Action)(methodHandle method, TRAPS); 63215911Sjfv 64215911Sjfv enum PublicConstants { 65215911Sjfv count_increment = count_grain, // use this value to increment the 32bit _counter word 66215911Sjfv count_mask_value = count_mask // use this value to mask the backedge counter 67215911Sjfv }; 68215911Sjfv 69215911Sjfv enum State { 70215911Sjfv wait_for_nothing, // do nothing when count() > limit() 71215911Sjfv wait_for_compile, // introduce nmethod when count() > limit() 72215911Sjfv number_of_states // must be <= state_limit 73215911Sjfv }; 74215911Sjfv 75215911Sjfv // Manipulation 76215911Sjfv void reset(); // sets state to wait state 77215911Sjfv void init(); // sets state into original state 78215911Sjfv void set_state(State state); // sets state and initializes counter correspondingly 79215911Sjfv inline void set(State state, int count); // sets state and counter 80283620Serj inline void decay(); // decay counter (divide by two) 81215911Sjfv void set_carry(); // set the sticky carry bit 82283620Serj 83283620Serj // Accessors 84283620Serj State state() const { return (State)(_counter & state_mask); } 85215911Sjfv bool carry() const { return (_counter & carry_mask) != 0; } 86215911Sjfv int limit() const { return CompileThreshold; } 87215911Sjfv Action action() const { return _action[state()]; } 88215911Sjfv int count() const { return _counter >> number_of_noncount_bits; } 89215911Sjfv 90215911Sjfv int get_InvocationLimit() const { return InterpreterInvocationLimit >> number_of_noncount_bits; } 91215911Sjfv int get_BackwardBranchLimit() const { return InterpreterBackwardBranchLimit >> number_of_noncount_bits; } 92215911Sjfv int get_ProfileLimit() const { return InterpreterProfileLimit >> number_of_noncount_bits; } 93215911Sjfv 94215911Sjfv // Test counter using scaled limits like the asm interpreter would do rather than doing 95215911Sjfv // the shifts to normalize the counter. 96215911Sjfv 97215911Sjfv bool reached_InvocationLimit() const { return _counter >= (unsigned int) InterpreterInvocationLimit; } 98215911Sjfv bool reached_BackwardBranchLimit() const { return _counter >= (unsigned int) InterpreterBackwardBranchLimit; } 99215911Sjfv 100215911Sjfv // Do this just like asm interpreter does for max speed 101215911Sjfv bool reached_ProfileLimit(InvocationCounter *back_edge_count) const { 102215911Sjfv return (_counter && count_mask) + back_edge_count->_counter >= (unsigned int) InterpreterProfileLimit; 103215911Sjfv } 104215911Sjfv 105215911Sjfv void increment() { _counter += count_increment; } 106215911Sjfv 107215911Sjfv 108215911Sjfv // Printing 109215911Sjfv void print(); 110215911Sjfv void print_short(); 111215911Sjfv 112215911Sjfv // Miscellaneous 113215911Sjfv static ByteSize counter_offset() { return byte_offset_of(InvocationCounter, _counter); } 114215911Sjfv static void reinitialize(bool delay_overflow); 115215911Sjfv 116215911Sjfv private: 117215911Sjfv static int _init [number_of_states]; // the counter limits 118215911Sjfv static Action _action[number_of_states]; // the actions 119215911Sjfv 120215911Sjfv static void def(State state, int init, Action action); 121215911Sjfv static const char* state_as_string(State state); 122215911Sjfv static const char* state_as_short_string(State state); 123215911Sjfv}; 124215911Sjfv 125215911Sjfvinline void InvocationCounter::set(State state, int count) { 126215911Sjfv assert(0 <= state && state < number_of_states, "illegal state"); 127215911Sjfv int carry = (_counter & carry_mask); // the carry bit is sticky 128215911Sjfv _counter = (count << number_of_noncount_bits) | carry | state; 129215911Sjfv} 130215911Sjfv 131215911Sjfvinline void InvocationCounter::decay() { 132215911Sjfv int c = count(); 133215911Sjfv int new_count = c >> 1; 134215911Sjfv // prevent from going to zero, to distinguish from never-executed methods 135215911Sjfv if (c > 0 && new_count == 0) new_count = 1; 136215911Sjfv set(state(), new_count); 137215911Sjfv} 138215911Sjfv