6966589: hs16-b08 causes java.lang.StackOverflowError
authorminqi
Thu, 07 Oct 2010 13:49:40 -0700
changeset 7910 135031ddb2bb
parent 7909 96e81d4e789c
child 7911 be4352e4480c
child 7915 c726d9cdeb6e
6966589: hs16-b08 causes java.lang.StackOverflowError Reviewed-by: mchung, dholmes, chrisphi
hotspot/src/share/vm/classfile/classLoader.cpp
hotspot/src/share/vm/classfile/classLoader.hpp
--- a/hotspot/src/share/vm/classfile/classLoader.cpp	Thu Jan 13 22:54:23 2011 -0800
+++ b/hotspot/src/share/vm/classfile/classLoader.cpp	Thu Oct 07 13:49:40 2010 -0700
@@ -1382,3 +1382,61 @@
 }
 
 #endif //PRODUCT
+
+// Please keep following two functions at end of this file. With them placed at top or in middle of the file,
+// they could get inlined by agressive compiler, an unknown trick, see bug 6966589.
+void PerfClassTraceTime::initialize() {
+  if (!UsePerfData) return;
+
+  if (_eventp != NULL) {
+    // increment the event counter
+    _eventp->inc();
+  }
+
+  // stop the current active thread-local timer to measure inclusive time
+  _prev_active_event = -1;
+  for (int i=0; i < EVENT_TYPE_COUNT; i++) {
+     if (_timers[i].is_active()) {
+       assert(_prev_active_event == -1, "should have only one active timer");
+       _prev_active_event = i;
+       _timers[i].stop();
+     }
+  }
+
+  if (_recursion_counters == NULL || (_recursion_counters[_event_type])++ == 0) {
+    // start the inclusive timer if not recursively called
+    _t.start();
+  }
+
+  // start thread-local timer of the given event type
+   if (!_timers[_event_type].is_active()) {
+    _timers[_event_type].start();
+  }
+}
+
+PerfClassTraceTime::~PerfClassTraceTime() {
+  if (!UsePerfData) return;
+
+  // stop the thread-local timer as the event completes
+  // and resume the thread-local timer of the event next on the stack
+  _timers[_event_type].stop();
+  jlong selftime = _timers[_event_type].ticks();
+
+  if (_prev_active_event >= 0) {
+    _timers[_prev_active_event].start();
+  }
+
+  if (_recursion_counters != NULL && --(_recursion_counters[_event_type]) > 0) return;
+
+  // increment the counters only on the leaf call
+  _t.stop();
+  _timep->inc(_t.ticks());
+  if (_selftimep != NULL) {
+    _selftimep->inc(selftime);
+  }
+  // add all class loading related event selftime to the accumulated time counter
+  ClassLoader::perf_accumulated_time()->inc(selftime);
+
+  // reset the timer
+  _timers[_event_type].reset();
+}
--- a/hotspot/src/share/vm/classfile/classLoader.hpp	Thu Jan 13 22:54:23 2011 -0800
+++ b/hotspot/src/share/vm/classfile/classLoader.hpp	Thu Oct 07 13:49:40 2010 -0700
@@ -356,111 +356,57 @@
 // (i.e. only one event type) are active at a time even multiple PerfClassTraceTime
 // instances have been created as multiple events are happening.
 class PerfClassTraceTime {
-  public:
-    enum {
-       CLASS_LOAD   = 0,
-       PARSE_CLASS  = 1,
-       CLASS_LINK   = 2,
-       CLASS_VERIFY = 3,
-       CLASS_CLINIT = 4,
-       DEFINE_CLASS = 5,
-       EVENT_TYPE_COUNT = 6
-    };
-  protected:
-    // _t tracks time from initialization to destruction of this timer instance
-    // including time for all other event types, and recursive calls of this type.
-    // When a timer is called recursively, the elapsedTimer _t would not be used.
-    elapsedTimer     _t;
-    PerfLongCounter* _timep;
-    PerfLongCounter* _selftimep;
-    PerfLongCounter* _eventp;
-    // pointer to thread-local recursion counter and timer array
-    // The thread_local timers track cumulative time for specific event types
-    // exclusive of time for other event types, but including recursive calls
-    // of the same type.
-    int*             _recursion_counters;
-    elapsedTimer*    _timers;
-    int              _event_type;
-    int              _prev_active_event;
-
-  public:
-
-    inline PerfClassTraceTime(PerfLongCounter* timep,     /* counter incremented with inclusive time */
-                              PerfLongCounter* selftimep, /* counter incremented with exclusive time */
-                              PerfLongCounter* eventp,    /* event counter */
-                              int* recursion_counters,    /* thread-local recursion counter array */
-                              elapsedTimer* timers,       /* thread-local timer array */
-                              int type                    /* event type */ ) :
-        _timep(timep), _selftimep(selftimep), _eventp(eventp), _recursion_counters(recursion_counters), _timers(timers), _event_type(type) {
-      initialize();
-    }
-
-    inline PerfClassTraceTime(PerfLongCounter* timep,     /* counter incremented with inclusive time */
-                              elapsedTimer* timers,       /* thread-local timer array */
-                              int type                    /* event type */ ) :
-        _timep(timep), _selftimep(NULL), _eventp(NULL), _recursion_counters(NULL), _timers(timers), _event_type(type) {
-      initialize();
-    }
-
-    void initialize() {
-      if (!UsePerfData) return;
+ public:
+  enum {
+    CLASS_LOAD   = 0,
+    PARSE_CLASS  = 1,
+    CLASS_LINK   = 2,
+    CLASS_VERIFY = 3,
+    CLASS_CLINIT = 4,
+    DEFINE_CLASS = 5,
+    EVENT_TYPE_COUNT = 6
+  };
+ protected:
+  // _t tracks time from initialization to destruction of this timer instance
+  // including time for all other event types, and recursive calls of this type.
+  // When a timer is called recursively, the elapsedTimer _t would not be used.
+  elapsedTimer     _t;
+  PerfLongCounter* _timep;
+  PerfLongCounter* _selftimep;
+  PerfLongCounter* _eventp;
+  // pointer to thread-local recursion counter and timer array
+  // The thread_local timers track cumulative time for specific event types
+  // exclusive of time for other event types, but including recursive calls
+  // of the same type.
+  int*             _recursion_counters;
+  elapsedTimer*    _timers;
+  int              _event_type;
+  int              _prev_active_event;
 
-      if (_eventp != NULL) {
-        // increment the event counter
-        _eventp->inc();
-      }
+ public:
 
-      // stop the current active thread-local timer to measure inclusive time
-      _prev_active_event = -1;
-      for (int i=0; i < EVENT_TYPE_COUNT; i++) {
-         if (_timers[i].is_active()) {
-           assert(_prev_active_event == -1, "should have only one active timer");
-           _prev_active_event = i;
-           _timers[i].stop();
-         }
-      }
-
-      if (_recursion_counters == NULL || (_recursion_counters[_event_type])++ == 0) {
-        // start the inclusive timer if not recursively called
-        _t.start();
-      }
-
-      // start thread-local timer of the given event type
-      if (!_timers[_event_type].is_active()) {
-        _timers[_event_type].start();
-      }
-    }
+  inline PerfClassTraceTime(PerfLongCounter* timep,     /* counter incremented with inclusive time */
+                            PerfLongCounter* selftimep, /* counter incremented with exclusive time */
+                            PerfLongCounter* eventp,    /* event counter */
+                            int* recursion_counters,    /* thread-local recursion counter array */
+                            elapsedTimer* timers,       /* thread-local timer array */
+                            int type                    /* event type */ ) :
+      _timep(timep), _selftimep(selftimep), _eventp(eventp), _recursion_counters(recursion_counters), _timers(timers), _event_type(type) {
+    initialize();
+  }
 
-    inline void suspend() { _t.stop(); _timers[_event_type].stop(); }
-    inline void resume()  { _t.start(); _timers[_event_type].start(); }
-
-    ~PerfClassTraceTime() {
-      if (!UsePerfData) return;
-
-      // stop the thread-local timer as the event completes
-      // and resume the thread-local timer of the event next on the stack
-      _timers[_event_type].stop();
-      jlong selftime = _timers[_event_type].ticks();
-
-      if (_prev_active_event >= 0) {
-        _timers[_prev_active_event].start();
-      }
+  inline PerfClassTraceTime(PerfLongCounter* timep,     /* counter incremented with inclusive time */
+                            elapsedTimer* timers,       /* thread-local timer array */
+                            int type                    /* event type */ ) :
+      _timep(timep), _selftimep(NULL), _eventp(NULL), _recursion_counters(NULL), _timers(timers), _event_type(type) {
+    initialize();
+  }
 
-      if (_recursion_counters != NULL && --(_recursion_counters[_event_type]) > 0) return;
+  inline void suspend() { _t.stop(); _timers[_event_type].stop(); }
+  inline void resume()  { _t.start(); _timers[_event_type].start(); }
 
-      // increment the counters only on the leaf call
-      _t.stop();
-      _timep->inc(_t.ticks());
-      if (_selftimep != NULL) {
-        _selftimep->inc(selftime);
-      }
-      // add all class loading related event selftime to the accumulated time counter
-      ClassLoader::perf_accumulated_time()->inc(selftime);
-
-      // reset the timer
-      _timers[_event_type].reset();
-    }
+  ~PerfClassTraceTime();
+  void initialize();
 };
 
-
 #endif // SHARE_VM_CLASSFILE_CLASSLOADER_HPP