--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/CLHSDB.java Wed Jul 03 14:50:10 2013 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/CLHSDB.java Wed Jul 03 15:04:53 2013 -0700
@@ -31,13 +31,19 @@
import java.util.*;
public class CLHSDB {
+
+ public CLHSDB(JVMDebugger d) {
+ jvmDebugger = d;
+ }
+
public static void main(String[] args) {
new CLHSDB(args).run();
}
- private void run() {
- // At this point, if pidText != null we are supposed to attach to it.
- // Else, if execPath != null, it is the path of a jdk/bin/java
+ public void run() {
+ // If jvmDebugger is already set, we have been given a JVMDebugger.
+ // Otherwise, if pidText != null we are supposed to attach to it.
+ // Finally, if execPath != null, it is the path of a jdk/bin/java
// and coreFilename is the pathname of a core file we are
// supposed to attach to.
@@ -49,7 +55,9 @@
}
});
- if (pidText != null) {
+ if (jvmDebugger != null) {
+ attachDebugger(jvmDebugger);
+ } else if (pidText != null) {
attachDebugger(pidText);
} else if (execPath != null) {
attachDebugger(execPath, coreFilename);
@@ -96,6 +104,7 @@
// Internals only below this point
//
private HotSpotAgent agent;
+ private JVMDebugger jvmDebugger;
private boolean attached;
// These had to be made data members because they are referenced in inner classes.
private String pidText;
@@ -120,7 +129,7 @@
case (1):
if (args[0].equals("help") || args[0].equals("-help")) {
doUsage();
- System.exit(0);
+ return;
}
// If all numbers, it is a PID to attach to
// Else, it is a pathname to a .../bin/java for a core file.
@@ -142,10 +151,15 @@
default:
System.out.println("HSDB Error: Too many options specified");
doUsage();
- System.exit(1);
+ return;
}
}
+ private void attachDebugger(JVMDebugger d) {
+ agent.attach(d);
+ attached = true;
+ }
+
/** NOTE we are in a different thread here than either the main
thread or the Swing/AWT event handler thread, so we must be very
careful when creating or removing widgets */
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java Wed Jul 03 14:50:10 2013 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java Wed Jul 03 15:04:53 2013 -0700
@@ -101,6 +101,9 @@
import sun.jvm.hotspot.utilities.soql.JSJavaScriptEngine;
public class CommandProcessor {
+
+ volatile boolean quit;
+
public abstract static class DebuggerInterface {
public abstract HotSpotAgent getAgent();
public abstract boolean isAttached();
@@ -1135,7 +1138,7 @@
usage();
} else {
debugger.detach();
- System.exit(0);
+ quit = true;
}
}
},
@@ -1714,7 +1717,7 @@
}
protected void quit() {
debugger.detach();
- System.exit(0);
+ quit = true;
}
protected BufferedReader getInputReader() {
return in;
@@ -1781,7 +1784,7 @@
public void run(boolean prompt) {
// Process interactive commands.
- while (true) {
+ while (!quit) {
if (prompt) printPrompt();
String ln = null;
try {
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/HSDB.java Wed Jul 03 14:50:10 2013 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/HSDB.java Wed Jul 03 15:04:53 2013 -0700
@@ -59,8 +59,11 @@
// Internals only below this point
//
private HotSpotAgent agent;
+ private JVMDebugger jvmDebugger;
private JDesktopPane desktop;
private boolean attached;
+ private boolean argError;
+ private JFrame frame;
/** List <JMenuItem> */
private java.util.List attachMenuItems;
/** List <JMenuItem> */
@@ -85,6 +88,11 @@
System.out.println(" path-to-corefile: Debug this corefile. The default is 'core'");
System.out.println(" If no arguments are specified, you can select what to do from the GUI.\n");
HotSpotAgent.showUsage();
+ argError = true;
+ }
+
+ public HSDB(JVMDebugger d) {
+ jvmDebugger = d;
}
private HSDB(String[] args) {
@@ -95,7 +103,6 @@
case (1):
if (args[0].equals("help") || args[0].equals("-help")) {
doUsage();
- System.exit(0);
}
// If all numbers, it is a PID to attach to
// Else, it is a pathname to a .../bin/java for a core file.
@@ -117,24 +124,29 @@
default:
System.out.println("HSDB Error: Too many options specified");
doUsage();
- System.exit(1);
}
}
- private void run() {
- // At this point, if pidText != null we are supposed to attach to it.
- // Else, if execPath != null, it is the path of a jdk/bin/java
- // and coreFilename is the pathname of a core file we are
- // supposed to attach to.
+ // close this tool without calling System.exit
+ protected void closeUI() {
+ workerThread.shutdown();
+ frame.dispose();
+ }
+
+ public void run() {
+ // Don't start the UI if there were bad arguments.
+ if (argError) {
+ return;
+ }
agent = new HotSpotAgent();
workerThread = new WorkerThread();
attachMenuItems = new java.util.ArrayList();
detachMenuItems = new java.util.ArrayList();
- JFrame frame = new JFrame("HSDB - HotSpot Debugger");
+ frame = new JFrame("HSDB - HotSpot Debugger");
frame.setSize(800, 600);
- frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
+ frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
JMenuBar menuBar = new JMenuBar();
@@ -197,7 +209,7 @@
item = createMenuItem("Exit",
new ActionListener() {
public void actionPerformed(ActionEvent e) {
- System.exit(0);
+ closeUI();
}
});
item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, ActionEvent.ALT_MASK));
@@ -406,7 +418,15 @@
}
});
- if (pidText != null) {
+ // If jvmDebugger is already set, we have been given a JVMDebugger.
+ // Otherwise, if pidText != null we are supposed to attach to it.
+ // Finally, if execPath != null, it is the path of a jdk/bin/java
+ // and coreFilename is the pathname of a core file we are
+ // supposed to attach to.
+
+ if (jvmDebugger != null) {
+ attach(jvmDebugger);
+ } else if (pidText != null) {
attach(pidText);
} else if (execPath != null) {
attach(execPath, coreFilename);
@@ -1113,6 +1133,12 @@
});
}
+ // Attach to existing JVMDebugger, which should be already attached to a core/process.
+ private void attach(JVMDebugger d) {
+ attached = true;
+ showThreadsDialog();
+ }
+
/** NOTE we are in a different thread here than either the main
thread or the Swing/AWT event handler thread, so we must be very
careful when creating or removing widgets */
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java Wed Jul 03 14:50:10 2013 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java Wed Jul 03 15:04:53 2013 -0700
@@ -25,6 +25,8 @@
package sun.jvm.hotspot;
import java.rmi.RemoteException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
import sun.jvm.hotspot.debugger.Debugger;
import sun.jvm.hotspot.debugger.DebuggerException;
@@ -63,7 +65,6 @@
private String os;
private String cpu;
- private String fileSep;
// The system can work in several ways:
// - Attaching to local process
@@ -155,6 +156,14 @@
go();
}
+ /** This uses a JVMDebugger that is already attached to the core or process */
+ public synchronized void attach(JVMDebugger d)
+ throws DebuggerException {
+ debugger = d;
+ isServer = false;
+ go();
+ }
+
/** This attaches to a "debug server" on a remote machine; this
remote server has already attached to a process or opened a
core file and is waiting for RMI calls on the Debugger object to
@@ -303,28 +312,37 @@
// server, but not client attaching to server)
//
- try {
- os = PlatformInfo.getOS();
- cpu = PlatformInfo.getCPU();
- }
- catch (UnsupportedPlatformException e) {
- throw new DebuggerException(e);
- }
- fileSep = System.getProperty("file.separator");
+ // Handle existing or alternate JVMDebugger:
+ // these will set os, cpu independently of our PlatformInfo implementation.
+ String alternateDebugger = System.getProperty("sa.altDebugger");
+ if (debugger != null) {
+ setupDebuggerExisting();
+
+ } else if (alternateDebugger != null) {
+ setupDebuggerAlternate(alternateDebugger);
- if (os.equals("solaris")) {
- setupDebuggerSolaris();
- } else if (os.equals("win32")) {
- setupDebuggerWin32();
- } else if (os.equals("linux")) {
- setupDebuggerLinux();
- } else if (os.equals("bsd")) {
- setupDebuggerBsd();
- } else if (os.equals("darwin")) {
- setupDebuggerDarwin();
} else {
- // Add support for more operating systems here
- throw new DebuggerException("Operating system " + os + " not yet supported");
+ // Otherwise, os, cpu are those of our current platform:
+ try {
+ os = PlatformInfo.getOS();
+ cpu = PlatformInfo.getCPU();
+ } catch (UnsupportedPlatformException e) {
+ throw new DebuggerException(e);
+ }
+ if (os.equals("solaris")) {
+ setupDebuggerSolaris();
+ } else if (os.equals("win32")) {
+ setupDebuggerWin32();
+ } else if (os.equals("linux")) {
+ setupDebuggerLinux();
+ } else if (os.equals("bsd")) {
+ setupDebuggerBsd();
+ } else if (os.equals("darwin")) {
+ setupDebuggerDarwin();
+ } else {
+ // Add support for more operating systems here
+ throw new DebuggerException("Operating system " + os + " not yet supported");
+ }
}
if (isServer) {
@@ -423,6 +441,41 @@
// OS-specific debugger setup/connect routines
//
+ // Use the existing JVMDebugger, as passed to our constructor.
+ // Retrieve os and cpu from that debugger, not the current platform.
+ private void setupDebuggerExisting() {
+
+ os = debugger.getOS();
+ cpu = debugger.getCPU();
+ setupJVMLibNames(os);
+ machDesc = debugger.getMachineDescription();
+ }
+
+ // Given a classname, load an alternate implementation of JVMDebugger.
+ private void setupDebuggerAlternate(String alternateName) {
+
+ try {
+ Class c = Class.forName(alternateName);
+ Constructor cons = c.getConstructor();
+ debugger = (JVMDebugger) cons.newInstance();
+ attachDebugger();
+ setupDebuggerExisting();
+
+ } catch (ClassNotFoundException cnfe) {
+ throw new DebuggerException("Cannot find alternate SA Debugger: '" + alternateName + "'");
+ } catch (NoSuchMethodException nsme) {
+ throw new DebuggerException("Alternate SA Debugger: '" + alternateName + "' has missing constructor.");
+ } catch (InstantiationException ie) {
+ throw new DebuggerException("Alternate SA Debugger: '" + alternateName + "' fails to initialise: ", ie);
+ } catch (IllegalAccessException iae) {
+ throw new DebuggerException("Alternate SA Debugger: '" + alternateName + "' fails to initialise: ", iae);
+ } catch (InvocationTargetException iae) {
+ throw new DebuggerException("Alternate SA Debugger: '" + alternateName + "' fails to initialise: ", iae);
+ }
+
+ System.err.println("Loaded alternate HotSpot SA Debugger: " + alternateName);
+ }
+
//
// Solaris
//
@@ -466,6 +519,11 @@
debugger = new RemoteDebuggerClient(remote);
machDesc = ((RemoteDebuggerClient) debugger).getMachineDescription();
os = debugger.getOS();
+ setupJVMLibNames(os);
+ cpu = debugger.getCPU();
+ }
+
+ private void setupJVMLibNames(String os) {
if (os.equals("solaris")) {
setupJVMLibNamesSolaris();
} else if (os.equals("win32")) {
@@ -479,8 +537,6 @@
} else {
throw new RuntimeException("Unknown OS type");
}
-
- cpu = debugger.getCPU();
}
private void setupJVMLibNamesSolaris() {
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxAddress.java Wed Jul 03 14:50:10 2013 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxAddress.java Wed Jul 03 15:04:53 2013 -0700
@@ -26,11 +26,11 @@
import sun.jvm.hotspot.debugger.*;
-class LinuxAddress implements Address {
+public class LinuxAddress implements Address {
protected LinuxDebugger debugger;
protected long addr;
- LinuxAddress(LinuxDebugger debugger, long addr) {
+ public LinuxAddress(LinuxDebugger debugger, long addr) {
this.debugger = debugger;
this.addr = addr;
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxOopHandle.java Wed Jul 03 14:50:10 2013 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxOopHandle.java Wed Jul 03 15:04:53 2013 -0700
@@ -26,8 +26,8 @@
import sun.jvm.hotspot.debugger.*;
-class LinuxOopHandle extends LinuxAddress implements OopHandle {
- LinuxOopHandle(LinuxDebugger debugger, long addr) {
+public class LinuxOopHandle extends LinuxAddress implements OopHandle {
+ public LinuxOopHandle(LinuxDebugger debugger, long addr) {
super(debugger, addr);
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java Wed Jul 03 14:50:10 2013 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java Wed Jul 03 15:04:53 2013 -0700
@@ -246,7 +246,7 @@
}
}
- private static final boolean disableDerivedPrinterTableCheck;
+ private static final boolean disableDerivedPointerTableCheck;
private static final Properties saProps;
static {
@@ -256,12 +256,12 @@
url = VM.class.getClassLoader().getResource("sa.properties");
saProps.load(new BufferedInputStream(url.openStream()));
} catch (Exception e) {
- throw new RuntimeException("Unable to load properties " +
+ System.err.println("Unable to load properties " +
(url == null ? "null" : url.toString()) +
": " + e.getMessage());
}
- disableDerivedPrinterTableCheck = System.getProperty("sun.jvm.hotspot.runtime.VM.disableDerivedPointerTableCheck") != null;
+ disableDerivedPointerTableCheck = System.getProperty("sun.jvm.hotspot.runtime.VM.disableDerivedPointerTableCheck") != null;
}
private VM(TypeDataBase db, JVMDebugger debugger, boolean isBigEndian) {
@@ -371,7 +371,8 @@
/** This is used by the debugging system */
public static void initialize(TypeDataBase db, JVMDebugger debugger) {
if (soleInstance != null) {
- throw new RuntimeException("Attempt to initialize VM twice");
+ // Using multiple SA Tool classes in the same process creates a call here.
+ return;
}
soleInstance = new VM(db, debugger, debugger.getMachineDescription().isBigEndian());
@@ -683,7 +684,7 @@
/** Returns true if C2 derived pointer table should be used, false otherwise */
public boolean useDerivedPointerTable() {
- return !disableDerivedPrinterTableCheck;
+ return !disableDerivedPointerTableCheck;
}
/** Returns the code cache; should not be used if is core build */
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/ClassLoaderStats.java Wed Jul 03 14:50:10 2013 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/ClassLoaderStats.java Wed Jul 03 15:04:53 2013 -0700
@@ -41,6 +41,14 @@
public class ClassLoaderStats extends Tool {
boolean verbose = true;
+ public ClassLoaderStats() {
+ super();
+ }
+
+ public ClassLoaderStats(JVMDebugger d) {
+ super(d);
+ }
+
public static void main(String[] args) {
ClassLoaderStats cls = new ClassLoaderStats();
cls.start(args);
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/FinalizerInfo.java Wed Jul 03 14:50:10 2013 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/FinalizerInfo.java Wed Jul 03 15:04:53 2013 -0700
@@ -24,6 +24,7 @@
package sun.jvm.hotspot.tools;
+import sun.jvm.hotspot.debugger.JVMDebugger;
import sun.jvm.hotspot.tools.*;
import sun.jvm.hotspot.oops.*;
@@ -42,6 +43,15 @@
* summary of these objects in the form of a histogram.
*/
public class FinalizerInfo extends Tool {
+
+ public FinalizerInfo() {
+ super();
+ }
+
+ public FinalizerInfo(JVMDebugger d) {
+ super(d);
+ }
+
public static void main(String[] args) {
FinalizerInfo finfo = new FinalizerInfo();
finfo.start(args);
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/FlagDumper.java Wed Jul 03 14:50:10 2013 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/FlagDumper.java Wed Jul 03 15:04:53 2013 -0700
@@ -25,10 +25,19 @@
package sun.jvm.hotspot.tools;
import java.io.PrintStream;
+import sun.jvm.hotspot.debugger.JVMDebugger;
import sun.jvm.hotspot.runtime.*;
public class FlagDumper extends Tool {
+ public FlagDumper() {
+ super();
+ }
+
+ public FlagDumper(JVMDebugger d) {
+ super(d);
+ }
+
public void run() {
VM.Flag[] flags = VM.getVM().getCommandLineFlags();
PrintStream out = System.out;
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapDumper.java Wed Jul 03 14:50:10 2013 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapDumper.java Wed Jul 03 15:04:53 2013 -0700
@@ -25,6 +25,7 @@
package sun.jvm.hotspot.tools;
import sun.jvm.hotspot.utilities.HeapHprofBinWriter;
+import sun.jvm.hotspot.debugger.JVMDebugger;
import java.io.IOException;
/*
@@ -42,6 +43,11 @@
this.dumpFile = dumpFile;
}
+ public HeapDumper(String dumpFile, JVMDebugger d) {
+ super(d);
+ this.dumpFile = dumpFile;
+ }
+
protected void printFlagsUsage() {
System.out.println(" <no option>\tto dump heap to " +
DEFAULT_DUMP_FILE);
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java Wed Jul 03 14:50:10 2013 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java Wed Jul 03 15:04:53 2013 -0700
@@ -29,12 +29,21 @@
import sun.jvm.hotspot.gc_implementation.g1.*;
import sun.jvm.hotspot.gc_implementation.parallelScavenge.*;
import sun.jvm.hotspot.gc_implementation.shared.*;
+import sun.jvm.hotspot.debugger.JVMDebugger;
import sun.jvm.hotspot.memory.*;
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.runtime.*;
public class HeapSummary extends Tool {
+ public HeapSummary() {
+ super();
+ }
+
+ public HeapSummary(JVMDebugger d) {
+ super(d);
+ }
+
public static void main(String[] args) {
HeapSummary hs = new HeapSummary();
hs.start(args);
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JInfo.java Wed Jul 03 14:50:10 2013 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JInfo.java Wed Jul 03 15:04:53 2013 -0700
@@ -25,12 +25,21 @@
package sun.jvm.hotspot.tools;
import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.debugger.JVMDebugger;
public class JInfo extends Tool {
+ public JInfo() {
+ super();
+ }
+
public JInfo(int m) {
mode = m;
}
+ public JInfo(JVMDebugger d) {
+ super(d);
+ }
+
protected boolean needsJavaPrefix() {
return false;
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JMap.java Wed Jul 03 14:50:10 2013 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JMap.java Wed Jul 03 15:04:53 2013 -0700
@@ -25,6 +25,7 @@
package sun.jvm.hotspot.tools;
import java.io.*;
+import sun.jvm.hotspot.debugger.JVMDebugger;
import sun.jvm.hotspot.utilities.*;
public class JMap extends Tool {
@@ -36,6 +37,10 @@
this(MODE_PMAP);
}
+ public JMap(JVMDebugger d) {
+ super(d);
+ }
+
protected boolean needsJavaPrefix() {
return false;
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JSnap.java Wed Jul 03 14:50:10 2013 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JSnap.java Wed Jul 03 15:04:53 2013 -0700
@@ -25,9 +25,19 @@
package sun.jvm.hotspot.tools;
import java.io.*;
+import sun.jvm.hotspot.debugger.JVMDebugger;
import sun.jvm.hotspot.runtime.*;
public class JSnap extends Tool {
+
+ public JSnap() {
+ super();
+ }
+
+ public JSnap(JVMDebugger d) {
+ super(d);
+ }
+
public void run() {
final PrintStream out = System.out;
if (PerfMemory.initialized()) {
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JStack.java Wed Jul 03 14:50:10 2013 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JStack.java Wed Jul 03 15:04:53 2013 -0700
@@ -24,6 +24,8 @@
package sun.jvm.hotspot.tools;
+import sun.jvm.hotspot.debugger.JVMDebugger;
+
public class JStack extends Tool {
public JStack(boolean mixedMode, boolean concurrentLocks) {
this.mixedMode = mixedMode;
@@ -34,6 +36,10 @@
this(true, true);
}
+ public JStack(JVMDebugger d) {
+ super(d);
+ }
+
protected boolean needsJavaPrefix() {
return false;
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/ObjectHistogram.java Wed Jul 03 14:50:10 2013 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/ObjectHistogram.java Wed Jul 03 15:04:53 2013 -0700
@@ -33,6 +33,14 @@
an object histogram from a remote or crashed VM. */
public class ObjectHistogram extends Tool {
+ public ObjectHistogram() {
+ super();
+ }
+
+ public ObjectHistogram(JVMDebugger d) {
+ super(d);
+ }
+
public void run() {
run(System.out, System.err);
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PMap.java Wed Jul 03 14:50:10 2013 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PMap.java Wed Jul 03 15:04:53 2013 -0700
@@ -31,6 +31,15 @@
import sun.jvm.hotspot.runtime.*;
public class PMap extends Tool {
+
+ public PMap() {
+ super();
+ }
+
+ public PMap(JVMDebugger d) {
+ super(d);
+ }
+
public void run() {
run(System.out);
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java Wed Jul 03 14:50:10 2013 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java Wed Jul 03 15:04:53 2013 -0700
@@ -45,6 +45,10 @@
this(true, true);
}
+ public PStack(JVMDebugger d) {
+ super(d);
+ }
+
public void run() {
run(System.out);
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/StackTrace.java Wed Jul 03 14:50:10 2013 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/StackTrace.java Wed Jul 03 15:04:53 2013 -0700
@@ -45,6 +45,16 @@
run(System.out);
}
+ public StackTrace(JVMDebugger d) {
+ super(d);
+ }
+
+ public StackTrace(JVMDebugger d, boolean v, boolean concurrentLocks) {
+ super(d);
+ this.verbose = v;
+ this.concurrentLocks = concurrentLocks;
+ }
+
public void run(java.io.PrintStream tty) {
// Ready to go with the database...
try {
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/SysPropsDumper.java Wed Jul 03 14:50:10 2013 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/SysPropsDumper.java Wed Jul 03 15:04:53 2013 -0700
@@ -27,10 +27,19 @@
import java.io.PrintStream;
import java.util.*;
+import sun.jvm.hotspot.debugger.JVMDebugger;
import sun.jvm.hotspot.runtime.*;
public class SysPropsDumper extends Tool {
+ public SysPropsDumper() {
+ super();
+ }
+
+ public SysPropsDumper(JVMDebugger d) {
+ super(d);
+ }
+
public void run() {
Properties sysProps = VM.getVM().getSystemProperties();
PrintStream out = System.out;
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/Tool.java Wed Jul 03 14:50:10 2013 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/Tool.java Wed Jul 03 15:04:53 2013 -0700
@@ -35,6 +35,7 @@
public abstract class Tool implements Runnable {
private HotSpotAgent agent;
+ private JVMDebugger jvmDebugger;
private int debugeeType;
// debugeeType is one of constants below
@@ -42,6 +43,13 @@
protected static final int DEBUGEE_CORE = 1;
protected static final int DEBUGEE_REMOTE = 2;
+ public Tool() {
+ }
+
+ public Tool(JVMDebugger d) {
+ jvmDebugger = d;
+ }
+
public String getName() {
return getClass().getName();
}
@@ -90,7 +98,6 @@
protected void usage() {
printUsage();
- System.exit(1);
}
/*
@@ -106,13 +113,13 @@
protected void stop() {
if (agent != null) {
agent.detach();
- System.exit(0);
}
}
protected void start(String[] args) {
if ((args.length < 1) || (args.length > 2)) {
usage();
+ return;
}
// Attempt to handle -h or -help or some invalid flag
@@ -185,13 +192,31 @@
}
if (e.getMessage() != null) {
err.print(e.getMessage());
+ e.printStackTrace();
}
err.println();
- System.exit(1);
+ return;
}
err.println("Debugger attached successfully.");
+ startInternal();
+ }
+ // When using an existing JVMDebugger.
+ public void start() {
+
+ if (jvmDebugger == null) {
+ throw new RuntimeException("Tool.start() called with no JVMDebugger set.");
+ }
+ agent = new HotSpotAgent();
+ agent.attach(jvmDebugger);
+ startInternal();
+ }
+
+ // Remains of the start mechanism, common to both start methods.
+ private void startInternal() {
+
+ PrintStream err = System.err;
VM vm = VM.getVM();
if (vm.isCore()) {
err.println("Core build detected.");
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java Wed Jul 03 14:50:10 2013 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java Wed Jul 03 15:04:53 2013 -0700
@@ -25,6 +25,7 @@
package sun.jvm.hotspot.tools.jcore;
import java.io.*;
+import java.lang.reflect.Constructor;
import java.util.jar.JarOutputStream;
import java.util.jar.JarEntry;
import java.util.jar.Manifest;
@@ -38,6 +39,16 @@
private ClassFilter classFilter;
private String outputDirectory;
private JarOutputStream jarStream;
+ private String pkgList;
+
+ public ClassDump() {
+ super();
+ }
+
+ public ClassDump(JVMDebugger d, String pkgList) {
+ super(d);
+ this.pkgList = pkgList;
+ }
public void setClassFilter(ClassFilter cf) {
classFilter = cf;
@@ -63,6 +74,25 @@
public void run() {
// Ready to go with the database...
try {
+ // The name of the filter always comes from a System property.
+ // If we have a pkgList, pass it, otherwise let the filter read
+ // its own System property for the list of classes.
+ String filterClassName = System.getProperty("sun.jvm.hotspot.tools.jcore.filter",
+ "sun.jvm.hotspot.tools.jcore.PackageNameFilter");
+ try {
+ Class filterClass = Class.forName(filterClassName);
+ if (pkgList == null) {
+ classFilter = (ClassFilter) filterClass.newInstance();
+ } else {
+ Constructor con = filterClass.getConstructor(String.class);
+ classFilter = (ClassFilter) con.newInstance(pkgList);
+ }
+ } catch(Exception exp) {
+ System.err.println("Warning: Can not create class filter!");
+ }
+
+ String outputDirectory = System.getProperty("sun.jvm.hotspot.tools.jcore.outputDir", ".");
+ setOutputDirectory(outputDirectory);
// walk through the system dictionary
SystemDictionary dict = VM.getVM().getSystemDictionary();
@@ -139,26 +169,8 @@
}
public static void main(String[] args) {
- // load class filters
- ClassFilter classFilter = null;
- String filterClassName = System.getProperty("sun.jvm.hotspot.tools.jcore.filter");
- if (filterClassName != null) {
- try {
- Class filterClass = Class.forName(filterClassName);
- classFilter = (ClassFilter) filterClass.newInstance();
- } catch(Exception exp) {
- System.err.println("Warning: Can not create class filter!");
- }
- }
-
- String outputDirectory = System.getProperty("sun.jvm.hotspot.tools.jcore.outputDir");
- if (outputDirectory == null)
- outputDirectory = ".";
-
ClassDump cd = new ClassDump();
- cd.setClassFilter(classFilter);
- cd.setOutputDirectory(outputDirectory);
cd.start(args);
cd.stop();
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/soql/JSDB.java Wed Jul 03 14:50:10 2013 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/soql/JSDB.java Wed Jul 03 15:04:53 2013 -0700
@@ -24,12 +24,22 @@
package sun.jvm.hotspot.tools.soql;
+import sun.jvm.hotspot.debugger.JVMDebugger;
import sun.jvm.hotspot.tools.*;
import sun.jvm.hotspot.utilities.*;
import sun.jvm.hotspot.utilities.soql.*;
/** This is command line JavaScript debugger console */
public class JSDB extends Tool {
+
+ public JSDB() {
+ super();
+ }
+
+ public JSDB(JVMDebugger d) {
+ super(d);
+ }
+
public static void main(String[] args) {
JSDB jsdb = new JSDB();
jsdb.start(args);
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/soql/SOQL.java Wed Jul 03 14:50:10 2013 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/soql/SOQL.java Wed Jul 03 15:04:53 2013 -0700
@@ -44,6 +44,14 @@
soql.stop();
}
+ public SOQL() {
+ super();
+ }
+
+ public SOQL(JVMDebugger d) {
+ super(d);
+ }
+
protected SOQLEngine soqlEngine;
protected BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
protected PrintStream out = System.out;
--- a/hotspot/src/cpu/sparc/vm/frame_sparc.cpp Wed Jul 03 14:50:10 2013 -0700
+++ b/hotspot/src/cpu/sparc/vm/frame_sparc.cpp Wed Jul 03 15:04:53 2013 -0700
@@ -257,11 +257,6 @@
return false;
}
- // Could be a zombie method
- if (sender_blob->is_zombie() || sender_blob->is_unloaded()) {
- return false;
- }
-
// It should be safe to construct the sender though it might not be valid
frame sender(_SENDER_SP, younger_sp, adjusted_stack);
--- a/hotspot/src/os/solaris/dtrace/jhelper.d Wed Jul 03 14:50:10 2013 -0700
+++ b/hotspot/src/os/solaris/dtrace/jhelper.d Wed Jul 03 15:04:53 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, 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
@@ -332,12 +332,15 @@
this->nameSymbol = copyin_ptr(this->constantPool +
this->nameIndex * sizeof (pointer) + SIZE_ConstantPool);
+ /* The symbol is a CPSlot and has lower bit set to indicate metadata */
+ this->nameSymbol &= (~1); /* remove metadata lsb */
this->nameSymbolLength = copyin_uint16(this->nameSymbol +
OFFSET_Symbol_length);
this->signatureSymbol = copyin_ptr(this->constantPool +
this->signatureIndex * sizeof (pointer) + SIZE_ConstantPool);
+ this->signatureSymbol &= (~1); /* remove metadata lsb */
this->signatureSymbolLength = copyin_uint16(this->signatureSymbol +
OFFSET_Symbol_length);
--- a/hotspot/src/share/vm/memory/filemap.cpp Wed Jul 03 14:50:10 2013 -0700
+++ b/hotspot/src/share/vm/memory/filemap.cpp Wed Jul 03 15:04:53 2013 -0700
@@ -549,3 +549,13 @@
return false;
}
+
+void FileMapInfo::print_shared_spaces() {
+ gclog_or_tty->print_cr("Shared Spaces:");
+ for (int i = 0; i < MetaspaceShared::n_regions; i++) {
+ struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i];
+ gclog_or_tty->print(" %s " INTPTR_FORMAT "-" INTPTR_FORMAT,
+ shared_region_name[i],
+ si->_base, si->_base + si->_used);
+ }
+}
--- a/hotspot/src/share/vm/memory/filemap.hpp Wed Jul 03 14:50:10 2013 -0700
+++ b/hotspot/src/share/vm/memory/filemap.hpp Wed Jul 03 15:04:53 2013 -0700
@@ -149,6 +149,7 @@
// Return true if given address is in the mapped shared space.
bool is_in_shared_space(const void* p) NOT_CDS_RETURN_(false);
+ void print_shared_spaces() NOT_CDS_RETURN;
};
#endif // SHARE_VM_MEMORY_FILEMAP_HPP
--- a/hotspot/src/share/vm/memory/metaspace.cpp Wed Jul 03 14:50:10 2013 -0700
+++ b/hotspot/src/share/vm/memory/metaspace.cpp Wed Jul 03 15:04:53 2013 -0700
@@ -70,7 +70,7 @@
SpecializedChunk = 128,
ClassSmallChunk = 256,
SmallChunk = 512,
- ClassMediumChunk = 1 * K,
+ ClassMediumChunk = 4 * K,
MediumChunk = 8 * K,
HumongousChunkGranularity = 8
};
@@ -580,7 +580,6 @@
// Number of small chunks to allocate to a manager
// If class space manager, small chunks are unlimited
static uint const _small_chunk_limit;
- bool has_small_chunk_limit() { return !vs_list()->is_class(); }
// Sum of all space in allocated chunks
size_t _allocated_blocks_words;
@@ -1298,13 +1297,18 @@
bool MetaspaceGC::should_expand(VirtualSpaceList* vsl, size_t word_size) {
- size_t committed_capacity_bytes = MetaspaceAux::allocated_capacity_bytes();
// If the user wants a limit, impose one.
- size_t max_metaspace_size_bytes = MaxMetaspaceSize;
- size_t metaspace_size_bytes = MetaspaceSize;
- if (!FLAG_IS_DEFAULT(MaxMetaspaceSize) &&
- MetaspaceAux::reserved_in_bytes() >= MaxMetaspaceSize) {
- return false;
+ // The reason for someone using this flag is to limit reserved space. So
+ // for non-class virtual space, compare against virtual spaces that are reserved.
+ // For class virtual space, we only compare against the committed space, not
+ // reserved space, because this is a larger space prereserved for compressed
+ // class pointers.
+ if (!FLAG_IS_DEFAULT(MaxMetaspaceSize)) {
+ size_t real_allocated = Metaspace::space_list()->virtual_space_total() +
+ MetaspaceAux::allocated_capacity_bytes(Metaspace::ClassType);
+ if (real_allocated >= MaxMetaspaceSize) {
+ return false;
+ }
}
// Class virtual space should always be expanded. Call GC for the other
@@ -1318,11 +1322,12 @@
}
-
// If the capacity is below the minimum capacity, allow the
// expansion. Also set the high-water-mark (capacity_until_GC)
// to that minimum capacity so that a GC will not be induced
// until that minimum capacity is exceeded.
+ size_t committed_capacity_bytes = MetaspaceAux::allocated_capacity_bytes();
+ size_t metaspace_size_bytes = MetaspaceSize;
if (committed_capacity_bytes < metaspace_size_bytes ||
capacity_until_GC() == 0) {
set_capacity_until_GC(metaspace_size_bytes);
@@ -1854,13 +1859,11 @@
Metachunk* chunk = chunks_in_use(index);
// Count the free space in all the chunk but not the
// current chunk from which allocations are still being done.
- if (chunk != NULL) {
- Metachunk* prev = chunk;
- while (chunk != NULL && chunk != current_chunk()) {
+ while (chunk != NULL) {
+ if (chunk != current_chunk()) {
result += chunk->free_word_size();
- prev = chunk;
- chunk = chunk->next();
}
+ chunk = chunk->next();
}
return result;
}
@@ -1949,8 +1952,7 @@
// chunks will be allocated.
size_t chunk_word_size;
if (chunks_in_use(MediumIndex) == NULL &&
- (!has_small_chunk_limit() ||
- sum_count_in_chunks_in_use(SmallIndex) < _small_chunk_limit)) {
+ sum_count_in_chunks_in_use(SmallIndex) < _small_chunk_limit) {
chunk_word_size = (size_t) small_chunk_size();
if (word_size + Metachunk::overhead() > small_chunk_size()) {
chunk_word_size = medium_chunk_size();
@@ -2659,10 +2661,10 @@
// Print total fragmentation for class and data metaspaces separately
void MetaspaceAux::print_waste(outputStream* out) {
- size_t specialized_waste = 0, small_waste = 0, medium_waste = 0, large_waste = 0;
- size_t specialized_count = 0, small_count = 0, medium_count = 0, large_count = 0;
- size_t cls_specialized_waste = 0, cls_small_waste = 0, cls_medium_waste = 0, cls_large_waste = 0;
- size_t cls_specialized_count = 0, cls_small_count = 0, cls_medium_count = 0, cls_large_count = 0;
+ size_t specialized_waste = 0, small_waste = 0, medium_waste = 0;
+ size_t specialized_count = 0, small_count = 0, medium_count = 0, humongous_count = 0;
+ size_t cls_specialized_waste = 0, cls_small_waste = 0, cls_medium_waste = 0;
+ size_t cls_specialized_count = 0, cls_small_count = 0, cls_medium_count = 0, cls_humongous_count = 0;
ClassLoaderDataGraphMetaspaceIterator iter;
while (iter.repeat()) {
@@ -2674,8 +2676,7 @@
small_count += msp->vsm()->sum_count_in_chunks_in_use(SmallIndex);
medium_waste += msp->vsm()->sum_waste_in_chunks_in_use(MediumIndex);
medium_count += msp->vsm()->sum_count_in_chunks_in_use(MediumIndex);
- large_waste += msp->vsm()->sum_waste_in_chunks_in_use(HumongousIndex);
- large_count += msp->vsm()->sum_count_in_chunks_in_use(HumongousIndex);
+ humongous_count += msp->vsm()->sum_count_in_chunks_in_use(HumongousIndex);
cls_specialized_waste += msp->class_vsm()->sum_waste_in_chunks_in_use(SpecializedIndex);
cls_specialized_count += msp->class_vsm()->sum_count_in_chunks_in_use(SpecializedIndex);
@@ -2683,20 +2684,23 @@
cls_small_count += msp->class_vsm()->sum_count_in_chunks_in_use(SmallIndex);
cls_medium_waste += msp->class_vsm()->sum_waste_in_chunks_in_use(MediumIndex);
cls_medium_count += msp->class_vsm()->sum_count_in_chunks_in_use(MediumIndex);
- cls_large_waste += msp->class_vsm()->sum_waste_in_chunks_in_use(HumongousIndex);
- cls_large_count += msp->class_vsm()->sum_count_in_chunks_in_use(HumongousIndex);
+ cls_humongous_count += msp->class_vsm()->sum_count_in_chunks_in_use(HumongousIndex);
}
}
out->print_cr("Total fragmentation waste (words) doesn't count free space");
out->print_cr(" data: " SIZE_FORMAT " specialized(s) " SIZE_FORMAT ", "
SIZE_FORMAT " small(s) " SIZE_FORMAT ", "
- SIZE_FORMAT " medium(s) " SIZE_FORMAT,
+ SIZE_FORMAT " medium(s) " SIZE_FORMAT ", "
+ "large count " SIZE_FORMAT,
specialized_count, specialized_waste, small_count,
- small_waste, medium_count, medium_waste);
+ small_waste, medium_count, medium_waste, humongous_count);
out->print_cr(" class: " SIZE_FORMAT " specialized(s) " SIZE_FORMAT ", "
- SIZE_FORMAT " small(s) " SIZE_FORMAT,
+ SIZE_FORMAT " small(s) " SIZE_FORMAT ", "
+ SIZE_FORMAT " medium(s) " SIZE_FORMAT ", "
+ "large count " SIZE_FORMAT,
cls_specialized_count, cls_specialized_waste,
- cls_small_count, cls_small_waste);
+ cls_small_count, cls_small_waste,
+ cls_medium_count, cls_medium_waste, cls_humongous_count);
}
// Dump global metaspace things from the end of ClassLoaderDataGraph
@@ -3037,18 +3041,24 @@
if (Verbose && TraceMetadataChunkAllocation) {
gclog_or_tty->print_cr("Metaspace allocation failed for size "
SIZE_FORMAT, word_size);
- if (loader_data->metaspace_or_null() != NULL) loader_data->metaspace_or_null()->dump(gclog_or_tty);
+ if (loader_data->metaspace_or_null() != NULL) loader_data->dump(gclog_or_tty);
MetaspaceAux::dump(gclog_or_tty);
}
// -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support
- report_java_out_of_memory("Metadata space");
+ const char* space_string = (mdtype == ClassType) ? "Class Metadata space" :
+ "Metadata space";
+ report_java_out_of_memory(space_string);
if (JvmtiExport::should_post_resource_exhausted()) {
JvmtiExport::post_resource_exhausted(
JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR,
- "Metadata space");
+ space_string);
}
- THROW_OOP_0(Universe::out_of_memory_error_perm_gen());
+ if (mdtype == ClassType) {
+ THROW_OOP_0(Universe::out_of_memory_error_class_metaspace());
+ } else {
+ THROW_OOP_0(Universe::out_of_memory_error_metaspace());
+ }
}
}
return Metablock::initialize(result, word_size);
--- a/hotspot/src/share/vm/memory/metaspaceShared.cpp Wed Jul 03 14:50:10 2013 -0700
+++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp Wed Jul 03 15:04:53 2013 -0700
@@ -826,35 +826,15 @@
bool reading() const { return true; }
};
-
-// Save bounds of shared spaces mapped in.
-static char* _ro_base = NULL;
-static char* _rw_base = NULL;
-static char* _md_base = NULL;
-static char* _mc_base = NULL;
-
// Return true if given address is in the mapped shared space.
bool MetaspaceShared::is_in_shared_space(const void* p) {
- if (_ro_base == NULL || _rw_base == NULL) {
- return false;
- } else {
- return ((p >= _ro_base && p < (_ro_base + SharedReadOnlySize)) ||
- (p >= _rw_base && p < (_rw_base + SharedReadWriteSize)));
- }
+ return UseSharedSpaces && FileMapInfo::current_info()->is_in_shared_space(p);
}
void MetaspaceShared::print_shared_spaces() {
- gclog_or_tty->print_cr("Shared Spaces:");
- gclog_or_tty->print(" read-only " INTPTR_FORMAT "-" INTPTR_FORMAT,
- _ro_base, _ro_base + SharedReadOnlySize);
- gclog_or_tty->print(" read-write " INTPTR_FORMAT "-" INTPTR_FORMAT,
- _rw_base, _rw_base + SharedReadWriteSize);
- gclog_or_tty->cr();
- gclog_or_tty->print(" misc-data " INTPTR_FORMAT "-" INTPTR_FORMAT,
- _md_base, _md_base + SharedMiscDataSize);
- gclog_or_tty->print(" misc-code " INTPTR_FORMAT "-" INTPTR_FORMAT,
- _mc_base, _mc_base + SharedMiscCodeSize);
- gclog_or_tty->cr();
+ if (UseSharedSpaces) {
+ FileMapInfo::current_info()->print_shared_spaces();
+ }
}
@@ -874,6 +854,11 @@
assert(!DumpSharedSpaces, "Should not be called with DumpSharedSpaces");
+ char* _ro_base = NULL;
+ char* _rw_base = NULL;
+ char* _md_base = NULL;
+ char* _mc_base = NULL;
+
// Map each shared region
if ((_ro_base = mapinfo->map_region(ro)) != NULL &&
(_rw_base = mapinfo->map_region(rw)) != NULL &&
--- a/hotspot/src/share/vm/memory/referenceProcessorStats.hpp Wed Jul 03 14:50:10 2013 -0700
+++ b/hotspot/src/share/vm/memory/referenceProcessorStats.hpp Wed Jul 03 15:04:53 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, 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
--- a/hotspot/src/share/vm/memory/universe.cpp Wed Jul 03 14:50:10 2013 -0700
+++ b/hotspot/src/share/vm/memory/universe.cpp Wed Jul 03 15:04:53 2013 -0700
@@ -111,7 +111,8 @@
LatestMethodOopCache* Universe::_pd_implies_cache = NULL;
ActiveMethodOopsCache* Universe::_reflect_invoke_cache = NULL;
oop Universe::_out_of_memory_error_java_heap = NULL;
-oop Universe::_out_of_memory_error_perm_gen = NULL;
+oop Universe::_out_of_memory_error_metaspace = NULL;
+oop Universe::_out_of_memory_error_class_metaspace = NULL;
oop Universe::_out_of_memory_error_array_size = NULL;
oop Universe::_out_of_memory_error_gc_overhead_limit = NULL;
objArrayOop Universe::_preallocated_out_of_memory_error_array = NULL;
@@ -180,7 +181,8 @@
f->do_oop((oop*)&_the_null_string);
f->do_oop((oop*)&_the_min_jint_string);
f->do_oop((oop*)&_out_of_memory_error_java_heap);
- f->do_oop((oop*)&_out_of_memory_error_perm_gen);
+ f->do_oop((oop*)&_out_of_memory_error_metaspace);
+ f->do_oop((oop*)&_out_of_memory_error_class_metaspace);
f->do_oop((oop*)&_out_of_memory_error_array_size);
f->do_oop((oop*)&_out_of_memory_error_gc_overhead_limit);
f->do_oop((oop*)&_preallocated_out_of_memory_error_array);
@@ -563,7 +565,8 @@
// a potential loop which could happen if an out of memory occurs when attempting
// to allocate the backtrace.
return ((throwable() != Universe::_out_of_memory_error_java_heap) &&
- (throwable() != Universe::_out_of_memory_error_perm_gen) &&
+ (throwable() != Universe::_out_of_memory_error_metaspace) &&
+ (throwable() != Universe::_out_of_memory_error_class_metaspace) &&
(throwable() != Universe::_out_of_memory_error_array_size) &&
(throwable() != Universe::_out_of_memory_error_gc_overhead_limit));
}
@@ -1014,7 +1017,8 @@
k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_OutOfMemoryError(), true, CHECK_false);
k_h = instanceKlassHandle(THREAD, k);
Universe::_out_of_memory_error_java_heap = k_h->allocate_instance(CHECK_false);
- Universe::_out_of_memory_error_perm_gen = k_h->allocate_instance(CHECK_false);
+ Universe::_out_of_memory_error_metaspace = k_h->allocate_instance(CHECK_false);
+ Universe::_out_of_memory_error_class_metaspace = k_h->allocate_instance(CHECK_false);
Universe::_out_of_memory_error_array_size = k_h->allocate_instance(CHECK_false);
Universe::_out_of_memory_error_gc_overhead_limit =
k_h->allocate_instance(CHECK_false);
@@ -1047,7 +1051,9 @@
java_lang_Throwable::set_message(Universe::_out_of_memory_error_java_heap, msg());
msg = java_lang_String::create_from_str("Metadata space", CHECK_false);
- java_lang_Throwable::set_message(Universe::_out_of_memory_error_perm_gen, msg());
+ java_lang_Throwable::set_message(Universe::_out_of_memory_error_metaspace, msg());
+ msg = java_lang_String::create_from_str("Class Metadata space", CHECK_false);
+ java_lang_Throwable::set_message(Universe::_out_of_memory_error_class_metaspace, msg());
msg = java_lang_String::create_from_str("Requested array size exceeds VM limit", CHECK_false);
java_lang_Throwable::set_message(Universe::_out_of_memory_error_array_size, msg());
--- a/hotspot/src/share/vm/memory/universe.hpp Wed Jul 03 14:50:10 2013 -0700
+++ b/hotspot/src/share/vm/memory/universe.hpp Wed Jul 03 15:04:53 2013 -0700
@@ -178,10 +178,12 @@
static LatestMethodOopCache* _loader_addClass_cache; // method for registering loaded classes in class loader vector
static LatestMethodOopCache* _pd_implies_cache; // method for checking protection domain attributes
static ActiveMethodOopsCache* _reflect_invoke_cache; // method for security checks
- static oop _out_of_memory_error_java_heap; // preallocated error object (no backtrace)
- static oop _out_of_memory_error_perm_gen; // preallocated error object (no backtrace)
- static oop _out_of_memory_error_array_size;// preallocated error object (no backtrace)
- static oop _out_of_memory_error_gc_overhead_limit; // preallocated error object (no backtrace)
+ // preallocated error objects (no backtrace)
+ static oop _out_of_memory_error_java_heap;
+ static oop _out_of_memory_error_metaspace;
+ static oop _out_of_memory_error_class_metaspace;
+ static oop _out_of_memory_error_array_size;
+ static oop _out_of_memory_error_gc_overhead_limit;
static Array<int>* _the_empty_int_array; // Canonicalized int array
static Array<u2>* _the_empty_short_array; // Canonicalized short array
@@ -352,7 +354,8 @@
// may or may not have a backtrace. If error has a backtrace then the stack trace is already
// filled in.
static oop out_of_memory_error_java_heap() { return gen_out_of_memory_error(_out_of_memory_error_java_heap); }
- static oop out_of_memory_error_perm_gen() { return gen_out_of_memory_error(_out_of_memory_error_perm_gen); }
+ static oop out_of_memory_error_metaspace() { return gen_out_of_memory_error(_out_of_memory_error_metaspace); }
+ static oop out_of_memory_error_class_metaspace() { return gen_out_of_memory_error(_out_of_memory_error_class_metaspace); }
static oop out_of_memory_error_array_size() { return gen_out_of_memory_error(_out_of_memory_error_array_size); }
static oop out_of_memory_error_gc_overhead_limit() { return gen_out_of_memory_error(_out_of_memory_error_gc_overhead_limit); }
--- a/hotspot/src/share/vm/prims/jni.cpp Wed Jul 03 14:50:10 2013 -0700
+++ b/hotspot/src/share/vm/prims/jni.cpp Wed Jul 03 15:04:53 2013 -0700
@@ -879,7 +879,7 @@
env, capacity);
#endif /* USDT2 */
//%note jni_11
- if (capacity < 0 && capacity > MAX_REASONABLE_LOCAL_CAPACITY) {
+ if (capacity < 0 || capacity > MAX_REASONABLE_LOCAL_CAPACITY) {
#ifndef USDT2
DTRACE_PROBE1(hotspot_jni, PushLocalFrame__return, JNI_ERR);
#else /* USDT2 */
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp Wed Jul 03 14:50:10 2013 -0700
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Wed Jul 03 15:04:53 2013 -0700
@@ -437,10 +437,6 @@
static_field(Universe, _main_thread_group, oop) \
static_field(Universe, _system_thread_group, oop) \
static_field(Universe, _the_empty_class_klass_array, objArrayOop) \
- static_field(Universe, _out_of_memory_error_java_heap, oop) \
- static_field(Universe, _out_of_memory_error_perm_gen, oop) \
- static_field(Universe, _out_of_memory_error_array_size, oop) \
- static_field(Universe, _out_of_memory_error_gc_overhead_limit, oop) \
static_field(Universe, _null_ptr_exception_instance, oop) \
static_field(Universe, _arithmetic_exception_instance, oop) \
static_field(Universe, _vm_exception, oop) \
--- a/hotspot/src/share/vm/services/memReporter.cpp Wed Jul 03 14:50:10 2013 -0700
+++ b/hotspot/src/share/vm/services/memReporter.cpp Wed Jul 03 15:04:53 2013 -0700
@@ -188,8 +188,8 @@
(MallocCallsitePointer*)prev_malloc_itr.current();
while (cur_malloc_callsite != NULL || prev_malloc_callsite != NULL) {
- if (prev_malloc_callsite == NULL ||
- cur_malloc_callsite->addr() < prev_malloc_callsite->addr()) {
+ if (prev_malloc_callsite == NULL) {
+ assert(cur_malloc_callsite != NULL, "sanity check");
// this is a new callsite
_outputer.diff_malloc_callsite(cur_malloc_callsite->addr(),
amount_in_current_scale(cur_malloc_callsite->amount()),
@@ -197,22 +197,42 @@
diff_in_current_scale(cur_malloc_callsite->amount(), 0),
diff(cur_malloc_callsite->count(), 0));
cur_malloc_callsite = (MallocCallsitePointer*)cur_malloc_itr.next();
- } else if (cur_malloc_callsite == NULL ||
- cur_malloc_callsite->addr() > prev_malloc_callsite->addr()) {
+ } else if (cur_malloc_callsite == NULL) {
+ assert(prev_malloc_callsite != NULL, "Sanity check");
// this callsite is already gone
_outputer.diff_malloc_callsite(prev_malloc_callsite->addr(),
- amount_in_current_scale(0), 0,
+ 0, 0,
diff_in_current_scale(0, prev_malloc_callsite->amount()),
diff(0, prev_malloc_callsite->count()));
prev_malloc_callsite = (MallocCallsitePointer*)prev_malloc_itr.next();
- } else { // the same callsite
- _outputer.diff_malloc_callsite(cur_malloc_callsite->addr(),
- amount_in_current_scale(cur_malloc_callsite->amount()),
- cur_malloc_callsite->count(),
- diff_in_current_scale(cur_malloc_callsite->amount(), prev_malloc_callsite->amount()),
- diff(cur_malloc_callsite->count(), prev_malloc_callsite->count()));
- cur_malloc_callsite = (MallocCallsitePointer*)cur_malloc_itr.next();
- prev_malloc_callsite = (MallocCallsitePointer*)prev_malloc_itr.next();
+ } else {
+ assert(cur_malloc_callsite != NULL, "Sanity check");
+ assert(prev_malloc_callsite != NULL, "Sanity check");
+ if (cur_malloc_callsite->addr() < prev_malloc_callsite->addr()) {
+ // this is a new callsite
+ _outputer.diff_malloc_callsite(cur_malloc_callsite->addr(),
+ amount_in_current_scale(cur_malloc_callsite->amount()),
+ cur_malloc_callsite->count(),
+ diff_in_current_scale(cur_malloc_callsite->amount(), 0),
+ diff(cur_malloc_callsite->count(), 0));
+ cur_malloc_callsite = (MallocCallsitePointer*)cur_malloc_itr.next();
+ } else if (cur_malloc_callsite->addr() > prev_malloc_callsite->addr()) {
+ // this callsite is already gone
+ _outputer.diff_malloc_callsite(prev_malloc_callsite->addr(),
+ 0, 0,
+ diff_in_current_scale(0, prev_malloc_callsite->amount()),
+ diff(0, prev_malloc_callsite->count()));
+ prev_malloc_callsite = (MallocCallsitePointer*)prev_malloc_itr.next();
+ } else {
+ // the same callsite
+ _outputer.diff_malloc_callsite(cur_malloc_callsite->addr(),
+ amount_in_current_scale(cur_malloc_callsite->amount()),
+ cur_malloc_callsite->count(),
+ diff_in_current_scale(cur_malloc_callsite->amount(), prev_malloc_callsite->amount()),
+ diff(cur_malloc_callsite->count(), prev_malloc_callsite->count()));
+ cur_malloc_callsite = (MallocCallsitePointer*)cur_malloc_itr.next();
+ prev_malloc_callsite = (MallocCallsitePointer*)prev_malloc_itr.next();
+ }
}
}
--- a/hotspot/src/share/vm/trace/trace.xml Wed Jul 03 14:50:10 2013 -0700
+++ b/hotspot/src/share/vm/trace/trace.xml Wed Jul 03 15:04:53 2013 -0700
@@ -158,7 +158,7 @@
<structvalue type="MetaspaceSizes" field="classSpace" label="Class"/>
</event>
- <event id="PSHeapSummary" path="vm/gc/heap/ps_summary" label="ParallelScavengeHeap Summary" is_instant="true">
+ <event id="PSHeapSummary" path="vm/gc/heap/ps_summary" label="Parallel Scavenge Heap Summary" is_instant="true">
<value type="UINT" field="gcId" label="GC ID" relation="GC_ID"/>
<value type="GCWHEN" field="when" label="When" />
@@ -203,7 +203,7 @@
<value type="G1YCTYPE" field="type" label="Type" />
</event>
- <event id="EvacuationInfo" path="vm/gc/detailed/evacuation_info" label="Evacuation Info" is_instant="true">
+ <event id="EvacuationInfo" path="vm/gc/detailed/evacuation_info" label="Evacuation Information" is_instant="true">
<value type="UINT" field="gcId" label="GC ID" relation="GC_ID"/>
<value type="UINT" field="cSetRegions" label="Collection Set Regions"/>
<value type="BYTES64" field="cSetUsedBefore" label="Collection Set Before" description="Memory usage before GC in the collection set regions"/>
@@ -211,7 +211,7 @@
<value type="UINT" field="allocationRegions" label="Allocation Regions" description="Regions chosen as allocation regions during evacuation (includes survivors and old space regions)"/>
<value type="BYTES64" field="allocRegionsUsedBefore" label="Alloc Regions Before" description="Memory usage before GC in allocation regions"/>
<value type="BYTES64" field="allocRegionsUsedAfter" label="Alloc Regions After" description="Memory usage after GC in allocation regions"/>
- <value type="BYTES64" field="bytesCopied" label="BytesCopied"/>
+ <value type="BYTES64" field="bytesCopied" label="Bytes Copied"/>
<value type="UINT" field="regionsFreed" label="Regions Freed"/>
</event>
@@ -240,14 +240,14 @@
<event id="PromotionFailed" path="vm/gc/detailed/promotion_failed" label="Promotion Failed" is_instant="true"
description="Promotion of an object failed">
<value type="UINT" field="gcId" label="GC ID" relation="GC_ID"/>
- <structvalue type="CopyFailed" field="data" label="data"/>
+ <structvalue type="CopyFailed" field="data" label="Data"/>
<value type="OSTHREAD" field="thread" label="Running thread"/>
</event>
<event id="EvacuationFailed" path="vm/gc/detailed/evacuation_failed" label="Evacuation Failed" is_instant="true"
description="Evacuation of an object failed">
<value type="UINT" field="gcId" label="GC ID" relation="GC_ID"/>
- <structvalue type="CopyFailed" field="data" label="data"/>
+ <structvalue type="CopyFailed" field="data" label="Data"/>
</event>
<event id="ConcurrentModeFailure" path="vm/gc/detailed/concurrent_mode_failure" label="Concurrent Mode Failure"
@@ -309,7 +309,7 @@
<value type="USHORT" field="sweepFractionIndex" label="Fraction Index"/>
<value type="UINT" field="sweptCount" label="Methods Swept"/>
<value type="UINT" field="flushedCount" label="Methods Flushed"/>
- <value type="UINT" field="markedCount" label="Methods Reclaim"/>
+ <value type="UINT" field="markedCount" label="Methods Reclaimed"/>
<value type="UINT" field="zombifiedCount" label="Methods Zombified"/>
</event>
--- a/hotspot/src/share/vm/utilities/vmError.cpp Wed Jul 03 14:50:10 2013 -0700
+++ b/hotspot/src/share/vm/utilities/vmError.cpp Wed Jul 03 15:04:53 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, 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
@@ -799,6 +799,14 @@
VMError* volatile VMError::first_error = NULL;
volatile jlong VMError::first_error_tid = -1;
+// An error could happen before tty is initialized or after it has been
+// destroyed. Here we use a very simple unbuffered fdStream for printing.
+// Only out.print_raw() and out.print_raw_cr() should be used, as other
+// printing methods need to allocate large buffer on stack. To format a
+// string, use jio_snprintf() with a static buffer or use staticBufferStream.
+fdStream VMError::out(defaultStream::output_fd());
+fdStream VMError::log; // error log used by VMError::report_and_die()
+
/** Expand a pattern into a buffer starting at pos and open a file using constructed path */
static int expand_and_open(const char* pattern, char* buf, size_t buflen, size_t pos) {
int fd = -1;
@@ -853,13 +861,6 @@
// Don't allocate large buffer on stack
static char buffer[O_BUFLEN];
- // An error could happen before tty is initialized or after it has been
- // destroyed. Here we use a very simple unbuffered fdStream for printing.
- // Only out.print_raw() and out.print_raw_cr() should be used, as other
- // printing methods need to allocate large buffer on stack. To format a
- // string, use jio_snprintf() with a static buffer or use staticBufferStream.
- static fdStream out(defaultStream::output_fd());
-
// How many errors occurred in error handler when reporting first_error.
static int recursive_error_count;
@@ -868,7 +869,6 @@
static bool out_done = false; // done printing to standard out
static bool log_done = false; // done saving error log
static bool transmit_report_done = false; // done error reporting
- static fdStream log; // error log
// disble NMT to avoid further exception
MemTracker::shutdown(MemTracker::NMT_error_reporting);
--- a/hotspot/src/share/vm/utilities/vmError.hpp Wed Jul 03 14:50:10 2013 -0700
+++ b/hotspot/src/share/vm/utilities/vmError.hpp Wed Jul 03 15:04:53 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, 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
@@ -96,6 +96,9 @@
return (id != OOM_MALLOC_ERROR) && (id != OOM_MMAP_ERROR);
}
+ static fdStream out;
+ static fdStream log; // error log used by VMError::report_and_die()
+
public:
// Constructor for crashes