提交 fa57b8a1 编写于 作者: T tamao

Merge

...@@ -31,13 +31,19 @@ import java.io.*; ...@@ -31,13 +31,19 @@ import java.io.*;
import java.util.*; import java.util.*;
public class CLHSDB { public class CLHSDB {
public CLHSDB(JVMDebugger d) {
jvmDebugger = d;
}
public static void main(String[] args) { public static void main(String[] args) {
new CLHSDB(args).run(); new CLHSDB(args).run();
} }
private void run() { public void run() {
// At this point, if pidText != null we are supposed to attach to it. // If jvmDebugger is already set, we have been given a JVMDebugger.
// Else, if execPath != null, it is the path of a jdk/bin/java // 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 // and coreFilename is the pathname of a core file we are
// supposed to attach to. // supposed to attach to.
...@@ -49,7 +55,9 @@ public class CLHSDB { ...@@ -49,7 +55,9 @@ public class CLHSDB {
} }
}); });
if (pidText != null) { if (jvmDebugger != null) {
attachDebugger(jvmDebugger);
} else if (pidText != null) {
attachDebugger(pidText); attachDebugger(pidText);
} else if (execPath != null) { } else if (execPath != null) {
attachDebugger(execPath, coreFilename); attachDebugger(execPath, coreFilename);
...@@ -96,6 +104,7 @@ public class CLHSDB { ...@@ -96,6 +104,7 @@ public class CLHSDB {
// Internals only below this point // Internals only below this point
// //
private HotSpotAgent agent; private HotSpotAgent agent;
private JVMDebugger jvmDebugger;
private boolean attached; private boolean attached;
// These had to be made data members because they are referenced in inner classes. // These had to be made data members because they are referenced in inner classes.
private String pidText; private String pidText;
...@@ -120,7 +129,7 @@ public class CLHSDB { ...@@ -120,7 +129,7 @@ public class CLHSDB {
case (1): case (1):
if (args[0].equals("help") || args[0].equals("-help")) { if (args[0].equals("help") || args[0].equals("-help")) {
doUsage(); doUsage();
System.exit(0); return;
} }
// If all numbers, it is a PID to attach to // If all numbers, it is a PID to attach to
// Else, it is a pathname to a .../bin/java for a core file. // Else, it is a pathname to a .../bin/java for a core file.
...@@ -142,8 +151,13 @@ public class CLHSDB { ...@@ -142,8 +151,13 @@ public class CLHSDB {
default: default:
System.out.println("HSDB Error: Too many options specified"); System.out.println("HSDB Error: Too many options specified");
doUsage(); 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 /** NOTE we are in a different thread here than either the main
......
...@@ -101,6 +101,9 @@ import sun.jvm.hotspot.utilities.soql.JSJavaFactoryImpl; ...@@ -101,6 +101,9 @@ import sun.jvm.hotspot.utilities.soql.JSJavaFactoryImpl;
import sun.jvm.hotspot.utilities.soql.JSJavaScriptEngine; import sun.jvm.hotspot.utilities.soql.JSJavaScriptEngine;
public class CommandProcessor { public class CommandProcessor {
volatile boolean quit;
public abstract static class DebuggerInterface { public abstract static class DebuggerInterface {
public abstract HotSpotAgent getAgent(); public abstract HotSpotAgent getAgent();
public abstract boolean isAttached(); public abstract boolean isAttached();
...@@ -1135,7 +1138,7 @@ public class CommandProcessor { ...@@ -1135,7 +1138,7 @@ public class CommandProcessor {
usage(); usage();
} else { } else {
debugger.detach(); debugger.detach();
System.exit(0); quit = true;
} }
} }
}, },
...@@ -1714,7 +1717,7 @@ public class CommandProcessor { ...@@ -1714,7 +1717,7 @@ public class CommandProcessor {
} }
protected void quit() { protected void quit() {
debugger.detach(); debugger.detach();
System.exit(0); quit = true;
} }
protected BufferedReader getInputReader() { protected BufferedReader getInputReader() {
return in; return in;
...@@ -1781,7 +1784,7 @@ public class CommandProcessor { ...@@ -1781,7 +1784,7 @@ public class CommandProcessor {
public void run(boolean prompt) { public void run(boolean prompt) {
// Process interactive commands. // Process interactive commands.
while (true) { while (!quit) {
if (prompt) printPrompt(); if (prompt) printPrompt();
String ln = null; String ln = null;
try { try {
......
...@@ -59,8 +59,11 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener { ...@@ -59,8 +59,11 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener {
// Internals only below this point // Internals only below this point
// //
private HotSpotAgent agent; private HotSpotAgent agent;
private JVMDebugger jvmDebugger;
private JDesktopPane desktop; private JDesktopPane desktop;
private boolean attached; private boolean attached;
private boolean argError;
private JFrame frame;
/** List <JMenuItem> */ /** List <JMenuItem> */
private java.util.List attachMenuItems; private java.util.List attachMenuItems;
/** List <JMenuItem> */ /** List <JMenuItem> */
...@@ -85,6 +88,11 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener { ...@@ -85,6 +88,11 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener {
System.out.println(" path-to-corefile: Debug this corefile. The default is 'core'"); 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"); System.out.println(" If no arguments are specified, you can select what to do from the GUI.\n");
HotSpotAgent.showUsage(); HotSpotAgent.showUsage();
argError = true;
}
public HSDB(JVMDebugger d) {
jvmDebugger = d;
} }
private HSDB(String[] args) { private HSDB(String[] args) {
...@@ -95,7 +103,6 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener { ...@@ -95,7 +103,6 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener {
case (1): case (1):
if (args[0].equals("help") || args[0].equals("-help")) { if (args[0].equals("help") || args[0].equals("-help")) {
doUsage(); doUsage();
System.exit(0);
} }
// If all numbers, it is a PID to attach to // If all numbers, it is a PID to attach to
// Else, it is a pathname to a .../bin/java for a core file. // Else, it is a pathname to a .../bin/java for a core file.
...@@ -117,24 +124,29 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener { ...@@ -117,24 +124,29 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener {
default: default:
System.out.println("HSDB Error: Too many options specified"); System.out.println("HSDB Error: Too many options specified");
doUsage(); doUsage();
System.exit(1);
} }
} }
private void run() { // close this tool without calling System.exit
// At this point, if pidText != null we are supposed to attach to it. protected void closeUI() {
// Else, if execPath != null, it is the path of a jdk/bin/java workerThread.shutdown();
// and coreFilename is the pathname of a core file we are frame.dispose();
// supposed to attach to. }
public void run() {
// Don't start the UI if there were bad arguments.
if (argError) {
return;
}
agent = new HotSpotAgent(); agent = new HotSpotAgent();
workerThread = new WorkerThread(); workerThread = new WorkerThread();
attachMenuItems = new java.util.ArrayList(); attachMenuItems = new java.util.ArrayList();
detachMenuItems = 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.setSize(800, 600);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
JMenuBar menuBar = new JMenuBar(); JMenuBar menuBar = new JMenuBar();
...@@ -197,7 +209,7 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener { ...@@ -197,7 +209,7 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener {
item = createMenuItem("Exit", item = createMenuItem("Exit",
new ActionListener() { new ActionListener() {
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
System.exit(0); closeUI();
} }
}); });
item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, ActionEvent.ALT_MASK)); item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, ActionEvent.ALT_MASK));
...@@ -406,7 +418,15 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener { ...@@ -406,7 +418,15 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener {
} }
}); });
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); attach(pidText);
} else if (execPath != null) { } else if (execPath != null) {
attach(execPath, coreFilename); attach(execPath, coreFilename);
...@@ -1113,6 +1133,12 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener { ...@@ -1113,6 +1133,12 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener {
}); });
} }
// 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 /** 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 thread or the Swing/AWT event handler thread, so we must be very
careful when creating or removing widgets */ careful when creating or removing widgets */
......
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
package sun.jvm.hotspot; package sun.jvm.hotspot;
import java.rmi.RemoteException; 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.Debugger;
import sun.jvm.hotspot.debugger.DebuggerException; import sun.jvm.hotspot.debugger.DebuggerException;
...@@ -63,7 +65,6 @@ public class HotSpotAgent { ...@@ -63,7 +65,6 @@ public class HotSpotAgent {
private String os; private String os;
private String cpu; private String cpu;
private String fileSep;
// The system can work in several ways: // The system can work in several ways:
// - Attaching to local process // - Attaching to local process
...@@ -155,6 +156,14 @@ public class HotSpotAgent { ...@@ -155,6 +156,14 @@ public class HotSpotAgent {
go(); 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 /** This attaches to a "debug server" on a remote machine; this
remote server has already attached to a process or opened a remote server has already attached to a process or opened a
core file and is waiting for RMI calls on the Debugger object to core file and is waiting for RMI calls on the Debugger object to
...@@ -303,15 +312,23 @@ public class HotSpotAgent { ...@@ -303,15 +312,23 @@ public class HotSpotAgent {
// server, but not client attaching to server) // server, but not client attaching to server)
// //
// 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);
} else {
// Otherwise, os, cpu are those of our current platform:
try { try {
os = PlatformInfo.getOS(); os = PlatformInfo.getOS();
cpu = PlatformInfo.getCPU(); cpu = PlatformInfo.getCPU();
} } catch (UnsupportedPlatformException e) {
catch (UnsupportedPlatformException e) {
throw new DebuggerException(e); throw new DebuggerException(e);
} }
fileSep = System.getProperty("file.separator");
if (os.equals("solaris")) { if (os.equals("solaris")) {
setupDebuggerSolaris(); setupDebuggerSolaris();
} else if (os.equals("win32")) { } else if (os.equals("win32")) {
...@@ -326,6 +343,7 @@ public class HotSpotAgent { ...@@ -326,6 +343,7 @@ public class HotSpotAgent {
// Add support for more operating systems here // Add support for more operating systems here
throw new DebuggerException("Operating system " + os + " not yet supported"); throw new DebuggerException("Operating system " + os + " not yet supported");
} }
}
if (isServer) { if (isServer) {
RemoteDebuggerServer remote = null; RemoteDebuggerServer remote = null;
...@@ -423,6 +441,41 @@ public class HotSpotAgent { ...@@ -423,6 +441,41 @@ public class HotSpotAgent {
// OS-specific debugger setup/connect routines // 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 // Solaris
// //
...@@ -466,6 +519,11 @@ public class HotSpotAgent { ...@@ -466,6 +519,11 @@ public class HotSpotAgent {
debugger = new RemoteDebuggerClient(remote); debugger = new RemoteDebuggerClient(remote);
machDesc = ((RemoteDebuggerClient) debugger).getMachineDescription(); machDesc = ((RemoteDebuggerClient) debugger).getMachineDescription();
os = debugger.getOS(); os = debugger.getOS();
setupJVMLibNames(os);
cpu = debugger.getCPU();
}
private void setupJVMLibNames(String os) {
if (os.equals("solaris")) { if (os.equals("solaris")) {
setupJVMLibNamesSolaris(); setupJVMLibNamesSolaris();
} else if (os.equals("win32")) { } else if (os.equals("win32")) {
...@@ -479,8 +537,6 @@ public class HotSpotAgent { ...@@ -479,8 +537,6 @@ public class HotSpotAgent {
} else { } else {
throw new RuntimeException("Unknown OS type"); throw new RuntimeException("Unknown OS type");
} }
cpu = debugger.getCPU();
} }
private void setupJVMLibNamesSolaris() { private void setupJVMLibNamesSolaris() {
......
...@@ -26,11 +26,11 @@ package sun.jvm.hotspot.debugger.linux; ...@@ -26,11 +26,11 @@ package sun.jvm.hotspot.debugger.linux;
import sun.jvm.hotspot.debugger.*; import sun.jvm.hotspot.debugger.*;
class LinuxAddress implements Address { public class LinuxAddress implements Address {
protected LinuxDebugger debugger; protected LinuxDebugger debugger;
protected long addr; protected long addr;
LinuxAddress(LinuxDebugger debugger, long addr) { public LinuxAddress(LinuxDebugger debugger, long addr) {
this.debugger = debugger; this.debugger = debugger;
this.addr = addr; this.addr = addr;
} }
......
...@@ -26,8 +26,8 @@ package sun.jvm.hotspot.debugger.linux; ...@@ -26,8 +26,8 @@ package sun.jvm.hotspot.debugger.linux;
import sun.jvm.hotspot.debugger.*; import sun.jvm.hotspot.debugger.*;
class LinuxOopHandle extends LinuxAddress implements OopHandle { public class LinuxOopHandle extends LinuxAddress implements OopHandle {
LinuxOopHandle(LinuxDebugger debugger, long addr) { public LinuxOopHandle(LinuxDebugger debugger, long addr) {
super(debugger, addr); super(debugger, addr);
} }
......
...@@ -246,7 +246,7 @@ public class VM { ...@@ -246,7 +246,7 @@ public class VM {
} }
} }
private static final boolean disableDerivedPrinterTableCheck; private static final boolean disableDerivedPointerTableCheck;
private static final Properties saProps; private static final Properties saProps;
static { static {
...@@ -256,12 +256,12 @@ public class VM { ...@@ -256,12 +256,12 @@ public class VM {
url = VM.class.getClassLoader().getResource("sa.properties"); url = VM.class.getClassLoader().getResource("sa.properties");
saProps.load(new BufferedInputStream(url.openStream())); saProps.load(new BufferedInputStream(url.openStream()));
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException("Unable to load properties " + System.err.println("Unable to load properties " +
(url == null ? "null" : url.toString()) + (url == null ? "null" : url.toString()) +
": " + e.getMessage()); ": " + 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) { private VM(TypeDataBase db, JVMDebugger debugger, boolean isBigEndian) {
...@@ -371,7 +371,8 @@ public class VM { ...@@ -371,7 +371,8 @@ public class VM {
/** This is used by the debugging system */ /** This is used by the debugging system */
public static void initialize(TypeDataBase db, JVMDebugger debugger) { public static void initialize(TypeDataBase db, JVMDebugger debugger) {
if (soleInstance != null) { 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()); soleInstance = new VM(db, debugger, debugger.getMachineDescription().isBigEndian());
...@@ -683,7 +684,7 @@ public class VM { ...@@ -683,7 +684,7 @@ public class VM {
/** Returns true if C2 derived pointer table should be used, false otherwise */ /** Returns true if C2 derived pointer table should be used, false otherwise */
public boolean useDerivedPointerTable() { public boolean useDerivedPointerTable() {
return !disableDerivedPrinterTableCheck; return !disableDerivedPointerTableCheck;
} }
/** Returns the code cache; should not be used if is core build */ /** Returns the code cache; should not be used if is core build */
......
...@@ -41,6 +41,14 @@ import sun.jvm.hotspot.utilities.*; ...@@ -41,6 +41,14 @@ import sun.jvm.hotspot.utilities.*;
public class ClassLoaderStats extends Tool { public class ClassLoaderStats extends Tool {
boolean verbose = true; boolean verbose = true;
public ClassLoaderStats() {
super();
}
public ClassLoaderStats(JVMDebugger d) {
super(d);
}
public static void main(String[] args) { public static void main(String[] args) {
ClassLoaderStats cls = new ClassLoaderStats(); ClassLoaderStats cls = new ClassLoaderStats();
cls.start(args); cls.start(args);
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
package sun.jvm.hotspot.tools; package sun.jvm.hotspot.tools;
import sun.jvm.hotspot.debugger.JVMDebugger;
import sun.jvm.hotspot.tools.*; import sun.jvm.hotspot.tools.*;
import sun.jvm.hotspot.oops.*; import sun.jvm.hotspot.oops.*;
...@@ -42,6 +43,15 @@ import java.util.Comparator; ...@@ -42,6 +43,15 @@ import java.util.Comparator;
* summary of these objects in the form of a histogram. * summary of these objects in the form of a histogram.
*/ */
public class FinalizerInfo extends Tool { public class FinalizerInfo extends Tool {
public FinalizerInfo() {
super();
}
public FinalizerInfo(JVMDebugger d) {
super(d);
}
public static void main(String[] args) { public static void main(String[] args) {
FinalizerInfo finfo = new FinalizerInfo(); FinalizerInfo finfo = new FinalizerInfo();
finfo.start(args); finfo.start(args);
......
...@@ -25,10 +25,19 @@ ...@@ -25,10 +25,19 @@
package sun.jvm.hotspot.tools; package sun.jvm.hotspot.tools;
import java.io.PrintStream; import java.io.PrintStream;
import sun.jvm.hotspot.debugger.JVMDebugger;
import sun.jvm.hotspot.runtime.*; import sun.jvm.hotspot.runtime.*;
public class FlagDumper extends Tool { public class FlagDumper extends Tool {
public FlagDumper() {
super();
}
public FlagDumper(JVMDebugger d) {
super(d);
}
public void run() { public void run() {
VM.Flag[] flags = VM.getVM().getCommandLineFlags(); VM.Flag[] flags = VM.getVM().getCommandLineFlags();
PrintStream out = System.out; PrintStream out = System.out;
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
package sun.jvm.hotspot.tools; package sun.jvm.hotspot.tools;
import sun.jvm.hotspot.utilities.HeapHprofBinWriter; import sun.jvm.hotspot.utilities.HeapHprofBinWriter;
import sun.jvm.hotspot.debugger.JVMDebugger;
import java.io.IOException; import java.io.IOException;
/* /*
...@@ -42,6 +43,11 @@ public class HeapDumper extends Tool { ...@@ -42,6 +43,11 @@ public class HeapDumper extends Tool {
this.dumpFile = dumpFile; this.dumpFile = dumpFile;
} }
public HeapDumper(String dumpFile, JVMDebugger d) {
super(d);
this.dumpFile = dumpFile;
}
protected void printFlagsUsage() { protected void printFlagsUsage() {
System.out.println(" <no option>\tto dump heap to " + System.out.println(" <no option>\tto dump heap to " +
DEFAULT_DUMP_FILE); DEFAULT_DUMP_FILE);
......
...@@ -29,12 +29,21 @@ import sun.jvm.hotspot.gc_interface.*; ...@@ -29,12 +29,21 @@ import sun.jvm.hotspot.gc_interface.*;
import sun.jvm.hotspot.gc_implementation.g1.*; import sun.jvm.hotspot.gc_implementation.g1.*;
import sun.jvm.hotspot.gc_implementation.parallelScavenge.*; import sun.jvm.hotspot.gc_implementation.parallelScavenge.*;
import sun.jvm.hotspot.gc_implementation.shared.*; import sun.jvm.hotspot.gc_implementation.shared.*;
import sun.jvm.hotspot.debugger.JVMDebugger;
import sun.jvm.hotspot.memory.*; import sun.jvm.hotspot.memory.*;
import sun.jvm.hotspot.oops.*; import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.runtime.*; import sun.jvm.hotspot.runtime.*;
public class HeapSummary extends Tool { public class HeapSummary extends Tool {
public HeapSummary() {
super();
}
public HeapSummary(JVMDebugger d) {
super(d);
}
public static void main(String[] args) { public static void main(String[] args) {
HeapSummary hs = new HeapSummary(); HeapSummary hs = new HeapSummary();
hs.start(args); hs.start(args);
......
...@@ -25,12 +25,21 @@ ...@@ -25,12 +25,21 @@
package sun.jvm.hotspot.tools; package sun.jvm.hotspot.tools;
import sun.jvm.hotspot.runtime.*; import sun.jvm.hotspot.runtime.*;
import sun.jvm.hotspot.debugger.JVMDebugger;
public class JInfo extends Tool { public class JInfo extends Tool {
public JInfo() {
super();
}
public JInfo(int m) { public JInfo(int m) {
mode = m; mode = m;
} }
public JInfo(JVMDebugger d) {
super(d);
}
protected boolean needsJavaPrefix() { protected boolean needsJavaPrefix() {
return false; return false;
} }
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
package sun.jvm.hotspot.tools; package sun.jvm.hotspot.tools;
import java.io.*; import java.io.*;
import sun.jvm.hotspot.debugger.JVMDebugger;
import sun.jvm.hotspot.utilities.*; import sun.jvm.hotspot.utilities.*;
public class JMap extends Tool { public class JMap extends Tool {
...@@ -36,6 +37,10 @@ public class JMap extends Tool { ...@@ -36,6 +37,10 @@ public class JMap extends Tool {
this(MODE_PMAP); this(MODE_PMAP);
} }
public JMap(JVMDebugger d) {
super(d);
}
protected boolean needsJavaPrefix() { protected boolean needsJavaPrefix() {
return false; return false;
} }
......
...@@ -25,9 +25,19 @@ ...@@ -25,9 +25,19 @@
package sun.jvm.hotspot.tools; package sun.jvm.hotspot.tools;
import java.io.*; import java.io.*;
import sun.jvm.hotspot.debugger.JVMDebugger;
import sun.jvm.hotspot.runtime.*; import sun.jvm.hotspot.runtime.*;
public class JSnap extends Tool { public class JSnap extends Tool {
public JSnap() {
super();
}
public JSnap(JVMDebugger d) {
super(d);
}
public void run() { public void run() {
final PrintStream out = System.out; final PrintStream out = System.out;
if (PerfMemory.initialized()) { if (PerfMemory.initialized()) {
......
...@@ -24,6 +24,8 @@ ...@@ -24,6 +24,8 @@
package sun.jvm.hotspot.tools; package sun.jvm.hotspot.tools;
import sun.jvm.hotspot.debugger.JVMDebugger;
public class JStack extends Tool { public class JStack extends Tool {
public JStack(boolean mixedMode, boolean concurrentLocks) { public JStack(boolean mixedMode, boolean concurrentLocks) {
this.mixedMode = mixedMode; this.mixedMode = mixedMode;
...@@ -34,6 +36,10 @@ public class JStack extends Tool { ...@@ -34,6 +36,10 @@ public class JStack extends Tool {
this(true, true); this(true, true);
} }
public JStack(JVMDebugger d) {
super(d);
}
protected boolean needsJavaPrefix() { protected boolean needsJavaPrefix() {
return false; return false;
} }
......
...@@ -33,6 +33,14 @@ import java.io.PrintStream; ...@@ -33,6 +33,14 @@ import java.io.PrintStream;
an object histogram from a remote or crashed VM. */ an object histogram from a remote or crashed VM. */
public class ObjectHistogram extends Tool { public class ObjectHistogram extends Tool {
public ObjectHistogram() {
super();
}
public ObjectHistogram(JVMDebugger d) {
super(d);
}
public void run() { public void run() {
run(System.out, System.err); run(System.out, System.err);
} }
......
...@@ -31,6 +31,15 @@ import sun.jvm.hotspot.debugger.cdbg.*; ...@@ -31,6 +31,15 @@ import sun.jvm.hotspot.debugger.cdbg.*;
import sun.jvm.hotspot.runtime.*; import sun.jvm.hotspot.runtime.*;
public class PMap extends Tool { public class PMap extends Tool {
public PMap() {
super();
}
public PMap(JVMDebugger d) {
super(d);
}
public void run() { public void run() {
run(System.out); run(System.out);
} }
......
...@@ -45,6 +45,10 @@ public class PStack extends Tool { ...@@ -45,6 +45,10 @@ public class PStack extends Tool {
this(true, true); this(true, true);
} }
public PStack(JVMDebugger d) {
super(d);
}
public void run() { public void run() {
run(System.out); run(System.out);
} }
......
...@@ -45,6 +45,16 @@ public class StackTrace extends Tool { ...@@ -45,6 +45,16 @@ public class StackTrace extends Tool {
run(System.out); 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) { public void run(java.io.PrintStream tty) {
// Ready to go with the database... // Ready to go with the database...
try { try {
......
...@@ -27,10 +27,19 @@ package sun.jvm.hotspot.tools; ...@@ -27,10 +27,19 @@ package sun.jvm.hotspot.tools;
import java.io.PrintStream; import java.io.PrintStream;
import java.util.*; import java.util.*;
import sun.jvm.hotspot.debugger.JVMDebugger;
import sun.jvm.hotspot.runtime.*; import sun.jvm.hotspot.runtime.*;
public class SysPropsDumper extends Tool { public class SysPropsDumper extends Tool {
public SysPropsDumper() {
super();
}
public SysPropsDumper(JVMDebugger d) {
super(d);
}
public void run() { public void run() {
Properties sysProps = VM.getVM().getSystemProperties(); Properties sysProps = VM.getVM().getSystemProperties();
PrintStream out = System.out; PrintStream out = System.out;
......
...@@ -35,6 +35,7 @@ import sun.jvm.hotspot.debugger.*; ...@@ -35,6 +35,7 @@ import sun.jvm.hotspot.debugger.*;
public abstract class Tool implements Runnable { public abstract class Tool implements Runnable {
private HotSpotAgent agent; private HotSpotAgent agent;
private JVMDebugger jvmDebugger;
private int debugeeType; private int debugeeType;
// debugeeType is one of constants below // debugeeType is one of constants below
...@@ -42,6 +43,13 @@ public abstract class Tool implements Runnable { ...@@ -42,6 +43,13 @@ public abstract class Tool implements Runnable {
protected static final int DEBUGEE_CORE = 1; protected static final int DEBUGEE_CORE = 1;
protected static final int DEBUGEE_REMOTE = 2; protected static final int DEBUGEE_REMOTE = 2;
public Tool() {
}
public Tool(JVMDebugger d) {
jvmDebugger = d;
}
public String getName() { public String getName() {
return getClass().getName(); return getClass().getName();
} }
...@@ -90,7 +98,6 @@ public abstract class Tool implements Runnable { ...@@ -90,7 +98,6 @@ public abstract class Tool implements Runnable {
protected void usage() { protected void usage() {
printUsage(); printUsage();
System.exit(1);
} }
/* /*
...@@ -106,13 +113,13 @@ public abstract class Tool implements Runnable { ...@@ -106,13 +113,13 @@ public abstract class Tool implements Runnable {
protected void stop() { protected void stop() {
if (agent != null) { if (agent != null) {
agent.detach(); agent.detach();
System.exit(0);
} }
} }
protected void start(String[] args) { protected void start(String[] args) {
if ((args.length < 1) || (args.length > 2)) { if ((args.length < 1) || (args.length > 2)) {
usage(); usage();
return;
} }
// Attempt to handle -h or -help or some invalid flag // Attempt to handle -h or -help or some invalid flag
...@@ -185,13 +192,31 @@ public abstract class Tool implements Runnable { ...@@ -185,13 +192,31 @@ public abstract class Tool implements Runnable {
} }
if (e.getMessage() != null) { if (e.getMessage() != null) {
err.print(e.getMessage()); err.print(e.getMessage());
e.printStackTrace();
} }
err.println(); err.println();
System.exit(1); return;
} }
err.println("Debugger attached successfully."); 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(); VM vm = VM.getVM();
if (vm.isCore()) { if (vm.isCore()) {
err.println("Core build detected."); err.println("Core build detected.");
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
package sun.jvm.hotspot.tools.jcore; package sun.jvm.hotspot.tools.jcore;
import java.io.*; import java.io.*;
import java.lang.reflect.Constructor;
import java.util.jar.JarOutputStream; import java.util.jar.JarOutputStream;
import java.util.jar.JarEntry; import java.util.jar.JarEntry;
import java.util.jar.Manifest; import java.util.jar.Manifest;
...@@ -38,6 +39,16 @@ public class ClassDump extends Tool { ...@@ -38,6 +39,16 @@ public class ClassDump extends Tool {
private ClassFilter classFilter; private ClassFilter classFilter;
private String outputDirectory; private String outputDirectory;
private JarOutputStream jarStream; 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) { public void setClassFilter(ClassFilter cf) {
classFilter = cf; classFilter = cf;
...@@ -63,6 +74,25 @@ public class ClassDump extends Tool { ...@@ -63,6 +74,25 @@ public class ClassDump extends Tool {
public void run() { public void run() {
// Ready to go with the database... // Ready to go with the database...
try { 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 // walk through the system dictionary
SystemDictionary dict = VM.getVM().getSystemDictionary(); SystemDictionary dict = VM.getVM().getSystemDictionary();
...@@ -139,26 +169,8 @@ public class ClassDump extends Tool { ...@@ -139,26 +169,8 @@ public class ClassDump extends Tool {
} }
public static void main(String[] args) { 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(); ClassDump cd = new ClassDump();
cd.setClassFilter(classFilter);
cd.setOutputDirectory(outputDirectory);
cd.start(args); cd.start(args);
cd.stop(); cd.stop();
} }
......
...@@ -24,12 +24,22 @@ ...@@ -24,12 +24,22 @@
package sun.jvm.hotspot.tools.soql; package sun.jvm.hotspot.tools.soql;
import sun.jvm.hotspot.debugger.JVMDebugger;
import sun.jvm.hotspot.tools.*; import sun.jvm.hotspot.tools.*;
import sun.jvm.hotspot.utilities.*; import sun.jvm.hotspot.utilities.*;
import sun.jvm.hotspot.utilities.soql.*; import sun.jvm.hotspot.utilities.soql.*;
/** This is command line JavaScript debugger console */ /** This is command line JavaScript debugger console */
public class JSDB extends Tool { public class JSDB extends Tool {
public JSDB() {
super();
}
public JSDB(JVMDebugger d) {
super(d);
}
public static void main(String[] args) { public static void main(String[] args) {
JSDB jsdb = new JSDB(); JSDB jsdb = new JSDB();
jsdb.start(args); jsdb.start(args);
......
...@@ -44,6 +44,14 @@ public class SOQL extends Tool { ...@@ -44,6 +44,14 @@ public class SOQL extends Tool {
soql.stop(); soql.stop();
} }
public SOQL() {
super();
}
public SOQL(JVMDebugger d) {
super(d);
}
protected SOQLEngine soqlEngine; protected SOQLEngine soqlEngine;
protected BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); protected BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
protected PrintStream out = System.out; protected PrintStream out = System.out;
......
...@@ -257,11 +257,6 @@ bool frame::safe_for_sender(JavaThread *thread) { ...@@ -257,11 +257,6 @@ bool frame::safe_for_sender(JavaThread *thread) {
return false; 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 // It should be safe to construct the sender though it might not be valid
frame sender(_SENDER_SP, younger_sp, adjusted_stack); frame sender(_SENDER_SP, younger_sp, adjusted_stack);
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -332,12 +332,15 @@ dtrace:helper:ustack: ...@@ -332,12 +332,15 @@ dtrace:helper:ustack:
this->nameSymbol = copyin_ptr(this->constantPool + this->nameSymbol = copyin_ptr(this->constantPool +
this->nameIndex * sizeof (pointer) + SIZE_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 + this->nameSymbolLength = copyin_uint16(this->nameSymbol +
OFFSET_Symbol_length); OFFSET_Symbol_length);
this->signatureSymbol = copyin_ptr(this->constantPool + this->signatureSymbol = copyin_ptr(this->constantPool +
this->signatureIndex * sizeof (pointer) + SIZE_ConstantPool); this->signatureIndex * sizeof (pointer) + SIZE_ConstantPool);
this->signatureSymbol &= (~1); /* remove metadata lsb */
this->signatureSymbolLength = copyin_uint16(this->signatureSymbol + this->signatureSymbolLength = copyin_uint16(this->signatureSymbol +
OFFSET_Symbol_length); OFFSET_Symbol_length);
......
...@@ -549,3 +549,13 @@ bool FileMapInfo::is_in_shared_space(const void* p) { ...@@ -549,3 +549,13 @@ bool FileMapInfo::is_in_shared_space(const void* p) {
return false; 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);
}
}
...@@ -149,6 +149,7 @@ public: ...@@ -149,6 +149,7 @@ public:
// Return true if given address is in the mapped shared space. // Return true if given address is in the mapped shared space.
bool is_in_shared_space(const void* p) NOT_CDS_RETURN_(false); 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 #endif // SHARE_VM_MEMORY_FILEMAP_HPP
...@@ -70,7 +70,7 @@ enum ChunkSizes { // in words. ...@@ -70,7 +70,7 @@ enum ChunkSizes { // in words.
SpecializedChunk = 128, SpecializedChunk = 128,
ClassSmallChunk = 256, ClassSmallChunk = 256,
SmallChunk = 512, SmallChunk = 512,
ClassMediumChunk = 1 * K, ClassMediumChunk = 4 * K,
MediumChunk = 8 * K, MediumChunk = 8 * K,
HumongousChunkGranularity = 8 HumongousChunkGranularity = 8
}; };
...@@ -580,7 +580,6 @@ class SpaceManager : public CHeapObj<mtClass> { ...@@ -580,7 +580,6 @@ class SpaceManager : public CHeapObj<mtClass> {
// Number of small chunks to allocate to a manager // Number of small chunks to allocate to a manager
// If class space manager, small chunks are unlimited // If class space manager, small chunks are unlimited
static uint const _small_chunk_limit; static uint const _small_chunk_limit;
bool has_small_chunk_limit() { return !vs_list()->is_class(); }
// Sum of all space in allocated chunks // Sum of all space in allocated chunks
size_t _allocated_blocks_words; size_t _allocated_blocks_words;
...@@ -1298,14 +1297,19 @@ size_t MetaspaceGC::delta_capacity_until_GC(size_t word_size) { ...@@ -1298,14 +1297,19 @@ size_t MetaspaceGC::delta_capacity_until_GC(size_t word_size) {
bool MetaspaceGC::should_expand(VirtualSpaceList* vsl, size_t word_size) { 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. // If the user wants a limit, impose one.
size_t max_metaspace_size_bytes = MaxMetaspaceSize; // The reason for someone using this flag is to limit reserved space. So
size_t metaspace_size_bytes = MetaspaceSize; // for non-class virtual space, compare against virtual spaces that are reserved.
if (!FLAG_IS_DEFAULT(MaxMetaspaceSize) && // For class virtual space, we only compare against the committed space, not
MetaspaceAux::reserved_in_bytes() >= MaxMetaspaceSize) { // 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; return false;
} }
}
// Class virtual space should always be expanded. Call GC for the other // Class virtual space should always be expanded. Call GC for the other
// metadata virtual space. // metadata virtual space.
...@@ -1318,11 +1322,12 @@ bool MetaspaceGC::should_expand(VirtualSpaceList* vsl, size_t word_size) { ...@@ -1318,11 +1322,12 @@ bool MetaspaceGC::should_expand(VirtualSpaceList* vsl, size_t word_size) {
} }
// If the capacity is below the minimum capacity, allow the // If the capacity is below the minimum capacity, allow the
// expansion. Also set the high-water-mark (capacity_until_GC) // expansion. Also set the high-water-mark (capacity_until_GC)
// to that minimum capacity so that a GC will not be induced // to that minimum capacity so that a GC will not be induced
// until that minimum capacity is exceeded. // 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 || if (committed_capacity_bytes < metaspace_size_bytes ||
capacity_until_GC() == 0) { capacity_until_GC() == 0) {
set_capacity_until_GC(metaspace_size_bytes); set_capacity_until_GC(metaspace_size_bytes);
...@@ -1854,13 +1859,11 @@ size_t SpaceManager::sum_waste_in_chunks_in_use(ChunkIndex index) const { ...@@ -1854,13 +1859,11 @@ size_t SpaceManager::sum_waste_in_chunks_in_use(ChunkIndex index) const {
Metachunk* chunk = chunks_in_use(index); Metachunk* chunk = chunks_in_use(index);
// Count the free space in all the chunk but not the // Count the free space in all the chunk but not the
// current chunk from which allocations are still being done. // current chunk from which allocations are still being done.
if (chunk != NULL) { while (chunk != NULL) {
Metachunk* prev = chunk; if (chunk != current_chunk()) {
while (chunk != NULL && chunk != current_chunk()) {
result += chunk->free_word_size(); result += chunk->free_word_size();
prev = chunk;
chunk = chunk->next();
} }
chunk = chunk->next();
} }
return result; return result;
} }
...@@ -1949,8 +1952,7 @@ size_t SpaceManager::calc_chunk_size(size_t word_size) { ...@@ -1949,8 +1952,7 @@ size_t SpaceManager::calc_chunk_size(size_t word_size) {
// chunks will be allocated. // chunks will be allocated.
size_t chunk_word_size; size_t chunk_word_size;
if (chunks_in_use(MediumIndex) == NULL && 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(); chunk_word_size = (size_t) small_chunk_size();
if (word_size + Metachunk::overhead() > small_chunk_size()) { if (word_size + Metachunk::overhead() > small_chunk_size()) {
chunk_word_size = medium_chunk_size(); chunk_word_size = medium_chunk_size();
...@@ -2659,10 +2661,10 @@ void MetaspaceAux::print_on(outputStream* out, Metaspace::MetadataType mdtype) { ...@@ -2659,10 +2661,10 @@ void MetaspaceAux::print_on(outputStream* out, Metaspace::MetadataType mdtype) {
// Print total fragmentation for class and data metaspaces separately // Print total fragmentation for class and data metaspaces separately
void MetaspaceAux::print_waste(outputStream* out) { void MetaspaceAux::print_waste(outputStream* out) {
size_t specialized_waste = 0, small_waste = 0, medium_waste = 0, large_waste = 0; size_t specialized_waste = 0, small_waste = 0, medium_waste = 0;
size_t specialized_count = 0, small_count = 0, medium_count = 0, large_count = 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, cls_large_waste = 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_large_count = 0; size_t cls_specialized_count = 0, cls_small_count = 0, cls_medium_count = 0, cls_humongous_count = 0;
ClassLoaderDataGraphMetaspaceIterator iter; ClassLoaderDataGraphMetaspaceIterator iter;
while (iter.repeat()) { while (iter.repeat()) {
...@@ -2674,8 +2676,7 @@ void MetaspaceAux::print_waste(outputStream* out) { ...@@ -2674,8 +2676,7 @@ void MetaspaceAux::print_waste(outputStream* out) {
small_count += msp->vsm()->sum_count_in_chunks_in_use(SmallIndex); small_count += msp->vsm()->sum_count_in_chunks_in_use(SmallIndex);
medium_waste += msp->vsm()->sum_waste_in_chunks_in_use(MediumIndex); medium_waste += msp->vsm()->sum_waste_in_chunks_in_use(MediumIndex);
medium_count += msp->vsm()->sum_count_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); humongous_count += msp->vsm()->sum_count_in_chunks_in_use(HumongousIndex);
large_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_waste += msp->class_vsm()->sum_waste_in_chunks_in_use(SpecializedIndex);
cls_specialized_count += msp->class_vsm()->sum_count_in_chunks_in_use(SpecializedIndex); cls_specialized_count += msp->class_vsm()->sum_count_in_chunks_in_use(SpecializedIndex);
...@@ -2683,20 +2684,23 @@ void MetaspaceAux::print_waste(outputStream* out) { ...@@ -2683,20 +2684,23 @@ void MetaspaceAux::print_waste(outputStream* out) {
cls_small_count += msp->class_vsm()->sum_count_in_chunks_in_use(SmallIndex); 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_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_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_humongous_count += msp->class_vsm()->sum_count_in_chunks_in_use(HumongousIndex);
cls_large_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("Total fragmentation waste (words) doesn't count free space");
out->print_cr(" data: " SIZE_FORMAT " specialized(s) " SIZE_FORMAT ", " out->print_cr(" data: " SIZE_FORMAT " specialized(s) " SIZE_FORMAT ", "
SIZE_FORMAT " small(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, 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 ", " 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_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 // Dump global metaspace things from the end of ClassLoaderDataGraph
...@@ -3037,18 +3041,24 @@ Metablock* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size, ...@@ -3037,18 +3041,24 @@ Metablock* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size,
if (Verbose && TraceMetadataChunkAllocation) { if (Verbose && TraceMetadataChunkAllocation) {
gclog_or_tty->print_cr("Metaspace allocation failed for size " gclog_or_tty->print_cr("Metaspace allocation failed for size "
SIZE_FORMAT, word_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); MetaspaceAux::dump(gclog_or_tty);
} }
// -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support // -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()) { if (JvmtiExport::should_post_resource_exhausted()) {
JvmtiExport::post_resource_exhausted( JvmtiExport::post_resource_exhausted(
JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR, JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR,
"Metadata space"); space_string);
}
if (mdtype == ClassType) {
THROW_OOP_0(Universe::out_of_memory_error_class_metaspace());
} else {
THROW_OOP_0(Universe::out_of_memory_error_metaspace());
} }
THROW_OOP_0(Universe::out_of_memory_error_perm_gen());
} }
} }
return Metablock::initialize(result, word_size); return Metablock::initialize(result, word_size);
......
...@@ -826,35 +826,15 @@ public: ...@@ -826,35 +826,15 @@ public:
bool reading() const { return true; } 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. // Return true if given address is in the mapped shared space.
bool MetaspaceShared::is_in_shared_space(const void* p) { bool MetaspaceShared::is_in_shared_space(const void* p) {
if (_ro_base == NULL || _rw_base == NULL) { return UseSharedSpaces && FileMapInfo::current_info()->is_in_shared_space(p);
return false;
} else {
return ((p >= _ro_base && p < (_ro_base + SharedReadOnlySize)) ||
(p >= _rw_base && p < (_rw_base + SharedReadWriteSize)));
}
} }
void MetaspaceShared::print_shared_spaces() { void MetaspaceShared::print_shared_spaces() {
gclog_or_tty->print_cr("Shared Spaces:"); if (UseSharedSpaces) {
gclog_or_tty->print(" read-only " INTPTR_FORMAT "-" INTPTR_FORMAT, FileMapInfo::current_info()->print_shared_spaces();
_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();
} }
...@@ -874,6 +854,11 @@ bool MetaspaceShared::map_shared_spaces(FileMapInfo* mapinfo) { ...@@ -874,6 +854,11 @@ bool MetaspaceShared::map_shared_spaces(FileMapInfo* mapinfo) {
assert(!DumpSharedSpaces, "Should not be called with DumpSharedSpaces"); 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 // Map each shared region
if ((_ro_base = mapinfo->map_region(ro)) != NULL && if ((_ro_base = mapinfo->map_region(ro)) != NULL &&
(_rw_base = mapinfo->map_region(rw)) != NULL && (_rw_base = mapinfo->map_region(rw)) != NULL &&
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
......
...@@ -111,7 +111,8 @@ LatestMethodOopCache* Universe::_loader_addClass_cache = NULL; ...@@ -111,7 +111,8 @@ LatestMethodOopCache* Universe::_loader_addClass_cache = NULL;
LatestMethodOopCache* Universe::_pd_implies_cache = NULL; LatestMethodOopCache* Universe::_pd_implies_cache = NULL;
ActiveMethodOopsCache* Universe::_reflect_invoke_cache = NULL; ActiveMethodOopsCache* Universe::_reflect_invoke_cache = NULL;
oop Universe::_out_of_memory_error_java_heap = 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_array_size = NULL;
oop Universe::_out_of_memory_error_gc_overhead_limit = NULL; oop Universe::_out_of_memory_error_gc_overhead_limit = NULL;
objArrayOop Universe::_preallocated_out_of_memory_error_array = NULL; objArrayOop Universe::_preallocated_out_of_memory_error_array = NULL;
...@@ -180,7 +181,8 @@ void Universe::oops_do(OopClosure* f, bool do_all) { ...@@ -180,7 +181,8 @@ void Universe::oops_do(OopClosure* f, bool do_all) {
f->do_oop((oop*)&_the_null_string); f->do_oop((oop*)&_the_null_string);
f->do_oop((oop*)&_the_min_jint_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_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_array_size);
f->do_oop((oop*)&_out_of_memory_error_gc_overhead_limit); f->do_oop((oop*)&_out_of_memory_error_gc_overhead_limit);
f->do_oop((oop*)&_preallocated_out_of_memory_error_array); f->do_oop((oop*)&_preallocated_out_of_memory_error_array);
...@@ -563,7 +565,8 @@ bool Universe::should_fill_in_stack_trace(Handle throwable) { ...@@ -563,7 +565,8 @@ bool Universe::should_fill_in_stack_trace(Handle throwable) {
// a potential loop which could happen if an out of memory occurs when attempting // a potential loop which could happen if an out of memory occurs when attempting
// to allocate the backtrace. // to allocate the backtrace.
return ((throwable() != Universe::_out_of_memory_error_java_heap) && 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_array_size) &&
(throwable() != Universe::_out_of_memory_error_gc_overhead_limit)); (throwable() != Universe::_out_of_memory_error_gc_overhead_limit));
} }
...@@ -1014,7 +1017,8 @@ bool universe_post_init() { ...@@ -1014,7 +1017,8 @@ bool universe_post_init() {
k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_OutOfMemoryError(), true, CHECK_false); k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_OutOfMemoryError(), true, CHECK_false);
k_h = instanceKlassHandle(THREAD, k); k_h = instanceKlassHandle(THREAD, k);
Universe::_out_of_memory_error_java_heap = k_h->allocate_instance(CHECK_false); 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_array_size = k_h->allocate_instance(CHECK_false);
Universe::_out_of_memory_error_gc_overhead_limit = Universe::_out_of_memory_error_gc_overhead_limit =
k_h->allocate_instance(CHECK_false); k_h->allocate_instance(CHECK_false);
...@@ -1047,7 +1051,9 @@ bool universe_post_init() { ...@@ -1047,7 +1051,9 @@ bool universe_post_init() {
java_lang_Throwable::set_message(Universe::_out_of_memory_error_java_heap, msg()); java_lang_Throwable::set_message(Universe::_out_of_memory_error_java_heap, msg());
msg = java_lang_String::create_from_str("Metadata space", CHECK_false); 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); 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()); java_lang_Throwable::set_message(Universe::_out_of_memory_error_array_size, msg());
......
...@@ -178,10 +178,12 @@ class Universe: AllStatic { ...@@ -178,10 +178,12 @@ class Universe: AllStatic {
static LatestMethodOopCache* _loader_addClass_cache; // method for registering loaded classes in class loader vector 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 LatestMethodOopCache* _pd_implies_cache; // method for checking protection domain attributes
static ActiveMethodOopsCache* _reflect_invoke_cache; // method for security checks static ActiveMethodOopsCache* _reflect_invoke_cache; // method for security checks
static oop _out_of_memory_error_java_heap; // preallocated error object (no backtrace) // preallocated error objects (no backtrace)
static oop _out_of_memory_error_perm_gen; // preallocated error object (no backtrace) static oop _out_of_memory_error_java_heap;
static oop _out_of_memory_error_array_size;// preallocated error object (no backtrace) static oop _out_of_memory_error_metaspace;
static oop _out_of_memory_error_gc_overhead_limit; // preallocated error object (no backtrace) 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<int>* _the_empty_int_array; // Canonicalized int array
static Array<u2>* _the_empty_short_array; // Canonicalized short array static Array<u2>* _the_empty_short_array; // Canonicalized short array
...@@ -352,7 +354,8 @@ class Universe: AllStatic { ...@@ -352,7 +354,8 @@ class Universe: AllStatic {
// may or may not have a backtrace. If error has a backtrace then the stack trace is already // may or may not have a backtrace. If error has a backtrace then the stack trace is already
// filled in. // 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_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_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); } static oop out_of_memory_error_gc_overhead_limit() { return gen_out_of_memory_error(_out_of_memory_error_gc_overhead_limit); }
......
...@@ -879,7 +879,7 @@ JNI_ENTRY(jint, jni_PushLocalFrame(JNIEnv *env, jint capacity)) ...@@ -879,7 +879,7 @@ JNI_ENTRY(jint, jni_PushLocalFrame(JNIEnv *env, jint capacity))
env, capacity); env, capacity);
#endif /* USDT2 */ #endif /* USDT2 */
//%note jni_11 //%note jni_11
if (capacity < 0 && capacity > MAX_REASONABLE_LOCAL_CAPACITY) { if (capacity < 0 || capacity > MAX_REASONABLE_LOCAL_CAPACITY) {
#ifndef USDT2 #ifndef USDT2
DTRACE_PROBE1(hotspot_jni, PushLocalFrame__return, JNI_ERR); DTRACE_PROBE1(hotspot_jni, PushLocalFrame__return, JNI_ERR);
#else /* USDT2 */ #else /* USDT2 */
......
...@@ -437,10 +437,6 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary; ...@@ -437,10 +437,6 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
static_field(Universe, _main_thread_group, oop) \ static_field(Universe, _main_thread_group, oop) \
static_field(Universe, _system_thread_group, oop) \ static_field(Universe, _system_thread_group, oop) \
static_field(Universe, _the_empty_class_klass_array, objArrayOop) \ 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, _null_ptr_exception_instance, oop) \
static_field(Universe, _arithmetic_exception_instance, oop) \ static_field(Universe, _arithmetic_exception_instance, oop) \
static_field(Universe, _vm_exception, oop) \ static_field(Universe, _vm_exception, oop) \
......
...@@ -188,8 +188,8 @@ void BaselineReporter::diff_callsites(const MemBaseline& cur, const MemBaseline& ...@@ -188,8 +188,8 @@ void BaselineReporter::diff_callsites(const MemBaseline& cur, const MemBaseline&
(MallocCallsitePointer*)prev_malloc_itr.current(); (MallocCallsitePointer*)prev_malloc_itr.current();
while (cur_malloc_callsite != NULL || prev_malloc_callsite != NULL) { while (cur_malloc_callsite != NULL || prev_malloc_callsite != NULL) {
if (prev_malloc_callsite == NULL || if (prev_malloc_callsite == NULL) {
cur_malloc_callsite->addr() < prev_malloc_callsite->addr()) { assert(cur_malloc_callsite != NULL, "sanity check");
// this is a new callsite // this is a new callsite
_outputer.diff_malloc_callsite(cur_malloc_callsite->addr(), _outputer.diff_malloc_callsite(cur_malloc_callsite->addr(),
amount_in_current_scale(cur_malloc_callsite->amount()), amount_in_current_scale(cur_malloc_callsite->amount()),
...@@ -197,15 +197,34 @@ void BaselineReporter::diff_callsites(const MemBaseline& cur, const MemBaseline& ...@@ -197,15 +197,34 @@ void BaselineReporter::diff_callsites(const MemBaseline& cur, const MemBaseline&
diff_in_current_scale(cur_malloc_callsite->amount(), 0), diff_in_current_scale(cur_malloc_callsite->amount(), 0),
diff(cur_malloc_callsite->count(), 0)); diff(cur_malloc_callsite->count(), 0));
cur_malloc_callsite = (MallocCallsitePointer*)cur_malloc_itr.next(); cur_malloc_callsite = (MallocCallsitePointer*)cur_malloc_itr.next();
} else if (cur_malloc_callsite == NULL || } else if (cur_malloc_callsite == NULL) {
cur_malloc_callsite->addr() > prev_malloc_callsite->addr()) { assert(prev_malloc_callsite != NULL, "Sanity check");
// this callsite is already gone // this callsite is already gone
_outputer.diff_malloc_callsite(prev_malloc_callsite->addr(), _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_in_current_scale(0, prev_malloc_callsite->amount()),
diff(0, prev_malloc_callsite->count())); diff(0, prev_malloc_callsite->count()));
prev_malloc_callsite = (MallocCallsitePointer*)prev_malloc_itr.next(); prev_malloc_callsite = (MallocCallsitePointer*)prev_malloc_itr.next();
} else { // the same callsite } 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(), _outputer.diff_malloc_callsite(cur_malloc_callsite->addr(),
amount_in_current_scale(cur_malloc_callsite->amount()), amount_in_current_scale(cur_malloc_callsite->amount()),
cur_malloc_callsite->count(), cur_malloc_callsite->count(),
...@@ -215,6 +234,7 @@ void BaselineReporter::diff_callsites(const MemBaseline& cur, const MemBaseline& ...@@ -215,6 +234,7 @@ void BaselineReporter::diff_callsites(const MemBaseline& cur, const MemBaseline&
prev_malloc_callsite = (MallocCallsitePointer*)prev_malloc_itr.next(); prev_malloc_callsite = (MallocCallsitePointer*)prev_malloc_itr.next();
} }
} }
}
// walk virtual memory callsite // walk virtual memory callsite
MemPointerArrayIteratorImpl cur_vm_itr(pBL_cur->_vm_cs); MemPointerArrayIteratorImpl cur_vm_itr(pBL_cur->_vm_cs);
......
...@@ -158,7 +158,7 @@ Declares a structure type that can be used in other events. ...@@ -158,7 +158,7 @@ Declares a structure type that can be used in other events.
<structvalue type="MetaspaceSizes" field="classSpace" label="Class"/> <structvalue type="MetaspaceSizes" field="classSpace" label="Class"/>
</event> </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="UINT" field="gcId" label="GC ID" relation="GC_ID"/>
<value type="GCWHEN" field="when" label="When" /> <value type="GCWHEN" field="when" label="When" />
...@@ -203,7 +203,7 @@ Declares a structure type that can be used in other events. ...@@ -203,7 +203,7 @@ Declares a structure type that can be used in other events.
<value type="G1YCTYPE" field="type" label="Type" /> <value type="G1YCTYPE" field="type" label="Type" />
</event> </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="gcId" label="GC ID" relation="GC_ID"/>
<value type="UINT" field="cSetRegions" label="Collection Set Regions"/> <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"/> <value type="BYTES64" field="cSetUsedBefore" label="Collection Set Before" description="Memory usage before GC in the collection set regions"/>
...@@ -211,7 +211,7 @@ Declares a structure type that can be used in other events. ...@@ -211,7 +211,7 @@ Declares a structure type that can be used in other events.
<value type="UINT" field="allocationRegions" label="Allocation Regions" description="Regions chosen as allocation regions during evacuation (includes survivors and old space regions)"/> <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="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="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"/> <value type="UINT" field="regionsFreed" label="Regions Freed"/>
</event> </event>
...@@ -240,14 +240,14 @@ Declares a structure type that can be used in other events. ...@@ -240,14 +240,14 @@ Declares a structure type that can be used in other events.
<event id="PromotionFailed" path="vm/gc/detailed/promotion_failed" label="Promotion Failed" is_instant="true" <event id="PromotionFailed" path="vm/gc/detailed/promotion_failed" label="Promotion Failed" is_instant="true"
description="Promotion of an object failed"> description="Promotion of an object failed">
<value type="UINT" field="gcId" label="GC ID" relation="GC_ID"/> <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"/> <value type="OSTHREAD" field="thread" label="Running thread"/>
</event> </event>
<event id="EvacuationFailed" path="vm/gc/detailed/evacuation_failed" label="Evacuation Failed" is_instant="true" <event id="EvacuationFailed" path="vm/gc/detailed/evacuation_failed" label="Evacuation Failed" is_instant="true"
description="Evacuation of an object failed"> description="Evacuation of an object failed">
<value type="UINT" field="gcId" label="GC ID" relation="GC_ID"/> <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>
<event id="ConcurrentModeFailure" path="vm/gc/detailed/concurrent_mode_failure" label="Concurrent Mode Failure" <event id="ConcurrentModeFailure" path="vm/gc/detailed/concurrent_mode_failure" label="Concurrent Mode Failure"
...@@ -309,7 +309,7 @@ Declares a structure type that can be used in other events. ...@@ -309,7 +309,7 @@ Declares a structure type that can be used in other events.
<value type="USHORT" field="sweepFractionIndex" label="Fraction Index"/> <value type="USHORT" field="sweepFractionIndex" label="Fraction Index"/>
<value type="UINT" field="sweptCount" label="Methods Swept"/> <value type="UINT" field="sweptCount" label="Methods Swept"/>
<value type="UINT" field="flushedCount" label="Methods Flushed"/> <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"/> <value type="UINT" field="zombifiedCount" label="Methods Zombified"/>
</event> </event>
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -799,6 +799,14 @@ void VMError::report(outputStream* st) { ...@@ -799,6 +799,14 @@ void VMError::report(outputStream* st) {
VMError* volatile VMError::first_error = NULL; VMError* volatile VMError::first_error = NULL;
volatile jlong VMError::first_error_tid = -1; 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 */ /** 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) { static int expand_and_open(const char* pattern, char* buf, size_t buflen, size_t pos) {
int fd = -1; int fd = -1;
...@@ -853,13 +861,6 @@ void VMError::report_and_die() { ...@@ -853,13 +861,6 @@ void VMError::report_and_die() {
// Don't allocate large buffer on stack // Don't allocate large buffer on stack
static char buffer[O_BUFLEN]; 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. // How many errors occurred in error handler when reporting first_error.
static int recursive_error_count; static int recursive_error_count;
...@@ -868,7 +869,6 @@ void VMError::report_and_die() { ...@@ -868,7 +869,6 @@ void VMError::report_and_die() {
static bool out_done = false; // done printing to standard out static bool out_done = false; // done printing to standard out
static bool log_done = false; // done saving error log static bool log_done = false; // done saving error log
static bool transmit_report_done = false; // done error reporting static bool transmit_report_done = false; // done error reporting
static fdStream log; // error log
// disble NMT to avoid further exception // disble NMT to avoid further exception
MemTracker::shutdown(MemTracker::NMT_error_reporting); MemTracker::shutdown(MemTracker::NMT_error_reporting);
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -96,6 +96,9 @@ class VMError : public StackObj { ...@@ -96,6 +96,9 @@ class VMError : public StackObj {
return (id != OOM_MALLOC_ERROR) && (id != OOM_MMAP_ERROR); return (id != OOM_MALLOC_ERROR) && (id != OOM_MMAP_ERROR);
} }
static fdStream out;
static fdStream log; // error log used by VMError::report_and_die()
public: public:
// Constructor for crashes // Constructor for crashes
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册