< prev index next >
src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaVFrame.java
Print this page
*** 1,7 ****
/*
! * Copyright (c) 2000, 2007, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
--- 1,7 ----
/*
! * Copyright (c) 2000, 2017, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*** 26,43 ****
import java.io.*;
import java.util.*;
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.utilities.*;
public abstract class JavaVFrame extends VFrame {
/** JVM state */
public abstract Method getMethod();
public abstract int getBCI();
public abstract StackValueCollection getLocals();
public abstract StackValueCollection getExpressions();
! public abstract List getMonitors(); // List<MonitorInfo>
/** Test operation */
public boolean isJavaFrame() { return true; }
/** Package-internal constructor */
--- 26,48 ----
import java.io.*;
import java.util.*;
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.utilities.*;
+ import sun.jvm.hotspot.debugger.*;
public abstract class JavaVFrame extends VFrame {
+
+ private static final String ADDRESS_FORMAT = VM.getVM().isLP64() ? "0x%016x"
+ : "0x%08x";
+
/** JVM state */
public abstract Method getMethod();
public abstract int getBCI();
public abstract StackValueCollection getLocals();
public abstract StackValueCollection getExpressions();
! public abstract List<MonitorInfo> getMonitors();
/** Test operation */
public boolean isJavaFrame() { return true; }
/** Package-internal constructor */
*** 47,59 ****
/** Get monitor (if any) that this JavaVFrame is trying to enter */
// FIXME: not yet implemented
// public Address getPendingMonitor(int frameCount);
/** Printing used during stack dumps */
! // FIXME: not yet implemented
! // void print_lock_info(int frame_count);
/** Printing operations */
//
// FIXME: implement visitor pattern for traversing vframe contents?
--- 52,180 ----
/** Get monitor (if any) that this JavaVFrame is trying to enter */
// FIXME: not yet implemented
// public Address getPendingMonitor(int frameCount);
+ public void printLockedObjectClassName(PrintStream tty,
+ OopHandle hobj, String lockState) {
+ if (hobj.asLongValue() != 0L) {
+ tty.format("\t- %s <" + ADDRESS_FORMAT + "> ",
+ lockState, hobj.asLongValue());
+
+ Klass klass = Oop.getKlassForOopHandle(hobj);
+ String klassName = klass.getName().asString();
+ tty.print("(a ");
+ if (klassName.equals("java/lang/Class")) {
+ Oop obj = VM.getVM().getObjectHeap().newOop(hobj);
+ klassName = java_lang_Class.asExternalName(obj);
+ tty.print("java.lang.Class for ");
+ }
+ tty.println(klassName.replace('/', '.') + ")");
+ }
+ }
+
/** Printing used during stack dumps */
! public void printLockInfo(PrintStream tty, int frameCount) {
! // If this is the first frame and it is java.lang.Object.wait(...)
! // then print out the receiver. Locals are not always available,
! // e.g., compiled native frames have no scope so there are no locals.
! if (frameCount == 0) {
! if (getMethod().getName().asString().equals("wait") &&
! getMethod().getMethodHolder().getName().asString().equals("java/lang/Object")) {
! String waitState = "waiting on"; // assume we are waiting
! // If earlier in the output we reported java.lang.Thread.State ==
! // "WAITING (on object monitor)" and now we report "waiting on", then
! // we are still waiting for notification or timeout. Otherwise if
! // we earlier reported java.lang.Thread.State == "BLOCKED (on object
! // monitor)", then we are actually waiting to re-lock the monitor.
! // At this level we can't distinguish the two cases to report
! // "waited on" rather than "waiting on" for the second case.
! StackValueCollection locs = getLocals();
! if (!locs.isEmpty()) {
! StackValue sv = locs.get(0);
! if (sv.getType() == BasicType.getTObject()) {
! OopHandle o = sv.getObject();
! printLockedObjectClassName(tty, o, waitState);
! }
! } else {
! tty.println("\t- " + waitState + " <no object reference available>");
! }
! } else if (thread.getCurrentParkBlocker() != null) {
! Oop obj = thread.getCurrentParkBlocker();
! Klass k = obj.getKlass();
! tty.format("\t- parking to wait for <" + ADDRESS_FORMAT + "> (a %s)",
! obj.getHandle().asLongValue(), k.getName().asString());
! tty.println();
! }
! }
!
! // Print out all monitors that we have locked, or are trying to lock,
! // including re-locking after being notified or timing out in a wait().
! List<MonitorInfo> mons = getMonitors();
! if (!mons.isEmpty()) {
! boolean foundFirstMonitor = false;
! for (int index = mons.size() - 1; index >= 0; index--) {
! MonitorInfo monitor = mons.get(index);
! if (monitor.eliminated() && isCompiledFrame()) { // Eliminated in compiled code
! if (monitor.ownerIsScalarReplaced()) {
! Klass k = Oop.getKlassForOopHandle(monitor.ownerKlass());
! tty.println("\t- eliminated <owner is scalar replaced> (a " + k.getName().asString() + ")");
! } else if (monitor.owner() != null) {
! printLockedObjectClassName(tty, monitor.owner(), "eliminated");
! }
! continue;
! }
! if (monitor.owner() != null) {
! // the monitor is associated with an object, i.e., it is locked
!
! Mark mark = null;
! String lockState = "locked";
! if (!foundFirstMonitor && frameCount == 0) {
! // If this is the first frame and we haven't found an owned
! // monitor before, then we need to see if we have completed
! // the lock or if we are blocked trying to acquire it. Only
! // an inflated monitor that is first on the monitor list in
! // the first frame can block us on a monitor enter.
! mark = new Mark(monitor.owner());
! if (mark.hasMonitor() &&
! ( // we have marked ourself as pending on this monitor
! mark.monitor().equals(thread.getCurrentPendingMonitor()) ||
! // we are not the owner of this monitor
! !mark.monitor().isEntered(thread)
! )) {
! lockState = "waiting to lock";
! } else {
! // We own the monitor which is not as interesting so
! // disable the extra printing below.
! mark = null;
! }
! } else if (frameCount != 0) {
! // This is not the first frame so we either own this monitor
! // or we owned the monitor before and called wait(). Because
! // wait() could have been called on any monitor in a lower
! // numbered frame on the stack, we have to check all the
! // monitors on the list for this frame.
! mark = new Mark(monitor.owner());
! if (mark.hasMonitor() &&
! ( // we have marked ourself as pending on this monitor
! mark.monitor().equals(thread.getCurrentPendingMonitor()) ||
! // we are not the owner of this monitor
! !mark.monitor().isEntered(thread)
! )) {
! lockState = "waiting to re-lock in wait()";
! } else {
! // We own the monitor which is not as interesting so
! // disable the extra printing below.
! mark = null;
! }
! }
! printLockedObjectClassName(tty, monitor.owner(), lockState);
! foundFirstMonitor = true;
! }
! }
! }
! }
/** Printing operations */
//
// FIXME: implement visitor pattern for traversing vframe contents?
*** 71,96 ****
tty.println();
tty.println("\tbci:\t" + getBCI());
printStackValuesOn(tty, "locals", getLocals());
printStackValuesOn(tty, "expressions", getExpressions());
-
- // List<MonitorInfo>
- // FIXME: not yet implemented
- // List list = getMonitors();
- // if (list.isEmpty()) {
- // return;
- // }
- // for (int index = 0; index < list.size(); index++) {
- // MonitorInfo monitor = (MonitorInfo) list.get(index);
- // tty.print("\t obj\t");
- // monitor.getOwner().printValueOn(tty);
- // tty.println();
- // tty.print("\t ");
- // monitor.lock().printOn(tty);
- // tty.println();
- // }
}
public void printActivation(int index) {
printActivationOn(System.out, index);
}
--- 192,201 ----
< prev index next >