6966589: hs16-b08 causes java.lang.StackOverflowError
Reviewed-by: mchung, dholmes, chrisphi
--- 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