提交 80fce3f6 编写于 作者: M minqi

6966589: hs16-b08 causes java.lang.StackOverflowError

Reviewed-by: mchung, dholmes, chrisphi
上级 edd1af5d
...@@ -1382,3 +1382,61 @@ void ClassLoader::compile_the_world_in(char* name, Handle loader, TRAPS) { ...@@ -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 { ...@@ -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:
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;
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 public:
// 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) { inline PerfClassTraceTime(PerfLongCounter* timep, /* counter incremented with inclusive time */
_timers[_prev_active_event].start(); 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();
}
if (_recursion_counters != NULL && --(_recursion_counters[_event_type]) > 0) return; 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();
}
// increment the counters only on the leaf call inline void suspend() { _t.stop(); _timers[_event_type].stop(); }
_t.stop(); inline void resume() { _t.start(); _timers[_event_type].start(); }
_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 ~PerfClassTraceTime();
_timers[_event_type].reset(); void initialize();
}
}; };
#endif // SHARE_VM_CLASSFILE_CLASSLOADER_HPP #endif // SHARE_VM_CLASSFILE_CLASSLOADER_HPP
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册