6966589: hs16-b08 causes java.lang.StackOverflowError
Reviewed-by: mchung, dholmes, chrisphi
This commit is contained in:
parent
bb7771888b
commit
612faf72b7
@ -1382,3 +1382,61 @@ void ClassLoader::compile_the_world_in(char* name, Handle loader, TRAPS) {
|
||||
}
|
||||
|
||||
#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();
|
||||
}
|
||||
|
@ -356,111 +356,57 @@ class ClassLoader: AllStatic {
|
||||
// (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:
|
||||
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:
|
||||
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 */
|
||||
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();
|
||||
}
|
||||
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;
|
||||
inline void suspend() { _t.stop(); _timers[_event_type].stop(); }
|
||||
inline void resume() { _t.start(); _timers[_event_type].start(); }
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
~PerfClassTraceTime();
|
||||
void initialize();
|
||||
};
|
||||
|
||||
|
||||
#endif // SHARE_VM_CLASSFILE_CLASSLOADER_HPP
|
||||
|
Loading…
x
Reference in New Issue
Block a user