hotspot/src/share/vm/oops/method.hpp
changeset 17000 11bf92e571a2
parent 16617 6235d2c7549f
child 17002 d86c9dfa4a5f
--- a/hotspot/src/share/vm/oops/method.hpp	Thu Apr 04 21:15:43 2013 -0700
+++ b/hotspot/src/share/vm/oops/method.hpp	Tue Apr 09 17:17:41 2013 -0400
@@ -31,6 +31,7 @@
 #include "interpreter/invocationCounter.hpp"
 #include "oops/annotations.hpp"
 #include "oops/constantPool.hpp"
+#include "oops/methodCounters.hpp"
 #include "oops/instanceKlass.hpp"
 #include "oops/oop.hpp"
 #include "oops/typeArrayOop.hpp"
@@ -100,6 +101,7 @@
 class LocalVariableTableElement;
 class AdapterHandlerEntry;
 class MethodData;
+class MethodCounters;
 class ConstMethod;
 class InlineTableSizes;
 class KlassSizeStats;
@@ -109,7 +111,7 @@
  private:
   ConstMethod*      _constMethod;                // Method read-only data.
   MethodData*       _method_data;
-  int               _interpreter_invocation_count; // Count of times invoked (reused as prev_event_count in tiered)
+  MethodCounters*   _method_counters;
   AccessFlags       _access_flags;               // Access flags
   int               _vtable_index;               // vtable index of this method (see VtableIndexFlag)
                                                  // note: can have vtables with >2**16 elements (because of inheritance)
@@ -124,15 +126,6 @@
                     _hidden           : 1,
                     _dont_inline      : 1,
                                       : 3;
-  u2                _interpreter_throwout_count; // Count of times method was exited via exception while interpreting
-  u2                _number_of_breakpoints;      // fullspeed debugging support
-  InvocationCounter _invocation_counter;         // Incremented before each activation of the method - used to trigger frequency-based optimizations
-  InvocationCounter _backedge_counter;           // Incremented before each backedge taken - used to trigger frequencey-based optimizations
-
-#ifdef TIERED
-  float             _rate;                        // Events (invocation and backedge counter increments) per millisecond
-  jlong             _prev_time;                   // Previous time the rate was acquired
-#endif
 
 #ifndef PRODUCT
   int               _compiled_invocation_count;  // Number of nmethod invocations so far (for perf. debugging)
@@ -247,11 +240,31 @@
   void clear_all_breakpoints();
   // Tracking number of breakpoints, for fullspeed debugging.
   // Only mutated by VM thread.
-  u2   number_of_breakpoints() const             { return _number_of_breakpoints; }
-  void incr_number_of_breakpoints()              { ++_number_of_breakpoints; }
-  void decr_number_of_breakpoints()              { --_number_of_breakpoints; }
+  u2   number_of_breakpoints()             const {
+    if (method_counters() == NULL) {
+      return 0;
+    } else {
+      return method_counters()->number_of_breakpoints();
+    }
+  }
+  void incr_number_of_breakpoints(TRAPS)         {
+    MethodCounters* mcs = get_method_counters(CHECK);
+    if (mcs != NULL) {
+      mcs->incr_number_of_breakpoints();
+    }
+  }
+  void decr_number_of_breakpoints(TRAPS)         {
+    MethodCounters* mcs = get_method_counters(CHECK);
+    if (mcs != NULL) {
+      mcs->decr_number_of_breakpoints();
+    }
+  }
   // Initialization only
-  void clear_number_of_breakpoints()             { _number_of_breakpoints = 0; }
+  void clear_number_of_breakpoints()             {
+    if (method_counters() != NULL) {
+      method_counters()->clear_number_of_breakpoints();
+    }
+  }
 
   // index into InstanceKlass methods() array
   // note: also used by jfr
@@ -288,14 +301,20 @@
   void set_highest_osr_comp_level(int level);
 
   // Count of times method was exited via exception while interpreting
