< prev index next >

src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaVFrame.java

Print this page


   1 /*
   2  * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 package sun.jvm.hotspot.runtime;
  26 
  27 import java.io.*;
  28 import java.util.*;
  29 import sun.jvm.hotspot.oops.*;
  30 import sun.jvm.hotspot.utilities.*;

  31 
  32 public abstract class JavaVFrame extends VFrame {




  33   /** JVM state */
  34   public abstract Method getMethod();
  35   public abstract int    getBCI();
  36   public abstract StackValueCollection getLocals();
  37   public abstract StackValueCollection getExpressions();
  38   public abstract List   getMonitors();    // List<MonitorInfo>
  39 
  40   /** Test operation */
  41   public boolean isJavaFrame() { return true; }
  42 
  43   /** Package-internal constructor */
  44   JavaVFrame(Frame fr, RegisterMap regMap, JavaThread thread) {
  45     super(fr, regMap, thread);
  46   }
  47 
  48   /** Get monitor (if any) that this JavaVFrame is trying to enter */
  49   // FIXME: not yet implemented
  50   //  public Address getPendingMonitor(int frameCount);
  51 


















  52   /** Printing used during stack dumps */
  53   // FIXME: not yet implemented
  54   //  void print_lock_info(int frame_count);


































































































  55 
  56   /** Printing operations */
  57 
  58   //
  59   // FIXME: implement visitor pattern for traversing vframe contents?
  60   //
  61 
  62   public void print() {
  63     printOn(System.out);
  64   }
  65 
  66   public void printOn(PrintStream tty) {
  67     super.printOn(tty);
  68 
  69     tty.print("\t");
  70     getMethod().printValueOn(tty);
  71     tty.println();
  72     tty.println("\tbci:\t" + getBCI());
  73 
  74     printStackValuesOn(tty, "locals",      getLocals());


   1 /*
   2  * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 package sun.jvm.hotspot.runtime;
  26 
  27 import java.io.*;
  28 import java.util.*;
  29 import sun.jvm.hotspot.oops.*;
  30 import sun.jvm.hotspot.utilities.*;
  31 import sun.jvm.hotspot.debugger.*;
  32 
  33 public abstract class JavaVFrame extends VFrame {
  34 
  35   private static final String ADDRESS_FORMAT = VM.getVM().isLP64() ? "0x%016x"
  36                                                                    : "0x%08x";
  37 
  38   /** JVM state */
  39   public abstract Method getMethod();
  40   public abstract int    getBCI();
  41   public abstract StackValueCollection getLocals();
  42   public abstract StackValueCollection getExpressions();
  43   public abstract List<MonitorInfo> getMonitors();
  44 
  45   /** Test operation */
  46   public boolean isJavaFrame() { return true; }
  47 
  48   /** Package-internal constructor */
  49   JavaVFrame(Frame fr, RegisterMap regMap, JavaThread thread) {
  50     super(fr, regMap, thread);
  51   }
  52 
  53   /** Get monitor (if any) that this JavaVFrame is trying to enter */
  54   // FIXME: not yet implemented
  55   //  public Address getPendingMonitor(int frameCount);
  56 
  57   public void printLockedObjectClassName(PrintStream tty,
  58                                          OopHandle hobj, String lockState) {
  59     if (hobj.asLongValue() != 0L) {
  60       tty.format("\t- %s <" + ADDRESS_FORMAT + "> ",
  61                  lockState, hobj.asLongValue());
  62 
  63       Klass klass = Oop.getKlassForOopHandle(hobj);
  64       String klassName = klass.getName().asString();
  65       tty.print("(a ");
  66       if (klassName.equals("java/lang/Class")) {
  67         Oop obj = VM.getVM().getObjectHeap().newOop(hobj);
  68         klassName = java_lang_Class.asExternalName(obj);
  69         tty.print("java.lang.Class for ");
  70       }
  71       tty.println(klassName.replace('/', '.') + ")");
  72     }
  73   }
  74 
  75   /** Printing used during stack dumps */
  76   public void printLockInfo(PrintStream tty, int frameCount) {
  77     // If this is the first frame and it is java.lang.Object.wait(...)
  78     // then print out the receiver. Locals are not always available,
  79     // e.g., compiled native frames have no scope so there are no locals.
  80     if (frameCount == 0) {
  81       if (getMethod().getName().asString().equals("wait") &&
  82           getMethod().getMethodHolder().getName().asString().equals("java/lang/Object")) {
  83         String waitState = "waiting on"; // assume we are waiting
  84         // If earlier in the output we reported java.lang.Thread.State ==
  85         // "WAITING (on object monitor)" and now we report "waiting on", then
  86         // we are still waiting for notification or timeout. Otherwise if
  87         // we earlier reported java.lang.Thread.State == "BLOCKED (on object
  88         // monitor)", then we are actually waiting to re-lock the monitor.
  89         // At this level we can't distinguish the two cases to report
  90         // "waited on" rather than "waiting on" for the second case.
  91         StackValueCollection locs = getLocals();
  92         if (!locs.isEmpty()) {
  93           StackValue sv = locs.get(0);
  94           if (sv.getType() == BasicType.getTObject()) {
  95             OopHandle o = sv.getObject();
  96             printLockedObjectClassName(tty, o, waitState);
  97           }
  98         } else {
  99           tty.println("\t- " + waitState + " <no object reference available>");
 100         }
 101       } else if (thread.getCurrentParkBlocker() != null) {
 102         Oop obj = thread.getCurrentParkBlocker();
 103         Klass k = obj.getKlass();
 104         tty.format("\t- parking to wait for <" + ADDRESS_FORMAT + "> (a %s)",
 105                    obj.getHandle().asLongValue(), k.getName().asString());
 106         tty.println();
 107       }
 108     }
 109 
 110     // Print out all monitors that we have locked, or are trying to lock,
 111     // including re-locking after being notified or timing out in a wait().
 112     List<MonitorInfo> mons = getMonitors();
 113     if (!mons.isEmpty()) {
 114       boolean foundFirstMonitor = false;
 115       for (int index = mons.size() - 1; index >= 0; index--) {
 116         MonitorInfo monitor = mons.get(index);
 117         if (monitor.eliminated() && isCompiledFrame()) { // Eliminated in compiled code
 118           if (monitor.ownerIsScalarReplaced()) {
 119             Klass k = Oop.getKlassForOopHandle(monitor.ownerKlass());
 120             tty.println("\t- eliminated <owner is scalar replaced> (a " + k.getName().asString() + ")");
 121           } else if (monitor.owner() != null) {
 122             printLockedObjectClassName(tty, monitor.owner(), "eliminated");
 123           }
 124           continue;
 125         }
 126         if (monitor.owner() != null) {
 127           // the monitor is associated with an object, i.e., it is locked
 128 
 129           Mark mark = null;
 130           String lockState = "locked";
 131           if (!foundFirstMonitor && frameCount == 0) {
 132             // If this is the first frame and we haven't found an owned
 133             // monitor before, then we need to see if we have completed
 134             // the lock or if we are blocked trying to acquire it. Only
 135             // an inflated monitor that is first on the monitor list in
 136             // the first frame can block us on a monitor enter.
 137             mark = new Mark(monitor.owner());
 138             if (mark.hasMonitor() &&
 139                 ( // we have marked ourself as pending on this monitor
 140                   mark.monitor().equals(thread.getCurrentPendingMonitor()) ||
 141                   // we are not the owner of this monitor
 142                   !mark.monitor().isEntered(thread)
 143                 )) {
 144               lockState = "waiting to lock";
 145             } else {
 146               // We own the monitor which is not as interesting so
 147               // disable the extra printing below.
 148               mark = null;
 149             }
 150           } else if (frameCount != 0) {
 151             // This is not the first frame so we either own this monitor
 152             // or we owned the monitor before and called wait(). Because
 153             // wait() could have been called on any monitor in a lower
 154             // numbered frame on the stack, we have to check all the
 155             // monitors on the list for this frame.
 156             mark = new Mark(monitor.owner());
 157             if (mark.hasMonitor() &&
 158                 ( // we have marked ourself as pending on this monitor
 159                   mark.monitor().equals(thread.getCurrentPendingMonitor()) ||
 160                   // we are not the owner of this monitor
 161                   !mark.monitor().isEntered(thread)
 162                 )) {
 163               lockState = "waiting to re-lock in wait()";
 164             } else {
 165               // We own the monitor which is not as interesting so
 166               // disable the extra printing below.
 167               mark = null;
 168             }
 169           }
 170           printLockedObjectClassName(tty, monitor.owner(), lockState);
 171           foundFirstMonitor = true;
 172         }
 173       }
 174     }
 175   }
 176 
 177   /** Printing operations */
 178 
 179   //
 180   // FIXME: implement visitor pattern for traversing vframe contents?
 181   //
 182 
 183   public void print() {
 184     printOn(System.out);
 185   }
 186 
 187   public void printOn(PrintStream tty) {
 188     super.printOn(tty);
 189 
 190     tty.print("\t");
 191     getMethod().printValueOn(tty);
 192     tty.println();
 193     tty.println("\tbci:\t" + getBCI());
 194 
 195     printStackValuesOn(tty, "locals",      getLocals());


< prev index next >