8259809: Remove PerfEvent class loading locking counters
Reviewed-by: redestad, iklam
This commit is contained in:
parent
b4ace3e979
commit
81a66dfa81
@ -132,11 +132,6 @@ PerfCounter* ClassLoader::_perf_define_appclass_time = NULL;
|
|||||||
PerfCounter* ClassLoader::_perf_define_appclass_selftime = NULL;
|
PerfCounter* ClassLoader::_perf_define_appclass_selftime = NULL;
|
||||||
PerfCounter* ClassLoader::_perf_app_classfile_bytes_read = NULL;
|
PerfCounter* ClassLoader::_perf_app_classfile_bytes_read = NULL;
|
||||||
PerfCounter* ClassLoader::_perf_sys_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;
|
|
||||||
PerfCounter* ClassLoader::_sync_JVMDefineClassLockFreeCounter = NULL;
|
|
||||||
PerfCounter* ClassLoader::_sync_JNIDefineClassLockFreeCounter = NULL;
|
|
||||||
PerfCounter* ClassLoader::_unsafe_defineClassCallCounter = NULL;
|
PerfCounter* ClassLoader::_unsafe_defineClassCallCounter = NULL;
|
||||||
|
|
||||||
GrowableArray<ModuleClassPathList*>* ClassLoader::_patch_mod_entries = NULL;
|
GrowableArray<ModuleClassPathList*>* ClassLoader::_patch_mod_entries = NULL;
|
||||||
@ -1462,25 +1457,7 @@ void ClassLoader::initialize() {
|
|||||||
NEWPERFBYTECOUNTER(_perf_app_classfile_bytes_read, SUN_CLS, "appClassBytes");
|
NEWPERFBYTECOUNTER(_perf_app_classfile_bytes_read, SUN_CLS, "appClassBytes");
|
||||||
NEWPERFBYTECOUNTER(_perf_sys_classfile_bytes_read, SUN_CLS, "sysClassBytes");
|
NEWPERFBYTECOUNTER(_perf_sys_classfile_bytes_read, SUN_CLS, "sysClassBytes");
|
||||||
|
|
||||||
|
NEWPERFEVENTCOUNTER(_unsafe_defineClassCallCounter, SUN_CLS, "unsafeDefineClassCalls");
|
||||||
// The following performance counters are added for measuring the impact
|
|
||||||
// of the bug fix of 6365597. They are mainly focused on finding out
|
|
||||||
// the behavior of system & user-defined classloader lock, whether
|
|
||||||
// ClassLoader.loadClass/findClass is being called synchronized or not.
|
|
||||||
NEWPERFEVENTCOUNTER(_sync_systemLoaderLockContentionRate, SUN_CLS,
|
|
||||||
"systemLoaderLockContentionRate");
|
|
||||||
NEWPERFEVENTCOUNTER(_sync_nonSystemLoaderLockContentionRate, SUN_CLS,
|
|
||||||
"nonSystemLoaderLockContentionRate");
|
|
||||||
NEWPERFEVENTCOUNTER(_sync_JVMFindLoadedClassLockFreeCounter, SUN_CLS,
|
|
||||||
"jvmFindLoadedClassNoLockCalls");
|
|
||||||
NEWPERFEVENTCOUNTER(_sync_JVMDefineClassLockFreeCounter, SUN_CLS,
|
|
||||||
"jvmDefineClassNoLockCalls");
|
|
||||||
|
|
||||||
NEWPERFEVENTCOUNTER(_sync_JNIDefineClassLockFreeCounter, SUN_CLS,
|
|
||||||
"jniDefineClassNoLockCalls");
|
|
||||||
|
|
||||||
NEWPERFEVENTCOUNTER(_unsafe_defineClassCallCounter, SUN_CLS,
|
|
||||||
"unsafeDefineClassCalls");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// lookup java library entry points
|
// lookup java library entry points
|
||||||
|
@ -182,12 +182,6 @@ class ClassLoader: AllStatic {
|
|||||||
static PerfCounter* _perf_app_classfile_bytes_read;
|
static PerfCounter* _perf_app_classfile_bytes_read;
|
||||||
static PerfCounter* _perf_sys_classfile_bytes_read;
|
static PerfCounter* _perf_sys_classfile_bytes_read;
|
||||||
|
|
||||||
static PerfCounter* _sync_systemLoaderLockContentionRate;
|
|
||||||
static PerfCounter* _sync_nonSystemLoaderLockContentionRate;
|
|
||||||
static PerfCounter* _sync_JVMFindLoadedClassLockFreeCounter;
|
|
||||||
static PerfCounter* _sync_JVMDefineClassLockFreeCounter;
|
|
||||||
static PerfCounter* _sync_JNIDefineClassLockFreeCounter;
|
|
||||||
|
|
||||||
static PerfCounter* _unsafe_defineClassCallCounter;
|
static PerfCounter* _unsafe_defineClassCallCounter;
|
||||||
|
|
||||||
// The boot class path consists of 3 ordered pieces:
|
// The boot class path consists of 3 ordered pieces:
|
||||||
@ -305,31 +299,6 @@ class ClassLoader: AllStatic {
|
|||||||
static PerfCounter* perf_app_classfile_bytes_read() { return _perf_app_classfile_bytes_read; }
|
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; }
|
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() {
|
|
||||||
return _sync_systemLoaderLockContentionRate;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Record how often non system loader lock object is contended
|
|
||||||
static PerfCounter* sync_nonSystemLoaderLockContentionRate() {
|
|
||||||
return _sync_nonSystemLoaderLockContentionRate;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Record how many calls to JVM_FindLoadedClass w/o holding a lock
|
|
||||||
static PerfCounter* sync_JVMFindLoadedClassLockFreeCounter() {
|
|
||||||
return _sync_JVMFindLoadedClassLockFreeCounter;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Record how many calls to JVM_DefineClass w/o holding a lock
|
|
||||||
static PerfCounter* sync_JVMDefineClassLockFreeCounter() {
|
|
||||||
return _sync_JVMDefineClassLockFreeCounter;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Record how many calls to jni_DefineClass w/o holding a lock
|
|
||||||
static PerfCounter* sync_JNIDefineClassLockFreeCounter() {
|
|
||||||
return _sync_JNIDefineClassLockFreeCounter;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Record how many calls to Unsafe_DefineClass
|
// Record how many calls to Unsafe_DefineClass
|
||||||
static PerfCounter* unsafe_defineClassCallCounter() {
|
static PerfCounter* unsafe_defineClassCallCounter() {
|
||||||
return _unsafe_defineClassCallCounter;
|
return _unsafe_defineClassCallCounter;
|
||||||
|
@ -192,22 +192,6 @@ Handle SystemDictionary::compute_loader_lock_object(Thread* thread, Handle class
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method is added to check how often we have to wait to grab loader
|
|
||||||
// lock. The results are being recorded in the performance counters defined in
|
|
||||||
// ClassLoader::_sync_nonSystemLoaderLockContentionRate.
|
|
||||||
void SystemDictionary::check_loader_lock_contention(Thread* thread, Handle loader_lock) {
|
|
||||||
if (!UsePerfData) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (loader_lock.is_null()) return;
|
|
||||||
|
|
||||||
if (ObjectSynchronizer::query_lock_ownership(thread->as_Java_thread(), loader_lock)
|
|
||||||
== ObjectSynchronizer::owner_other) {
|
|
||||||
ClassLoader::sync_nonSystemLoaderLockContentionRate()->inc();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Resolving of classes
|
// Resolving of classes
|
||||||
|
|
||||||
@ -731,7 +715,6 @@ InstanceKlass* SystemDictionary::resolve_instance_class_or_null(Symbol* name,
|
|||||||
// ParallelCapable Classloaders and the bootstrap classloader
|
// ParallelCapable Classloaders and the bootstrap classloader
|
||||||
// do not acquire lock here.
|
// do not acquire lock here.
|
||||||
Handle lockObject = compute_loader_lock_object(THREAD, class_loader);
|
Handle lockObject = compute_loader_lock_object(THREAD, class_loader);
|
||||||
check_loader_lock_contention(THREAD, lockObject);
|
|
||||||
ObjectLocker ol(lockObject, THREAD);
|
ObjectLocker ol(lockObject, THREAD);
|
||||||
|
|
||||||
// Check again (after locking) if the class already exists in SystemDictionary
|
// Check again (after locking) if the class already exists in SystemDictionary
|
||||||
@ -1108,7 +1091,6 @@ InstanceKlass* SystemDictionary::resolve_from_stream(Symbol* class_name,
|
|||||||
// Classloaders that support parallelism, e.g. bootstrap classloader,
|
// Classloaders that support parallelism, e.g. bootstrap classloader,
|
||||||
// do not acquire lock here
|
// do not acquire lock here
|
||||||
Handle lockObject = compute_loader_lock_object(THREAD, class_loader);
|
Handle lockObject = compute_loader_lock_object(THREAD, class_loader);
|
||||||
check_loader_lock_contention(THREAD, lockObject);
|
|
||||||
ObjectLocker ol(lockObject, THREAD);
|
ObjectLocker ol(lockObject, THREAD);
|
||||||
|
|
||||||
// Parse the stream and create a klass.
|
// Parse the stream and create a klass.
|
||||||
@ -1397,7 +1379,6 @@ InstanceKlass* SystemDictionary::load_shared_class(InstanceKlass* ik,
|
|||||||
{
|
{
|
||||||
HandleMark hm(THREAD);
|
HandleMark hm(THREAD);
|
||||||
Handle lockObject = compute_loader_lock_object(THREAD, class_loader);
|
Handle lockObject = compute_loader_lock_object(THREAD, class_loader);
|
||||||
check_loader_lock_contention(THREAD, lockObject);
|
|
||||||
ObjectLocker ol(lockObject, THREAD);
|
ObjectLocker ol(lockObject, THREAD);
|
||||||
// prohibited package check assumes all classes loaded from archive call
|
// prohibited package check assumes all classes loaded from archive call
|
||||||
// restore_unshareable_info which calls ik->set_package()
|
// restore_unshareable_info which calls ik->set_package()
|
||||||
|
@ -610,7 +610,6 @@ protected:
|
|||||||
TRAPS);
|
TRAPS);
|
||||||
static InstanceKlass* load_instance_class(Symbol* class_name, Handle class_loader, TRAPS);
|
static InstanceKlass* load_instance_class(Symbol* class_name, Handle class_loader, TRAPS);
|
||||||
static Handle compute_loader_lock_object(Thread* thread, Handle class_loader);
|
static Handle compute_loader_lock_object(Thread* thread, Handle class_loader);
|
||||||
static void check_loader_lock_contention(Thread* thread, Handle loader_lock);
|
|
||||||
static bool is_parallelCapable(Handle class_loader);
|
static bool is_parallelCapable(Handle class_loader);
|
||||||
static bool is_parallelDefine(Handle class_loader);
|
static bool is_parallelDefine(Handle class_loader);
|
||||||
|
|
||||||
|
@ -281,16 +281,6 @@ JNI_ENTRY(jclass, jni_DefineClass(JNIEnv *env, const char *name, jobject loaderR
|
|||||||
ResourceMark rm(THREAD);
|
ResourceMark rm(THREAD);
|
||||||
ClassFileStream st((u1*)buf, bufLen, NULL, ClassFileStream::verify);
|
ClassFileStream st((u1*)buf, bufLen, NULL, ClassFileStream::verify);
|
||||||
Handle class_loader (THREAD, JNIHandles::resolve(loaderRef));
|
Handle class_loader (THREAD, JNIHandles::resolve(loaderRef));
|
||||||
|
|
||||||
if (UsePerfData && !class_loader.is_null()) {
|
|
||||||
// check whether the current caller thread holds the lock or not.
|
|
||||||
// If not, increment the corresponding counter
|
|
||||||
if (ObjectSynchronizer::
|
|
||||||
query_lock_ownership(thread, class_loader) !=
|
|
||||||
ObjectSynchronizer::owner_self) {
|
|
||||||
ClassLoader::sync_JNIDefineClassLockFreeCounter()->inc();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Klass* k = SystemDictionary::resolve_from_stream(class_name,
|
Klass* k = SystemDictionary::resolve_from_stream(class_name,
|
||||||
class_loader,
|
class_loader,
|
||||||
Handle(),
|
Handle(),
|
||||||
|
@ -840,19 +840,6 @@ JVM_ENTRY(jclass, JVM_FindClassFromClass(JNIEnv *env, const char *name,
|
|||||||
return result;
|
return result;
|
||||||
JVM_END
|
JVM_END
|
||||||
|
|
||||||
static void is_lock_held_by_thread(Handle loader, PerfCounter* counter, TRAPS) {
|
|
||||||
if (loader.is_null()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check whether the current caller thread holds the lock or not.
|
|
||||||
// If not, increment the corresponding counter
|
|
||||||
if (ObjectSynchronizer::query_lock_ownership(THREAD->as_Java_thread(), loader) !=
|
|
||||||
ObjectSynchronizer::owner_self) {
|
|
||||||
counter->inc();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// common code for JVM_DefineClass() and JVM_DefineClassWithSource()
|
// common code for JVM_DefineClass() and JVM_DefineClassWithSource()
|
||||||
static jclass jvm_define_class_common(const char *name,
|
static jclass jvm_define_class_common(const char *name,
|
||||||
jobject loader, const jbyte *buf,
|
jobject loader, const jbyte *buf,
|
||||||
@ -881,11 +868,6 @@ static jclass jvm_define_class_common(const char *name,
|
|||||||
ResourceMark rm(THREAD);
|
ResourceMark rm(THREAD);
|
||||||
ClassFileStream st((u1*)buf, len, source, ClassFileStream::verify);
|
ClassFileStream st((u1*)buf, len, source, ClassFileStream::verify);
|
||||||
Handle class_loader (THREAD, JNIHandles::resolve(loader));
|
Handle class_loader (THREAD, JNIHandles::resolve(loader));
|
||||||
if (UsePerfData) {
|
|
||||||
is_lock_held_by_thread(class_loader,
|
|
||||||
ClassLoader::sync_JVMDefineClassLockFreeCounter(),
|
|
||||||
THREAD);
|
|
||||||
}
|
|
||||||
Handle protection_domain (THREAD, JNIHandles::resolve(pd));
|
Handle protection_domain (THREAD, JNIHandles::resolve(pd));
|
||||||
Klass* k = SystemDictionary::resolve_from_stream(class_name,
|
Klass* k = SystemDictionary::resolve_from_stream(class_name,
|
||||||
class_loader,
|
class_loader,
|
||||||
@ -1095,12 +1077,6 @@ JVM_ENTRY(jclass, JVM_FindLoadedClass(JNIEnv *env, jobject loader, jstring name)
|
|||||||
// The Java level wrapper will perform the necessary security check allowing
|
// The Java level wrapper will perform the necessary security check allowing
|
||||||
// us to pass the NULL as the initiating class loader.
|
// us to pass the NULL as the initiating class loader.
|
||||||
Handle h_loader(THREAD, JNIHandles::resolve(loader));
|
Handle h_loader(THREAD, JNIHandles::resolve(loader));
|
||||||
if (UsePerfData) {
|
|
||||||
is_lock_held_by_thread(h_loader,
|
|
||||||
ClassLoader::sync_JVMFindLoadedClassLockFreeCounter(),
|
|
||||||
THREAD);
|
|
||||||
}
|
|
||||||
|
|
||||||
Klass* k = SystemDictionary::find_instance_or_array_klass(klass_name,
|
Klass* k = SystemDictionary::find_instance_or_array_klass(klass_name,
|
||||||
h_loader,
|
h_loader,
|
||||||
Handle(),
|
Handle(),
|
||||||
|
@ -1039,53 +1039,6 @@ bool ObjectSynchronizer::current_thread_holds_lock(JavaThread* thread,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Be aware of this method could revoke bias of the lock object.
|
|
||||||
// This method queries the ownership of the lock handle specified by 'h_obj'.
|
|
||||||
// If the current thread owns the lock, it returns owner_self. If no
|
|
||||||
// thread owns the lock, it returns owner_none. Otherwise, it will return
|
|
||||||
// owner_other.
|
|
||||||
ObjectSynchronizer::LockOwnership ObjectSynchronizer::query_lock_ownership
|
|
||||||
(JavaThread *self, Handle h_obj) {
|
|
||||||
// The caller must beware this method can revoke bias, and
|
|
||||||
// revocation can result in a safepoint.
|
|
||||||
assert(!SafepointSynchronize::is_at_safepoint(), "invariant");
|
|
||||||
assert(self->thread_state() != _thread_blocked, "invariant");
|
|
||||||
|
|
||||||
// Possible mark states: neutral, biased, stack-locked, inflated
|
|
||||||
|
|
||||||
if (UseBiasedLocking && h_obj()->mark().has_bias_pattern()) {
|
|
||||||
// CASE: biased
|
|
||||||
BiasedLocking::revoke(h_obj, self);
|
|
||||||
assert(!h_obj->mark().has_bias_pattern(),
|
|
||||||
"biases should be revoked by now");
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(self == JavaThread::current(), "Can only be called on current thread");
|
|
||||||
oop obj = h_obj();
|
|
||||||
markWord mark = read_stable_mark(obj);
|
|
||||||
|
|
||||||
// CASE: stack-locked. Mark points to a BasicLock on the owner's stack.
|
|
||||||
if (mark.has_locker()) {
|
|
||||||
return self->is_lock_owned((address)mark.locker()) ?
|
|
||||||
owner_self : owner_other;
|
|
||||||
}
|
|
||||||
|
|
||||||
// CASE: inflated. Mark (tagged pointer) points to an ObjectMonitor.
|
|
||||||
if (mark.has_monitor()) {
|
|
||||||
// The first stage of async deflation does not affect any field
|
|
||||||
// used by this comparison so the ObjectMonitor* is usable here.
|
|
||||||
ObjectMonitor* monitor = mark.monitor();
|
|
||||||
void* owner = monitor->owner();
|
|
||||||
if (owner == NULL) return owner_none;
|
|
||||||
return (owner == self ||
|
|
||||||
self->is_lock_owned((address)owner)) ? owner_self : owner_other;
|
|
||||||
}
|
|
||||||
|
|
||||||
// CASE: neutral
|
|
||||||
assert(mark.is_neutral(), "sanity check");
|
|
||||||
return owner_none; // it's unlocked
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: jvmti should call this
|
// FIXME: jvmti should call this
|
||||||
JavaThread* ObjectSynchronizer::get_lock_owner(ThreadsList * t_list, Handle h_obj) {
|
JavaThread* ObjectSynchronizer::get_lock_owner(ThreadsList * t_list, Handle h_obj) {
|
||||||
if (UseBiasedLocking) {
|
if (UseBiasedLocking) {
|
||||||
|
@ -39,12 +39,6 @@ class ObjectSynchronizer : AllStatic {
|
|||||||
friend class VMStructs;
|
friend class VMStructs;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef enum {
|
|
||||||
owner_self,
|
|
||||||
owner_none,
|
|
||||||
owner_other
|
|
||||||
} LockOwnership;
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
inflate_cause_vm_internal = 0,
|
inflate_cause_vm_internal = 0,
|
||||||
inflate_cause_monitor_enter = 1,
|
inflate_cause_monitor_enter = 1,
|
||||||
@ -106,7 +100,6 @@ class ObjectSynchronizer : AllStatic {
|
|||||||
|
|
||||||
// java.lang.Thread support
|
// java.lang.Thread support
|
||||||
static bool current_thread_holds_lock(JavaThread* thread, Handle h_obj);
|
static bool current_thread_holds_lock(JavaThread* thread, Handle h_obj);
|
||||||
static LockOwnership query_lock_ownership(JavaThread* self, Handle h_obj);
|
|
||||||
|
|
||||||
static JavaThread* get_lock_owner(ThreadsList * t_list, Handle h_obj);
|
static JavaThread* get_lock_owner(ThreadsList * t_list, Handle h_obj);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user