Path: blob/master/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaVFrame.java
41161 views
/*1* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324package sun.jvm.hotspot.runtime;2526import java.io.*;27import java.util.*;28import sun.jvm.hotspot.oops.*;29import sun.jvm.hotspot.utilities.*;30import sun.jvm.hotspot.debugger.*;3132public abstract class JavaVFrame extends VFrame {3334private static final String ADDRESS_FORMAT = VM.getVM().isLP64() ? "0x%016x"35: "0x%08x";3637/** JVM state */38public abstract Method getMethod();39public abstract int getBCI();40public abstract StackValueCollection getLocals();41public abstract StackValueCollection getExpressions();42public abstract List<MonitorInfo> getMonitors();4344/** Test operation */45public boolean isJavaFrame() { return true; }4647/** Package-internal constructor */48JavaVFrame(Frame fr, RegisterMap regMap, JavaThread thread) {49super(fr, regMap, thread);50}5152/** Get monitor (if any) that this JavaVFrame is trying to enter */53// FIXME: not yet implemented54// public Address getPendingMonitor(int frameCount);5556public void printLockedObjectClassName(PrintStream tty,57OopHandle hobj, String lockState) {58if (hobj.asLongValue() != 0L) {59tty.format("\t- %s <" + ADDRESS_FORMAT + "> ",60lockState, hobj.asLongValue());6162Klass klass = Oop.getKlassForOopHandle(hobj);63String klassName = klass.getName().asString();64tty.print("(a ");65if (klassName.equals("java/lang/Class")) {66Oop obj = VM.getVM().getObjectHeap().newOop(hobj);67klassName = java_lang_Class.asExternalName(obj);68tty.print("java.lang.Class for ");69}70tty.println(klassName.replace('/', '.') + ")");71}72}7374private String identifyLockState(MonitorInfo monitor, String waitingState) {75Mark mark = new Mark(monitor.owner());76if (mark.hasMonitor() &&77( // we have marked ourself as pending on this monitor78mark.monitor().equals(thread.getCurrentPendingMonitor()) ||79// we are not the owner of this monitor80!mark.monitor().isEntered(thread)81)) {82return waitingState;83}84return "locked";85}8687/** Printing used during stack dumps */88public void printLockInfo(PrintStream tty, int frameCount) {89// If this is the first frame and it is java.lang.Object.wait(...)90// then print out the receiver. Locals are not always available,91// e.g., compiled native frames have no scope so there are no locals.92if (frameCount == 0) {93if (getMethod().getName().asString().equals("wait") &&94getMethod().getMethodHolder().getName().asString().equals("java/lang/Object")) {95String waitState = "waiting on"; // assume we are waiting96// If earlier in the output we reported java.lang.Thread.State ==97// "WAITING (on object monitor)" and now we report "waiting on", then98// we are still waiting for notification or timeout. Otherwise if99// we earlier reported java.lang.Thread.State == "BLOCKED (on object100// monitor)", then we are actually waiting to re-lock the monitor.101StackValueCollection locs = getLocals();102if (!locs.isEmpty()) {103StackValue sv = locs.get(0);104if (sv.getType() == BasicType.getTObject()) {105OopHandle o = sv.getObject();106if (OopUtilities.threadOopGetThreadStatus(thread.getThreadObj()) == OopUtilities.THREAD_STATUS_BLOCKED_ON_MONITOR_ENTER) {107waitState = "waiting to re-lock in wait()";108}109printLockedObjectClassName(tty, o, waitState);110}111} else {112tty.println("\t- " + waitState + " <no object reference available>");113}114} else if (thread.getCurrentParkBlocker() != null) {115Oop obj = thread.getCurrentParkBlocker();116Klass k = obj.getKlass();117tty.format("\t- parking to wait for <" + ADDRESS_FORMAT + "> (a %s)",118obj.getHandle().asLongValue(), k.getName().asString());119tty.println();120}121}122123// Print out all monitors that we have locked, or are trying to lock,124// including re-locking after being notified or timing out in a wait().125List<MonitorInfo> mons = getMonitors();126if (!mons.isEmpty()) {127boolean foundFirstMonitor = false;128for (int index = mons.size() - 1; index >= 0; index--) {129MonitorInfo monitor = mons.get(index);130if (monitor.eliminated() && isCompiledFrame()) { // Eliminated in compiled code131if (monitor.ownerIsScalarReplaced()) {132Klass k = Oop.getKlassForOopHandle(monitor.ownerKlass());133tty.println("\t- eliminated <owner is scalar replaced> (a " + k.getName().asString() + ")");134} else if (monitor.owner() != null) {135printLockedObjectClassName(tty, monitor.owner(), "eliminated");136}137continue;138}139if (monitor.owner() != null) {140// the monitor is associated with an object, i.e., it is locked141String lockState = "locked";142if (!foundFirstMonitor && frameCount == 0) {143// If this is the first frame and we haven't found an owned144// monitor before, then we need to see if we have completed145// the lock or if we are blocked trying to acquire it. Only146// an inflated monitor that is first on the monitor list in147// the first frame can block us on a monitor enter.148lockState = identifyLockState(monitor, "waiting to lock");149}150printLockedObjectClassName(tty, monitor.owner(), lockState);151foundFirstMonitor = true;152}153}154}155}156157/** Printing operations */158159//160// FIXME: implement visitor pattern for traversing vframe contents?161//162163public void print() {164printOn(System.out);165}166167public void printOn(PrintStream tty) {168super.printOn(tty);169170tty.print("\t");171getMethod().printValueOn(tty);172tty.println();173tty.println("\tbci:\t" + getBCI());174175printStackValuesOn(tty, "locals", getLocals());176printStackValuesOn(tty, "expressions", getExpressions());177}178179public void printActivation(int index) {180printActivationOn(System.out, index);181}182183public void printActivationOn(PrintStream tty, int index) {184// frame number and method185tty.print(index + " - ");186printValueOn(tty);187tty.println();188189if (VM.getVM().wizardMode()) {190printOn(tty);191tty.println();192}193}194195/** Verification operations */196public void verify() {197}198199public boolean equals(Object o) {200if (o == null || !(o instanceof JavaVFrame)) {201return false;202}203204JavaVFrame other = (JavaVFrame) o;205206// Check static part207if (!getMethod().equals(other.getMethod())) {208return false;209}210211if (getBCI() != other.getBCI()) {212return false;213}214215// dynamic part - we just compare the frame pointer216if (! getFrame().equals(other.getFrame())) {217return false;218}219return true;220}221222public int hashCode() {223return getMethod().hashCode() ^ getBCI() ^ getFrame().hashCode();224}225226/** Structural compare */227public boolean structuralCompare(JavaVFrame other) {228// Check static part229if (!getMethod().equals(other.getMethod())) {230return false;231}232233if (getBCI() != other.getBCI()) {234return false;235}236237// Check locals238StackValueCollection locs = getLocals();239StackValueCollection otherLocs = other.getLocals();240if (Assert.ASSERTS_ENABLED) {241Assert.that(locs.size() == otherLocs.size(), "sanity check");242}243for (int i = 0; i < locs.size(); i++) {244// it might happen the compiler reports a conflict and245// the interpreter reports a bogus int.246if ( isCompiledFrame() && (locs.get(i)).getType() == BasicType.getTConflict()) continue;247if (other.isCompiledFrame() && (otherLocs.get(i)).getType() == BasicType.getTConflict()) continue;248249if (!locs.get(i).equals(otherLocs.get(i))) {250return false;251}252}253254// Check expressions255StackValueCollection exprs = getExpressions();256StackValueCollection otherExprs = other.getExpressions();257if (Assert.ASSERTS_ENABLED) {258Assert.that(exprs.size() == otherExprs.size(), "sanity check");259}260for (int i = 0; i < exprs.size(); i++) {261if (!exprs.get(i).equals(otherExprs.get(i))) {262return false;263}264}265266return true;267}268269//--------------------------------------------------------------------------------270// Internals only below this point271//272273private void printStackValuesOn(PrintStream tty, String title, StackValueCollection values) {274if (values.isEmpty()) {275return;276}277tty.println("\t" + title + ":");278for (int index = 0; index < values.size(); index++) {279tty.print("\t" + index + "\t");280values.get(index).printOn(tty);281tty.println();282}283}284}285286287