8199882: compiler/uncommontrap/TestDeoptOOM.java failed w/ fatal error: ExceptionMark constructor expects no pending exceptions
Pre-load AbstractOwnableSynchronizer class instead of lazy loading it. Reviewed-by: sspitsyn, cjplummer, coleenp
This commit is contained in:
parent
6aa9e85a5e
commit
ab275c586e
@ -4257,7 +4257,7 @@ int java_lang_AssertionStatusDirectives::packages_offset;
|
||||
int java_lang_AssertionStatusDirectives::packageEnabled_offset;
|
||||
int java_lang_AssertionStatusDirectives::deflt_offset;
|
||||
int java_nio_Buffer::_limit_offset;
|
||||
int java_util_concurrent_locks_AbstractOwnableSynchronizer::_owner_offset = 0;
|
||||
int java_util_concurrent_locks_AbstractOwnableSynchronizer::_owner_offset;
|
||||
int reflect_ConstantPool::_oop_offset;
|
||||
int reflect_UnsafeStaticFieldAccessorImpl::_base_offset;
|
||||
|
||||
@ -4399,13 +4399,12 @@ void java_nio_Buffer::serialize(SerializeClosure* f) {
|
||||
}
|
||||
#endif
|
||||
|
||||
void java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(TRAPS) {
|
||||
if (_owner_offset != 0) return;
|
||||
#define AOS_FIELDS_DO(macro) \
|
||||
macro(_owner_offset, k, "exclusiveOwnerThread", thread_signature, false)
|
||||
|
||||
SystemDictionary::load_abstract_ownable_synchronizer_klass(CHECK);
|
||||
InstanceKlass* k = SystemDictionary::abstract_ownable_synchronizer_klass();
|
||||
compute_offset(_owner_offset, k,
|
||||
"exclusiveOwnerThread", vmSymbols::thread_signature());
|
||||
void java_util_concurrent_locks_AbstractOwnableSynchronizer::compute_offsets() {
|
||||
InstanceKlass* k = SystemDictionary::java_util_concurrent_locks_AbstractOwnableSynchronizer_klass();
|
||||
AOS_FIELDS_DO(FIELD_COMPUTE_OFFSET);
|
||||
}
|
||||
|
||||
oop java_util_concurrent_locks_AbstractOwnableSynchronizer::get_owner_threadObj(oop obj) {
|
||||
@ -4473,6 +4472,7 @@ void JavaClasses::compute_offsets() {
|
||||
java_lang_StackTraceElement::compute_offsets();
|
||||
java_lang_StackFrameInfo::compute_offsets();
|
||||
java_lang_LiveStackFrameInfo::compute_offsets();
|
||||
java_util_concurrent_locks_AbstractOwnableSynchronizer::compute_offsets();
|
||||
|
||||
// generated interpreter code wants to know about the offsets we just computed:
|
||||
AbstractAssembler::update_delayed_values();
|
||||
|
@ -1483,7 +1483,7 @@ class java_util_concurrent_locks_AbstractOwnableSynchronizer : AllStatic {
|
||||
private:
|
||||
static int _owner_offset;
|
||||
public:
|
||||
static void initialize(TRAPS);
|
||||
static void compute_offsets();
|
||||
static oop get_owner_threadObj(oop obj);
|
||||
};
|
||||
|
||||
|
@ -110,9 +110,6 @@ oop SystemDictionary::_java_platform_loader = NULL;
|
||||
|
||||
bool SystemDictionary::_has_checkPackageAccess = false;
|
||||
|
||||
// lazily initialized klass variables
|
||||
InstanceKlass* volatile SystemDictionary::_abstract_ownable_synchronizer_klass = NULL;
|
||||
|
||||
// Default ProtectionDomainCacheSize value
|
||||
|
||||
const int defaultProtectionDomainCacheSize = 1009;
|
||||
@ -1896,22 +1893,6 @@ void SystemDictionary::remove_classes_in_error_state() {
|
||||
ClassLoaderDataGraph::cld_do(&rcc);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Lazily load klasses
|
||||
|
||||
void SystemDictionary::load_abstract_ownable_synchronizer_klass(TRAPS) {
|
||||
// if multiple threads calling this function, only one thread will load
|
||||
// the class. The other threads will find the loaded version once the
|
||||
// class is loaded.
|
||||
Klass* aos = _abstract_ownable_synchronizer_klass;
|
||||
if (aos == NULL) {
|
||||
Klass* k = resolve_or_fail(vmSymbols::java_util_concurrent_locks_AbstractOwnableSynchronizer(), true, CHECK);
|
||||
// Force a fence to prevent any read before the write completes
|
||||
OrderAccess::fence();
|
||||
_abstract_ownable_synchronizer_klass = InstanceKlass::cast(k);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Initialization
|
||||
|
||||
|
@ -199,6 +199,9 @@ class OopStorage;
|
||||
do_klass(StackFrameInfo_klass, java_lang_StackFrameInfo, Opt ) \
|
||||
do_klass(LiveStackFrameInfo_klass, java_lang_LiveStackFrameInfo, Opt ) \
|
||||
\
|
||||
/* support for stack dump lock analysis */ \
|
||||
do_klass(java_util_concurrent_locks_AbstractOwnableSynchronizer_klass, java_util_concurrent_locks_AbstractOwnableSynchronizer, Pre ) \
|
||||
\
|
||||
/* Preload boxing klasses */ \
|
||||
do_klass(Boolean_klass, java_lang_Boolean, Pre ) \
|
||||
do_klass(Character_klass, java_lang_Character, Pre ) \
|
||||
@ -449,12 +452,6 @@ public:
|
||||
}
|
||||
static BasicType box_klass_type(Klass* k); // inverse of box_klass
|
||||
|
||||
// methods returning lazily loaded klasses
|
||||
// The corresponding method to load the class must be called before calling them.
|
||||
static InstanceKlass* abstract_ownable_synchronizer_klass() { return check_klass(_abstract_ownable_synchronizer_klass); }
|
||||
|
||||
static void load_abstract_ownable_synchronizer_klass(TRAPS);
|
||||
|
||||
protected:
|
||||
// Returns the class loader data to be used when looking up/updating the
|
||||
// system dictionary.
|
||||
@ -729,9 +726,6 @@ protected:
|
||||
// Variables holding commonly used klasses (preloaded)
|
||||
static InstanceKlass* _well_known_klasses[];
|
||||
|
||||
// Lazily loaded klasses
|
||||
static InstanceKlass* volatile _abstract_ownable_synchronizer_klass;
|
||||
|
||||
// table of box klasses (int_klass, etc.)
|
||||
static InstanceKlass* _box_klasses[T_VOID+1];
|
||||
|
||||
|
@ -204,13 +204,6 @@ void VM_Verify::doit() {
|
||||
}
|
||||
|
||||
bool VM_PrintThreads::doit_prologue() {
|
||||
// Make sure AbstractOwnableSynchronizer is loaded
|
||||
JavaThread* jt = JavaThread::current();
|
||||
java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(jt);
|
||||
if (jt->has_pending_exception()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get Heap_lock if concurrent locks will be dumped
|
||||
if (_print_concurrent_locks) {
|
||||
Heap_lock->lock();
|
||||
@ -248,19 +241,6 @@ VM_FindDeadlocks::~VM_FindDeadlocks() {
|
||||
}
|
||||
}
|
||||
|
||||
bool VM_FindDeadlocks::doit_prologue() {
|
||||
if (_concurrent_locks) {
|
||||
// Make sure AbstractOwnableSynchronizer is loaded
|
||||
JavaThread* jt = JavaThread::current();
|
||||
java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(jt);
|
||||
if (jt->has_pending_exception()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void VM_FindDeadlocks::doit() {
|
||||
// Update the hazard ptr in the originating thread to the current
|
||||
// list of threads. This VM operation needs the current list of
|
||||
@ -316,13 +296,6 @@ VM_ThreadDump::VM_ThreadDump(ThreadDumpResult* result,
|
||||
}
|
||||
|
||||
bool VM_ThreadDump::doit_prologue() {
|
||||
// Make sure AbstractOwnableSynchronizer is loaded
|
||||
JavaThread* jt = JavaThread::current();
|
||||
java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(jt);
|
||||
if (jt->has_pending_exception()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_with_locked_synchronizers) {
|
||||
// Acquire Heap_lock to dump concurrent locks
|
||||
Heap_lock->lock();
|
||||
|
@ -421,7 +421,6 @@ class VM_FindDeadlocks: public VM_Operation {
|
||||
DeadlockCycle* result() { return _deadlocks; };
|
||||
VMOp_Type type() const { return VMOp_FindDeadlocks; }
|
||||
void doit();
|
||||
bool doit_prologue();
|
||||
};
|
||||
|
||||
class ThreadDumpResult;
|
||||
|
@ -1081,9 +1081,6 @@ JVM_ENTRY(jint, jmm_GetThreadInfo(JNIEnv *env, jlongArray ids, jint maxDepth, jo
|
||||
"The length of the given ThreadInfo array does not match the length of the given array of thread IDs", -1);
|
||||
}
|
||||
|
||||
// make sure the AbstractOwnableSynchronizer klass is loaded before taking thread snapshots
|
||||
java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(CHECK_0);
|
||||
|
||||
// Must use ThreadDumpResult to store the ThreadSnapshot.
|
||||
// GC may occur after the thread snapshots are taken but before
|
||||
// this function returns. The threadObj and other oops kept
|
||||
@ -1154,9 +1151,6 @@ JVM_ENTRY(jobjectArray, jmm_DumpThreads(JNIEnv *env, jlongArray thread_ids, jboo
|
||||
jboolean locked_synchronizers, jint maxDepth))
|
||||
ResourceMark rm(THREAD);
|
||||
|
||||
// make sure the AbstractOwnableSynchronizer klass is loaded before taking thread snapshots
|
||||
java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(CHECK_NULL);
|
||||
|
||||
typeArrayOop ta = typeArrayOop(JNIHandles::resolve(thread_ids));
|
||||
int num_threads = (ta != NULL ? ta->length() : 0);
|
||||
typeArrayHandle ids_ah(THREAD, ta);
|
||||
|
@ -369,7 +369,7 @@ DeadlockCycle* ThreadService::find_deadlocks_at_safepoint(ThreadsList * t_list,
|
||||
}
|
||||
} else {
|
||||
if (concurrent_locks) {
|
||||
if (waitingToLockBlocker->is_a(SystemDictionary::abstract_ownable_synchronizer_klass())) {
|
||||
if (waitingToLockBlocker->is_a(SystemDictionary::java_util_concurrent_locks_AbstractOwnableSynchronizer_klass())) {
|
||||
oop threadObj = java_util_concurrent_locks_AbstractOwnableSynchronizer::get_owner_threadObj(waitingToLockBlocker);
|
||||
// This JavaThread (if there is one) is protected by the
|
||||
// ThreadsListSetter in VM_FindDeadlocks::doit().
|
||||
@ -678,8 +678,8 @@ void ConcurrentLocksDump::dump_at_safepoint() {
|
||||
GrowableArray<oop>* aos_objects = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<oop>(INITIAL_ARRAY_SIZE, true /* C_heap */);
|
||||
|
||||
// Find all instances of AbstractOwnableSynchronizer
|
||||
HeapInspection::find_instances_at_safepoint(SystemDictionary::abstract_ownable_synchronizer_klass(),
|
||||
aos_objects);
|
||||
HeapInspection::find_instances_at_safepoint(SystemDictionary::java_util_concurrent_locks_AbstractOwnableSynchronizer_klass(),
|
||||
aos_objects);
|
||||
// Build a map of thread to its owned AQS locks
|
||||
build_map(aos_objects);
|
||||
|
||||
@ -832,7 +832,7 @@ ThreadSnapshot::ThreadSnapshot(ThreadsList * t_list, JavaThread* thread) {
|
||||
_thread_status == java_lang_Thread::PARKED_TIMED)) {
|
||||
|
||||
_blocker_object = thread->current_park_blocker();
|
||||
if (_blocker_object != NULL && _blocker_object->is_a(SystemDictionary::abstract_ownable_synchronizer_klass())) {
|
||||
if (_blocker_object != NULL && _blocker_object->is_a(SystemDictionary::java_util_concurrent_locks_AbstractOwnableSynchronizer_klass())) {
|
||||
_blocker_object_owner = java_util_concurrent_locks_AbstractOwnableSynchronizer::get_owner_threadObj(_blocker_object);
|
||||
}
|
||||
}
|
||||
@ -923,7 +923,7 @@ void DeadlockCycle::print_on_with(ThreadsList * t_list, outputStream* st) const
|
||||
st->print(" waiting for ownable synchronizer " INTPTR_FORMAT ", (a %s)",
|
||||
p2i(waitingToLockBlocker),
|
||||
waitingToLockBlocker->klass()->external_name());
|
||||
assert(waitingToLockBlocker->is_a(SystemDictionary::abstract_ownable_synchronizer_klass()),
|
||||
assert(waitingToLockBlocker->is_a(SystemDictionary::java_util_concurrent_locks_AbstractOwnableSynchronizer_klass()),
|
||||
"Must be an AbstractOwnableSynchronizer");
|
||||
oop ownerObj = java_util_concurrent_locks_AbstractOwnableSynchronizer::get_owner_threadObj(waitingToLockBlocker);
|
||||
currentThread = java_lang_Thread::thread(ownerObj);
|
||||
|
Loading…
x
Reference in New Issue
Block a user