6857194: Add hotspot perf counters to aid class loading performance measurement
Add new jvmstat counters to measure detailed class loading time Reviewed-by: acorn, kamg
This commit is contained in:
parent
c8140c1078
commit
08f5aeffc1
@ -547,7 +547,6 @@ objArrayHandle ClassFileParser::parse_interfaces(constantPoolHandle cp,
|
||||
int length,
|
||||
Handle class_loader,
|
||||
Handle protection_domain,
|
||||
PerfTraceTime* vmtimer,
|
||||
symbolHandle class_name,
|
||||
TRAPS) {
|
||||
ClassFileStream* cfs = stream();
|
||||
@ -575,13 +574,11 @@ objArrayHandle ClassFileParser::parse_interfaces(constantPoolHandle cp,
|
||||
guarantee_property(unresolved_klass->byte_at(0) != JVM_SIGNATURE_ARRAY,
|
||||
"Bad interface name in class file %s", CHECK_(nullHandle));
|
||||
|
||||
vmtimer->suspend(); // do not count recursive loading twice
|
||||
// Call resolve_super so classcircularity is checked
|
||||
klassOop k = SystemDictionary::resolve_super_or_fail(class_name,
|
||||
unresolved_klass, class_loader, protection_domain,
|
||||
false, CHECK_(nullHandle));
|
||||
interf = KlassHandle(THREAD, k);
|
||||
vmtimer->resume();
|
||||
|
||||
if (LinkWellKnownClasses) // my super type is well known to me
|
||||
cp->klass_at_put(interface_index, interf()); // eagerly resolve
|
||||
@ -2558,7 +2555,15 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
|
||||
|
||||
ClassFileStream* cfs = stream();
|
||||
// Timing
|
||||
PerfTraceTime vmtimer(ClassLoader::perf_accumulated_time());
|
||||
assert(THREAD->is_Java_thread(), "must be a JavaThread");
|
||||
JavaThread* jt = (JavaThread*) THREAD;
|
||||
|
||||
PerfClassTraceTime ctimer(ClassLoader::perf_class_parse_time(),
|
||||
ClassLoader::perf_class_parse_selftime(),
|
||||
NULL,
|
||||
jt->get_thread_stat()->perf_recursion_counts_addr(),
|
||||
jt->get_thread_stat()->perf_timers_addr(),
|
||||
PerfClassTraceTime::PARSE_CLASS);
|
||||
|
||||
_has_finalizer = _has_empty_finalizer = _has_vanilla_constructor = false;
|
||||
|
||||
@ -2738,7 +2743,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
|
||||
if (itfs_len == 0) {
|
||||
local_interfaces = objArrayHandle(THREAD, Universe::the_empty_system_obj_array());
|
||||
} else {
|
||||
local_interfaces = parse_interfaces(cp, itfs_len, class_loader, protection_domain, &vmtimer, _class_name, CHECK_(nullHandle));
|
||||
local_interfaces = parse_interfaces(cp, itfs_len, class_loader, protection_domain, _class_name, CHECK_(nullHandle));
|
||||
}
|
||||
|
||||
// Fields (offsets are filled in later)
|
||||
@ -2782,6 +2787,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
|
||||
protection_domain,
|
||||
true,
|
||||
CHECK_(nullHandle));
|
||||
|
||||
KlassHandle kh (THREAD, k);
|
||||
super_klass = instanceKlassHandle(THREAD, kh());
|
||||
if (LinkWellKnownClasses) // my super class is well known to me
|
||||
|
@ -61,7 +61,6 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
|
||||
int length,
|
||||
Handle class_loader,
|
||||
Handle protection_domain,
|
||||
PerfTraceTime* vmtimer,
|
||||
symbolHandle class_name,
|
||||
TRAPS);
|
||||
|
||||
|
@ -48,9 +48,26 @@ static canonicalize_fn_t CanonicalizeEntry = NULL;
|
||||
PerfCounter* ClassLoader::_perf_accumulated_time = NULL;
|
||||
PerfCounter* ClassLoader::_perf_classes_inited = NULL;
|
||||
PerfCounter* ClassLoader::_perf_class_init_time = NULL;
|
||||
PerfCounter* ClassLoader::_perf_class_init_selftime = NULL;
|
||||
PerfCounter* ClassLoader::_perf_classes_verified = NULL;
|
||||
PerfCounter* ClassLoader::_perf_class_verify_time = NULL;
|
||||
PerfCounter* ClassLoader::_perf_class_verify_selftime = NULL;
|
||||
PerfCounter* ClassLoader::_perf_classes_linked = NULL;
|
||||
PerfCounter* ClassLoader::_perf_class_link_time = NULL;
|
||||
PerfCounter* ClassLoader::_perf_class_link_selftime = NULL;
|
||||
PerfCounter* ClassLoader::_perf_class_parse_time = NULL;
|
||||
PerfCounter* ClassLoader::_perf_class_parse_selftime = NULL;
|
||||
PerfCounter* ClassLoader::_perf_sys_class_lookup_time = NULL;
|
||||
PerfCounter* ClassLoader::_perf_shared_classload_time = NULL;
|
||||
PerfCounter* ClassLoader::_perf_sys_classload_time = NULL;
|
||||
PerfCounter* ClassLoader::_perf_app_classload_time = NULL;
|
||||
PerfCounter* ClassLoader::_perf_app_classload_selftime = NULL;
|
||||
PerfCounter* ClassLoader::_perf_app_classload_count = NULL;
|
||||
PerfCounter* ClassLoader::_perf_define_appclasses = NULL;
|
||||
PerfCounter* ClassLoader::_perf_define_appclass_time = NULL;
|
||||
PerfCounter* ClassLoader::_perf_define_appclass_selftime = NULL;
|
||||
PerfCounter* ClassLoader::_perf_app_classfile_bytes_read = NULL;
|
||||
PerfCounter* ClassLoader::_perf_sys_classfile_bytes_read = NULL;
|
||||
PerfCounter* ClassLoader::_sync_systemLoaderLockContentionRate = NULL;
|
||||
PerfCounter* ClassLoader::_sync_nonSystemLoaderLockContentionRate = NULL;
|
||||
PerfCounter* ClassLoader::_sync_JVMFindLoadedClassLockFreeCounter = NULL;
|
||||
@ -152,6 +169,9 @@ ClassFileStream* ClassPathDirEntry::open_stream(const char* name) {
|
||||
hpi::close(file_handle);
|
||||
// construct ClassFileStream
|
||||
if (num_read == (size_t)st.st_size) {
|
||||
if (UsePerfData) {
|
||||
ClassLoader::perf_sys_classfile_bytes_read()->inc(num_read);
|
||||
}
|
||||
return new ClassFileStream(buffer, st.st_size, _dir); // Resource allocated
|
||||
}
|
||||
}
|
||||
@ -198,6 +218,9 @@ ClassFileStream* ClassPathZipEntry::open_stream(const char* name) {
|
||||
buffer = NEW_RESOURCE_ARRAY(u1, filesize);
|
||||
if (!(*ReadEntry)(_zip, entry, buffer, filename)) return NULL;
|
||||
}
|
||||
if (UsePerfData) {
|
||||
ClassLoader::perf_sys_classfile_bytes_read()->inc(filesize);
|
||||
}
|
||||
// return result
|
||||
return new ClassFileStream(buffer, filesize, _zip_name); // Resource allocated
|
||||
}
|
||||
@ -825,7 +848,9 @@ instanceKlassHandle ClassLoader::load_classfile(symbolHandle h_name, TRAPS) {
|
||||
ClassFileStream* stream = NULL;
|
||||
int classpath_index = 0;
|
||||
{
|
||||
PerfTraceTime vmtimer(perf_accumulated_time());
|
||||
PerfClassTraceTime vmtimer(perf_sys_class_lookup_time(),
|
||||
((JavaThread*) THREAD)->get_thread_stat()->perf_timers_addr(),
|
||||
PerfClassTraceTime::CLASS_LOAD);
|
||||
ClassPathEntry* e = _first_entry;
|
||||
while (e != NULL) {
|
||||
stream = e->open_stream(name);
|
||||
@ -890,11 +915,29 @@ void ClassLoader::initialize() {
|
||||
// jvmstat performance counters
|
||||
NEWPERFTICKCOUNTER(_perf_accumulated_time, SUN_CLS, "time");
|
||||
NEWPERFTICKCOUNTER(_perf_class_init_time, SUN_CLS, "classInitTime");
|
||||
NEWPERFTICKCOUNTER(_perf_class_init_selftime, SUN_CLS, "classInitTime.self");
|
||||
NEWPERFTICKCOUNTER(_perf_class_verify_time, SUN_CLS, "classVerifyTime");
|
||||
NEWPERFTICKCOUNTER(_perf_class_verify_selftime, SUN_CLS, "classVerifyTime.self");
|
||||
NEWPERFTICKCOUNTER(_perf_class_link_time, SUN_CLS, "classLinkedTime");
|
||||
|
||||
NEWPERFTICKCOUNTER(_perf_class_link_selftime, SUN_CLS, "classLinkedTime.self");
|
||||
NEWPERFEVENTCOUNTER(_perf_classes_inited, SUN_CLS, "initializedClasses");
|
||||
NEWPERFEVENTCOUNTER(_perf_classes_linked, SUN_CLS, "linkedClasses");
|
||||
NEWPERFEVENTCOUNTER(_perf_classes_verified, SUN_CLS, "verifiedClasses");
|
||||
|
||||
NEWPERFTICKCOUNTER(_perf_class_parse_time, SUN_CLS, "parseClassTime");
|
||||
NEWPERFTICKCOUNTER(_perf_class_parse_selftime, SUN_CLS, "parseClassTime.self");
|
||||
NEWPERFTICKCOUNTER(_perf_sys_class_lookup_time, SUN_CLS, "lookupSysClassTime");
|
||||
NEWPERFTICKCOUNTER(_perf_shared_classload_time, SUN_CLS, "sharedClassLoadTime");
|
||||
NEWPERFTICKCOUNTER(_perf_sys_classload_time, SUN_CLS, "sysClassLoadTime");
|
||||
NEWPERFTICKCOUNTER(_perf_app_classload_time, SUN_CLS, "appClassLoadTime");
|
||||
NEWPERFTICKCOUNTER(_perf_app_classload_selftime, SUN_CLS, "appClassLoadTime.self");
|
||||
NEWPERFEVENTCOUNTER(_perf_app_classload_count, SUN_CLS, "appClassLoadCount");
|
||||
NEWPERFTICKCOUNTER(_perf_define_appclasses, SUN_CLS, "defineAppClasses");
|
||||
NEWPERFTICKCOUNTER(_perf_define_appclass_time, SUN_CLS, "defineAppClassTime");
|
||||
NEWPERFTICKCOUNTER(_perf_define_appclass_selftime, SUN_CLS, "defineAppClassTime.self");
|
||||
NEWPERFBYTECOUNTER(_perf_app_classfile_bytes_read, SUN_CLS, "appClassBytes");
|
||||
NEWPERFBYTECOUNTER(_perf_sys_classfile_bytes_read, SUN_CLS, "sysClassBytes");
|
||||
|
||||
|
||||
// The following performance counters are added for measuring the impact
|
||||
// of the bug fix of 6365597. They are mainly focused on finding out
|
||||
|
@ -149,9 +149,26 @@ class ClassLoader: AllStatic {
|
||||
static PerfCounter* _perf_accumulated_time;
|
||||
static PerfCounter* _perf_classes_inited;
|
||||
static PerfCounter* _perf_class_init_time;
|
||||
static PerfCounter* _perf_class_init_selftime;
|
||||
static PerfCounter* _perf_classes_verified;
|
||||
static PerfCounter* _perf_class_verify_time;
|
||||
static PerfCounter* _perf_class_verify_selftime;
|
||||
static PerfCounter* _perf_classes_linked;
|
||||
static PerfCounter* _perf_class_link_time;
|
||||
static PerfCounter* _perf_class_link_selftime;
|
||||
static PerfCounter* _perf_class_parse_time;
|
||||
static PerfCounter* _perf_class_parse_selftime;
|
||||
static PerfCounter* _perf_sys_class_lookup_time;
|
||||
static PerfCounter* _perf_shared_classload_time;
|
||||
static PerfCounter* _perf_sys_classload_time;
|
||||
static PerfCounter* _perf_app_classload_time;
|
||||
static PerfCounter* _perf_app_classload_selftime;
|
||||
static PerfCounter* _perf_app_classload_count;
|
||||
static PerfCounter* _perf_define_appclasses;
|
||||
static PerfCounter* _perf_define_appclass_time;
|
||||
static PerfCounter* _perf_define_appclass_selftime;
|
||||
static PerfCounter* _perf_app_classfile_bytes_read;
|
||||
static PerfCounter* _perf_sys_classfile_bytes_read;
|
||||
|
||||
static PerfCounter* _sync_systemLoaderLockContentionRate;
|
||||
static PerfCounter* _sync_nonSystemLoaderLockContentionRate;
|
||||
@ -196,12 +213,29 @@ class ClassLoader: AllStatic {
|
||||
static void print_bootclasspath();
|
||||
|
||||
// Timing
|
||||
static PerfCounter* perf_accumulated_time() { return _perf_accumulated_time; }
|
||||
static PerfCounter* perf_classes_inited() { return _perf_classes_inited; }
|
||||
static PerfCounter* perf_class_init_time() { return _perf_class_init_time; }
|
||||
static PerfCounter* perf_class_verify_time() { return _perf_class_verify_time; }
|
||||
static PerfCounter* perf_classes_linked() { return _perf_classes_linked; }
|
||||
static PerfCounter* perf_class_link_time() { return _perf_class_link_time; }
|
||||
static PerfCounter* perf_accumulated_time() { return _perf_accumulated_time; }
|
||||
static PerfCounter* perf_classes_inited() { return _perf_classes_inited; }
|
||||
static PerfCounter* perf_class_init_time() { return _perf_class_init_time; }
|
||||
static PerfCounter* perf_class_init_selftime() { return _perf_class_init_selftime; }
|
||||
static PerfCounter* perf_classes_verified() { return _perf_classes_verified; }
|
||||
static PerfCounter* perf_class_verify_time() { return _perf_class_verify_time; }
|
||||
static PerfCounter* perf_class_verify_selftime() { return _perf_class_verify_selftime; }
|
||||
static PerfCounter* perf_classes_linked() { return _perf_classes_linked; }
|
||||
static PerfCounter* perf_class_link_time() { return _perf_class_link_time; }
|
||||
static PerfCounter* perf_class_link_selftime() { return _perf_class_link_selftime; }
|
||||
static PerfCounter* perf_class_parse_time() { return _perf_class_parse_time; }
|
||||
static PerfCounter* perf_class_parse_selftime() { return _perf_class_parse_selftime; }
|
||||
static PerfCounter* perf_sys_class_lookup_time() { return _perf_sys_class_lookup_time; }
|
||||
static PerfCounter* perf_shared_classload_time() { return _perf_shared_classload_time; }
|
||||
static PerfCounter* perf_sys_classload_time() { return _perf_sys_classload_time; }
|
||||
static PerfCounter* perf_app_classload_time() { return _perf_app_classload_time; }
|
||||
static PerfCounter* perf_app_classload_selftime() { return _perf_app_classload_selftime; }
|
||||
static PerfCounter* perf_app_classload_count() { return _perf_app_classload_count; }
|
||||
static PerfCounter* perf_define_appclasses() { return _perf_define_appclasses; }
|
||||
static PerfCounter* perf_define_appclass_time() { return _perf_define_appclass_time; }
|
||||
static PerfCounter* perf_define_appclass_selftime() { return _perf_define_appclass_selftime; }
|
||||
static PerfCounter* perf_app_classfile_bytes_read() { return _perf_app_classfile_bytes_read; }
|
||||
static PerfCounter* perf_sys_classfile_bytes_read() { return _perf_sys_classfile_bytes_read; }
|
||||
|
||||
// Record how often system loader lock object is contended
|
||||
static PerfCounter* sync_systemLoaderLockContentionRate() {
|
||||
@ -307,3 +341,118 @@ class ClassLoader: AllStatic {
|
||||
static int compile_the_world_counter() { return _compile_the_world_counter; }
|
||||
#endif //PRODUCT
|
||||
};
|
||||
|
||||
// PerfClassTraceTime is used to measure time for class loading related events.
|
||||
// This class tracks cumulative time and exclusive time for specific event types.
|
||||
// During the execution of one event, other event types (e.g. class loading and
|
||||
// resolution) as well as recursive calls of the same event type could happen.
|
||||
// Only one elapsed timer (cumulative) and one thread-local self timer (exclusive)
|
||||
// (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;
|
||||
|
||||
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();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1306,13 +1306,18 @@ static instanceKlassHandle download_and_retry_class_load(
|
||||
instanceKlassHandle SystemDictionary::load_instance_class(symbolHandle class_name, Handle class_loader, TRAPS) {
|
||||
instanceKlassHandle nh = instanceKlassHandle(); // null Handle
|
||||
if (class_loader.is_null()) {
|
||||
|
||||
// Search the shared system dictionary for classes preloaded into the
|
||||
// shared spaces.
|
||||
instanceKlassHandle k;
|
||||
k = load_shared_class(class_name, class_loader, THREAD);
|
||||
{
|
||||
PerfTraceTime vmtimer(ClassLoader::perf_shared_classload_time());
|
||||
k = load_shared_class(class_name, class_loader, THREAD);
|
||||
}
|
||||
|
||||
if (k.is_null()) {
|
||||
// Use VM class loader
|
||||
PerfTraceTime vmtimer(ClassLoader::perf_sys_classload_time());
|
||||
k = ClassLoader::load_classfile(class_name, CHECK_(nh));
|
||||
}
|
||||
|
||||
@ -1334,6 +1339,16 @@ instanceKlassHandle SystemDictionary::load_instance_class(symbolHandle class_nam
|
||||
// Use user specified class loader to load class. Call loadClass operation on class_loader.
|
||||
ResourceMark rm(THREAD);
|
||||
|
||||
assert(THREAD->is_Java_thread(), "must be a JavaThread");
|
||||
JavaThread* jt = (JavaThread*) THREAD;
|
||||
|
||||
PerfClassTraceTime vmtimer(ClassLoader::perf_app_classload_time(),
|
||||
ClassLoader::perf_app_classload_selftime(),
|
||||
ClassLoader::perf_app_classload_count(),
|
||||
jt->get_thread_stat()->perf_recursion_counts_addr(),
|
||||
jt->get_thread_stat()->perf_timers_addr(),
|
||||
PerfClassTraceTime::CLASS_LOAD);
|
||||
|
||||
Handle s = java_lang_String::create_from_symbol(class_name, CHECK_(nh));
|
||||
// Translate to external class name format, i.e., convert '/' chars to '.'
|
||||
Handle string = java_lang_String::externalize_classname(s, CHECK_(nh));
|
||||
|
@ -874,6 +874,7 @@ classFileParser.cpp signature.hpp
|
||||
classFileParser.cpp symbolOop.hpp
|
||||
classFileParser.cpp symbolTable.hpp
|
||||
classFileParser.cpp systemDictionary.hpp
|
||||
classFileParser.cpp threadService.hpp
|
||||
classFileParser.cpp timer.hpp
|
||||
classFileParser.cpp universe.inline.hpp
|
||||
classFileParser.cpp verificationType.hpp
|
||||
@ -926,6 +927,7 @@ classLoader.cpp os_<os_family>.inline.hpp
|
||||
classLoader.cpp symbolOop.hpp
|
||||
classLoader.cpp systemDictionary.hpp
|
||||
classLoader.cpp threadCritical.hpp
|
||||
classLoader.cpp threadService.hpp
|
||||
classLoader.cpp timer.hpp
|
||||
classLoader.cpp universe.inline.hpp
|
||||
classLoader.cpp vmSymbols.hpp
|
||||
@ -4026,6 +4028,7 @@ systemDictionary.cpp placeholders.hpp
|
||||
systemDictionary.cpp resolutionErrors.hpp
|
||||
systemDictionary.cpp signature.hpp
|
||||
systemDictionary.cpp systemDictionary.hpp
|
||||
systemDictionary.cpp threadService.hpp
|
||||
systemDictionary.cpp typeArrayKlass.hpp
|
||||
systemDictionary.cpp vmSymbols.hpp
|
||||
|
||||
|
@ -158,9 +158,6 @@ bool instanceKlass::link_class_impl(
|
||||
// timer handles recursion
|
||||
assert(THREAD->is_Java_thread(), "non-JavaThread in link_class_impl");
|
||||
JavaThread* jt = (JavaThread*)THREAD;
|
||||
PerfTraceTimedEvent vmtimer(ClassLoader::perf_class_link_time(),
|
||||
ClassLoader::perf_classes_linked(),
|
||||
jt->get_thread_stat()->class_link_recursion_count_addr());
|
||||
|
||||
// link super class before linking this class
|
||||
instanceKlassHandle super(THREAD, this_oop->super());
|
||||
@ -194,6 +191,15 @@ bool instanceKlass::link_class_impl(
|
||||
return true;
|
||||
}
|
||||
|
||||
// trace only the link time for this klass that includes
|
||||
// the verification time
|
||||
PerfClassTraceTime vmtimer(ClassLoader::perf_class_link_time(),
|
||||
ClassLoader::perf_class_link_selftime(),
|
||||
ClassLoader::perf_classes_linked(),
|
||||
jt->get_thread_stat()->perf_recursion_counts_addr(),
|
||||
jt->get_thread_stat()->perf_timers_addr(),
|
||||
PerfClassTraceTime::CLASS_LINK);
|
||||
|
||||
// verification & rewriting
|
||||
{
|
||||
ObjectLocker ol(this_oop, THREAD);
|
||||
@ -203,12 +209,14 @@ bool instanceKlass::link_class_impl(
|
||||
if (!this_oop->is_linked()) {
|
||||
if (!this_oop->is_rewritten()) {
|
||||
{
|
||||
assert(THREAD->is_Java_thread(), "non-JavaThread in link_class_impl");
|
||||
JavaThread* jt = (JavaThread*)THREAD;
|
||||
// Timer includes any side effects of class verification (resolution,
|
||||
// etc), but not recursive entry into verify_code().
|
||||
PerfTraceTime timer(ClassLoader::perf_class_verify_time(),
|
||||
jt->get_thread_stat()->class_verify_recursion_count_addr());
|
||||
PerfClassTraceTime timer(ClassLoader::perf_class_verify_time(),
|
||||
ClassLoader::perf_class_verify_selftime(),
|
||||
ClassLoader::perf_classes_verified(),
|
||||
jt->get_thread_stat()->perf_recursion_counts_addr(),
|
||||
jt->get_thread_stat()->perf_timers_addr(),
|
||||
PerfClassTraceTime::CLASS_VERIFY);
|
||||
bool verify_ok = verify_code(this_oop, throw_verifyerror, THREAD);
|
||||
if (!verify_ok) {
|
||||
return false;
|
||||
@ -350,9 +358,12 @@ void instanceKlass::initialize_impl(instanceKlassHandle this_oop, TRAPS) {
|
||||
JavaThread* jt = (JavaThread*)THREAD;
|
||||
// Timer includes any side effects of class initialization (resolution,
|
||||
// etc), but not recursive entry into call_class_initializer().
|
||||
PerfTraceTimedEvent timer(ClassLoader::perf_class_init_time(),
|
||||
ClassLoader::perf_classes_inited(),
|
||||
jt->get_thread_stat()->class_init_recursion_count_addr());
|
||||
PerfClassTraceTime timer(ClassLoader::perf_class_init_time(),
|
||||
ClassLoader::perf_class_init_selftime(),
|
||||
ClassLoader::perf_classes_inited(),
|
||||
jt->get_thread_stat()->perf_recursion_counts_addr(),
|
||||
jt->get_thread_stat()->perf_timers_addr(),
|
||||
PerfClassTraceTime::CLASS_CLINIT);
|
||||
this_oop->call_class_initializer(THREAD);
|
||||
}
|
||||
|
||||
|
@ -756,6 +756,20 @@ static void is_lock_held_by_thread(Handle loader, PerfCounter* counter, TRAPS) {
|
||||
static jclass jvm_define_class_common(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd, const char *source, TRAPS) {
|
||||
if (source == NULL) source = "__JVM_DefineClass__";
|
||||
|
||||
assert(THREAD->is_Java_thread(), "must be a JavaThread");
|
||||
JavaThread* jt = (JavaThread*) THREAD;
|
||||
|
||||
PerfClassTraceTime vmtimer(ClassLoader::perf_define_appclass_time(),
|
||||
ClassLoader::perf_define_appclass_selftime(),
|
||||
ClassLoader::perf_define_appclasses(),
|
||||
jt->get_thread_stat()->perf_recursion_counts_addr(),
|
||||
jt->get_thread_stat()->perf_timers_addr(),
|
||||
PerfClassTraceTime::DEFINE_CLASS);
|
||||
|
||||
if (UsePerfData) {
|
||||
ClassLoader::perf_app_classfile_bytes_read()->inc(len);
|
||||
}
|
||||
|
||||
// Since exceptions can be thrown, class initialization can take place
|
||||
// if name is NULL no check for class name in .class stream has to be made.
|
||||
symbolHandle class_name;
|
||||
|
@ -868,6 +868,10 @@ class PerfDataManager : AllStatic {
|
||||
{counter = PerfDataManager::create_counter(counter_ns, counter_name, \
|
||||
PerfData::U_Events,CHECK);}
|
||||
|
||||
#define NEWPERFBYTECOUNTER(counter, counter_ns, counter_name) \
|
||||
{counter = PerfDataManager::create_counter(counter_ns, counter_name, \
|
||||
PerfData::U_Bytes,CHECK);}
|
||||
|
||||
// Utility Classes
|
||||
|
||||
/*
|
||||
|
@ -688,10 +688,9 @@ ThreadStatistics::ThreadStatistics() {
|
||||
_contended_enter_count = 0;
|
||||
_monitor_wait_count = 0;
|
||||
_sleep_count = 0;
|
||||
_class_init_recursion_count = 0;
|
||||
_class_verify_recursion_count = 0;
|
||||
_count_pending_reset = false;
|
||||
_timer_pending_reset = false;
|
||||
memset((void*) _perf_recursion_counts, 0, sizeof(_perf_recursion_counts));
|
||||
}
|
||||
|
||||
ThreadSnapshot::ThreadSnapshot(JavaThread* thread) {
|
||||
|
@ -120,9 +120,8 @@ private:
|
||||
bool _timer_pending_reset;
|
||||
|
||||
// Keep accurate times for potentially recursive class operations
|
||||
int _class_init_recursion_count;
|
||||
int _class_verify_recursion_count;
|
||||
int _class_link_recursion_count;
|
||||
int _perf_recursion_counts[6];
|
||||
elapsedTimer _perf_timers[6];
|
||||
|
||||
// utility functions
|
||||
void check_and_reset_count() {
|
||||
@ -165,9 +164,8 @@ public:
|
||||
void reset_count_stat() { _count_pending_reset = true; }
|
||||
void reset_time_stat() { _timer_pending_reset = true; }
|
||||
|
||||
int* class_init_recursion_count_addr() { return &_class_init_recursion_count; }
|
||||
int* class_verify_recursion_count_addr() { return &_class_verify_recursion_count; }
|
||||
int* class_link_recursion_count_addr() { return &_class_link_recursion_count; }
|
||||
int* perf_recursion_counts_addr() { return _perf_recursion_counts; }
|
||||
elapsedTimer* perf_timers_addr() { return _perf_timers; }
|
||||
};
|
||||
|
||||
// Thread snapshot to represent the thread state and statistics
|
||||
|
Loading…
Reference in New Issue
Block a user