8259809: Remove PerfEvent class loading locking counters

Reviewed-by: redestad, iklam
This commit is contained in:
Coleen Phillimore 2021-01-26 11:50:10 +00:00
parent b4ace3e979
commit 81a66dfa81
8 changed files with 1 additions and 163 deletions

View File

@ -132,11 +132,6 @@ 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;
PerfCounter* ClassLoader::_sync_JVMDefineClassLockFreeCounter = NULL;
PerfCounter* ClassLoader::_sync_JNIDefineClassLockFreeCounter = NULL;
PerfCounter* ClassLoader::_unsafe_defineClassCallCounter = 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_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
// 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");
NEWPERFEVENTCOUNTER(_unsafe_defineClassCallCounter, SUN_CLS, "unsafeDefineClassCalls");
}
// lookup java library entry points

View File

@ -182,12 +182,6 @@ class ClassLoader: AllStatic {
static PerfCounter* _perf_app_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;
// 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_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
static PerfCounter* unsafe_defineClassCallCounter() {
return _unsafe_defineClassCallCounter;

View File

@ -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
@ -731,7 +715,6 @@ InstanceKlass* SystemDictionary::resolve_instance_class_or_null(Symbol* name,
// ParallelCapable Classloaders and the bootstrap classloader
// do not acquire lock here.
Handle lockObject = compute_loader_lock_object(THREAD, class_loader);
check_loader_lock_contention(THREAD, lockObject);
ObjectLocker ol(lockObject, THREAD);
// 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,
// do not acquire lock here
Handle lockObject = compute_loader_lock_object(THREAD, class_loader);
check_loader_lock_contention(THREAD, lockObject);
ObjectLocker ol(lockObject, THREAD);
// Parse the stream and create a klass.
@ -1397,7 +1379,6 @@ InstanceKlass* SystemDictionary::load_shared_class(InstanceKlass* ik,
{
HandleMark hm(THREAD);
Handle lockObject = compute_loader_lock_object(THREAD, class_loader);
check_loader_lock_contention(THREAD, lockObject);
ObjectLocker ol(lockObject, THREAD);
// prohibited package check assumes all classes loaded from archive call
// restore_unshareable_info which calls ik->set_package()

View File

@ -610,7 +610,6 @@ protected:
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 void check_loader_lock_contention(Thread* thread, Handle loader_lock);
static bool is_parallelCapable(Handle class_loader);
static bool is_parallelDefine(Handle class_loader);

View File

@ -281,16 +281,6 @@ JNI_ENTRY(jclass, jni_DefineClass(JNIEnv *env, const char *name, jobject loaderR
ResourceMark rm(THREAD);
ClassFileStream st((u1*)buf, bufLen, NULL, ClassFileStream::verify);
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,
class_loader,
Handle(),

View File

@ -840,19 +840,6 @@ JVM_ENTRY(jclass, JVM_FindClassFromClass(JNIEnv *env, const char *name,
return result;
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()
static jclass jvm_define_class_common(const char *name,
jobject loader, const jbyte *buf,
@ -881,11 +868,6 @@ static jclass jvm_define_class_common(const char *name,
ResourceMark rm(THREAD);
ClassFileStream st((u1*)buf, len, source, ClassFileStream::verify);
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));
Klass* k = SystemDictionary::resolve_from_stream(class_name,
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
// us to pass the NULL as the initiating class 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,
h_loader,
Handle(),

View File

@ -1039,53 +1039,6 @@ bool ObjectSynchronizer::current_thread_holds_lock(JavaThread* thread,
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
JavaThread* ObjectSynchronizer::get_lock_owner(ThreadsList * t_list, Handle h_obj) {
if (UseBiasedLocking) {

View File

@ -39,12 +39,6 @@ class ObjectSynchronizer : AllStatic {
friend class VMStructs;
public:
typedef enum {
owner_self,
owner_none,
owner_other
} LockOwnership;
typedef enum {
inflate_cause_vm_internal = 0,
inflate_cause_monitor_enter = 1,
@ -106,7 +100,6 @@ class ObjectSynchronizer : AllStatic {
// java.lang.Thread support
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);