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
|
#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
|
// (i.e. only one event type) are active at a time even multiple PerfClassTraceTime
|
||||||
// instances have been created as multiple events are happening.
|
// instances have been created as multiple events are happening.
|
||||||
class PerfClassTraceTime {
|
class PerfClassTraceTime {
|
||||||
public:
|
public:
|
||||||
enum {
|
enum {
|
||||||
CLASS_LOAD = 0,
|
CLASS_LOAD = 0,
|
||||||
PARSE_CLASS = 1,
|
PARSE_CLASS = 1,
|
||||||
CLASS_LINK = 2,
|
CLASS_LINK = 2,
|
||||||
CLASS_VERIFY = 3,
|
CLASS_VERIFY = 3,
|
||||||
CLASS_CLINIT = 4,
|
CLASS_CLINIT = 4,
|
||||||
DEFINE_CLASS = 5,
|
DEFINE_CLASS = 5,
|
||||||
EVENT_TYPE_COUNT = 6
|
EVENT_TYPE_COUNT = 6
|
||||||
};
|
};
|
||||||
protected:
|
protected:
|
||||||
// _t tracks time from initialization to destruction of this timer instance
|
// _t tracks time from initialization to destruction of this timer instance
|
||||||
// including time for all other event types, and recursive calls of this type.
|
// 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.
|
// When a timer is called recursively, the elapsedTimer _t would not be used.
|
||||||
elapsedTimer _t;
|
elapsedTimer _t;
|
||||||
PerfLongCounter* _timep;
|
PerfLongCounter* _timep;
|
||||||
PerfLongCounter* _selftimep;
|
PerfLongCounter* _selftimep;
|
||||||
PerfLongCounter* _eventp;
|
PerfLongCounter* _eventp;
|
||||||
// pointer to thread-local recursion counter and timer array
|
// pointer to thread-local recursion counter and timer array
|
||||||
// The thread_local timers track cumulative time for specific event types
|
// The thread_local timers track cumulative time for specific event types
|
||||||
// exclusive of time for other event types, but including recursive calls
|
// exclusive of time for other event types, but including recursive calls
|
||||||
// of the same type.
|
// of the same type.
|
||||||
int* _recursion_counters;
|
int* _recursion_counters;
|
||||||
elapsedTimer* _timers;
|
elapsedTimer* _timers;
|
||||||
int _event_type;
|
int _event_type;
|
||||||
int _prev_active_event;
|
int _prev_active_event;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
inline PerfClassTraceTime(PerfLongCounter* timep, /* counter incremented with inclusive time */
|
inline PerfClassTraceTime(PerfLongCounter* timep, /* counter incremented with inclusive time */
|
||||||
PerfLongCounter* selftimep, /* counter incremented with exclusive time */
|
PerfLongCounter* selftimep, /* counter incremented with exclusive time */
|
||||||
PerfLongCounter* eventp, /* event counter */
|
PerfLongCounter* eventp, /* event counter */
|
||||||
int* recursion_counters, /* thread-local recursion counter array */
|
int* recursion_counters, /* thread-local recursion counter array */
|
||||||
elapsedTimer* timers, /* thread-local timer array */
|
elapsedTimer* timers, /* thread-local timer array */
|
||||||
int type /* event type */ ) :
|
int type /* event type */ ) :
|
||||||
_timep(timep), _selftimep(selftimep), _eventp(eventp), _recursion_counters(recursion_counters), _timers(timers), _event_type(type) {
|
_timep(timep), _selftimep(selftimep), _eventp(eventp), _recursion_counters(recursion_counters), _timers(timers), _event_type(type) {
|
||||||
initialize();
|
initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline PerfClassTraceTime(PerfLongCounter* timep, /* counter incremented with inclusive time */
|
inline PerfClassTraceTime(PerfLongCounter* timep, /* counter incremented with inclusive time */
|
||||||
elapsedTimer* timers, /* thread-local timer array */
|
elapsedTimer* timers, /* thread-local timer array */
|
||||||
int type /* event type */ ) :
|
int type /* event type */ ) :
|
||||||
_timep(timep), _selftimep(NULL), _eventp(NULL), _recursion_counters(NULL), _timers(timers), _event_type(type) {
|
_timep(timep), _selftimep(NULL), _eventp(NULL), _recursion_counters(NULL), _timers(timers), _event_type(type) {
|
||||||
initialize();
|
initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void initialize() {
|
inline void suspend() { _t.stop(); _timers[_event_type].stop(); }
|
||||||
if (!UsePerfData) return;
|
inline void resume() { _t.start(); _timers[_event_type].start(); }
|
||||||
|
|
||||||
if (_eventp != NULL) {
|
~PerfClassTraceTime();
|
||||||
// increment the event counter
|
void initialize();
|
||||||
_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();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // SHARE_VM_CLASSFILE_CLASSLOADER_HPP
|
#endif // SHARE_VM_CLASSFILE_CLASSLOADER_HPP
|
||||||
|
Loading…
x
Reference in New Issue
Block a user