src/share/vm/interpreter/invocationCounter.hpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hs-comp Cdiff src/share/vm/interpreter/invocationCounter.hpp

src/share/vm/interpreter/invocationCounter.hpp

Print this page
rev 7045 : 7115356: assert(!m->was_never_executed()) failed
Summary: Race when asserting on invocation counters
Reviewed-by:

*** 28,100 **** #include "memory/allocation.hpp" #include "runtime/handles.hpp" #include "utilities/exceptions.hpp" // InvocationCounters are used to trigger actions when a limit (threshold) is reached. - // For different states, different limits and actions can be defined in the initialization - // routine of InvocationCounters. // ! // Implementation notes: For space reasons, state & counter are both encoded in one word, ! // The state is encoded using some of the least significant bits, the counter is using the // more significant bits. The counter is incremented before a method is activated and an ! // action is triggered when when count() > limit(). class InvocationCounter VALUE_OBJ_CLASS_SPEC { friend class VMStructs; friend class ciReplay; ! private: // bit no: |31 3| 2 | 1 0 | ! unsigned int _counter; // format: [count|carry|state] enum PrivateConstants { - number_of_state_bits = 2, number_of_carry_bits = 1, ! number_of_noncount_bits = number_of_state_bits + number_of_carry_bits, number_of_count_bits = BitsPerInt - number_of_noncount_bits, ! state_limit = nth_bit(number_of_state_bits), ! count_grain = nth_bit(number_of_state_bits + number_of_carry_bits), ! carry_mask = right_n_bits(number_of_carry_bits) << number_of_state_bits, ! state_mask = right_n_bits(number_of_state_bits), ! status_mask = right_n_bits(number_of_state_bits + number_of_carry_bits), ! count_mask = ((int)(-1) ^ status_mask) }; public: static int InterpreterInvocationLimit; // CompileThreshold scaled for interpreter use static int InterpreterBackwardBranchLimit; // A separate threshold for on stack replacement static int InterpreterProfileLimit; // Profiling threshold scaled for interpreter use - typedef address (*Action)(methodHandle method, TRAPS); - enum PublicConstants { count_increment = count_grain, // use this value to increment the 32bit _counter word count_mask_value = count_mask, // use this value to mask the backedge counter count_shift = number_of_noncount_bits, count_limit = nth_bit(number_of_count_bits - 1) }; - enum State { - wait_for_nothing, // do nothing when count() > limit() - wait_for_compile, // introduce nmethod when count() > limit() - number_of_states // must be <= state_limit - }; - // Manipulation ! void reset(); // sets state to wait state ! void init(); // sets state into original state ! void set_state(State state); // sets state and initializes counter correspondingly ! inline void set(State state, int count); // sets state and counter inline void decay(); // decay counter (divide by two) ! void set_carry(); // set the sticky carry bit ! void set_carry_flag() { _counter |= carry_mask; } ! int raw_counter() { return _counter; } // Accessors - State state() const { return (State)(_counter & state_mask); } bool carry() const { return (_counter & carry_mask) != 0; } - int limit() const { return CompileThreshold; } - Action action() const { return _action[state()]; } int count() const { return _counter >> number_of_noncount_bits; } int get_InvocationLimit() const { return InterpreterInvocationLimit >> number_of_noncount_bits; } int get_BackwardBranchLimit() const { return InterpreterBackwardBranchLimit >> number_of_noncount_bits; } int get_ProfileLimit() const { return InterpreterProfileLimit >> number_of_noncount_bits; } --- 28,93 ---- #include "memory/allocation.hpp" #include "runtime/handles.hpp" #include "utilities/exceptions.hpp" // InvocationCounters are used to trigger actions when a limit (threshold) is reached. // ! // Implementation notes: For space reasons, counter & carry are both encoded in one word, ! // The carry is encoded using the least significant bits the counter is using the // more significant bits. The counter is incremented before a method is activated and an ! // action is triggered when when count() > the limit for that counter type. class InvocationCounter VALUE_OBJ_CLASS_SPEC { friend class VMStructs; friend class ciReplay; ! private: // bit no: |31 1| 0 | ! unsigned int _counter; // format: [count|carry| enum PrivateConstants { number_of_carry_bits = 1, ! number_of_noncount_bits = number_of_carry_bits, number_of_count_bits = BitsPerInt - number_of_noncount_bits, ! count_grain = nth_bit(number_of_carry_bits), ! carry_mask = right_n_bits(number_of_carry_bits), ! count_mask = ((int)(-1) ^ carry_mask) }; public: static int InterpreterInvocationLimit; // CompileThreshold scaled for interpreter use static int InterpreterBackwardBranchLimit; // A separate threshold for on stack replacement static int InterpreterProfileLimit; // Profiling threshold scaled for interpreter use enum PublicConstants { count_increment = count_grain, // use this value to increment the 32bit _counter word count_mask_value = count_mask, // use this value to mask the backedge counter count_shift = number_of_noncount_bits, count_limit = nth_bit(number_of_count_bits - 1) }; // Manipulation ! void reset(); // reset counter, but not to zero ! void init(); // sets counters into original state ! inline void set_count(int count); // sets counter inline void decay(); // decay counter (divide by two) ! void set_carry_and_reduce(); // set the sticky carry bit and reduce counter ! void set_carry_if_necessary(); // set carry if counter is big enough ! void increment() { _counter += count_increment; } ! // primitive read and write ! uint raw_counter() { return _counter; } ! private: ! void set_raw(uint counter) { _counter = counter; } ! ! // operate on local counter without committing to memory ! inline void set_count(uint* counter, int count); ! void set_carry_flag(uint* counter) { *counter |= carry_mask; } ! int count(uint counter) { return counter >> number_of_noncount_bits; } ! bool carry(uint counter) { return (counter & carry_mask) != 0; } + public: // Accessors bool carry() const { return (_counter & carry_mask) != 0; } int count() const { return _counter >> number_of_noncount_bits; } int get_InvocationLimit() const { return InterpreterInvocationLimit >> number_of_noncount_bits; } int get_BackwardBranchLimit() const { return InterpreterBackwardBranchLimit >> number_of_noncount_bits; } int get_ProfileLimit() const { return InterpreterProfileLimit >> number_of_noncount_bits; }
*** 116,156 **** return (_counter & count_mask) + (back_edge_count->_counter & count_mask) >= (unsigned int) InterpreterProfileLimit; } #endif // CC_INTERP - void increment() { _counter += count_increment; } - - // Printing void print(); void print_short(); // Miscellaneous static ByteSize counter_offset() { return byte_offset_of(InvocationCounter, _counter); } static void reinitialize(bool delay_overflow); - - private: - static int _init [number_of_states]; // the counter limits - static Action _action[number_of_states]; // the actions - - static void def(State state, int init, Action action); - static const char* state_as_string(State state); - static const char* state_as_short_string(State state); }; ! inline void InvocationCounter::set(State state, int count) { ! assert(0 <= state && state < number_of_states, "illegal state"); ! int carry = (_counter & carry_mask); // the carry bit is sticky ! _counter = (count << number_of_noncount_bits) | carry | state; } inline void InvocationCounter::decay() { int c = count(); int new_count = c >> 1; // prevent from going to zero, to distinguish from never-executed methods if (c > 0 && new_count == 0) new_count = 1; ! set(state(), new_count); } - #endif // SHARE_VM_INTERPRETER_INVOCATIONCOUNTER_HPP --- 109,139 ---- return (_counter & count_mask) + (back_edge_count->_counter & count_mask) >= (unsigned int) InterpreterProfileLimit; } #endif // CC_INTERP // Printing void print(); void print_short(); // Miscellaneous static ByteSize counter_offset() { return byte_offset_of(InvocationCounter, _counter); } static void reinitialize(bool delay_overflow); }; ! inline void InvocationCounter::set_count(int count) { ! _counter = (count << number_of_noncount_bits) | (_counter & carry_mask); ! } ! ! inline void InvocationCounter::set_count(uint *counter, int count) { ! *counter = (count << number_of_noncount_bits) | (*counter & carry_mask); } inline void InvocationCounter::decay() { int c = count(); int new_count = c >> 1; // prevent from going to zero, to distinguish from never-executed methods if (c > 0 && new_count == 0) new_count = 1; ! set_count(new_count); } #endif // SHARE_VM_INTERPRETER_INVOCATIONCOUNTER_HPP
src/share/vm/interpreter/invocationCounter.hpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File