< 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?
< prev index next >