Merge
authortamao
Wed, 03 Jul 2013 15:04:53 -0700
changeset 18499 e57ed7bc904b
parent 18498 bbe17f2007db (current diff)
parent 18492 ab4fbcf75767 (diff)
child 18502 99eeba7bb2b1
child 18510 b4df166cc411
Merge
--- 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