diff -r 511dd7b5313b -r 76dbe86f3d82 hotspot/src/share/vm/runtime/synchronizer.cpp --- a/hotspot/src/share/vm/runtime/synchronizer.cpp Thu Feb 04 14:06:43 2016 +0100 +++ b/hotspot/src/share/vm/runtime/synchronizer.cpp Thu Feb 04 18:28:52 2016 +0100 @@ -42,6 +42,8 @@ #include "runtime/synchronizer.hpp" #include "runtime/thread.inline.hpp" #include "runtime/vframe.hpp" +#include "trace/traceMacros.hpp" +#include "trace/tracing.hpp" #include "utilities/dtrace.hpp" #include "utilities/events.hpp" #include "utilities/preserveException.hpp" @@ -130,6 +132,10 @@ static volatile int gMonitorFreeCount = 0; // # on gFreeList static volatile int gMonitorPopulation = 0; // # Extant -- in circulation +static void post_monitor_inflate_event(EventJavaMonitorInflate&, + const oop, + const ObjectSynchronizer::InflateCause); + #define CHAINMARKER (cast_to_oop(-1)) @@ -304,7 +310,9 @@ } } - ObjectSynchronizer::inflate(THREAD, object)->exit(true, THREAD); + ObjectSynchronizer::inflate(THREAD, + object, + inflate_cause_vm_internal)->exit(true, THREAD); } // ----------------------------------------------------------------------------- @@ -338,7 +346,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 @@ -368,7 +378,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); } @@ -381,7 +393,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); } @@ -396,7 +410,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); } @@ -410,7 +424,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)) { @@ -453,7 +469,10 @@ TEVENT(wait - throw IAX); THROW_MSG_0(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); @@ -473,7 +492,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) { @@ -486,7 +507,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() @@ -500,7 +523,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); } // ----------------------------------------------------------------------------- @@ -749,7 +774,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"); @@ -1283,17 +1308,22 @@ 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); } +ObjectMonitor * NOINLINE ObjectSynchronizer::inflate(Thread * Self, + oop object, + const InflateCause cause) { -ObjectMonitor * NOINLINE ObjectSynchronizer::inflate(Thread * Self, - oop object) { // Inflate mutates the heap ... // Relaxing assertion for bug 6320749. assert(Universe::verify_in_progress() || !SafepointSynchronize::is_at_safepoint(), "invariant"); + EventJavaMonitorInflate event; + for (;;) { const markOop mark = object->mark(); assert(!mark->has_bias_pattern(), "invariant"); @@ -1311,6 +1341,7 @@ assert(inf->header()->is_neutral(), "invariant"); assert(inf->object() == object, "invariant"); assert(ObjectSynchronizer::verify_objmon_isinpool(inf), "monitor is invalid"); + event.cancel(); // let's not post an inflation event, unless we did the deed ourselves return inf; } @@ -1423,6 +1454,9 @@ object->klass()->external_name()); } } + if (event.should_commit()) { + post_monitor_inflate_event(event, object, cause); + } return m; } @@ -1471,6 +1505,9 @@ object->klass()->external_name()); } } + if (event.should_commit()) { + post_monitor_inflate_event(event, object, cause); + } return m; } } @@ -1742,6 +1779,33 @@ THREAD->clear_pending_exception(); } +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 ObjectSynchronizer::InflateCause cause) { +#if INCLUDE_TRACE + assert(event.should_commit(), "check outside"); + event.set_klass(obj->klass()); + event.set_address((TYPE_ADDRESS)(uintptr_t)(void*)obj); + event.set_cause((u1)cause); + event.commit(); +#endif +} + //------------------------------------------------------------------------------ // Debugging code