src/share/vm/interpreter/invocationCounter.hpp

changeset 435
a61af66fc99e
child 1907
c18cbe5936b8
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/share/vm/interpreter/invocationCounter.hpp	Sat Dec 01 00:00:00 2007 +0000
     1.3 @@ -0,0 +1,137 @@
     1.4 +/*
     1.5 + * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
     1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.7 + *
     1.8 + * This code is free software; you can redistribute it and/or modify it
     1.9 + * under the terms of the GNU General Public License version 2 only, as
    1.10 + * published by the Free Software Foundation.
    1.11 + *
    1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.15 + * version 2 for more details (a copy is included in the LICENSE file that
    1.16 + * accompanied this code).
    1.17 + *
    1.18 + * You should have received a copy of the GNU General Public License version
    1.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.21 + *
    1.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    1.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
    1.24 + * have any questions.
    1.25 + *
    1.26 + */
    1.27 +
    1.28 +// InvocationCounters are used to trigger actions when a limit (threshold) is reached.
    1.29 +// For different states, different limits and actions can be defined in the initialization
    1.30 +// routine of InvocationCounters.
    1.31 +//
    1.32 +// Implementation notes: For space reasons, state & counter are both encoded in one word,
    1.33 +// The state is encoded using some of the least significant bits, the counter is using the
    1.34 +// more significant bits. The counter is incremented before a method is activated and an
    1.35 +// action is triggered when when count() > limit().
    1.36 +
    1.37 +class InvocationCounter VALUE_OBJ_CLASS_SPEC {
    1.38 +  friend class VMStructs;
    1.39 + private:                             // bit no: |31  3|  2  | 1 0 |
    1.40 +  unsigned int _counter;              // format: [count|carry|state]
    1.41 +
    1.42 +  enum PrivateConstants {
    1.43 +    number_of_state_bits = 2,
    1.44 +    number_of_carry_bits = 1,
    1.45 +    number_of_noncount_bits = number_of_state_bits + number_of_carry_bits,
    1.46 +    number_of_count_bits = BitsPerInt - number_of_noncount_bits,
    1.47 +    state_limit          = nth_bit(number_of_state_bits),
    1.48 +    count_grain          = nth_bit(number_of_state_bits + number_of_carry_bits),
    1.49 +    count_limit          = nth_bit(number_of_count_bits - 1),
    1.50 +    carry_mask           = right_n_bits(number_of_carry_bits) << number_of_state_bits,
    1.51 +    state_mask           = right_n_bits(number_of_state_bits),
    1.52 +    status_mask          = right_n_bits(number_of_state_bits + number_of_carry_bits),
    1.53 +    count_mask           = ((int)(-1) ^ status_mask)
    1.54 +  };
    1.55 +
    1.56 + public:
    1.57 +  static int InterpreterInvocationLimit;        // CompileThreshold scaled for interpreter use
    1.58 +  static int Tier1InvocationLimit;              // CompileThreshold scaled for tier1 use
    1.59 +  static int Tier1BackEdgeLimit;                // BackEdgeThreshold scaled for tier1 use
    1.60 +
    1.61 +  static int InterpreterBackwardBranchLimit;    // A separate threshold for on stack replacement
    1.62 +
    1.63 +  static int InterpreterProfileLimit;           // Profiling threshold scaled for interpreter use
    1.64 +
    1.65 +  typedef address (*Action)(methodHandle method, TRAPS);
    1.66 +
    1.67 +  enum PublicConstants {
    1.68 +    count_increment      = count_grain,          // use this value to increment the 32bit _counter word
    1.69 +    count_mask_value     = count_mask            // use this value to mask the backedge counter
    1.70 +  };
    1.71 +
    1.72 +  enum State {
    1.73 +    wait_for_nothing,                            // do nothing when count() > limit()
    1.74 +    wait_for_compile,                            // introduce nmethod when count() > limit()
    1.75 +    number_of_states                             // must be <= state_limit
    1.76 +  };
    1.77 +
    1.78 +  // Manipulation
    1.79 +  void reset();                                  // sets state to wait state
    1.80 +  void init();                                   // sets state into original state
    1.81 +  void set_state(State state);                   // sets state and initializes counter correspondingly
    1.82 +  inline void set(State state, int count);       // sets state and counter
    1.83 +  inline void decay();                           // decay counter (divide by two)
    1.84 +  void set_carry();                              // set the sticky carry bit
    1.85 +
    1.86 +  // Accessors
    1.87 +  State  state() const                           { return (State)(_counter & state_mask); }
    1.88 +  bool   carry() const                           { return (_counter & carry_mask) != 0; }
    1.89 +  int    limit() const                           { return CompileThreshold; }
    1.90 +  Action action() const                          { return _action[state()]; }
    1.91 +  int    count() const                           { return _counter >> number_of_noncount_bits; }
    1.92 +
    1.93 +  int   get_InvocationLimit() const              { return InterpreterInvocationLimit >> number_of_noncount_bits; }
    1.94 +  int   get_BackwardBranchLimit() const          { return InterpreterBackwardBranchLimit >> number_of_noncount_bits; }
    1.95 +  int   get_ProfileLimit() const                 { return InterpreterProfileLimit >> number_of_noncount_bits; }
    1.96 +
    1.97 +  // Test counter using scaled limits like the asm interpreter would do rather than doing
    1.98 +  // the shifts to normalize the counter.
    1.99 +
   1.100 +  bool   reached_InvocationLimit() const         { return _counter >= (unsigned int) InterpreterInvocationLimit; }
   1.101 +  bool   reached_BackwardBranchLimit() const     { return _counter >= (unsigned int) InterpreterBackwardBranchLimit; }
   1.102 +
   1.103 +  // Do this just like asm interpreter does for max speed
   1.104 +  bool   reached_ProfileLimit(InvocationCounter *back_edge_count) const {
   1.105 +    return (_counter && count_mask) + back_edge_count->_counter >= (unsigned int) InterpreterProfileLimit;
   1.106 +  }
   1.107 +
   1.108 +  void increment()                               { _counter += count_increment; }
   1.109 +
   1.110 +
   1.111 +  // Printing
   1.112 +  void   print();
   1.113 +  void   print_short();
   1.114 +
   1.115 +  // Miscellaneous
   1.116 +  static ByteSize counter_offset()               { return byte_offset_of(InvocationCounter, _counter); }
   1.117 +  static void reinitialize(bool delay_overflow);
   1.118 +
   1.119 + private:
   1.120 +  static int         _init  [number_of_states];  // the counter limits
   1.121 +  static Action      _action[number_of_states];  // the actions
   1.122 +
   1.123 +  static void        def(State state, int init, Action action);
   1.124 +  static const char* state_as_string(State state);
   1.125 +  static const char* state_as_short_string(State state);
   1.126 +};
   1.127 +
   1.128 +inline void InvocationCounter::set(State state, int count) {
   1.129 +  assert(0 <= state && state < number_of_states, "illegal state");
   1.130 +  int carry = (_counter & carry_mask);    // the carry bit is sticky
   1.131 +  _counter = (count << number_of_noncount_bits) | carry | state;
   1.132 +}
   1.133 +
   1.134 +inline void InvocationCounter::decay() {
   1.135 +  int c = count();
   1.136 +  int new_count = c >> 1;
   1.137 +  // prevent from going to zero, to distinguish from never-executed methods
   1.138 +  if (c > 0 && new_count == 0) new_count = 1;
   1.139 +  set(state(), new_count);
   1.140 +}

mercurial