# HG changeset patch # User fyang # Date 1608277303 -28800 # Node ID 3b1ad311bf91efb28f1d0c8580f191e3bd723ff3 # Parent caca9fa8d83355b7271c8d71b4281e69e901057d 8258669: fastdebug jvm crashes when do event based tracing for monitor inflation Reviewed-by: phh diff -r caca9fa8d833 -r 3b1ad311bf91 src/share/vm/jfr/recorder/checkpoint/types/jfrType.cpp --- a/src/share/vm/jfr/recorder/checkpoint/types/jfrType.cpp Tue Sep 03 10:03:13 2019 +0200 +++ b/src/share/vm/jfr/recorder/checkpoint/types/jfrType.cpp Fri Dec 18 15:41:43 2020 +0800 @@ -151,13 +151,12 @@ } void MonitorInflateCauseConstant::serialize(JfrCheckpointWriter& writer) { - // XXX no such counters. implement? -// static const u4 nof_entries = ObjectSynchronizer::inflate_cause_nof; -// writer.write_count(nof_entries); -// for (u4 i = 0; i < nof_entries; ++i) { -// writer.write_key(i); -// writer.write(ObjectSynchronizer::inflate_cause_name((ObjectSynchronizer::InflateCause)i)); -// } + static const u4 nof_entries = ObjectSynchronizer::inflate_cause_nof; + writer.write_count(nof_entries); + for (u4 i = 0; i < nof_entries; ++i) { + writer.write_key(i); + writer.write(ObjectSynchronizer::inflate_cause_name((ObjectSynchronizer::InflateCause)i)); + } } void GCCauseConstant::serialize(JfrCheckpointWriter& writer) { diff -r caca9fa8d833 -r 3b1ad311bf91 src/share/vm/runtime/synchronizer.cpp --- a/src/share/vm/runtime/synchronizer.cpp Tue Sep 03 10:03:13 2019 +0200 +++ b/src/share/vm/runtime/synchronizer.cpp Fri Dec 18 15:41:43 2020 +0800 @@ -216,7 +216,9 @@ } } - ObjectSynchronizer::inflate(THREAD, object)->exit (true, THREAD) ; + ObjectSynchronizer::inflate(THREAD, + object, + inflate_cause_vm_internal)->exit(true, THREAD); } // ----------------------------------------------------------------------------- @@ -258,7 +260,9 @@ // must be non-zero to avoid looking like a re-entrant lock, // and must not look locked either. lock->set_displaced_header(markOopDesc::unused_mark()); - ObjectSynchronizer::inflate(THREAD, obj())->enter(THREAD); + ObjectSynchronizer::inflate(THREAD, + obj(), + inflate_cause_monitor_enter)->enter(THREAD); } // This routine is used to handle interpreter/compiler slow case @@ -288,7 +292,9 @@ assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); } - ObjectMonitor* monitor = ObjectSynchronizer::inflate(THREAD, obj()); + ObjectMonitor* monitor = ObjectSynchronizer::inflate(THREAD, + obj(), + inflate_cause_vm_internal); return monitor->complete_exit(THREAD); } @@ -301,7 +307,9 @@ assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); } - ObjectMonitor* monitor = ObjectSynchronizer::inflate(THREAD, obj()); + ObjectMonitor* monitor = ObjectSynchronizer::inflate(THREAD, + obj(), + inflate_cause_vm_internal); monitor->reenter(recursion, THREAD); } @@ -316,7 +324,7 @@ assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); } THREAD->set_current_pending_monitor_is_from_java(false); - ObjectSynchronizer::inflate(THREAD, obj())->enter(THREAD); + ObjectSynchronizer::inflate(THREAD, obj(), inflate_cause_jni_enter)->enter(THREAD); THREAD->set_current_pending_monitor_is_from_java(true); } @@ -342,7 +350,9 @@ } assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); - ObjectMonitor* monitor = ObjectSynchronizer::inflate(THREAD, obj); + ObjectMonitor* monitor = ObjectSynchronizer::inflate(THREAD, + obj, + inflate_cause_jni_exit); // If this thread has locked the object, exit the monitor. Note: can't use // monitor->check(CHECK); must exit even if an exception is pending. if (monitor->check(THREAD)) { @@ -385,7 +395,10 @@ TEVENT (wait - throw IAX) ; THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "timeout value is negative"); } - ObjectMonitor* monitor = ObjectSynchronizer::inflate(THREAD, obj()); + ObjectMonitor* monitor = ObjectSynchronizer::inflate(THREAD, + obj(), + inflate_cause_wait); + DTRACE_MONITOR_WAIT_PROBE(monitor, obj(), THREAD, millis); monitor->wait(millis, true, THREAD); @@ -404,7 +417,9 @@ TEVENT (wait - throw IAX) ; THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "timeout value is negative"); } - ObjectSynchronizer::inflate(THREAD, obj()) -> wait(millis, false, THREAD) ; + ObjectSynchronizer::inflate(THREAD, + obj(), + inflate_cause_wait)->wait(millis, false, THREAD) ; } void ObjectSynchronizer::notify(Handle obj, TRAPS) { @@ -417,7 +432,9 @@ if (mark->has_locker() && THREAD->is_lock_owned((address)mark->locker())) { return; } - ObjectSynchronizer::inflate(THREAD, obj())->notify(THREAD); + ObjectSynchronizer::inflate(THREAD, + obj(), + inflate_cause_notify)->notify(THREAD); } // NOTE: see comment of notify() @@ -431,7 +448,9 @@ if (mark->has_locker() && THREAD->is_lock_owned((address)mark->locker())) { return; } - ObjectSynchronizer::inflate(THREAD, obj())->notifyAll(THREAD); + ObjectSynchronizer::inflate(THREAD, + obj(), + inflate_cause_notify)->notifyAll(THREAD); } // ----------------------------------------------------------------------------- @@ -686,7 +705,7 @@ } // Inflate the monitor to set hash code - monitor = ObjectSynchronizer::inflate(Self, obj); + monitor = ObjectSynchronizer::inflate(Self, obj, inflate_cause_hash_code); // Load displaced header and check it has hash code mark = monitor->header(); assert (mark->is_neutral(), "invariant") ; @@ -1183,12 +1202,29 @@ TEVENT (omFlush) ; } +const char* ObjectSynchronizer::inflate_cause_name(const InflateCause cause) { + switch (cause) { + case inflate_cause_vm_internal: return "VM Internal"; + case inflate_cause_monitor_enter: return "Monitor Enter"; + case inflate_cause_wait: return "Monitor Wait"; + case inflate_cause_notify: return "Monitor Notify"; + case inflate_cause_hash_code: return "Monitor Hash Code"; + case inflate_cause_jni_enter: return "JNI Monitor Enter"; + case inflate_cause_jni_exit: return "JNI Monitor Exit"; + default: + ShouldNotReachHere(); + } + return "Unknown"; +} + static void post_monitor_inflate_event(EventJavaMonitorInflate* event, - const oop obj) { + const oop obj, + const ObjectSynchronizer::InflateCause cause) { assert(event != NULL, "invariant"); assert(event->should_commit(), "invariant"); event->set_monitorClass(obj->klass()); event->set_address((uintptr_t)(void*)obj); + event->set_cause((u1)cause); event->commit(); } @@ -1200,7 +1236,9 @@ assert(mark->monitor()->header()->is_neutral(), "monitor must record a good object header"); return mark->monitor(); } - return ObjectSynchronizer::inflate(Thread::current(), obj); + return ObjectSynchronizer::inflate(Thread::current(), + obj, + inflate_cause_vm_internal); } @@ -1208,7 +1246,9 @@ // multiple locks occupy the same $ line. Padding might be appropriate. -ObjectMonitor * ATTR ObjectSynchronizer::inflate (Thread * Self, oop object) { +ObjectMonitor * ATTR ObjectSynchronizer::inflate (Thread * Self, + oop object, + const InflateCause cause) { // Inflate mutates the heap ... // Relaxing assertion for bug 6320749. assert (Universe::verify_in_progress() || @@ -1347,7 +1387,7 @@ } } if (event.should_commit()) { - post_monitor_inflate_event(&event, object); + post_monitor_inflate_event(&event, object, cause); } return m ; } @@ -1400,7 +1440,7 @@ } } if (event.should_commit()) { - post_monitor_inflate_event(&event, object); + post_monitor_inflate_event(&event, object, cause); } return m ; } diff -r caca9fa8d833 -r 3b1ad311bf91 src/share/vm/runtime/synchronizer.hpp --- a/src/share/vm/runtime/synchronizer.hpp Tue Sep 03 10:03:13 2019 +0200 +++ b/src/share/vm/runtime/synchronizer.hpp Fri Dec 18 15:41:43 2020 +0800 @@ -42,6 +42,18 @@ owner_none, owner_other } LockOwnership; + + typedef enum { + inflate_cause_vm_internal = 0, + inflate_cause_monitor_enter = 1, + inflate_cause_wait = 2, + inflate_cause_notify = 3, + inflate_cause_hash_code = 4, + inflate_cause_jni_enter = 5, + inflate_cause_jni_exit = 6, + inflate_cause_nof = 7 // Number of causes + } InflateCause; + // exit must be implemented non-blocking, since the compiler cannot easily handle // deoptimization at monitor exit. Hence, it does not take a Handle argument. @@ -90,9 +102,10 @@ static void omFlush (Thread * Self) ; // Inflate light weight monitor to heavy weight monitor - static ObjectMonitor* inflate(Thread * Self, oop obj); + static ObjectMonitor* inflate(Thread * Self, oop obj, const InflateCause cause); // This version is only for internal use static ObjectMonitor* inflate_helper(oop obj); + static const char* inflate_cause_name(const InflateCause cause); // Returns the identity hash value for an oop // NOTE: It may cause monitor inflation