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