8069412: Locks need better debug-printing support
Summary: Added better debug-printing support and enhanced LogCompilation tool
Reviewed-by: kvn, roland, dholmes
--- a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java Mon Feb 16 08:47:39 2015 -0800
+++ b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java Tue Feb 17 13:54:53 2015 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,12 +24,12 @@
/**
* A SAX based parser of LogCompilation output from HotSpot. It takes a complete
- * @author never
*/
package com.sun.hotspot.tools.compiler;
import java.io.FileReader;
+import java.io.PrintStream;
import java.io.Reader;
import java.util.ArrayDeque;
import java.util.ArrayList;
@@ -134,6 +134,44 @@
}
};
+ class Jvms {
+ Jvms(Method method, int bci) {
+ this.method = method;
+ this.bci = bci;
+ }
+ final public Method method;
+ final public int bci;
+ final public String toString() {
+ return "@" + bci + " " + method;
+ }
+ }
+
+ class LockElimination extends BasicLogEvent {
+
+ ArrayList<Jvms> jvms = new ArrayList<Jvms>(1);
+ final String kind;
+ final String classId;
+ final String tagName;
+ LockElimination(String tagName, double start, String id, String kind, String classId) {
+ super(start, id);
+ this.kind = kind;
+ this.classId = classId;
+ this.tagName = tagName;
+ }
+
+ @Override
+ public void print(PrintStream stream) {
+ stream.printf("%s %s %s %s %.3f ", getId(), tagName, kind, classId, getStart());
+ stream.print(jvms.toString());
+ stream.print("\n");
+ }
+
+ void addJVMS(Method method, int bci) {
+ jvms.add(new Jvms(method, bci));
+ }
+
+ }
+
private ArrayList<LogEvent> events = new ArrayList<LogEvent>();
private HashMap<String, String> types = new HashMap<String, String>();
@@ -147,6 +185,7 @@
private CallSite site;
private CallSite methodHandleSite;
private Stack<Phase> phaseStack = new Stack<Phase>();
+ private LockElimination currentLockElimination;
private UncommonTrapEvent currentTrap;
private Stack<CallSite> lateInlineScope;
private boolean lateInlining;
@@ -192,7 +231,12 @@
}
LogParser log = new LogParser();
- p.parse(new InputSource(reader), log);
+ try {
+ p.parse(new InputSource(reader), log);
+ } catch (Throwable th) {
+ th.printStackTrace();
+ // Carry on with what we've got...
+ }
// Associate compilations with their NMethods
for (NMethod nm : log.nmethods.values()) {
@@ -418,8 +462,23 @@
// uncommon trap inserted during parsing.
// ignore for now
}
+ } else if (qname.startsWith("eliminate_lock")) {
+ String id = atts.getValue("compile_id");
+ if (id != null) {
+ id = makeId(atts);
+ String kind = atts.getValue("kind");
+ String classId = atts.getValue("class_id");
+ currentLockElimination = new LockElimination(qname, Double.parseDouble(search(atts, "stamp")), id, kind, classId);
+ events.add(currentLockElimination);
+ }
} else if (qname.equals("late_inline")) {
- long inlineId = Long.parseLong(search(atts, "inline_id"));
+ long inlineId = 0;
+ try {
+ Long.parseLong(search(atts, "inline_id"));
+ } catch (InternalError ex) {
+ // Log files from older hotspots may lack inline_id,
+ // and zero is an acceptable substitute that allows processing to continue.
+ }
lateInlineScope = new Stack<CallSite>();
site = new CallSite(-999, method(search(atts, "method")));
site.setInlineId(inlineId);
@@ -428,13 +487,14 @@
// <jvms bci='4' method='java/io/DataInputStream readChar ()C' bytes='40' count='5815' iicount='20815'/>
if (currentTrap != null) {
currentTrap.addJVMS(atts.getValue("method"), Integer.parseInt(atts.getValue("bci")));
+ } else if (currentLockElimination != null) {
+ currentLockElimination.addJVMS(method(atts.getValue("method")), Integer.parseInt(atts.getValue("bci")));
} else if (lateInlineScope != null) {
bci = Integer.parseInt(search(atts, "bci"));
site = new CallSite(bci, method(search(atts, "method")));
lateInlineScope.push(site);
} else {
// Ignore <eliminate_allocation type='667'>,
- // <eliminate_lock lock='1'>,
// <replace_string_concat arguments='2' string_alloc='0' multiple='0'>
}
} else if (qname.equals("inline_id")) {
@@ -512,6 +572,8 @@
}
} else if (qname.equals("uncommon_trap")) {
currentTrap = null;
+ } else if (qname.startsWith("eliminate_lock")) {
+ currentLockElimination = null;
} else if (qname.equals("late_inline")) {
// Populate late inlining info.
if (scopes.size() != 0) {
@@ -522,8 +584,8 @@
CallSite caller = lateInlineScope.pop();
Method m = compile.getMethod();
if (m != caller.getMethod()) {
- System.out.println(m);
- System.out.println(caller.getMethod() + " bci: " + bci);
+ System.err.println(m);
+ System.err.println(caller.getMethod() + " bci: " + bci);
throw new InternalError("call site and late_inline info don't match");
}
--- a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/UncommonTrapEvent.java Mon Feb 16 08:47:39 2015 -0800
+++ b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/UncommonTrapEvent.java Tue Feb 17 13:54:53 2015 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -50,7 +50,7 @@
}
public void print(PrintStream stream) {
- stream.printf("%s uncommon trap %s %s\n", getId(), getReason(), getAction());
+ stream.printf("%s uncommon trap %.3f %s %s\n", getId(), getStart(), getReason(), getAction());
stream.print(getJvms());
}
--- a/hotspot/src/share/vm/oops/markOop.cpp Mon Feb 16 08:47:39 2015 -0800
+++ b/hotspot/src/share/vm/oops/markOop.cpp Tue Feb 17 13:54:53 2015 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,17 +25,40 @@
#include "precompiled.hpp"
#include "oops/markOop.hpp"
#include "runtime/thread.inline.hpp"
+#include "runtime/objectMonitor.inline.hpp"
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
void markOopDesc::print_on(outputStream* st) const {
- if (is_locked()) {
- st->print("locked(" INTPTR_FORMAT ")->", value());
- markOop(*(markOop*)value())->print_on(st);
+ if (is_marked()) {
+ st->print(" marked(" INTPTR_FORMAT ")", value());
+ } else if (is_locked()) {
+ st->print(" locked(" INTPTR_FORMAT ")->", value());
+ if (is_neutral()) {
+ st->print("is_neutral");
+ if (has_no_hash()) st->print(" no_hash");
+ else st->print(" hash=" INTPTR_FORMAT, hash());
+ st->print(" age=%d", age());
+ } else if (has_bias_pattern()) {
+ st->print("is_biased");
+ JavaThread* jt = biased_locker();
+ st->print(" biased_locker=" INTPTR_FORMAT, p2i(jt));
+ } else if (has_monitor()) {
+ ObjectMonitor* mon = monitor();
+ if (mon == NULL)
+ st->print("monitor=NULL");
+ else {
+ BasicLock * bl = (BasicLock *) mon->owner();
+ st->print("monitor={count="INTPTR_FORMAT",waiters="INTPTR_FORMAT",recursions="INTPTR_FORMAT",owner="INTPTR_FORMAT"}",
+ mon->count(), mon->waiters(), mon->recursions(), p2i(bl));
+ }
+ } else {
+ st->print("??");
+ }
} else {
assert(is_unlocked() || has_bias_pattern(), "just checking");
st->print("mark(");
- if (has_bias_pattern()) st->print("biased,");
+ if (has_bias_pattern()) st->print("biased,");
st->print("hash %#lx,", hash());
st->print("age %d)", age());
}
--- a/hotspot/src/share/vm/opto/callnode.cpp Mon Feb 16 08:47:39 2015 -0800
+++ b/hotspot/src/share/vm/opto/callnode.cpp Tue Feb 17 13:54:53 2015 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "compiler/compileLog.hpp"
#include "ci/bcEscapeAnalyzer.hpp"
#include "compiler/oopMap.hpp"
#include "opto/callGenerator.hpp"
@@ -1673,6 +1674,9 @@
// The lock could be marked eliminated by lock coarsening
// code during first IGVN before EA. Replace coarsened flag
// to eliminate all associated locks/unlocks.
+#ifdef ASSERT
+ this->log_lock_optimization(phase->C,"eliminate_lock_set_non_esc1");
+#endif
this->set_non_esc_obj();
return result;
}
@@ -1734,6 +1738,9 @@
AbstractLockNode* lock = lock_ops.at(i);
// Mark it eliminated by coarsening and update any counters
+#ifdef ASSERT
+ lock->log_lock_optimization(phase->C, "eliminate_lock_set_coarsened");
+#endif
lock->set_coarsened();
}
} else if (ctrl->is_Region() &&
@@ -1752,16 +1759,33 @@
//=============================================================================
bool LockNode::is_nested_lock_region() {
+ return is_nested_lock_region(NULL);
+}
+
+// p is used for access to compilation log; no logging if NULL
+bool LockNode::is_nested_lock_region(Compile * c) {
BoxLockNode* box = box_node()->as_BoxLock();
int stk_slot = box->stack_slot();
- if (stk_slot <= 0)
+ if (stk_slot <= 0) {
+#ifdef ASSERT
+ this->log_lock_optimization(c, "eliminate_lock_INLR_1");
+#endif
return false; // External lock or it is not Box (Phi node).
+ }
// Ignore complex cases: merged locks or multiple locks.
Node* obj = obj_node();
LockNode* unique_lock = NULL;
- if (!box->is_simple_lock_region(&unique_lock, obj) ||
- (unique_lock != this)) {
+ if (!box->is_simple_lock_region(&unique_lock, obj)) {
+#ifdef ASSERT
+ this->log_lock_optimization(c, "eliminate_lock_INLR_2a");
+#endif
+ return false;
+ }
+ if (unique_lock != this) {
+#ifdef ASSERT
+ this->log_lock_optimization(c, "eliminate_lock_INLR_2b");
+#endif
return false;
}
@@ -1781,6 +1805,9 @@
}
}
}
+#ifdef ASSERT
+ this->log_lock_optimization(c, "eliminate_lock_INLR_3");
+#endif
return false;
}
@@ -1812,12 +1839,43 @@
// The lock could be marked eliminated by lock coarsening
// code during first IGVN before EA. Replace coarsened flag
// to eliminate all associated locks/unlocks.
+#ifdef ASSERT
+ this->log_lock_optimization(phase->C, "eliminate_lock_set_non_esc2");
+#endif
this->set_non_esc_obj();
}
}
return result;
}
+const char * AbstractLockNode::kind_as_string() const {
+ return is_coarsened() ? "coarsened" :
+ is_nested() ? "nested" :
+ is_non_esc_obj() ? "non_escaping" :
+ "?";
+}
+
+void AbstractLockNode::log_lock_optimization(Compile *C, const char * tag) const {
+ if (C == NULL) {
+ return;
+ }
+ CompileLog* log = C->log();
+ if (log != NULL) {
+ log->begin_head("%s lock='%d' compile_id='%d' class_id='%s' kind='%s'",
+ tag, is_Lock(), C->compile_id(),
+ is_Unlock() ? "unlock" : is_Lock() ? "lock" : "?",
+ kind_as_string());
+ log->stamp();
+ log->end_head();
+ JVMState* p = is_Unlock() ? (as_Unlock()->dbg_jvms()) : jvms();
+ while (p != NULL) {
+ log->elem("jvms bci='%d' method='%d'", p->bci(), log->identify(p->method()));
+ p = p->caller();
+ }
+ log->tail(tag);
+ }
+}
+
ArrayCopyNode::ArrayCopyNode(Compile* C, bool alloc_tightly_coupled)
: CallNode(arraycopy_type(), NULL, TypeRawPtr::BOTTOM),
_alloc_tightly_coupled(alloc_tightly_coupled),
--- a/hotspot/src/share/vm/opto/callnode.hpp Mon Feb 16 08:47:39 2015 -0800
+++ b/hotspot/src/share/vm/opto/callnode.hpp Tue Feb 17 13:54:53 2015 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -985,6 +985,9 @@
bool is_coarsened() const { return (_kind == Coarsened); }
bool is_nested() const { return (_kind == Nested); }
+ const char * kind_as_string() const;
+ void log_lock_optimization(Compile* c, const char * tag) const;
+
void set_non_esc_obj() { _kind = NonEscObj; set_eliminated_lock_counter(); }
void set_coarsened() { _kind = Coarsened; set_eliminated_lock_counter(); }
void set_nested() { _kind = Nested; set_eliminated_lock_counter(); }
@@ -1045,15 +1048,24 @@
}
bool is_nested_lock_region(); // Is this Lock nested?
+ bool is_nested_lock_region(Compile * c); // Why isn't this Lock nested?
};
//------------------------------Unlock---------------------------------------
// High-level unlock operation
class UnlockNode : public AbstractLockNode {
+private:
+#ifdef ASSERT
+ JVMState* const _dbg_jvms; // Pointer to list of JVM State objects
+#endif
public:
virtual int Opcode() const;
virtual uint size_of() const; // Size is bigger
- UnlockNode(Compile* C, const TypeFunc *tf) : AbstractLockNode( tf ) {
+ UnlockNode(Compile* C, const TypeFunc *tf) : AbstractLockNode( tf )
+#ifdef ASSERT
+ , _dbg_jvms(NULL)
+#endif
+ {
init_class_id(Class_Unlock);
init_flags(Flag_is_macro);
C->add_macro_node(this);
@@ -1061,6 +1073,14 @@
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
// unlock is never a safepoint
virtual bool guaranteed_safepoint() { return false; }
+#ifdef ASSERT
+ void set_dbg_jvms(JVMState* s) {
+ *(JVMState**)&_dbg_jvms = s; // override const attribute in the accessor
+ }
+ JVMState* dbg_jvms() const { return _dbg_jvms; }
+#else
+ JVMState* dbg_jvms() const { return NULL; }
+#endif
};
class GraphKit;
--- a/hotspot/src/share/vm/opto/escape.cpp Mon Feb 16 08:47:39 2015 -0800
+++ b/hotspot/src/share/vm/opto/escape.cpp Tue Feb 17 13:54:53 2015 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1802,6 +1802,9 @@
// The lock could be marked eliminated by lock coarsening
// code during first IGVN before EA. Replace coarsened flag
// to eliminate all associated locks/unlocks.
+#ifdef ASSERT
+ alock->log_lock_optimization(C, "eliminate_lock_set_non_esc3");
+#endif
alock->set_non_esc_obj();
}
}
--- a/hotspot/src/share/vm/opto/graphKit.cpp Mon Feb 16 08:47:39 2015 -0800
+++ b/hotspot/src/share/vm/opto/graphKit.cpp Tue Feb 17 13:54:53 2015 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -3244,6 +3244,9 @@
const TypeFunc *tf = OptoRuntime::complete_monitor_exit_Type();
UnlockNode *unlock = new UnlockNode(C, tf);
+#ifdef ASSERT
+ unlock->set_dbg_jvms(sync_jvms());
+#endif
uint raw_idx = Compile::AliasIdxRaw;
unlock->init_req( TypeFunc::Control, control() );
unlock->init_req( TypeFunc::Memory , memory(raw_idx) );
--- a/hotspot/src/share/vm/opto/macro.cpp Mon Feb 16 08:47:39 2015 -0800
+++ b/hotspot/src/share/vm/opto/macro.cpp Tue Feb 17 13:54:53 2015 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1890,7 +1890,7 @@
// Box is used only in one lock region. Mark this box as eliminated.
_igvn.hash_delete(oldbox);
oldbox->as_BoxLock()->set_eliminated(); // This changes box's hash value
- _igvn.hash_insert(oldbox);
+ _igvn.hash_insert(oldbox);
for (uint i = 0; i < oldbox->outcnt(); i++) {
Node* u = oldbox->raw_out(i);
@@ -1899,6 +1899,9 @@
// Check lock's box since box could be referenced by Lock's debug info.
if (alock->box_node() == oldbox) {
// Mark eliminated all related locks and unlocks.
+#ifdef ASSERT
+ alock->log_lock_optimization(C, "eliminate_lock_set_non_esc4");
+#endif
alock->set_non_esc_obj();
}
}
@@ -1925,6 +1928,9 @@
AbstractLockNode* alock = u->as_AbstractLock();
if (alock->box_node() == oldbox && alock->obj_node()->eqv_uncast(obj)) {
// Replace Box and mark eliminated all related locks and unlocks.
+#ifdef ASSERT
+ alock->log_lock_optimization(C, "eliminate_lock_set_non_esc5");
+#endif
alock->set_non_esc_obj();
_igvn.rehash_node_delayed(alock);
alock->set_box_node(newbox);
@@ -1971,26 +1977,38 @@
return;
} else if (!alock->is_non_esc_obj()) { // Not eliminated or coarsened
// Only Lock node has JVMState needed here.
- if (alock->jvms() != NULL && alock->as_Lock()->is_nested_lock_region()) {
- // Mark eliminated related nested locks and unlocks.
- Node* obj = alock->obj_node();
- BoxLockNode* box_node = alock->box_node()->as_BoxLock();
- assert(!box_node->is_eliminated(), "should not be marked yet");
- // Note: BoxLock node is marked eliminated only here
- // and it is used to indicate that all associated lock
- // and unlock nodes are marked for elimination.
- box_node->set_eliminated(); // Box's hash is always NO_HASH here
- for (uint i = 0; i < box_node->outcnt(); i++) {
- Node* u = box_node->raw_out(i);
- if (u->is_AbstractLock()) {
- alock = u->as_AbstractLock();
- if (alock->box_node() == box_node) {
- // Verify that this Box is referenced only by related locks.
- assert(alock->obj_node()->eqv_uncast(obj), "");
- // Mark all related locks and unlocks.
- alock->set_nested();
+ // Not that preceding claim is documented anywhere else.
+ if (alock->jvms() != NULL) {
+ if (alock->as_Lock()->is_nested_lock_region()) {
+ // Mark eliminated related nested locks and unlocks.
+ Node* obj = alock->obj_node();
+ BoxLockNode* box_node = alock->box_node()->as_BoxLock();
+ assert(!box_node->is_eliminated(), "should not be marked yet");
+ // Note: BoxLock node is marked eliminated only here
+ // and it is used to indicate that all associated lock
+ // and unlock nodes are marked for elimination.
+ box_node->set_eliminated(); // Box's hash is always NO_HASH here
+ for (uint i = 0; i < box_node->outcnt(); i++) {
+ Node* u = box_node->raw_out(i);
+ if (u->is_AbstractLock()) {
+ alock = u->as_AbstractLock();
+ if (alock->box_node() == box_node) {
+ // Verify that this Box is referenced only by related locks.
+ assert(alock->obj_node()->eqv_uncast(obj), "");
+ // Mark all related locks and unlocks.
+#ifdef ASSERT
+ alock->log_lock_optimization(C, "eliminate_lock_set_nested");
+#endif
+ alock->set_nested();
+ }
}
}
+ } else {
+#ifdef ASSERT
+ alock->log_lock_optimization(C, "eliminate_lock_NOT_nested_lock_region");
+ if (C->log() != NULL)
+ alock->as_Lock()->is_nested_lock_region(C); // rerun for debugging output
+#endif
}
}
return;
@@ -2035,19 +2053,10 @@
assert(oldbox->is_eliminated(), "should be done already");
}
#endif
- CompileLog* log = C->log();
- if (log != NULL) {
- log->head("eliminate_lock lock='%d'",
- alock->is_Lock());
- JVMState* p = alock->jvms();
- while (p != NULL) {
- log->elem("jvms bci='%d' method='%d'", p->bci(), log->identify(p->method()));
- p = p->caller();
- }
- log->tail("eliminate_lock");
- }
- #ifndef PRODUCT
+ alock->log_lock_optimization(C, "eliminate_lock");
+
+#ifndef PRODUCT
if (PrintEliminateLocks) {
if (alock->is_Lock()) {
tty->print_cr("++++ Eliminated: %d Lock", alock->_idx);
@@ -2055,7 +2064,7 @@
tty->print_cr("++++ Eliminated: %d Unlock", alock->_idx);
}
}
- #endif
+#endif
Node* mem = alock->in(TypeFunc::Memory);
Node* ctrl = alock->in(TypeFunc::Control);
--- a/hotspot/src/share/vm/runtime/basicLock.cpp Mon Feb 16 08:47:39 2015 -0800
+++ b/hotspot/src/share/vm/runtime/basicLock.cpp Tue Feb 17 13:54:53 2015 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,9 @@
void BasicLock::print_on(outputStream* st) const {
st->print("monitor");
+ markOop moop = displaced_header();
+ if (moop != NULL)
+ moop->print_on(st);
}
void BasicLock::move_to(oop obj, BasicLock* dest) {
--- a/hotspot/src/share/vm/runtime/vframe.cpp Mon Feb 16 08:47:39 2015 -0800
+++ b/hotspot/src/share/vm/runtime/vframe.cpp Tue Feb 17 13:54:53 2015 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -189,6 +189,7 @@
if (monitor->eliminated() && is_compiled_frame()) { // Eliminated in compiled code
if (monitor->owner_is_scalar_replaced()) {
Klass* k = java_lang_Class::as_Klass(monitor->owner_klass());
+ // format below for lockbits matches this one.
st->print("\t- eliminated <owner is scalar replaced> (a %s)", k->external_name());
} else {
oop obj = monitor->owner();
@@ -206,9 +207,10 @@
// see if we have completed the lock or we are blocked trying to
// acquire it - we can only be blocked if the monitor is inflated
+ markOop mark = NULL;
const char *lock_state = "locked"; // assume we have the monitor locked
if (!found_first_monitor && frame_count == 0) {
- markOop mark = monitor->owner()->mark();
+ mark = monitor->owner()->mark();
if (mark->has_monitor() &&
( // we have marked ourself as pending on this monitor
mark->monitor() == thread()->current_pending_monitor() ||
@@ -216,11 +218,19 @@
!mark->monitor()->is_entered(thread())
)) {
lock_state = "waiting to lock";
+ } else {
+ mark = NULL; // Disable printing below
}
}
+ print_locked_object_class_name(st, monitor->owner(), lock_state);
+ if (Verbose && mark != NULL) {
+ // match with format above, replacing "-" with " ".
+ st->print("\t lockbits=");
+ mark->print_on(st);
+ st->cr();
+ }
found_first_monitor = true;
- print_locked_object_class_name(st, monitor->owner(), lock_state);
}
}
}
@@ -577,10 +587,15 @@
tty->print("( null )");
} else {
monitor->owner()->print_value();
- tty->print("(" INTPTR_FORMAT ")", (address)monitor->owner());
+ tty->print("(owner=" INTPTR_FORMAT ")", (address)monitor->owner());
}
- if (monitor->eliminated() && is_compiled_frame())
- tty->print(" ( lock is eliminated )");
+ if (monitor->eliminated()) {
+ if(is_compiled_frame()) {
+ tty->print(" ( lock is eliminated in compiled frame )");
+ } else {
+ tty->print(" ( lock is eliminated, frame not compiled )");
+ }
+ }
tty->cr();
tty->print("\t ");
monitor->lock()->print_on(tty);