< prev index next >
src/share/vm/runtime/synchronizer.cpp
Print this page
@@ -38,10 +38,11 @@
#include "runtime/synchronizer.hpp"
#include "runtime/thread.inline.hpp"
#include "utilities/dtrace.hpp"
#include "utilities/events.hpp"
#include "utilities/preserveException.hpp"
+#include "evtrace/traceEvents.hpp"
#ifdef TARGET_OS_FAMILY_linux
# include "os_linux.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_solaris
# include "os_solaris.inline.hpp"
@@ -278,33 +279,33 @@
// 2) wait on lock2
// 3) when notified on lock2, unlock lock2
// 4) reenter lock1 with original recursion count
// 5) lock lock2
// NOTE: must use heavy weight monitor to handle complete_exit/reenter()
-intptr_t ObjectSynchronizer::complete_exit(Handle obj, TRAPS) {
+void ObjectSynchronizer::complete_exit(Handle obj, intptr_t *saved_recursions, intptr_t *saved_trace_exit_stack, TRAPS) {
TEVENT (complete_exit) ;
if (UseBiasedLocking) {
BiasedLocking::revoke_and_rebias(obj, false, THREAD);
assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now");
}
ObjectMonitor* monitor = ObjectSynchronizer::inflate(THREAD, obj());
- return monitor->complete_exit(THREAD);
+ monitor->complete_exit(saved_recursions, saved_trace_exit_stack, THREAD);
}
// NOTE: must use heavy weight monitor to handle complete_exit/reenter()
-void ObjectSynchronizer::reenter(Handle obj, intptr_t recursion, TRAPS) {
+void ObjectSynchronizer::reenter(Handle obj, intptr_t saved_recursions, intptr_t saved_trace_exit_stack, TRAPS) {
TEVENT (reenter) ;
if (UseBiasedLocking) {
BiasedLocking::revoke_and_rebias(obj, false, THREAD);
assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now");
}
ObjectMonitor* monitor = ObjectSynchronizer::inflate(THREAD, obj());
- monitor->reenter(recursion, THREAD);
+ monitor->reenter(saved_recursions, saved_trace_exit_stack, THREAD);
}
// -----------------------------------------------------------------------------
// JNI locks on java objects
// NOTE: must use heavy weight monitor to handle jni monitor enter
void ObjectSynchronizer::jni_enter(Handle obj, TRAPS) { // possible entry from jni enter
@@ -1308,10 +1309,17 @@
// with CAS. That is, we can avoid the xchg-NULL .... ST idiom.
m->set_owner(mark->locker());
m->set_object(object);
// TODO-FIXME: assert BasicLock->dhw != 0.
+ // must get a sequence number before the monitor is published below
+ No_Safepoint_Verifier nsv(true, false);
+ intptr_t trace_seq;
+ if (EnableEventTracing) {
+ trace_seq = m->next_trace_seq();
+ }
+
// Must preserve store ordering. The monitor state must
// be stable at the time of publishing the monitor address.
guarantee (object->mark() == markOopDesc::INFLATING(), "invariant") ;
object->release_set_mark(markOopDesc::encode(m));
@@ -1325,10 +1333,13 @@
tty->print_cr("Inflating object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s",
(void *) object, (intptr_t) object->mark(),
object->klass()->external_name());
}
}
+ if (EnableEventTracing) {
+ TraceEvents::write_monitor_inflate(m, trace_seq);
+ }
return m ;
}
// CASE: neutral
// TODO-FIXME: for entry we currently inflate and then try to CAS _owner.
@@ -1350,16 +1361,28 @@
m->OwnerIsThread = 1 ;
m->_recursions = 0 ;
m->_Responsible = NULL ;
m->_SpinDuration = ObjectMonitor::Knob_SpinLimit ; // consider: keep metastats by type/class
+ // must get a sequence number before the monitor is published below
+ No_Safepoint_Verifier nsv(true, false);
+ intptr_t trace_seq;
+ if (EnableEventTracing) {
+ trace_seq = m->next_trace_seq();
+ }
+
if (Atomic::cmpxchg_ptr (markOopDesc::encode(m), object->mark_addr(), mark) != mark) {
m->set_object (NULL) ;
m->set_owner (NULL) ;
m->OwnerIsThread = 0 ;
m->Recycle() ;
omRelease (Self, m, true) ;
+
+ if (EnableEventTracing) { // must still consume our sequence number
+ TraceEvents::write_monitor_dummy(m, trace_seq);
+ }
+
m = NULL ;
continue ;
// interference - the markword changed - just retry.
// The state-transitions are one-way, so there's no chance of
// live-lock -- "Inflated" is an absorbing state.
@@ -1375,10 +1398,13 @@
tty->print_cr("Inflating object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s",
(void *) object, (intptr_t) object->mark(),
object->klass()->external_name());
}
}
+ if (EnableEventTracing) {
+ TraceEvents::write_monitor_inflate(m, trace_seq);
+ }
return m ;
}
}
// Note that we could encounter some performance loss through false-sharing as
@@ -1442,10 +1468,13 @@
ResourceMark rm;
tty->print_cr("Deflating object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s",
(void *) obj, (intptr_t) obj->mark(), obj->klass()->external_name());
}
}
+ if (EnableEventTracing) {
+ TraceEvents::write_monitor_deflate(mid);
+ }
// Restore the header back to obj
obj->release_set_mark(mid->header());
mid->clear();
@@ -1603,11 +1632,11 @@
public:
ReleaseJavaMonitorsClosure(Thread* thread) : THREAD(thread) {}
void do_monitor(ObjectMonitor* mid) {
if (mid->owner() == THREAD) {
- (void)mid->complete_exit(CHECK);
+ mid->complete_exit(NULL, NULL, CHECK);
}
}
};
// Release all inflated monitors owned by THREAD. Lightweight monitors are
< prev index next >