-  void interpreter_throwout_increment() {
-    if (_interpreter_throwout_count < 65534) {
-      _interpreter_throwout_count++;
+  void interpreter_throwout_increment(TRAPS) {
+    MethodCounters* mcs = get_method_counters(CHECK);
+    if (mcs != NULL) {
+      mcs->interpreter_throwout_increment();
     }
   }
 
-  int  interpreter_throwout_count() const        { return _interpreter_throwout_count; }
-  void set_interpreter_throwout_count(int count) { _interpreter_throwout_count = count; }
+  int  interpreter_throwout_count() const        {
+    if (method_counters() == NULL) {
+      return 0;
+    } else {
+      return method_counters()->interpreter_throwout_count();
+    }
+  }
 
   // size of parameters
   int  size_of_parameters() const                { return constMethod()->size_of_parameters(); }
@@ -339,23 +358,54 @@
   MethodData* method_data() const              {
     return _method_data;
   }
+
   void set_method_data(MethodData* data)       {
     _method_data = data;
   }
 
-  // invocation counter
-  InvocationCounter* invocation_counter() { return &_invocation_counter; }
-  InvocationCounter* backedge_counter()   { return &_backedge_counter; }
+  MethodCounters* method_counters() const {
+    return _method_counters;
+  }
+
+
+  void set_method_counters(MethodCounters* counters) {
+    _method_counters = counters;
+  }
 
 #ifdef TIERED
   // We are reusing interpreter_invocation_count as a holder for the previous event count!
   // We can do that since interpreter_invocation_count is not used in tiered.
-  int prev_event_count() const                   { return _interpreter_invocation_count;  }
-  void set_prev_event_count(int count)           { _interpreter_invocation_count = count; }
-  jlong prev_time() const                        { return _prev_time; }
-  void set_prev_time(jlong time)                 { _prev_time = time; }
-  float rate() const                             { return _rate; }
-  void set_rate(float rate)                      { _rate = rate; }
+  int prev_event_count() const                   {
+    if (method_counters() == NULL) {
+      return 0;
+    } else {
+      return method_counters()->interpreter_invocation_count();
+    }
+  }
+  void set_prev_event_count(int count, TRAPS)    {
+    MethodCounters* mcs = get_method_counters(CHECK);
+    if (mcs != NULL) {
+      mcs->set_interpreter_invocation_count(count);
+    }
+  }
+  jlong prev_time() const                        {
+    return method_counters() == NULL ? 0 : method_counters()->prev_time();
+  }
+  void set_prev_time(jlong time, TRAPS)          {
+    MethodCounters* mcs = get_method_counters(CHECK);
+    if (mcs != NULL) {
+      mcs->set_prev_time(time);
+    }
+  }
+  float rate() const                             {
+    return method_counters() == NULL ? 0 : method_counters()->rate();
+  }
+  void set_rate(float rate, TRAPS) {
+    MethodCounters* mcs = get_method_counters(CHECK);
+    if (mcs != NULL) {
+      mcs->set_rate(rate);
+    }
+  }
 #endif
 
   int invocation_count();
@@ -366,14 +416,17 @@
 
   static void build_interpreter_method_data(methodHandle method, TRAPS);
 
+  static MethodCounters* build_method_counters(Method* m, TRAPS);
+
   int interpreter_invocation_count() {
     if (TieredCompilation) return invocation_count();
-    else return _interpreter_invocation_count;
+    else return (method_counters() == NULL) ? 0 :
+                 method_counters()->interpreter_invocation_count();
   }
-  void set_interpreter_invocation_count(int count) { _interpreter_invocation_count = count; }
-  int increment_interpreter_invocation_count() {
+  int increment_interpreter_invocation_count(TRAPS) {
     if (TieredCompilation) ShouldNotReachHere();
-    return ++_interpreter_invocation_count;
+    MethodCounters* mcs = get_method_counters(CHECK_0);
+    return (mcs == NULL) ? 0 : mcs->increment_interpreter_invocation_count();
   }
 
 #ifndef PRODUCT
@@ -582,12 +635,12 @@
 #endif /* CC_INTERP */
   static ByteSize from_compiled_offset()         { return byte_offset_of(Method, _from_compiled_entry); }
   static ByteSize code_offset()                  { return byte_offset_of(Method, _code); }
-  static ByteSize invocation_counter_offset()    { return byte_offset_of(Method, _invocation_counter); }
-  static ByteSize backedge_counter_offset()      { return byte_offset_of(Method, _backedge_counter); }
   static ByteSize method_data_offset()           {
     return byte_offset_of(Method, _method_data);
   }
-  static ByteSize interpreter_invocation_counter_offset() { return byte_offset_of(Method, _interpreter_invocation_count); }
+  static ByteSize method_counters_offset()       {
+    return byte_offset_of(Method, _method_counters);
+  }
 #ifndef PRODUCT
   static ByteSize compiled_invocation_counter_offset() { return byte_offset_of(Method, _compiled_invocation_count); }
 #endif // not PRODUCT
@@ -598,8 +651,6 @@
 
   // for code generation
   static int method_data_offset_in_bytes()       { return offset_of(Method, _method_data); }
-  static int interpreter_invocation_counter_offset_in_bytes()
-                                                 { return offset_of(Method, _interpreter_invocation_count); }
   static int intrinsic_id_offset_in_bytes()      { return offset_of(Method, _intrinsic_id); }
   static int intrinsic_id_size_in_bytes()        { return sizeof(u1); }
 
@@ -757,6 +808,13 @@
  private:
   void print_made_not_compilable(int comp_level, bool is_osr, bool report, const char* reason);
 
+  MethodCounters* get_method_counters(TRAPS) {
+    if (_method_counters == NULL) {
+      build_method_counters(this, CHECK_AND_CLEAR_NULL);
+    }
+    return _method_counters;
+  }
+
  public:
   bool  is_not_c1_compilable() const          { return access_flags().is_not_c1_compilable(); }
   void set_not_c1_compilable()                {       _access_flags.set_not_c1_compilable();  }