提交 7cf63ee4 编写于 作者: M mchung

6857194: Add hotspot perf counters to aid class loading performance measurement

Summary: Add new jvmstat counters to measure detailed class loading time
Reviewed-by: acorn, kamg
上级 b8dad703
...@@ -547,7 +547,6 @@ objArrayHandle ClassFileParser::parse_interfaces(constantPoolHandle cp, ...@@ -547,7 +547,6 @@ objArrayHandle ClassFileParser::parse_interfaces(constantPoolHandle cp,
int length, int length,
Handle class_loader, Handle class_loader,
Handle protection_domain, Handle protection_domain,
PerfTraceTime* vmtimer,
symbolHandle class_name, symbolHandle class_name,
TRAPS) { TRAPS) {
ClassFileStream* cfs = stream(); ClassFileStream* cfs = stream();
...@@ -575,13 +574,11 @@ objArrayHandle ClassFileParser::parse_interfaces(constantPoolHandle cp, ...@@ -575,13 +574,11 @@ objArrayHandle ClassFileParser::parse_interfaces(constantPoolHandle cp,
guarantee_property(unresolved_klass->byte_at(0) != JVM_SIGNATURE_ARRAY, guarantee_property(unresolved_klass->byte_at(0) != JVM_SIGNATURE_ARRAY,
"Bad interface name in class file %s", CHECK_(nullHandle)); "Bad interface name in class file %s", CHECK_(nullHandle));
vmtimer->suspend(); // do not count recursive loading twice
// Call resolve_super so classcircularity is checked // Call resolve_super so classcircularity is checked
klassOop k = SystemDictionary::resolve_super_or_fail(class_name, klassOop k = SystemDictionary::resolve_super_or_fail(class_name,
unresolved_klass, class_loader, protection_domain, unresolved_klass, class_loader, protection_domain,
false, CHECK_(nullHandle)); false, CHECK_(nullHandle));
interf = KlassHandle(THREAD, k); interf = KlassHandle(THREAD, k);
vmtimer->resume();
if (LinkWellKnownClasses) // my super type is well known to me if (LinkWellKnownClasses) // my super type is well known to me
cp->klass_at_put(interface_index, interf()); // eagerly resolve cp->klass_at_put(interface_index, interf()); // eagerly resolve
...@@ -2558,7 +2555,15 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name, ...@@ -2558,7 +2555,15 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
ClassFileStream* cfs = stream(); ClassFileStream* cfs = stream();
// Timing // 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; _has_finalizer = _has_empty_finalizer = _has_vanilla_constructor = false;
...@@ -2738,7 +2743,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name, ...@@ -2738,7 +2743,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
if (itfs_len == 0) { if (itfs_len == 0) {
local_interfaces = objArrayHandle(THREAD, Universe::the_empty_system_obj_array()); local_interfaces = objArrayHandle(THREAD, Universe::the_empty_system_obj_array());
} else { } 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) // Fields (offsets are filled in later)
...@@ -2782,6 +2787,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name, ...@@ -2782,6 +2787,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
protection_domain, protection_domain,
true, true,
CHECK_(nullHandle)); CHECK_(nullHandle));
KlassHandle kh (THREAD, k); KlassHandle kh (THREAD, k);
super_klass = instanceKlassHandle(THREAD, kh()); super_klass = instanceKlassHandle(THREAD, kh());
if (LinkWellKnownClasses) // my super class is well known to me if (LinkWellKnownClasses) // my super class is well known to me
......
...@@ -61,7 +61,6 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC { ...@@ -61,7 +61,6 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
int length, int length,
Handle class_loader, Handle class_loader,
Handle protection_domain, Handle protection_domain,
PerfTraceTime* vmtimer,
symbolHandle class_name, symbolHandle class_name,
TRAPS); TRAPS);
......
...@@ -48,9 +48,26 @@ static canonicalize_fn_t CanonicalizeEntry = NULL; ...@@ -48,9 +48,26 @@ static canonicalize_fn_t CanonicalizeEntry = NULL;
PerfCounter* ClassLoader::_perf_accumulated_time = NULL; PerfCounter* ClassLoader::_perf_accumulated_time = NULL;
PerfCounter* ClassLoader::_perf_classes_inited = NULL; PerfCounter* ClassLoader::_perf_classes_inited = NULL;
PerfCounter* ClassLoader::_perf_class_init_time = 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_time = NULL;
PerfCounter* ClassLoader::_perf_class_verify_selftime = NULL;
PerfCounter* ClassLoader::_perf_classes_linked = NULL; PerfCounter* ClassLoader::_perf_classes_linked = NULL;
PerfCounter* ClassLoader::_perf_class_link_time = 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_systemLoaderLockContentionRate = NULL;
PerfCounter* ClassLoader::_sync_nonSystemLoaderLockContentionRate = NULL; PerfCounter* ClassLoader::_sync_nonSystemLoaderLockContentionRate = NULL;
PerfCounter* ClassLoader::_sync_JVMFindLoadedClassLockFreeCounter = NULL; PerfCounter* ClassLoader::_sync_JVMFindLoadedClassLockFreeCounter = NULL;
...@@ -152,6 +169,9 @@ ClassFileStream* ClassPathDirEntry::open_stream(const char* name) { ...@@ -152,6 +169,9 @@ ClassFileStream* ClassPathDirEntry::open_stream(const char* name) {
hpi::close(file_handle); hpi::close(file_handle);
// construct ClassFileStream // construct ClassFileStream
if (num_read == (size_t)st.st_size) { 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 return new ClassFileStream(buffer, st.st_size, _dir); // Resource allocated
} }
} }
...@@ -198,6 +218,9 @@ ClassFileStream* ClassPathZipEntry::open_stream(const char* name) { ...@@ -198,6 +218,9 @@ ClassFileStream* ClassPathZipEntry::open_stream(const char* name) {
buffer = NEW_RESOURCE_ARRAY(u1, filesize); buffer = NEW_RESOURCE_ARRAY(u1, filesize);
if (!(*ReadEntry)(_zip, entry, buffer, filename)) return NULL; if (!(*ReadEntry)(_zip, entry, buffer, filename)) return NULL;
} }
if (UsePerfData) {
ClassLoader::perf_sys_classfile_bytes_read()->inc(filesize);
}
// return result // return result
return new ClassFileStream(buffer, filesize, _zip_name); // Resource allocated return new ClassFileStream(buffer, filesize, _zip_name); // Resource allocated
} }
...@@ -825,7 +848,9 @@ instanceKlassHandle ClassLoader::load_classfile(symbolHandle h_name, TRAPS) { ...@@ -825,7 +848,9 @@ instanceKlassHandle ClassLoader::load_classfile(symbolHandle h_name, TRAPS) {
ClassFileStream* stream = NULL; ClassFileStream* stream = NULL;
int classpath_index = 0; 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; ClassPathEntry* e = _first_entry;
while (e != NULL) { while (e != NULL) {
stream = e->open_stream(name); stream = e->open_stream(name);
...@@ -890,11 +915,29 @@ void ClassLoader::initialize() { ...@@ -890,11 +915,29 @@ void ClassLoader::initialize() {
// jvmstat performance counters // jvmstat performance counters
NEWPERFTICKCOUNTER(_perf_accumulated_time, SUN_CLS, "time"); NEWPERFTICKCOUNTER(_perf_accumulated_time, SUN_CLS, "time");
NEWPERFTICKCOUNTER(_perf_class_init_time, SUN_CLS, "classInitTime"); 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_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_time, SUN_CLS, "classLinkedTime");
NEWPERFTICKCOUNTER(_perf_class_link_selftime, SUN_CLS, "classLinkedTime.self");
NEWPERFEVENTCOUNTER(_perf_classes_inited, SUN_CLS, "initializedClasses"); NEWPERFEVENTCOUNTER(_perf_classes_inited, SUN_CLS, "initializedClasses");
NEWPERFEVENTCOUNTER(_perf_classes_linked, SUN_CLS, "linkedClasses"); 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 // The following performance counters are added for measuring the impact
// of the bug fix of 6365597. They are mainly focused on finding out // of the bug fix of 6365597. They are mainly focused on finding out
......
...@@ -149,9 +149,26 @@ class ClassLoader: AllStatic { ...@@ -149,9 +149,26 @@ class ClassLoader: AllStatic {
static PerfCounter* _perf_accumulated_time; static PerfCounter* _perf_accumulated_time;
static PerfCounter* _perf_classes_inited; static PerfCounter* _perf_classes_inited;
static PerfCounter* _perf_class_init_time; 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_time;
static PerfCounter* _perf_class_verify_selftime;
static PerfCounter* _perf_classes_linked; static PerfCounter* _perf_classes_linked;
static PerfCounter* _perf_class_link_time; 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_systemLoaderLockContentionRate;
static PerfCounter* _sync_nonSystemLoaderLockContentionRate; static PerfCounter* _sync_nonSystemLoaderLockContentionRate;
...@@ -196,12 +213,29 @@ class ClassLoader: AllStatic { ...@@ -196,12 +213,29 @@ class ClassLoader: AllStatic {
static void print_bootclasspath(); static void print_bootclasspath();
// Timing // Timing
static PerfCounter* perf_accumulated_time() { return _perf_accumulated_time; } static PerfCounter* perf_accumulated_time() { return _perf_accumulated_time; }
static PerfCounter* perf_classes_inited() { return _perf_classes_inited; } 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_time() { return _perf_class_init_time; }
static PerfCounter* perf_class_verify_time() { return _perf_class_verify_time; } static PerfCounter* perf_class_init_selftime() { return _perf_class_init_selftime; }
static PerfCounter* perf_classes_linked() { return _perf_classes_linked; } static PerfCounter* perf_classes_verified() { return _perf_classes_verified; }
static PerfCounter* perf_class_link_time() { return _perf_class_link_time; } 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 // Record how often system loader lock object is contended
static PerfCounter* sync_systemLoaderLockContentionRate() { static PerfCounter* sync_systemLoaderLockContentionRate() {
...@@ -307,3 +341,118 @@ class ClassLoader: AllStatic { ...@@ -307,3 +341,118 @@ class ClassLoader: AllStatic {
static int compile_the_world_counter() { return _compile_the_world_counter; } static int compile_the_world_counter() { return _compile_the_world_counter; }
#endif //PRODUCT #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( ...@@ -1306,13 +1306,18 @@ static instanceKlassHandle download_and_retry_class_load(
instanceKlassHandle SystemDictionary::load_instance_class(symbolHandle class_name, Handle class_loader, TRAPS) { instanceKlassHandle SystemDictionary::load_instance_class(symbolHandle class_name, Handle class_loader, TRAPS) {
instanceKlassHandle nh = instanceKlassHandle(); // null Handle instanceKlassHandle nh = instanceKlassHandle(); // null Handle
if (class_loader.is_null()) { if (class_loader.is_null()) {
// Search the shared system dictionary for classes preloaded into the // Search the shared system dictionary for classes preloaded into the
// shared spaces. // shared spaces.
instanceKlassHandle k; 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()) { if (k.is_null()) {
// Use VM class loader // Use VM class loader
PerfTraceTime vmtimer(ClassLoader::perf_sys_classload_time());
k = ClassLoader::load_classfile(class_name, CHECK_(nh)); k = ClassLoader::load_classfile(class_name, CHECK_(nh));
} }
...@@ -1334,6 +1339,16 @@ instanceKlassHandle SystemDictionary::load_instance_class(symbolHandle class_nam ...@@ -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. // Use user specified class loader to load class. Call loadClass operation on class_loader.
ResourceMark rm(THREAD); 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)); Handle s = java_lang_String::create_from_symbol(class_name, CHECK_(nh));
// Translate to external class name format, i.e., convert '/' chars to '.' // Translate to external class name format, i.e., convert '/' chars to '.'
Handle string = java_lang_String::externalize_classname(s, CHECK_(nh)); Handle string = java_lang_String::externalize_classname(s, CHECK_(nh));
......
...@@ -874,6 +874,7 @@ classFileParser.cpp signature.hpp ...@@ -874,6 +874,7 @@ classFileParser.cpp signature.hpp
classFileParser.cpp symbolOop.hpp classFileParser.cpp symbolOop.hpp
classFileParser.cpp symbolTable.hpp classFileParser.cpp symbolTable.hpp
classFileParser.cpp systemDictionary.hpp classFileParser.cpp systemDictionary.hpp
classFileParser.cpp threadService.hpp
classFileParser.cpp timer.hpp classFileParser.cpp timer.hpp
classFileParser.cpp universe.inline.hpp classFileParser.cpp universe.inline.hpp
classFileParser.cpp verificationType.hpp classFileParser.cpp verificationType.hpp
...@@ -926,6 +927,7 @@ classLoader.cpp os_<os_family>.inline.hpp ...@@ -926,6 +927,7 @@ classLoader.cpp os_<os_family>.inline.hpp
classLoader.cpp symbolOop.hpp classLoader.cpp symbolOop.hpp
classLoader.cpp systemDictionary.hpp classLoader.cpp systemDictionary.hpp
classLoader.cpp threadCritical.hpp classLoader.cpp threadCritical.hpp
classLoader.cpp threadService.hpp
classLoader.cpp timer.hpp classLoader.cpp timer.hpp
classLoader.cpp universe.inline.hpp classLoader.cpp universe.inline.hpp
classLoader.cpp vmSymbols.hpp classLoader.cpp vmSymbols.hpp
...@@ -4026,6 +4028,7 @@ systemDictionary.cpp placeholders.hpp ...@@ -4026,6 +4028,7 @@ systemDictionary.cpp placeholders.hpp
systemDictionary.cpp resolutionErrors.hpp systemDictionary.cpp resolutionErrors.hpp
systemDictionary.cpp signature.hpp systemDictionary.cpp signature.hpp
systemDictionary.cpp systemDictionary.hpp systemDictionary.cpp systemDictionary.hpp
systemDictionary.cpp threadService.hpp
systemDictionary.cpp typeArrayKlass.hpp systemDictionary.cpp typeArrayKlass.hpp
systemDictionary.cpp vmSymbols.hpp systemDictionary.cpp vmSymbols.hpp
......
...@@ -158,9 +158,6 @@ bool instanceKlass::link_class_impl( ...@@ -158,9 +158,6 @@ bool instanceKlass::link_class_impl(
// timer handles recursion // timer handles recursion
assert(THREAD->is_Java_thread(), "non-JavaThread in link_class_impl"); assert(THREAD->is_Java_thread(), "non-JavaThread in link_class_impl");
JavaThread* jt = (JavaThread*)THREAD; 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 // link super class before linking this class
instanceKlassHandle super(THREAD, this_oop->super()); instanceKlassHandle super(THREAD, this_oop->super());
...@@ -194,6 +191,15 @@ bool instanceKlass::link_class_impl( ...@@ -194,6 +191,15 @@ bool instanceKlass::link_class_impl(
return true; 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 // verification & rewriting
{ {
ObjectLocker ol(this_oop, THREAD); ObjectLocker ol(this_oop, THREAD);
...@@ -203,12 +209,14 @@ bool instanceKlass::link_class_impl( ...@@ -203,12 +209,14 @@ bool instanceKlass::link_class_impl(
if (!this_oop->is_linked()) { if (!this_oop->is_linked()) {
if (!this_oop->is_rewritten()) { 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, // Timer includes any side effects of class verification (resolution,
// etc), but not recursive entry into verify_code(). // etc), but not recursive entry into verify_code().
PerfTraceTime timer(ClassLoader::perf_class_verify_time(), PerfClassTraceTime timer(ClassLoader::perf_class_verify_time(),
jt->get_thread_stat()->class_verify_recursion_count_addr()); 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); bool verify_ok = verify_code(this_oop, throw_verifyerror, THREAD);
if (!verify_ok) { if (!verify_ok) {
return false; return false;
...@@ -350,9 +358,12 @@ void instanceKlass::initialize_impl(instanceKlassHandle this_oop, TRAPS) { ...@@ -350,9 +358,12 @@ void instanceKlass::initialize_impl(instanceKlassHandle this_oop, TRAPS) {
JavaThread* jt = (JavaThread*)THREAD; JavaThread* jt = (JavaThread*)THREAD;
// Timer includes any side effects of class initialization (resolution, // Timer includes any side effects of class initialization (resolution,
// etc), but not recursive entry into call_class_initializer(). // etc), but not recursive entry into call_class_initializer().
PerfTraceTimedEvent timer(ClassLoader::perf_class_init_time(), PerfClassTraceTime timer(ClassLoader::perf_class_init_time(),
ClassLoader::perf_classes_inited(), ClassLoader::perf_class_init_selftime(),
jt->get_thread_stat()->class_init_recursion_count_addr()); 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); this_oop->call_class_initializer(THREAD);
} }
......
...@@ -756,6 +756,20 @@ static void is_lock_held_by_thread(Handle loader, PerfCounter* counter, TRAPS) { ...@@ -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) { 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__"; 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 // 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. // if name is NULL no check for class name in .class stream has to be made.
symbolHandle class_name; symbolHandle class_name;
......
...@@ -868,6 +868,10 @@ class PerfDataManager : AllStatic { ...@@ -868,6 +868,10 @@ class PerfDataManager : AllStatic {
{counter = PerfDataManager::create_counter(counter_ns, counter_name, \ {counter = PerfDataManager::create_counter(counter_ns, counter_name, \
PerfData::U_Events,CHECK);} 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 // Utility Classes
/* /*
......
...@@ -688,10 +688,9 @@ ThreadStatistics::ThreadStatistics() { ...@@ -688,10 +688,9 @@ ThreadStatistics::ThreadStatistics() {
_contended_enter_count = 0; _contended_enter_count = 0;
_monitor_wait_count = 0; _monitor_wait_count = 0;
_sleep_count = 0; _sleep_count = 0;
_class_init_recursion_count = 0;
_class_verify_recursion_count = 0;
_count_pending_reset = false; _count_pending_reset = false;
_timer_pending_reset = false; _timer_pending_reset = false;
memset((void*) _perf_recursion_counts, 0, sizeof(_perf_recursion_counts));
} }
ThreadSnapshot::ThreadSnapshot(JavaThread* thread) { ThreadSnapshot::ThreadSnapshot(JavaThread* thread) {
......
...@@ -120,9 +120,8 @@ private: ...@@ -120,9 +120,8 @@ private:
bool _timer_pending_reset; bool _timer_pending_reset;
// Keep accurate times for potentially recursive class operations // Keep accurate times for potentially recursive class operations
int _class_init_recursion_count; int _perf_recursion_counts[6];
int _class_verify_recursion_count; elapsedTimer _perf_timers[6];
int _class_link_recursion_count;
// utility functions // utility functions
void check_and_reset_count() { void check_and_reset_count() {
...@@ -165,9 +164,8 @@ public: ...@@ -165,9 +164,8 @@ public:
void reset_count_stat() { _count_pending_reset = true; } void reset_count_stat() { _count_pending_reset = true; }
void reset_time_stat() { _timer_pending_reset = true; } void reset_time_stat() { _timer_pending_reset = true; }
int* class_init_recursion_count_addr() { return &_class_init_recursion_count; } int* perf_recursion_counts_addr() { return _perf_recursion_counts; }
int* class_verify_recursion_count_addr() { return &_class_verify_recursion_count; } elapsedTimer* perf_timers_addr() { return _perf_timers; }
int* class_link_recursion_count_addr() { return &_class_link_recursion_count; }
}; };
// Thread snapshot to represent the thread state and statistics // Thread snapshot to represent the thread state and statistics
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册