Merge
authorkvn
Thu, 16 Apr 2015 14:05:48 -0700
changeset 30227 fdb68fee3e41
parent 30226 5f1a3a275862 (current diff)
parent 30182 1c980a880941 (diff)
child 30248 5c6dacbd17ae
child 30269 041d6fdcfa65
Merge
hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/SharedHeap.java
hotspot/src/cpu/x86/vm/templateTable_x86_32.hpp
hotspot/src/cpu/x86/vm/templateTable_x86_64.hpp
hotspot/src/cpu/x86/vm/vm_version_x86.cpp
hotspot/src/os/aix/vm/os_aix.cpp
hotspot/src/share/vm/classfile/vmSymbols.hpp
hotspot/src/share/vm/interpreter/linkResolver.cpp
hotspot/src/share/vm/memory/sharedHeap.cpp
hotspot/src/share/vm/memory/sharedHeap.hpp
hotspot/src/share/vm/oops/instanceClassLoaderKlass.cpp
hotspot/src/share/vm/oops/instanceKlass.cpp
hotspot/src/share/vm/oops/instanceKlass.hpp
hotspot/src/share/vm/oops/klassPS.hpp
hotspot/src/share/vm/oops/oop.pcgc.inline.hpp
hotspot/src/share/vm/oops/oop.psgc.inline.hpp
hotspot/src/share/vm/prims/whitebox.cpp
hotspot/src/share/vm/runtime/arguments.cpp
hotspot/src/share/vm/runtime/globals.hpp
hotspot/src/share/vm/runtime/vmStructs.cpp
--- a/hotspot/agent/src/share/classes/com/sun/java/swing/action/ActionManager.java	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/ActionManager.java	Thu Apr 16 14:05:48 2015 -0700
@@ -46,6 +46,11 @@
         return manager;
     }
 
+    protected static void setInstance(ActionManager m)
+    {
+        manager = m;
+    }
+
     protected abstract void addActions();
 
     protected void addAction(String cmdname, Action action)
@@ -90,6 +95,6 @@
 
     private HashMap actions;
     private static ActionUtilities utilities = new ActionUtilities();
-    protected static ActionManager manager;
+    private static ActionManager manager;
 
 }
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/G1CollectedHeap.java	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/G1CollectedHeap.java	Thu Apr 16 14:05:48 2015 -0700
@@ -29,9 +29,9 @@
 import java.util.Observer;
 
 import sun.jvm.hotspot.debugger.Address;
+import sun.jvm.hotspot.gc_interface.CollectedHeap;
 import sun.jvm.hotspot.gc_interface.CollectedHeapName;
 import sun.jvm.hotspot.memory.MemRegion;
-import sun.jvm.hotspot.memory.SharedHeap;
 import sun.jvm.hotspot.memory.SpaceClosure;
 import sun.jvm.hotspot.runtime.VM;
 import sun.jvm.hotspot.runtime.VMObjectFactory;
@@ -41,7 +41,7 @@
 
 // Mirror class for G1CollectedHeap.
 
-public class G1CollectedHeap extends SharedHeap {
+public class G1CollectedHeap extends CollectedHeap {
     // HeapRegionManager _hrm;
     static private long hrmFieldOffset;
     // MemRegion _g1_reserved;
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_interface/CollectedHeap.java	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_interface/CollectedHeap.java	Thu Apr 16 14:05:48 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, 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
@@ -32,7 +32,7 @@
 import sun.jvm.hotspot.runtime.*;
 import sun.jvm.hotspot.types.*;
 
-public class CollectedHeap extends VMObject {
+public abstract class CollectedHeap extends VMObject {
   private static long         reservedFieldOffset;
 
   static {
@@ -73,9 +73,7 @@
     return reservedRegion().contains(a);
   }
 
-  public CollectedHeapName kind() {
-    return CollectedHeapName.ABSTRACT;
-  }
+  public abstract CollectedHeapName kind();
 
   public void print() { printOn(System.out); }
   public void printOn(PrintStream tty) {
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_interface/CollectedHeapName.java	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_interface/CollectedHeapName.java	Thu Apr 16 14:05:48 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, 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
@@ -31,8 +31,6 @@
 
   private CollectedHeapName(String name) { this.name = name; }
 
-  public static final CollectedHeapName ABSTRACT = new CollectedHeapName("abstract");
-  public static final CollectedHeapName SHARED_HEAP = new CollectedHeapName("SharedHeap");
   public static final CollectedHeapName GEN_COLLECTED_HEAP = new CollectedHeapName("GenCollectedHeap");
   public static final CollectedHeapName G1_COLLECTED_HEAP = new CollectedHeapName("G1CollectedHeap");
   public static final CollectedHeapName PARALLEL_SCAVENGE_HEAP = new CollectedHeapName("ParallelScavengeHeap");
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/GenCollectedHeap.java	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/GenCollectedHeap.java	Thu Apr 16 14:05:48 2015 -0700
@@ -33,8 +33,7 @@
 import sun.jvm.hotspot.types.*;
 import sun.jvm.hotspot.utilities.*;
 
-public class GenCollectedHeap extends SharedHeap {
-  private static CIntegerField nGensField;
+public class GenCollectedHeap extends CollectedHeap {
   private static AddressField youngGenField;
   private static AddressField oldGenField;
 
@@ -54,7 +53,6 @@
   private static synchronized void initialize(TypeDataBase db) {
     Type type = db.lookupType("GenCollectedHeap");
 
-    nGensField = type.getCIntegerField("_n_gens");
     youngGenField = type.getAddressField("_young_gen");
     oldGenField = type.getAddressField("_old_gen");
 
@@ -70,7 +68,7 @@
   }
 
   public int nGens() {
-    return (int) nGensField.getValue(addr);
+    return 2; // Young + Old
   }
 
   public Generation getGen(int i) {
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/SharedHeap.java	Wed Apr 15 11:01:56 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2002, 2012, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.memory;
-
-import java.io.*;
-import java.util.*;
-
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.gc_interface.*;
-import sun.jvm.hotspot.runtime.*;
-import sun.jvm.hotspot.types.*;
-
-public abstract class SharedHeap extends CollectedHeap {
-  private static VirtualConstructor ctor;
-
-  static {
-    VM.registerVMInitializedObserver(new Observer() {
-        public void update(Observable o, Object data) {
-          initialize(VM.getVM().getTypeDataBase());
-        }
-      });
-  }
-
-  private static synchronized void initialize(TypeDataBase db) {
-    Type type = db.lookupType("SharedHeap");
-    ctor = new VirtualConstructor(db);
-  }
-
-  public SharedHeap(Address addr) {
-    super(addr);
-  }
-
-  public CollectedHeapName kind() {
-    return CollectedHeapName.SHARED_HEAP;
-  }
-  }
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/Universe.java	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/Universe.java	Thu Apr 16 14:05:48 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, 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
@@ -112,11 +112,7 @@
     return "";
   }
   public CollectedHeap heap() {
-    try {
-      return (CollectedHeap) heapConstructor.instantiateWrapperFor(collectedHeapField.getValue());
-    } catch (WrongTypeException e) {
-      return new CollectedHeap(collectedHeapField.getValue());
-    }
+    return (CollectedHeap) heapConstructor.instantiateWrapperFor(collectedHeapField.getValue());
   }
 
   public static long getNarrowOopBase() {
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java	Thu Apr 16 14:05:48 2015 -0700
@@ -81,53 +81,48 @@
       System.out.println();
       System.out.println("Heap Usage:");
 
-      if (heap instanceof SharedHeap) {
-         SharedHeap sharedHeap = (SharedHeap) heap;
-         if (sharedHeap instanceof GenCollectedHeap) {
-            GenCollectedHeap genHeap = (GenCollectedHeap) sharedHeap;
-            for (int n = 0; n < genHeap.nGens(); n++) {
-               Generation gen = genHeap.getGen(n);
-               if (gen instanceof sun.jvm.hotspot.memory.DefNewGeneration) {
-                  System.out.println("New Generation (Eden + 1 Survivor Space):");
-                  printGen(gen);
+      if (heap instanceof GenCollectedHeap) {
+         GenCollectedHeap genHeap = (GenCollectedHeap) heap;
+         for (int n = 0; n < genHeap.nGens(); n++) {
+            Generation gen = genHeap.getGen(n);
+            if (gen instanceof sun.jvm.hotspot.memory.DefNewGeneration) {
+               System.out.println("New Generation (Eden + 1 Survivor Space):");
+               printGen(gen);
 
-                  ContiguousSpace eden = ((DefNewGeneration)gen).eden();
-                  System.out.println("Eden Space:");
-                  printSpace(eden);
+               ContiguousSpace eden = ((DefNewGeneration)gen).eden();
+               System.out.println("Eden Space:");
+               printSpace(eden);
 
-                  ContiguousSpace from = ((DefNewGeneration)gen).from();
-                  System.out.println("From Space:");
-                  printSpace(from);
+               ContiguousSpace from = ((DefNewGeneration)gen).from();
+               System.out.println("From Space:");
+               printSpace(from);
 
-                  ContiguousSpace to = ((DefNewGeneration)gen).to();
-                  System.out.println("To Space:");
-                  printSpace(to);
-               } else {
-                  System.out.println(gen.name() + ":");
-                  printGen(gen);
-               }
+               ContiguousSpace to = ((DefNewGeneration)gen).to();
+               System.out.println("To Space:");
+               printSpace(to);
+            } else {
+               System.out.println(gen.name() + ":");
+               printGen(gen);
             }
-         } else if (sharedHeap instanceof G1CollectedHeap) {
-             G1CollectedHeap g1h = (G1CollectedHeap) sharedHeap;
-             G1MonitoringSupport g1mm = g1h.g1mm();
-             long edenRegionNum = g1mm.edenRegionNum();
-             long survivorRegionNum = g1mm.survivorRegionNum();
-             HeapRegionSetBase oldSet = g1h.oldSet();
-             HeapRegionSetBase humongousSet = g1h.humongousSet();
-             long oldRegionNum = oldSet.count().length()
-                          + humongousSet.count().capacity() / HeapRegion.grainBytes();
-             printG1Space("G1 Heap:", g1h.n_regions(),
-                          g1h.used(), g1h.capacity());
-             System.out.println("G1 Young Generation:");
-             printG1Space("Eden Space:", edenRegionNum,
-                          g1mm.edenUsed(), g1mm.edenCommitted());
-             printG1Space("Survivor Space:", survivorRegionNum,
-                          g1mm.survivorUsed(), g1mm.survivorCommitted());
-             printG1Space("G1 Old Generation:", oldRegionNum,
-                          g1mm.oldUsed(), g1mm.oldCommitted());
-         } else {
-             throw new RuntimeException("unknown SharedHeap type : " + heap.getClass());
          }
+      } else if (heap instanceof G1CollectedHeap) {
+          G1CollectedHeap g1h = (G1CollectedHeap) heap;
+          G1MonitoringSupport g1mm = g1h.g1mm();
+          long edenRegionNum = g1mm.edenRegionNum();
+          long survivorRegionNum = g1mm.survivorRegionNum();
+          HeapRegionSetBase oldSet = g1h.oldSet();
+          HeapRegionSetBase humongousSet = g1h.humongousSet();
+          long oldRegionNum = oldSet.count().length()
+                       + humongousSet.count().capacity() / HeapRegion.grainBytes();
+          printG1Space("G1 Heap:", g1h.n_regions(),
+                       g1h.used(), g1h.capacity());
+          System.out.println("G1 Young Generation:");
+          printG1Space("Eden Space:", edenRegionNum,
+                       g1mm.edenUsed(), g1mm.edenCommitted());
+          printG1Space("Survivor Space:", survivorRegionNum,
+                       g1mm.survivorUsed(), g1mm.survivorCommitted());
+          printG1Space("G1 Old Generation:", oldRegionNum,
+                       g1mm.oldUsed(), g1mm.oldCommitted());
       } else if (heap instanceof ParallelScavengeHeap) {
          ParallelScavengeHeap psh = (ParallelScavengeHeap) heap;
          PSYoungGen youngGen = psh.youngGen();
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/action/HSDBActionManager.java	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/action/HSDBActionManager.java	Thu Apr 16 14:05:48 2015 -0700
@@ -32,10 +32,12 @@
 public class HSDBActionManager extends ActionManager {
 
     public static ActionManager getInstance() {
-        if (manager == null) {
-            manager = new HSDBActionManager();
+        ActionManager m = ActionManager.getInstance();
+        if (m == null) {
+            m = new HSDBActionManager();
+            ActionManager.setInstance(m);
         }
-        return manager;
+        return m;
     }
 
     protected void addActions() {
--- a/hotspot/make/Makefile	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/make/Makefile	Thu Apr 16 14:05:48 2015 -0700
@@ -98,7 +98,7 @@
 COMMON_VM_OPTIMIZED_TARGETS=optimized optimized1 docs export_optimized
 
 # JDK directory list
-JDK_DIRS=bin include jre lib demo
+JDK_DIRS=bin include lib demo
 
 all:           all_product all_fastdebug
 
@@ -373,33 +373,33 @@
 	$(install-file)
 $(EXPORT_LIB_DIR)/%.lib:			$(C2_BUILD_DIR)/%.lib
 	$(install-file)
-$(EXPORT_JRE_BIN_DIR)/%.diz:			$(C2_BUILD_DIR)/%.diz
+$(EXPORT_BIN_DIR)/%.diz:			$(C2_BUILD_DIR)/%.diz
 	$(install-file)
-$(EXPORT_JRE_BIN_DIR)/%.dll:			$(C2_BUILD_DIR)/%.dll
+$(EXPORT_BIN_DIR)/%.dll:			$(C2_BUILD_DIR)/%.dll
 	$(install-file)
-$(EXPORT_JRE_BIN_DIR)/%.pdb:			$(C2_BUILD_DIR)/%.pdb
+$(EXPORT_BIN_DIR)/%.pdb:			$(C2_BUILD_DIR)/%.pdb
 	$(install-file)
-$(EXPORT_JRE_BIN_DIR)/%.map:			$(C2_BUILD_DIR)/%.map
+$(EXPORT_BIN_DIR)/%.map:			$(C2_BUILD_DIR)/%.map
 	$(install-file)
 # Unix
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(C2_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
+$(EXPORT_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(C2_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
 	$(install-file)
 $(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX):       $(C2_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
 	$(install-file)
 $(EXPORT_SERVER_DIR)/64/%.$(LIBRARY_SUFFIX):    $(C2_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
 	$(install-file)
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo: 	$(C2_BUILD_DIR)/%.debuginfo
+$(EXPORT_LIB_ARCH_DIR)/%.debuginfo: 	$(C2_BUILD_DIR)/%.debuginfo
 	$(install-file)
 $(EXPORT_SERVER_DIR)/%.debuginfo:       	$(C2_BUILD_DIR)/%.debuginfo
 	$(install-file)
 $(EXPORT_SERVER_DIR)/64/%.debuginfo:    	$(C2_BUILD_DIR)/%.debuginfo
 	$(install-file)
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.diz: 		$(C2_BUILD_DIR)/%.diz
+$(EXPORT_LIB_ARCH_DIR)/%.diz: 		$(C2_BUILD_DIR)/%.diz
 	$(install-file)
 $(EXPORT_SERVER_DIR)/64/%.diz:    		$(C2_BUILD_DIR)/%.diz
 	$(install-file)
 # MacOS X
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.dSYM: 		$(C2_BUILD_DIR)/%.dSYM
+$(EXPORT_LIB_ARCH_DIR)/%.dSYM: 		$(C2_BUILD_DIR)/%.dSYM
 	$(install-dir)
 $(EXPORT_SERVER_DIR)/%.dSYM:       		$(C2_BUILD_DIR)/%.dSYM
 	$(install-dir)
@@ -423,33 +423,33 @@
 	$(install-file)
 $(EXPORT_LIB_DIR)/%.lib:			$(C1_BUILD_DIR)/%.lib
 	$(install-file)
-$(EXPORT_JRE_BIN_DIR)/%.diz:			$(C1_BUILD_DIR)/%.diz
+$(EXPORT_BIN_DIR)/%.diz:			$(C1_BUILD_DIR)/%.diz
 	$(install-file)
-$(EXPORT_JRE_BIN_DIR)/%.dll:			$(C1_BUILD_DIR)/%.dll
+$(EXPORT_BIN_DIR)/%.dll:			$(C1_BUILD_DIR)/%.dll
 	$(install-file)
-$(EXPORT_JRE_BIN_DIR)/%.pdb:			$(C1_BUILD_DIR)/%.pdb
+$(EXPORT_BIN_DIR)/%.pdb:			$(C1_BUILD_DIR)/%.pdb
 	$(install-file)
-$(EXPORT_JRE_BIN_DIR)/%.map:			$(C1_BUILD_DIR)/%.map
+$(EXPORT_BIN_DIR)/%.map:			$(C1_BUILD_DIR)/%.map
 	$(install-file)
 # Unix
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(C1_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
+$(EXPORT_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(C1_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
 	$(install-file)
 $(EXPORT_CLIENT_DIR)/%.$(LIBRARY_SUFFIX):       $(C1_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
 	$(install-file)
 $(EXPORT_CLIENT_DIR)/64/%.$(LIBRARY_SUFFIX):    $(C1_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
 	$(install-file)
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo: 	$(C1_BUILD_DIR)/%.debuginfo
+$(EXPORT_LIB_ARCH_DIR)/%.debuginfo: 	$(C1_BUILD_DIR)/%.debuginfo
 	$(install-file)
 $(EXPORT_CLIENT_DIR)/%.debuginfo:       	$(C1_BUILD_DIR)/%.debuginfo
 	$(install-file)
 $(EXPORT_CLIENT_DIR)/64/%.debuginfo:    	$(C1_BUILD_DIR)/%.debuginfo
 	$(install-file)
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.diz: 		$(C1_BUILD_DIR)/%.diz
+$(EXPORT_LIB_ARCH_DIR)/%.diz: 		$(C1_BUILD_DIR)/%.diz
 	$(install-file)
 $(EXPORT_CLIENT_DIR)/64/%.diz:    		$(C1_BUILD_DIR)/%.diz
 	$(install-file)
 # MacOS X
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.dSYM: 		$(C1_BUILD_DIR)/%.dSYM
+$(EXPORT_LIB_ARCH_DIR)/%.dSYM: 		$(C1_BUILD_DIR)/%.dSYM
 	$(install-dir)
 $(EXPORT_CLIENT_DIR)/%.dSYM:       		$(C1_BUILD_DIR)/%.dSYM
 	$(install-dir)
@@ -473,28 +473,28 @@
 	$(install-file)
 $(EXPORT_LIB_DIR)/%.lib:			$(MINIMAL1_BUILD_DIR)/%.lib
 	$(install-file)
-$(EXPORT_JRE_BIN_DIR)/%.diz:			$(MINIMAL1_BUILD_DIR)/%.diz
+$(EXPORT_BIN_DIR)/%.diz:			$(MINIMAL1_BUILD_DIR)/%.diz
 	$(install-file)
-$(EXPORT_JRE_BIN_DIR)/%.dll:			$(MINIMAL1_BUILD_DIR)/%.dll
+$(EXPORT_BIN_DIR)/%.dll:			$(MINIMAL1_BUILD_DIR)/%.dll
 	$(install-file)
-$(EXPORT_JRE_BIN_DIR)/%.pdb:			$(MINIMAL1_BUILD_DIR)/%.pdb
+$(EXPORT_BIN_DIR)/%.pdb:			$(MINIMAL1_BUILD_DIR)/%.pdb
 	$(install-file)
-$(EXPORT_JRE_BIN_DIR)/%.map:			$(MINIMAL1_BUILD_DIR)/%.map
+$(EXPORT_BIN_DIR)/%.map:			$(MINIMAL1_BUILD_DIR)/%.map
 	$(install-file)
 # Unix
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX):	$(MINIMAL1_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
+$(EXPORT_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX):	$(MINIMAL1_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
 	$(install-file)
 $(EXPORT_MINIMAL_DIR)/%.$(LIBRARY_SUFFIX):	$(MINIMAL1_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
 	$(install-file)
 $(EXPORT_MINIMAL_DIR)/64/%.$(LIBRARY_SUFFIX):	$(MINIMAL1_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
 	$(install-file)
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo:		$(MINIMAL1_BUILD_DIR)/%.debuginfo
+$(EXPORT_LIB_ARCH_DIR)/%.debuginfo:		$(MINIMAL1_BUILD_DIR)/%.debuginfo
 	$(install-file)
 $(EXPORT_MINIMAL_DIR)/%.debuginfo:		$(MINIMAL1_BUILD_DIR)/%.debuginfo
 	$(install-file)
 $(EXPORT_MINIMAL_DIR)/64/%.debuginfo:		$(MINIMAL1_BUILD_DIR)/%.debuginfo
 	$(install-file)
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.diz:		$(MINIMAL1_BUILD_DIR)/%.diz
+$(EXPORT_LIB_ARCH_DIR)/%.diz:		$(MINIMAL1_BUILD_DIR)/%.diz
 	$(install-file)
 $(EXPORT_MINIMAL_DIR)/64/%.diz:			$(MINIMAL1_BUILD_DIR)/%.diz
 	$(install-file)
@@ -509,11 +509,11 @@
 $(EXPORT_INCLUDE_DIR)/%:			$(ZERO_BUILD_DIR)/../generated/jvmtifiles/%
 	$(install-file)
 # Unix
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(ZERO_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
+$(EXPORT_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(ZERO_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
 	$(install-file)
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo:		$(ZERO_BUILD_DIR)/%.debuginfo
+$(EXPORT_LIB_ARCH_DIR)/%.debuginfo:		$(ZERO_BUILD_DIR)/%.debuginfo
 	$(install-file)
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.diz:		$(ZERO_BUILD_DIR)/%.diz
+$(EXPORT_LIB_ARCH_DIR)/%.diz:		$(ZERO_BUILD_DIR)/%.diz
 	$(install-file)
 $(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX):       $(ZERO_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
 	$(install-file)
@@ -522,7 +522,7 @@
 $(EXPORT_SERVER_DIR)/%.diz:			$(ZERO_BUILD_DIR)/%.diz
 	$(install-file)
 # MacOS X
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.dSYM: 		$(ZERO_BUILD_DIR)/%.dSYM
+$(EXPORT_LIB_ARCH_DIR)/%.dSYM: 		$(ZERO_BUILD_DIR)/%.dSYM
 	$(install-dir)
 $(EXPORT_SERVER_DIR)/%.dSYM:			$(ZERO_BUILD_DIR)/%.dSYM
 	$(install-dir)
@@ -536,11 +536,11 @@
 $(EXPORT_INCLUDE_DIR)/%:			$(CORE_BUILD_DIR)/../generated/jvmtifiles/%
 	$(install-file)
 # Unix
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX):	$(CORE_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
+$(EXPORT_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX):	$(CORE_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
 	$(install-file)
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo:		$(CORE_BUILD_DIR)/%.debuginfo
+$(EXPORT_LIB_ARCH_DIR)/%.debuginfo:		$(CORE_BUILD_DIR)/%.debuginfo
 	$(install-file)
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.diz:		$(CORE_BUILD_DIR)/%.diz
+$(EXPORT_LIB_ARCH_DIR)/%.diz:		$(CORE_BUILD_DIR)/%.diz
 	$(install-file)
 $(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX):	$(CORE_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
 	$(install-file)
@@ -558,11 +558,11 @@
 $(EXPORT_INCLUDE_DIR)/%:			$(SHARK_BUILD_DIR)/../generated/jvmtifiles/%
 	$(install-file)
 # Unix
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(SHARK_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
+$(EXPORT_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(SHARK_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
 	$(install-file)
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo):	$(SHARK_BUILD_DIR)/%.debuginfo
+$(EXPORT_LIB_ARCH_DIR)/%.debuginfo):	$(SHARK_BUILD_DIR)/%.debuginfo
 	$(install-file)
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.diz:		$(SHARK_BUILD_DIR)/%.diz
+$(EXPORT_LIB_ARCH_DIR)/%.diz:		$(SHARK_BUILD_DIR)/%.diz
 	$(install-file)
 $(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX):       $(SHARK_BUILD_DIR)/%.$(LIBRARY_SUFFIX)
 	$(install-file)
@@ -571,7 +571,7 @@
 $(EXPORT_SERVER_DIR)/%.diz:			$(SHARK_BUILD_DIR)/%.diz
 	$(install-file)
 # MacOS X
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.dSYM: 		$(SHARK_BUILD_DIR)/%.dSYM
+$(EXPORT_LIB_ARCH_DIR)/%.dSYM: 		$(SHARK_BUILD_DIR)/%.dSYM
 	$(install-dir)
 $(EXPORT_SERVER_DIR)/%.dSYM:			$(SHARK_BUILD_DIR)/%.dSYM
 	$(install-dir)
--- a/hotspot/make/aix/makefiles/defs.make	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/make/aix/makefiles/defs.make	Thu Apr 16 14:05:48 2015 -0700
@@ -184,17 +184,17 @@
 EXPORT_LIST += $(EXPORT_DOCS_DIR)/platform/jvmti/jvmti.html
 
 # client and server subdirectories have symbolic links to ../libjsig.so
-EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.$(LIBRARY_SUFFIX)
+EXPORT_LIST += $(EXPORT_LIB_ARCH_DIR)/libjsig.$(LIBRARY_SUFFIX)
 #ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
 #  ifeq ($(ZIP_DEBUGINFO_FILES),1)
-#    EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.diz
+#    EXPORT_LIST += $(EXPORT_LIB_ARCH_DIR)/libjsig.diz
 #  else
-#    EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.debuginfo
+#    EXPORT_LIST += $(EXPORT_LIB_ARCH_DIR)/libjsig.debuginfo
 #  endif
 #endif
-EXPORT_SERVER_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/server
-EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client
-EXPORT_MINIMAL_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/minimal
+EXPORT_SERVER_DIR = $(EXPORT_LIB_ARCH_DIR)/server
+EXPORT_CLIENT_DIR = $(EXPORT_LIB_ARCH_DIR)/client
+EXPORT_MINIMAL_DIR = $(EXPORT_LIB_ARCH_DIR)/minimal
 
 ifeq ($(findstring true, $(JVM_VARIANT_SERVER) $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK) $(JVM_VARIANT_CORE)), true)
   EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
--- a/hotspot/make/aix/makefiles/vm.make	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/make/aix/makefiles/vm.make	Thu Apr 16 14:05:48 2015 -0700
@@ -122,7 +122,7 @@
 # By default, link the *.o into the library, not the executable.
 LINK_INTO$(LINK_INTO) = LIBJVM
 
-JDK_LIBDIR = $(JAVA_HOME)/jre/lib/$(LIBARCH)
+JDK_LIBDIR = $(JAVA_HOME)/lib/$(LIBARCH)
 
 #----------------------------------------------------------------------
 # jvm_db & dtrace
--- a/hotspot/make/bsd/makefiles/defs.make	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/make/bsd/makefiles/defs.make	Thu Apr 16 14:05:48 2015 -0700
@@ -265,23 +265,23 @@
 EXPORT_LIST += $(EXPORT_DOCS_DIR)/platform/jvmti/jvmti.html
 
 # client and server subdirectories have symbolic links to ../libjsig.so
-EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.$(LIBRARY_SUFFIX)
+EXPORT_LIST += $(EXPORT_LIB_ARCH_DIR)/libjsig.$(LIBRARY_SUFFIX)
 
 ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
   ifeq ($(ZIP_DEBUGINFO_FILES),1)
-      EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.diz
+      EXPORT_LIST += $(EXPORT_LIB_ARCH_DIR)/libjsig.diz
   else
     ifeq ($(OS_VENDOR), Darwin)
-        EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.$(LIBRARY_SUFFIX).dSYM
+        EXPORT_LIST += $(EXPORT_LIB_ARCH_DIR)/libjsig.$(LIBRARY_SUFFIX).dSYM
     else
-        EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.debuginfo
+        EXPORT_LIST += $(EXPORT_LIB_ARCH_DIR)/libjsig.debuginfo
     endif
   endif
 endif
 
-EXPORT_SERVER_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/server
-EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client
-EXPORT_MINIMAL_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/minimal
+EXPORT_SERVER_DIR = $(EXPORT_LIB_ARCH_DIR)/server
+EXPORT_CLIENT_DIR = $(EXPORT_LIB_ARCH_DIR)/client
+EXPORT_MINIMAL_DIR = $(EXPORT_LIB_ARCH_DIR)/minimal
 
 ifeq ($(findstring true, $(JVM_VARIANT_SERVER) $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
   EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
@@ -324,34 +324,34 @@
 
 # Serviceability Binaries
 # No SA Support for PPC, IA64, ARM or zero
-ADD_SA_BINARIES/x86   = $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.$(LIBRARY_SUFFIX) \
+ADD_SA_BINARIES/x86   = $(EXPORT_LIB_ARCH_DIR)/libsaproc.$(LIBRARY_SUFFIX) \
                         $(EXPORT_LIB_DIR)/sa-jdi.jar
 
 ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
   ifeq ($(ZIP_DEBUGINFO_FILES),1)
-      ADD_SA_BINARIES/x86 += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.diz
+      ADD_SA_BINARIES/x86 += $(EXPORT_LIB_ARCH_DIR)/libsaproc.diz
   else
     ifeq ($(OS_VENDOR), Darwin)
-        ADD_SA_BINARIES/x86 += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.$(LIBRARY_SUFFIX).dSYM
+        ADD_SA_BINARIES/x86 += $(EXPORT_LIB_ARCH_DIR)/libsaproc.$(LIBRARY_SUFFIX).dSYM
     else
-        ADD_SA_BINARIES/x86 += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.debuginfo
+        ADD_SA_BINARIES/x86 += $(EXPORT_LIB_ARCH_DIR)/libsaproc.debuginfo
     endif
   endif
 endif
 
-ADD_SA_BINARIES/sparc = $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.$(LIBRARY_SUFFIX) \
+ADD_SA_BINARIES/sparc = $(EXPORT_LIB_ARCH_DIR)/libsaproc.$(LIBRARY_SUFFIX) \
                         $(EXPORT_LIB_DIR)/sa-jdi.jar
-ADD_SA_BINARIES/universal = $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.$(LIBRARY_SUFFIX) \
+ADD_SA_BINARIES/universal = $(EXPORT_LIB_ARCH_DIR)/libsaproc.$(LIBRARY_SUFFIX) \
                             $(EXPORT_LIB_DIR)/sa-jdi.jar
 
 ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
   ifeq ($(ZIP_DEBUGINFO_FILES),1)
-      ADD_SA_BINARIES/universal += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.diz
+      ADD_SA_BINARIES/universal += $(EXPORT_LIB_ARCH_DIR)/libsaproc.diz
   else
     ifeq ($(OS_VENDOR), Darwin)
-        ADD_SA_BINARIES/universal += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.$(LIBRARY_SUFFIX).dSYM
+        ADD_SA_BINARIES/universal += $(EXPORT_LIB_ARCH_DIR)/libsaproc.$(LIBRARY_SUFFIX).dSYM
     else
-        ADD_SA_BINARIES/universal += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.debuginfo
+        ADD_SA_BINARIES/universal += $(EXPORT_LIB_ARCH_DIR)/libsaproc.debuginfo
     endif
   endif
 endif
@@ -388,25 +388,25 @@
     endif
 
     # Binaries to 'universalize' if built
-    UNIVERSAL_LIPO_LIST += $(EXPORT_JRE_LIB_DIR)/libjsig.$(LIBRARY_SUFFIX)
-    UNIVERSAL_LIPO_LIST += $(EXPORT_JRE_LIB_DIR)/libsaproc.$(LIBRARY_SUFFIX)
-    UNIVERSAL_LIPO_LIST += $(EXPORT_JRE_LIB_DIR)/server/libjvm.$(LIBRARY_SUFFIX)
-    UNIVERSAL_LIPO_LIST += $(EXPORT_JRE_LIB_DIR)/client/libjvm.$(LIBRARY_SUFFIX)
+    UNIVERSAL_LIPO_LIST += $(EXPORT_LIB_DIR)/libjsig.$(LIBRARY_SUFFIX)
+    UNIVERSAL_LIPO_LIST += $(EXPORT_LIB_DIR)/libsaproc.$(LIBRARY_SUFFIX)
+    UNIVERSAL_LIPO_LIST += $(EXPORT_LIB_DIR)/server/libjvm.$(LIBRARY_SUFFIX)
+    UNIVERSAL_LIPO_LIST += $(EXPORT_LIB_DIR)/client/libjvm.$(LIBRARY_SUFFIX)
 
     # Files to simply copy in place
-    UNIVERSAL_COPY_LIST += $(EXPORT_JRE_LIB_DIR)/server/Xusage.txt
-    UNIVERSAL_COPY_LIST += $(EXPORT_JRE_LIB_DIR)/client/Xusage.txt
+    UNIVERSAL_COPY_LIST += $(EXPORT_LIB_DIR)/server/Xusage.txt
+    UNIVERSAL_COPY_LIST += $(EXPORT_LIB_DIR)/client/Xusage.txt
     ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
       ifeq ($(ZIP_DEBUGINFO_FILES),1)
-          UNIVERSAL_COPY_LIST += $(EXPORT_JRE_LIB_DIR)/server/libjvm.diz
-          UNIVERSAL_COPY_LIST += $(EXPORT_JRE_LIB_DIR)/client/libjvm.diz
-          UNIVERSAL_COPY_LIST += $(EXPORT_JRE_LIB_DIR)/libjsig.diz
-          UNIVERSAL_COPY_LIST += $(EXPORT_JRE_LIB_DIR)/libsaproc.diz
+          UNIVERSAL_COPY_LIST += $(EXPORT_LIB_DIR)/server/libjvm.diz
+          UNIVERSAL_COPY_LIST += $(EXPORT_LIB_DIR)/client/libjvm.diz
+          UNIVERSAL_COPY_LIST += $(EXPORT_LIB_DIR)/libjsig.diz
+          UNIVERSAL_COPY_LIST += $(EXPORT_LIB_DIR)/libsaproc.diz
       else
-          UNIVERSAL_COPY_LIST += $(EXPORT_JRE_LIB_DIR)/server/libjvm.$(LIBRARY_SUFFIX).dSYM
-          UNIVERSAL_COPY_LIST += $(EXPORT_JRE_LIB_DIR)/client/libjvm.$(LIBRARY_SUFFIX).dSYM
-          UNIVERSAL_COPY_LIST += $(EXPORT_JRE_LIB_DIR)/libjsig.$(LIBRARY_SUFFIX).dSYM
-          UNIVERSAL_COPY_LIST += $(EXPORT_JRE_LIB_DIR)/libsaproc.$(LIBRARY_SUFFIX).dSYM
+          UNIVERSAL_COPY_LIST += $(EXPORT_LIB_DIR)/server/libjvm.$(LIBRARY_SUFFIX).dSYM
+          UNIVERSAL_COPY_LIST += $(EXPORT_LIB_DIR)/client/libjvm.$(LIBRARY_SUFFIX).dSYM
+          UNIVERSAL_COPY_LIST += $(EXPORT_LIB_DIR)/libjsig.$(LIBRARY_SUFFIX).dSYM
+          UNIVERSAL_COPY_LIST += $(EXPORT_LIB_DIR)/libsaproc.$(LIBRARY_SUFFIX).dSYM
       endif
     endif
 
--- a/hotspot/make/bsd/makefiles/universal.gmk	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/make/bsd/makefiles/universal.gmk	Thu Apr 16 14:05:48 2015 -0700
@@ -54,12 +54,12 @@
 
 # Consolidate architecture builds into a single Universal binary
 universalize: $(UNIVERSAL_LIPO_LIST) $(UNIVERSAL_COPY_LIST)
-	$(RM) -r $(EXPORT_PATH)/jre/lib/{i386,amd64}
+	$(RM) -r $(EXPORT_PATH)/lib/{i386,amd64}
 
 
 # Package built libraries in a universal binary
 $(UNIVERSAL_LIPO_LIST):
-	BUILT_LIPO_FILES="`find $(EXPORT_JRE_LIB_DIR)/{i386,amd64}/$(subst $(EXPORT_JRE_LIB_DIR)/,,$@) 2>/dev/null`" || test $$? = "1"; \
+	BUILT_LIPO_FILES="`find $(EXPORT_LIB_DIR)/{i386,amd64}/$(subst $(EXPORT_LIB_DIR)/,,$@) 2>/dev/null`" || test $$? = "1"; \
 	if [ -n "$${BUILT_LIPO_FILES}" ]; then \
 	  $(MKDIR) -p $(shell dirname $@); \
 	  lipo -create -output $@ $${BUILT_LIPO_FILES}; \
@@ -70,7 +70,7 @@
 # - copies directories; including empty dirs
 # - copies files, symlinks, other non-directory files
 $(UNIVERSAL_COPY_LIST):
-	BUILT_COPY_FILES="`find $(EXPORT_JRE_LIB_DIR)/{i386,amd64}/$(subst $(EXPORT_JRE_LIB_DIR)/,,$@) -prune 2>/dev/null`" || test $$? = "1"; \
+	BUILT_COPY_FILES="`find $(EXPORT_LIB_DIR)/{i386,amd64}/$(subst $(EXPORT_LIB_DIR)/,,$@) -prune 2>/dev/null`" || test $$? = "1"; \
 	if [ -n "$${BUILT_COPY_FILES}" ]; then \
 	  for i in $${BUILT_COPY_FILES}; do \
 	    $(MKDIR) -p $(shell dirname $@); \
@@ -80,21 +80,21 @@
 
 
 # Replace arch specific binaries with universal binaries
-# Do not touch jre/lib/{client,server}/libjsig.$(LIBRARY_SUFFIX)
+# Do not touch lib/{client,server}/libjsig.$(LIBRARY_SUFFIX)
 # That symbolic link belongs to the 'jdk' build.
 export_universal:
-	$(RM) -r $(EXPORT_PATH)/jre/lib/{i386,amd64}
-	$(RM) -r $(JDK_IMAGE_DIR)/jre/lib/{i386,amd64}
+	$(RM) -r $(EXPORT_PATH)/lib/{i386,amd64}
+	$(RM) -r $(JDK_IMAGE_DIR)/lib/{i386,amd64}
 	($(CD) $(EXPORT_PATH) && \
 	  $(TAR) -cf - *) | \
 	  ($(CD) $(JDK_IMAGE_DIR) && $(TAR) -xpf -)
 
 
 # Overlay universal binaries
-# Do not touch jre/lib/{client,server}/libjsig.$(LIBRARY_SUFFIX)
+# Do not touch lib/{client,server}/libjsig.$(LIBRARY_SUFFIX)
 # That symbolic link belongs to the 'jdk' build.
 copy_universal:
-	$(RM) -r $(JDK_IMAGE_DIR)$(COPY_SUBDIR)/jre/lib/{i386,amd64}
+	$(RM) -r $(JDK_IMAGE_DIR)$(COPY_SUBDIR)/lib/{i386,amd64}
 	($(CD) $(EXPORT_PATH)$(COPY_SUBDIR) && \
 	  $(TAR) -cf - *) | \
 	  ($(CD) $(JDK_IMAGE_DIR)$(COPY_SUBDIR) && $(TAR) -xpf -)
--- a/hotspot/make/defs.make	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/make/defs.make	Thu Apr 16 14:05:48 2015 -0700
@@ -350,15 +350,13 @@
 EXPORT_INCLUDE_DIR = $(EXPORT_PATH)/include
 EXPORT_DOCS_DIR = $(EXPORT_PATH)/docs
 EXPORT_LIB_DIR = $(EXPORT_PATH)/lib
-EXPORT_JRE_DIR = $(EXPORT_PATH)/jre
-EXPORT_JRE_BIN_DIR = $(EXPORT_JRE_DIR)/bin
-EXPORT_JRE_LIB_DIR = $(EXPORT_JRE_DIR)/lib
-EXPORT_JRE_LIB_ARCH_DIR = $(EXPORT_JRE_LIB_DIR)/$(LIBARCH)
+EXPORT_BIN_DIR = $(EXPORT_PATH)/bin
+EXPORT_LIB_ARCH_DIR = $(EXPORT_LIB_DIR)/$(LIBARCH)
 
 # non-universal macosx builds need to appear universal
 ifeq ($(OS_VENDOR), Darwin)
   ifneq ($(MACOSX_UNIVERSAL), true)
-    EXPORT_JRE_LIB_ARCH_DIR = $(EXPORT_JRE_LIB_DIR)
+    EXPORT_LIB_ARCH_DIR = $(EXPORT_LIB_DIR)
   endif
 endif
 
@@ -370,4 +368,3 @@
 EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jmm.h
 
 .PHONY: $(HS_ALT_MAKE)/defs.make
-
--- a/hotspot/make/linux/makefiles/defs.make	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/make/linux/makefiles/defs.make	Thu Apr 16 14:05:48 2015 -0700
@@ -244,17 +244,17 @@
 EXPORT_LIST += $(EXPORT_DOCS_DIR)/platform/jvmti/jvmti.html
 
 # client and server subdirectories have symbolic links to ../libjsig.so
-EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.$(LIBRARY_SUFFIX)
+EXPORT_LIST += $(EXPORT_LIB_ARCH_DIR)/libjsig.$(LIBRARY_SUFFIX)
 ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
   ifeq ($(ZIP_DEBUGINFO_FILES),1)
-    EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.diz
+    EXPORT_LIST += $(EXPORT_LIB_ARCH_DIR)/libjsig.diz
   else
-    EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.debuginfo
+    EXPORT_LIST += $(EXPORT_LIB_ARCH_DIR)/libjsig.debuginfo
   endif
 endif
-EXPORT_SERVER_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/server
-EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client
-EXPORT_MINIMAL_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/minimal
+EXPORT_SERVER_DIR = $(EXPORT_LIB_ARCH_DIR)/server
+EXPORT_CLIENT_DIR = $(EXPORT_LIB_ARCH_DIR)/client
+EXPORT_MINIMAL_DIR = $(EXPORT_LIB_ARCH_DIR)/minimal
 
 ifeq ($(findstring true, $(JVM_VARIANT_SERVER) $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK) $(JVM_VARIANT_CORE)), true)
   EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
@@ -295,14 +295,14 @@
 
 # Serviceability Binaries
 
-ADD_SA_BINARIES/DEFAULT = $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.$(LIBRARY_SUFFIX) \
+ADD_SA_BINARIES/DEFAULT = $(EXPORT_LIB_ARCH_DIR)/libsaproc.$(LIBRARY_SUFFIX) \
                           $(EXPORT_LIB_DIR)/sa-jdi.jar
 
 ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
   ifeq ($(ZIP_DEBUGINFO_FILES),1)
-    ADD_SA_BINARIES/DEFAULT += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.diz
+    ADD_SA_BINARIES/DEFAULT += $(EXPORT_LIB_ARCH_DIR)/libsaproc.diz
   else
-    ADD_SA_BINARIES/DEFAULT += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.debuginfo
+    ADD_SA_BINARIES/DEFAULT += $(EXPORT_LIB_ARCH_DIR)/libsaproc.debuginfo
   endif
 endif
 
--- a/hotspot/make/linux/makefiles/vm.make	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/make/linux/makefiles/vm.make	Thu Apr 16 14:05:48 2015 -0700
@@ -127,7 +127,7 @@
 # By default, link the *.o into the library, not the executable.
 LINK_INTO$(LINK_INTO) = LIBJVM
 
-JDK_LIBDIR = $(JAVA_HOME)/jre/lib/$(LIBARCH)
+JDK_LIBDIR = $(JAVA_HOME)/lib/$(LIBARCH)
 
 #----------------------------------------------------------------------
 # jvm_db & dtrace
--- a/hotspot/make/solaris/makefiles/defs.make	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/make/solaris/makefiles/defs.make	Thu Apr 16 14:05:48 2015 -0700
@@ -224,17 +224,17 @@
 EXPORT_LIST += $(EXPORT_DOCS_DIR)/platform/jvmti/jvmti.html
 
 # client and server subdirectories have symbolic links to ../libjsig.$(LIBRARY_SUFFIX)
-EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.$(LIBRARY_SUFFIX)
+EXPORT_LIST += $(EXPORT_LIB_ARCH_DIR)/libjsig.$(LIBRARY_SUFFIX)
 ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
   ifeq ($(ZIP_DEBUGINFO_FILES),1)
-    EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.diz
+    EXPORT_LIST += $(EXPORT_LIB_ARCH_DIR)/libjsig.diz
   else
-    EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.debuginfo
+    EXPORT_LIST += $(EXPORT_LIB_ARCH_DIR)/libjsig.debuginfo
   endif
 endif
 
-EXPORT_SERVER_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/server
-EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client
+EXPORT_SERVER_DIR = $(EXPORT_LIB_ARCH_DIR)/server
+EXPORT_CLIENT_DIR = $(EXPORT_LIB_ARCH_DIR)/client
 
 ifeq ($(JVM_VARIANT_SERVER),true)
   EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
@@ -295,12 +295,12 @@
   endif
 endif
 
-EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.$(LIBRARY_SUFFIX)
+EXPORT_LIST += $(EXPORT_LIB_ARCH_DIR)/libsaproc.$(LIBRARY_SUFFIX)
 ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
   ifeq ($(ZIP_DEBUGINFO_FILES),1)
-    EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.diz
+    EXPORT_LIST += $(EXPORT_LIB_ARCH_DIR)/libsaproc.diz
   else
-    EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.debuginfo
+    EXPORT_LIST += $(EXPORT_LIB_ARCH_DIR)/libsaproc.debuginfo
   endif
 endif
 EXPORT_LIST += $(EXPORT_LIB_DIR)/sa-jdi.jar
--- a/hotspot/make/solaris/makefiles/dtrace.make	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/make/solaris/makefiles/dtrace.make	Thu Apr 16 14:05:48 2015 -0700
@@ -130,8 +130,9 @@
 $(XLIBJVM_DTRACE): $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE)
 	@echo $(LOG_INFO) Making $@
 	$(QUIETLY) mkdir -p $(XLIBJVM_DIR) ; \
-	$(CC) $(SYMFLAG) $(ARCHFLAG/$(ISA)) -D$(TYPE) -I. \
-		$(SHARED_FLAG) $(LFLAGS_JVM_DTRACE) -o $@ $(DTRACE_SRCDIR)/$(JVM_DTRACE).c -lc -lthread -ldoor
+	$(CC) $(SYMFLAG) $(ARCHFLAG/$(ISA)) -D$(TYPE) -I. $(EXTRA_CFLAGS) \
+	    $(SHARED_FLAG) $(LFLAGS_JVM_DTRACE) -o $@ $(DTRACE_SRCDIR)/$(JVM_DTRACE).c \
+	    $(EXTRA_LDFLAGS) -lc -lthread -ldoor
 ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
 	$(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(XLIBJVM_DTRACE_DEBUGINFO)
 # Do this part in the $(XLIBJVM_DIR) subdir so $(XLIBJVM_DIR) is not
@@ -216,8 +217,9 @@
 
 $(LIBJVM_DTRACE): $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(XLIBJVM_DTRACE) $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE)
 	@echo $(LOG_INFO) Making $@
-	$(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) -D$(TYPE) -I.  \
-		$(SHARED_FLAG) $(LFLAGS_JVM_DTRACE) -o $@ $(DTRACE_SRCDIR)/$(JVM_DTRACE).c -lc -lthread -ldoor
+	$(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) -D$(TYPE) -I. $(EXTRA_CFLAGS) \
+	    $(SHARED_FLAG) $(LFLAGS_JVM_DTRACE) -o $@ $(DTRACE_SRCDIR)/$(JVM_DTRACE).c \
+	    $(EXTRA_LDFLAGS) -lc -lthread -ldoor
 ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
 	$(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBJVM_DTRACE_DEBUGINFO)
 	$(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DTRACE_DEBUGINFO) $@
--- a/hotspot/make/solaris/makefiles/jsig.make	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/make/solaris/makefiles/jsig.make	Thu Apr 16 14:05:48 2015 -0700
@@ -50,7 +50,9 @@
 $(LIBJSIG): $(JSIGSRCDIR)/jsig.c $(LIBJSIG_MAPFILE)
 	@echo $(LOG_INFO) Making signal interposition lib...
 	$(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) $(SHARED_FLAG) $(PICFLAG) \
-                         $(LFLAGS_JSIG) -o $@ $(JSIGSRCDIR)/jsig.c -ldl
+	                 $(EXTRA_CFLAGS) \
+                         $(LFLAGS_JSIG) $(EXTRA_LDFLAGS) \
+	                 -o $@ $(JSIGSRCDIR)/jsig.c -ldl
 ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
 	$(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBJSIG_DEBUGINFO)
 	$(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJSIG_DEBUGINFO) $@
--- a/hotspot/make/solaris/makefiles/product.make	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/make/solaris/makefiles/product.make	Thu Apr 16 14:05:48 2015 -0700
@@ -37,6 +37,11 @@
 OPT_CFLAGS/ciEnv.o = $(OPT_CFLAGS) -xinline=no%__1cFciEnvbFpost_compiled_method_load_event6MpnHnmethod__v_
 endif
 
+# Need extra inlining to get oop_ps_push_contents functions to perform well enough.
+ifndef USE_GCC
+OPT_CFLAGS/psPromotionManager.o = $(OPT_CFLAGS) -W2,-Ainline:inc=1000
+endif
+
 # (OPT_CFLAGS/SLOWER is also available, to alter compilation of buggy files)
 ifeq ("${Platform_compiler}", "sparcWorks")
 
--- a/hotspot/make/solaris/makefiles/saproc.make	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/make/solaris/makefiles/saproc.make	Thu Apr 16 14:05:48 2015 -0700
@@ -89,6 +89,17 @@
 # when actually building on Nevada-B158 or earlier:
 #SOLARIS_11_B159_OR_LATER=-DSOLARIS_11_B159_OR_LATER
 
+$(SADISOBJ): $(SADISSRCFILES)
+	           $(QUIETLY) $(CC)                                     \
+	           $(SYMFLAG) $(ARCHFLAG) $(SHARED_FLAG) $(PICFLAG)     \
+	           -I$(SASRCDIR)                                        \
+	           -I$(GENERATED)                                       \
+	           -I$(BOOT_JAVA_HOME)/include                          \
+	           -I$(BOOT_JAVA_HOME)/include/$(Platform_os_family)    \
+	           $(SOLARIS_11_B159_OR_LATER)                          \
+	           $(EXTRA_CFLAGS)					\
+	           $(SADISSRCFILES)                                     \
+	           -c -o $(SADISOBJ)
 
 $(LIBSAPROC): $(SASRCFILES) $(SADISOBJ) $(SAMAPFILE)
 	$(QUIETLY) if [ "$(BOOT_JAVA_HOME)" = "" ]; then \
@@ -103,23 +114,13 @@
 	           -I$(BOOT_JAVA_HOME)/include                          \
 	           -I$(BOOT_JAVA_HOME)/include/$(Platform_os_family)    \
 	           $(SOLARIS_11_B159_OR_LATER)                          \
+	           $(EXTRA_CXXFLAGS) $(EXTRA_LDFLAGS)			\
+	           $(SADISOBJ)                                          \
 	           $(SASRCFILES)                                        \
-	           $(SADISOBJ)                                          \
 	           $(SA_LFLAGS)                                         \
 	           -o $@                                                \
 	           -ldl -ldemangle -lthread -lc
 
-$(SADISOBJ): $(SADISSRCFILES)
-	           $(QUIETLY) $(CC)                                     \
-	           $(SYMFLAG) $(ARCHFLAG) $(SHARED_FLAG) $(PICFLAG)     \
-	           -I$(SASRCDIR)                                        \
-	           -I$(GENERATED)                                       \
-	           -I$(BOOT_JAVA_HOME)/include                          \
-	           -I$(BOOT_JAVA_HOME)/include/$(Platform_os_family)    \
-	           $(SOLARIS_11_B159_OR_LATER)                          \
-	           $(SADISSRCFILES)                                     \
-	           -c -o $(SADISOBJ)
-
 ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
 	$(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBSAPROC_DEBUGINFO)
 	$(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBSAPROC_DEBUGINFO) $@
--- a/hotspot/make/solaris/makefiles/vm.make	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/make/solaris/makefiles/vm.make	Thu Apr 16 14:05:48 2015 -0700
@@ -148,7 +148,7 @@
 # By default, link the *.o into the library, not the executable.
 LINK_INTO$(LINK_INTO) = LIBJVM
 
-JDK_LIBDIR = $(JAVA_HOME)/jre/lib/$(LIBARCH)
+JDK_LIBDIR = $(JAVA_HOME)/lib/$(LIBARCH)
 
 #----------------------------------------------------------------------
 # jvm_db & dtrace
@@ -288,6 +288,8 @@
 endif
 endif
 
+LFLAGS_VM += $(EXTRA_LDFLAGS)
+
 ifdef USE_GCC
 LINK_VM = $(LINK_LIB.CC)
 else
--- a/hotspot/make/windows/makefiles/defs.make	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/make/windows/makefiles/defs.make	Thu Apr 16 14:05:48 2015 -0700
@@ -249,8 +249,8 @@
   endif
 endif
 
-EXPORT_SERVER_DIR = $(EXPORT_JRE_BIN_DIR)/server
-EXPORT_CLIENT_DIR = $(EXPORT_JRE_BIN_DIR)/client
+EXPORT_SERVER_DIR = $(EXPORT_BIN_DIR)/server
+EXPORT_CLIENT_DIR = $(EXPORT_BIN_DIR)/client
 
 ifeq ($(JVM_VARIANT_SERVER),true)
   EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
@@ -280,13 +280,13 @@
 EXPORT_LIST += $(EXPORT_LIB_DIR)/jvm.lib
 
 ifeq ($(BUILD_WIN_SA), 1)
-  EXPORT_LIST += $(EXPORT_JRE_BIN_DIR)/sawindbg.$(LIBRARY_SUFFIX)
+  EXPORT_LIST += $(EXPORT_BIN_DIR)/sawindbg.$(LIBRARY_SUFFIX)
   ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
     ifeq ($(ZIP_DEBUGINFO_FILES),1)
-      EXPORT_LIST += $(EXPORT_JRE_BIN_DIR)/sawindbg.diz
+      EXPORT_LIST += $(EXPORT_BIN_DIR)/sawindbg.diz
     else
-      EXPORT_LIST += $(EXPORT_JRE_BIN_DIR)/sawindbg.pdb
-      EXPORT_LIST += $(EXPORT_JRE_BIN_DIR)/sawindbg.map
+      EXPORT_LIST += $(EXPORT_BIN_DIR)/sawindbg.pdb
+      EXPORT_LIST += $(EXPORT_BIN_DIR)/sawindbg.map
     endif
   endif
   EXPORT_LIST += $(EXPORT_LIB_DIR)/sa-jdi.jar
--- a/hotspot/make/windows/makefiles/sa.make	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/make/windows/makefiles/sa.make	Thu Apr 16 14:05:48 2015 -0700
@@ -91,6 +91,9 @@
 
 SAWINDBG=sawindbg.dll
 
+# Resource file containing VERSIONINFO
+SA_Res_Files=.\version.sares
+
 checkAndBuildSA:: $(SAWINDBG)
 
 # These do not need to be optimized (don't run a lot of code) and it
@@ -126,10 +129,13 @@
 # Note that we do not keep sawindbj.obj around as it would then
 # get included in the dumpbin command in build_vm_def.sh
 
+# Force resources to be rebuilt every time
+$(SA_Res_Files): FORCE
+
 # In VS2005 or VS2008 the link command creates a .manifest file that we want
 # to insert into the linked artifact so we do not need to track it separately.
 # Use ";#2" for .dll and ";#1" for .exe in the MT command below:
-$(SAWINDBG): $(SASRCFILES)
+$(SAWINDBG): $(SASRCFILES) $(SA_Res_Files)
 	set INCLUDE=$(SA_INCLUDE)$(INCLUDE)
 	$(CXX) @<<
 	  -I"$(BootStrapDir)/include" -I"$(BootStrapDir)/include/win32"
@@ -138,7 +144,7 @@
 	  -out:$*.obj
 <<
 	set LIB=$(SA_LIB)$(LIB)
-	$(LD) -out:$@ -DLL sawindbg.obj sadis.obj dbgeng.lib $(SA_LFLAGS)
+	$(LD) -out:$@ -DLL sawindbg.obj sadis.obj dbgeng.lib $(SA_LFLAGS) $(SA_Res_Files)
 !if "$(MT)" != ""
 	$(MT) -manifest $(@F).manifest -outputresource:$(@F);#2
 !endif
@@ -150,6 +156,9 @@
 !endif
 	-@rm -f $*.obj
 
+{$(COMMONSRC)\os\windows\vm}.rc.sares:
+        @$(RC) $(RC_FLAGS) /D "HS_FNAME=$(SAWINDBG)" /fo"$@" $<
+
 cleanall :
 	rm -rf $(GENERATED)/saclasses
 	rm -rf $(GENERATED)/sa-jdi.jar
--- a/hotspot/src/cpu/aarch64/vm/templateTable_aarch64.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/cpu/aarch64/vm/templateTable_aarch64.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -2138,30 +2138,7 @@
   __ br(Assembler::EQ, resolved);
 
   // resolve first time through
-  address entry;
-  switch (bytecode()) {
-  case Bytecodes::_getstatic:
-  case Bytecodes::_putstatic:
-  case Bytecodes::_getfield:
-  case Bytecodes::_putfield:
-    entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_get_put);
-    break;
-  case Bytecodes::_invokevirtual:
-  case Bytecodes::_invokespecial:
-  case Bytecodes::_invokestatic:
-  case Bytecodes::_invokeinterface:
-    entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invoke);
-    break;
-  case Bytecodes::_invokehandle:
-    entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokehandle);
-    break;
-  case Bytecodes::_invokedynamic:
-    entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic);
-    break;
-  default:
-    fatal(err_msg("unexpected bytecode: %s", Bytecodes::name(bytecode())));
-    break;
-  }
+  address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_from_cache);
   __ mov(temp, (int) bytecode());
   __ call_VM(noreg, entry, temp);
 
--- a/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2012, 2014 SAP AG. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -137,7 +137,6 @@
   void field_offset_at(int n, Register tmp, Register dest, Register base);
   int  field_offset_at(Register object, address bcp, int offset);
   void fast_iaaccess(int n, address bcp);
-  void fast_iagetfield(address bcp);
   void fast_iaputfield(address bcp, bool do_store_check);
 
   void index_check(Register array, Register index, int index_shift, Register tmp, Register res);
--- a/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -437,6 +437,14 @@
 }
 
 void TemplateTable::iload() {
+  iload_internal();
+}
+
+void TemplateTable::nofast_iload() {
+  iload_internal(may_not_rewrite);
+}
+
+void TemplateTable::iload_internal(RewriteControl rc) {
   transition(vtos, itos);
 
   // Get the local value into tos
@@ -445,7 +453,7 @@
 
   // Rewrite iload,iload  pair into fast_iload2
   //         iload,caload pair into fast_icaload
-  if (RewriteFrequentPairs) {
+  if (RewriteFrequentPairs && rc == may_rewrite) {
     Label Lrewrite, Ldone;
     Register Rnext_byte  = R3_ARG1,
              Rrewrite_to = R6_ARG4,
@@ -709,6 +717,14 @@
 }
 
 void TemplateTable::aload_0() {
+  aload_0_internal();
+}
+
+void TemplateTable::nofast_aload_0() {
+  aload_0_internal(may_not_rewrite);
+}
+
+void TemplateTable::aload_0_internal(RewriteControl rc) {
   transition(vtos, atos);
   // According to bytecode histograms, the pairs:
   //
@@ -732,7 +748,7 @@
   // These bytecodes with a small amount of code are most profitable
   // to rewrite.
 
-  if (RewriteFrequentPairs) {
+  if (RewriteFrequentPairs && rc == may_rewrite) {
 
     Label Lrewrite, Ldont_rewrite;
     Register Rnext_byte  = R3_ARG1,
@@ -2144,6 +2160,12 @@
   __ get_cache_and_index_at_bcp(Rcache, 1, index_size);
   Label Lresolved, Ldone;
 
+  Bytecodes::Code code = bytecode();
+  switch (code) {
+  case Bytecodes::_nofast_getfield: code = Bytecodes::_getfield; break;
+  case Bytecodes::_nofast_putfield: code = Bytecodes::_putfield; break;
+  }
+
   assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
   // We are resolved if the indices offset contains the current bytecode.
 #if defined(VM_LITTLE_ENDIAN)
@@ -2152,24 +2174,11 @@
   __ lbz(Rscratch, in_bytes(ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::indices_offset()) + 7 - (byte_no + 1), Rcache);
 #endif
   // Acquire by cmp-br-isync (see below).
-  __ cmpdi(CCR0, Rscratch, (int)bytecode());
+  __ cmpdi(CCR0, Rscratch, (int)code);
   __ beq(CCR0, Lresolved);
 
-  address entry = NULL;
-  switch (bytecode()) {
-    case Bytecodes::_getstatic      : // fall through
-    case Bytecodes::_putstatic      : // fall through
-    case Bytecodes::_getfield       : // fall through
-    case Bytecodes::_putfield       : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_get_put); break;
-    case Bytecodes::_invokevirtual  : // fall through
-    case Bytecodes::_invokespecial  : // fall through
-    case Bytecodes::_invokestatic   : // fall through
-    case Bytecodes::_invokeinterface: entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invoke); break;
-    case Bytecodes::_invokehandle   : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokehandle); break;
-    case Bytecodes::_invokedynamic  : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic); break;
-    default                         : ShouldNotReachHere(); break;
-  }
-  __ li(R4_ARG2, (int)bytecode());
+  address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_from_cache);
+  __ li(R4_ARG2, code);
   __ call_VM(noreg, entry, R4_ARG2, true);
 
   // Update registers with resolved info.
@@ -2350,7 +2359,7 @@
 }
 
 // PPC64: implement volatile loads as fence-store-acquire.
-void TemplateTable::getfield_or_static(int byte_no, bool is_static) {
+void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteControl rc) {
   transition(vtos, vtos);
 
   Label Lacquire, Lisync;
@@ -2366,7 +2375,7 @@
   static address field_branch_table[number_of_states],
                  static_branch_table[number_of_states];
 
-  address* branch_table = is_static ? static_branch_table : field_branch_table;
+  address* branch_table = (is_static || rc == may_not_rewrite) ? static_branch_table : field_branch_table;
 
   // Get field offset.
   resolve_cache_and_index(byte_no, Rcache, Rscratch, sizeof(u2));
@@ -2417,7 +2426,14 @@
 #ifdef ASSERT
   __ bind(LFlagInvalid);
   __ stop("got invalid flag", 0x654);
-
+#endif
+
+  if (!is_static && rc == may_not_rewrite) {
+    // We reuse the code from is_static.  It's jumped to via the table above.
+    return;
+  }
+
+#ifdef ASSERT
   // __ bind(Lvtos);
   address pc_before_fence = __ pc();
   __ fence(); // Volatile entry point (one instruction before non-volatile_entry point).
@@ -2434,7 +2450,9 @@
   branch_table[dtos] = __ pc(); // non-volatile_entry point
   __ lfdx(F15_ftos, Rclass_or_obj, Roffset);
   __ push(dtos);
-  if (!is_static) patch_bytecode(Bytecodes::_fast_dgetfield, Rbc, Rscratch);
+  if (!is_static && rc == may_rewrite) {
+    patch_bytecode(Bytecodes::_fast_dgetfield, Rbc, Rscratch);
+  }
   {
     Label acquire_double;
     __ beq(CCR6, acquire_double); // Volatile?
@@ -2453,7 +2471,9 @@
   branch_table[ftos] = __ pc(); // non-volatile_entry point
   __ lfsx(F15_ftos, Rclass_or_obj, Roffset);
   __ push(ftos);
-  if (!is_static) { patch_bytecode(Bytecodes::_fast_fgetfield, Rbc, Rscratch); }
+  if (!is_static && rc == may_rewrite) {
+    patch_bytecode(Bytecodes::_fast_fgetfield, Rbc, Rscratch);
+  }
   {
     Label acquire_float;
     __ beq(CCR6, acquire_float); // Volatile?
@@ -2472,7 +2492,9 @@
   branch_table[itos] = __ pc(); // non-volatile_entry point
   __ lwax(R17_tos, Rclass_or_obj, Roffset);
   __ push(itos);
-  if (!is_static) patch_bytecode(Bytecodes::_fast_igetfield, Rbc, Rscratch);
+  if (!is_static && rc == may_rewrite) {
+    patch_bytecode(Bytecodes::_fast_igetfield, Rbc, Rscratch);
+  }
   __ beq(CCR6, Lacquire); // Volatile?
   __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode()));
 
@@ -2483,7 +2505,9 @@
   branch_table[ltos] = __ pc(); // non-volatile_entry point
   __ ldx(R17_tos, Rclass_or_obj, Roffset);
   __ push(ltos);
-  if (!is_static) patch_bytecode(Bytecodes::_fast_lgetfield, Rbc, Rscratch);
+  if (!is_static && rc == may_rewrite) {
+    patch_bytecode(Bytecodes::_fast_lgetfield, Rbc, Rscratch);
+  }
   __ beq(CCR6, Lacquire); // Volatile?
   __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode()));
 
@@ -2495,7 +2519,9 @@
   __ lbzx(R17_tos, Rclass_or_obj, Roffset);
   __ extsb(R17_tos, R17_tos);
   __ push(btos);
-  if (!is_static) patch_bytecode(Bytecodes::_fast_bgetfield, Rbc, Rscratch);
+  if (!is_static && rc == may_rewrite) {
+    patch_bytecode(Bytecodes::_fast_bgetfield, Rbc, Rscratch);
+  }
   __ beq(CCR6, Lacquire); // Volatile?
   __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode()));
 
@@ -2506,7 +2532,9 @@
   branch_table[ctos] = __ pc(); // non-volatile_entry point
   __ lhzx(R17_tos, Rclass_or_obj, Roffset);
   __ push(ctos);
-  if (!is_static) patch_bytecode(Bytecodes::_fast_cgetfield, Rbc, Rscratch);
+  if (!is_static && rc == may_rewrite) {
+    patch_bytecode(Bytecodes::_fast_cgetfield, Rbc, Rscratch);
+  }
   __ beq(CCR6, Lacquire); // Volatile?
   __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode()));
 
@@ -2517,7 +2545,9 @@
   branch_table[stos] = __ pc(); // non-volatile_entry point
   __ lhax(R17_tos, Rclass_or_obj, Roffset);
   __ push(stos);
-  if (!is_static) patch_bytecode(Bytecodes::_fast_sgetfield, Rbc, Rscratch);
+  if (!is_static && rc == may_rewrite) {
+    patch_bytecode(Bytecodes::_fast_sgetfield, Rbc, Rscratch);
+  }
   __ beq(CCR6, Lacquire); // Volatile?
   __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode()));
 
@@ -2530,7 +2560,9 @@
   __ verify_oop(R17_tos);
   __ push(atos);
   //__ dcbt(R17_tos); // prefetch
-  if (!is_static) patch_bytecode(Bytecodes::_fast_agetfield, Rbc, Rscratch);
+  if (!is_static && rc == may_rewrite) {
+    patch_bytecode(Bytecodes::_fast_agetfield, Rbc, Rscratch);
+  }
   __ beq(CCR6, Lacquire); // Volatile?
   __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode()));
 
@@ -2553,6 +2585,10 @@
   getfield_or_static(byte_no, false);
 }
 
+void TemplateTable::nofast_getfield(int byte_no) {
+  getfield_or_static(byte_no, false, may_not_rewrite);
+}
+
 void TemplateTable::getstatic(int byte_no) {
   getfield_or_static(byte_no, true);
 }
@@ -2643,7 +2679,7 @@
 }
 
 // PPC64: implement volatile stores as release-store (return bytecode contains an additional release).
-void TemplateTable::putfield_or_static(int byte_no, bool is_static) {
+void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteControl rc) {
   Label Lvolatile;
 
   const Register Rcache        = R5_ARG3,  // Do not use ARG1/2 (causes trouble in jvmti_post_field_mod).
@@ -2657,10 +2693,12 @@
                  Rbc           = Rscratch3;
   const ConditionRegister CR_is_vol = CCR2; // Non-volatile condition register (survives runtime call in do_oop_store).
 
-  static address field_branch_table[number_of_states],
+  static address field_rw_branch_table[number_of_states],
+                 field_norw_branch_table[number_of_states],
                  static_branch_table[number_of_states];
 
-  address* branch_table = is_static ? static_branch_table : field_branch_table;
+  address* branch_table = is_static ? static_branch_table :
+    (rc == may_rewrite ? field_rw_branch_table : field_norw_branch_table);
 
   // Stack (grows up):
   //  value
@@ -2688,7 +2726,9 @@
 
   // Load from branch table and dispatch (volatile case: one instruction ahead).
   __ sldi(Rflags, Rflags, LogBytesPerWord);
-  if (!support_IRIW_for_not_multiple_copy_atomic_cpu) { __ cmpwi(CR_is_vol, Rscratch, 1); } // Volatile?
+  if (!support_IRIW_for_not_multiple_copy_atomic_cpu) {
+    __ cmpwi(CR_is_vol, Rscratch, 1);  // Volatile?
+  }
   __ sldi(Rscratch, Rscratch, exact_log2(BytesPerInstWord)); // Volatile? size of instruction 1 : 0.
   __ ldx(Rbtable, Rbtable, Rflags);
 
@@ -2715,9 +2755,13 @@
   assert(branch_table[dtos] == 0, "can't compute twice");
   branch_table[dtos] = __ pc(); // non-volatile_entry point
   __ pop(dtos);
-  if (!is_static) { pop_and_check_object(Rclass_or_obj); } // Kills R11_scratch1.
+  if (!is_static) {
+    pop_and_check_object(Rclass_or_obj);  // Kills R11_scratch1.
+  }
   __ stfdx(F15_ftos, Rclass_or_obj, Roffset);
-  if (!is_static) { patch_bytecode(Bytecodes::_fast_dputfield, Rbc, Rscratch, true, byte_no); }
+  if (!is_static && rc == may_rewrite) {
+    patch_bytecode(Bytecodes::_fast_dputfield, Rbc, Rscratch, true, byte_no);
+  }
   if (!support_IRIW_for_not_multiple_copy_atomic_cpu) {
     __ beq(CR_is_vol, Lvolatile); // Volatile?
   }
@@ -2731,7 +2775,9 @@
   __ pop(ftos);
   if (!is_static) { pop_and_check_object(Rclass_or_obj); } // Kills R11_scratch1.
   __ stfsx(F15_ftos, Rclass_or_obj, Roffset);
-  if (!is_static) { patch_bytecode(Bytecodes::_fast_fputfield, Rbc, Rscratch, true, byte_no); }
+  if (!is_static && rc == may_rewrite) {
+    patch_bytecode(Bytecodes::_fast_fputfield, Rbc, Rscratch, true, byte_no);
+  }
   if (!support_IRIW_for_not_multiple_copy_atomic_cpu) {
     __ beq(CR_is_vol, Lvolatile); // Volatile?
   }
@@ -2745,7 +2791,9 @@
   __ pop(itos);
   if (!is_static) { pop_and_check_object(Rclass_or_obj); } // Kills R11_scratch1.
   __ stwx(R17_tos, Rclass_or_obj, Roffset);
-  if (!is_static) { patch_bytecode(Bytecodes::_fast_iputfield, Rbc, Rscratch, true, byte_no); }
+  if (!is_static && rc == may_rewrite) {
+    patch_bytecode(Bytecodes::_fast_iputfield, Rbc, Rscratch, true, byte_no);
+  }
   if (!support_IRIW_for_not_multiple_copy_atomic_cpu) {
     __ beq(CR_is_vol, Lvolatile); // Volatile?
   }
@@ -2759,7 +2807,9 @@
   __ pop(ltos);
   if (!is_static) { pop_and_check_object(Rclass_or_obj); } // Kills R11_scratch1.
   __ stdx(R17_tos, Rclass_or_obj, Roffset);
-  if (!is_static) { patch_bytecode(Bytecodes::_fast_lputfield, Rbc, Rscratch, true, byte_no); }
+  if (!is_static && rc == may_rewrite) {
+    patch_bytecode(Bytecodes::_fast_lputfield, Rbc, Rscratch, true, byte_no);
+  }
   if (!support_IRIW_for_not_multiple_copy_atomic_cpu) {
     __ beq(CR_is_vol, Lvolatile); // Volatile?
   }
@@ -2773,7 +2823,9 @@
   __ pop(btos);
   if (!is_static) { pop_and_check_object(Rclass_or_obj); } // Kills R11_scratch1.
   __ stbx(R17_tos, Rclass_or_obj, Roffset);
-  if (!is_static) { patch_bytecode(Bytecodes::_fast_bputfield, Rbc, Rscratch, true, byte_no); }
+  if (!is_static && rc == may_rewrite) {
+    patch_bytecode(Bytecodes::_fast_bputfield, Rbc, Rscratch, true, byte_no);
+  }
   if (!support_IRIW_for_not_multiple_copy_atomic_cpu) {
     __ beq(CR_is_vol, Lvolatile); // Volatile?
   }
@@ -2787,7 +2839,9 @@
   __ pop(ctos);
   if (!is_static) { pop_and_check_object(Rclass_or_obj); } // Kills R11_scratch1..
   __ sthx(R17_tos, Rclass_or_obj, Roffset);
-  if (!is_static) { patch_bytecode(Bytecodes::_fast_cputfield, Rbc, Rscratch, true, byte_no); }
+  if (!is_static && rc == may_rewrite) {
+    patch_bytecode(Bytecodes::_fast_cputfield, Rbc, Rscratch, true, byte_no);
+  }
   if (!support_IRIW_for_not_multiple_copy_atomic_cpu) {
     __ beq(CR_is_vol, Lvolatile); // Volatile?
   }
@@ -2801,7 +2855,9 @@
   __ pop(stos);
   if (!is_static) { pop_and_check_object(Rclass_or_obj); } // Kills R11_scratch1.
   __ sthx(R17_tos, Rclass_or_obj, Roffset);
-  if (!is_static) { patch_bytecode(Bytecodes::_fast_sputfield, Rbc, Rscratch, true, byte_no); }
+  if (!is_static && rc == may_rewrite) {
+    patch_bytecode(Bytecodes::_fast_sputfield, Rbc, Rscratch, true, byte_no);
+  }
   if (!support_IRIW_for_not_multiple_copy_atomic_cpu) {
     __ beq(CR_is_vol, Lvolatile); // Volatile?
   }
@@ -2815,7 +2871,9 @@
   __ pop(atos);
   if (!is_static) { pop_and_check_object(Rclass_or_obj); } // kills R11_scratch1
   do_oop_store(_masm, Rclass_or_obj, Roffset, R17_tos, Rscratch, Rscratch2, Rscratch3, _bs->kind(), false /* precise */, true /* check null */);
-  if (!is_static) { patch_bytecode(Bytecodes::_fast_aputfield, Rbc, Rscratch, true, byte_no); }
+  if (!is_static && rc == may_rewrite) {
+    patch_bytecode(Bytecodes::_fast_aputfield, Rbc, Rscratch, true, byte_no);
+  }
   if (!support_IRIW_for_not_multiple_copy_atomic_cpu) {
     __ beq(CR_is_vol, Lvolatile); // Volatile?
     __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode()));
@@ -2839,6 +2897,10 @@
   putfield_or_static(byte_no, false);
 }
 
+void TemplateTable::nofast_putfield(int byte_no) {
+  putfield_or_static(byte_no, false, may_not_rewrite);
+}
+
 void TemplateTable::putstatic(int byte_no) {
   putfield_or_static(byte_no, true);
 }
@@ -3259,7 +3321,9 @@
   __ testbitdi(CCR0, R0, Rflags, ConstantPoolCacheEntry::is_vfinal_shift);
   __ bfalse(CCR0, LnotFinal);
 
-  patch_bytecode(Bytecodes::_fast_invokevfinal, Rnew_bc, R12_scratch2);
+  if (RewriteBytecodes && !UseSharedSpaces) {
+    patch_bytecode(Bytecodes::_fast_invokevfinal, Rnew_bc, R12_scratch2);
+  }
   invokevfinal_helper(Rvtableindex_or_method, Rflags, R11_scratch1, R12_scratch2);
 
   __ align(32, 12);
--- a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, 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
@@ -203,7 +203,6 @@
   void field_offset_at(int n, Register tmp, Register dest, Register base);
   int  field_offset_at(Register object, address bcp, int offset);
   void fast_iaaccess(int n, address bcp);
-  void fast_iagetfield(address bcp);
   void fast_iaputfield(address bcp, bool do_store_check );
 
   void index_check(Register array, Register index, int index_shift, Register tmp, Register res);
--- a/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -385,7 +385,6 @@
   __ verify_oop(Otos_i);
 }
 
-
 void TemplateTable::ldc2_w() {
   transition(vtos, vtos);
   Label Long, exit;
@@ -430,22 +429,28 @@
   __ bind(exit);
 }
 
-
 void TemplateTable::locals_index(Register reg, int offset) {
   __ ldub( at_bcp(offset), reg );
 }
 
-
 void TemplateTable::locals_index_wide(Register reg) {
   // offset is 2, not 1, because Lbcp points to wide prefix code
   __ get_2_byte_integer_at_bcp(2, G4_scratch, reg, InterpreterMacroAssembler::Unsigned);
 }
 
 void TemplateTable::iload() {
+  iload_internal();
+}
+
+void TemplateTable::nofast_iload() {
+  iload_internal(may_not_rewrite);
+}
+
+void TemplateTable::iload_internal(RewriteControl rc) {
   transition(vtos, itos);
   // Rewrite iload,iload  pair into fast_iload2
   //         iload,caload pair into fast_icaload
-  if (RewriteFrequentPairs) {
+  if (RewriteFrequentPairs && rc == may_rewrite) {
     Label rewrite, done;
 
     // get next byte
@@ -672,8 +677,15 @@
   __ ld_ptr( Llocals, Interpreter::local_offset_in_bytes(n), Otos_i );
 }
 
-
 void TemplateTable::aload_0() {
+  aload_0_internal();
+}
+
+void TemplateTable::nofast_aload_0() {
+  aload_0_internal(may_not_rewrite);
+}
+
+void TemplateTable::aload_0_internal(RewriteControl rc) {
   transition(vtos, atos);
 
   // According to bytecode histograms, the pairs:
@@ -687,7 +699,7 @@
   // bytecode into a pair bytecode; otherwise it rewrites the current
   // bytecode into _fast_aload_0 that doesn't do the pair check anymore.
   //
-  if (RewriteFrequentPairs) {
+  if (RewriteFrequentPairs && rc == may_rewrite) {
     Label rewrite, done;
 
     // get next byte
@@ -731,7 +743,6 @@
   }
 }
 
-
 void TemplateTable::istore() {
   transition(itos, vtos);
   locals_index(G3_scratch);
@@ -2045,30 +2056,21 @@
                                             Register index,
                                             size_t index_size) {
   // Depends on cpCacheOop layout!
+
   Label resolved;
-
-    assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
-    __ get_cache_and_index_and_bytecode_at_bcp(Rcache, index, Lbyte_code, byte_no, 1, index_size);
-    __ cmp(Lbyte_code, (int) bytecode());  // have we resolved this bytecode?
-    __ br(Assembler::equal, false, Assembler::pt, resolved);
-    __ delayed()->set((int)bytecode(), O1);
-
-  address entry;
-  switch (bytecode()) {
-    case Bytecodes::_getstatic      : // fall through
-    case Bytecodes::_putstatic      : // fall through
-    case Bytecodes::_getfield       : // fall through
-    case Bytecodes::_putfield       : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_get_put); break;
-    case Bytecodes::_invokevirtual  : // fall through
-    case Bytecodes::_invokespecial  : // fall through
-    case Bytecodes::_invokestatic   : // fall through
-    case Bytecodes::_invokeinterface: entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invoke);  break;
-    case Bytecodes::_invokehandle   : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokehandle);  break;
-    case Bytecodes::_invokedynamic  : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic);  break;
-    default:
-      fatal(err_msg("unexpected bytecode: %s", Bytecodes::name(bytecode())));
-      break;
+  Bytecodes::Code code = bytecode();
+  switch (code) {
+  case Bytecodes::_nofast_getfield: code = Bytecodes::_getfield; break;
+  case Bytecodes::_nofast_putfield: code = Bytecodes::_putfield; break;
   }
+
+  assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
+  __ get_cache_and_index_and_bytecode_at_bcp(Rcache, index, Lbyte_code, byte_no, 1, index_size);
+  __ cmp(Lbyte_code, code);  // have we resolved this bytecode?
+  __ br(Assembler::equal, false, Assembler::pt, resolved);
+  __ delayed()->set(code, O1);
+
+  address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_from_cache);
   // first time invocation - must resolve first
   __ call_VM(noreg, entry, O1);
   // Update registers with resolved info
@@ -2183,7 +2185,7 @@
   }
 }
 
-void TemplateTable::getfield_or_static(int byte_no, bool is_static) {
+void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteControl rc) {
   transition(vtos, vtos);
 
   Register Rcache = G3_scratch;
@@ -2231,7 +2233,7 @@
   __ load_heap_oop(Rclass, Roffset, Otos_i);
   __ verify_oop(Otos_i);
   __ push(atos);
-  if (!is_static) {
+  if (!is_static && rc == may_rewrite) {
     patch_bytecode(Bytecodes::_fast_agetfield, G3_scratch, G4_scratch);
   }
   __ ba(checkVolatile);
@@ -2246,7 +2248,7 @@
   // itos
   __ ld(Rclass, Roffset, Otos_i);
   __ push(itos);
-  if (!is_static) {
+  if (!is_static && rc == may_rewrite) {
     patch_bytecode(Bytecodes::_fast_igetfield, G3_scratch, G4_scratch);
   }
   __ ba(checkVolatile);
@@ -2262,7 +2264,7 @@
   // load must be atomic
   __ ld_long(Rclass, Roffset, Otos_l);
   __ push(ltos);
-  if (!is_static) {
+  if (!is_static && rc == may_rewrite) {
     patch_bytecode(Bytecodes::_fast_lgetfield, G3_scratch, G4_scratch);
   }
   __ ba(checkVolatile);
@@ -2277,7 +2279,7 @@
   // btos
   __ ldsb(Rclass, Roffset, Otos_i);
   __ push(itos);
-  if (!is_static) {
+  if (!is_static && rc == may_rewrite) {
     patch_bytecode(Bytecodes::_fast_bgetfield, G3_scratch, G4_scratch);
   }
   __ ba(checkVolatile);
@@ -2292,7 +2294,7 @@
   // ctos
   __ lduh(Rclass, Roffset, Otos_i);
   __ push(itos);
-  if (!is_static) {
+  if (!is_static && rc == may_rewrite) {
     patch_bytecode(Bytecodes::_fast_cgetfield, G3_scratch, G4_scratch);
   }
   __ ba(checkVolatile);
@@ -2307,7 +2309,7 @@
   // stos
   __ ldsh(Rclass, Roffset, Otos_i);
   __ push(itos);
-  if (!is_static) {
+  if (!is_static && rc == may_rewrite) {
     patch_bytecode(Bytecodes::_fast_sgetfield, G3_scratch, G4_scratch);
   }
   __ ba(checkVolatile);
@@ -2323,7 +2325,7 @@
   // ftos
   __ ldf(FloatRegisterImpl::S, Rclass, Roffset, Ftos_f);
   __ push(ftos);
-  if (!is_static) {
+  if (!is_static && rc == may_rewrite) {
     patch_bytecode(Bytecodes::_fast_fgetfield, G3_scratch, G4_scratch);
   }
   __ ba(checkVolatile);
@@ -2335,7 +2337,7 @@
   // dtos
   __ ldf(FloatRegisterImpl::D, Rclass, Roffset, Ftos_d);
   __ push(dtos);
-  if (!is_static) {
+  if (!is_static && rc == may_rewrite) {
     patch_bytecode(Bytecodes::_fast_dgetfield, G3_scratch, G4_scratch);
   }
 
@@ -2350,16 +2352,18 @@
   __ bind(exit);
 }
 
-
 void TemplateTable::getfield(int byte_no) {
   getfield_or_static(byte_no, false);
 }
 
+void TemplateTable::nofast_getfield(int byte_no) {
+  getfield_or_static(byte_no, false, may_not_rewrite);
+}
+
 void TemplateTable::getstatic(int byte_no) {
   getfield_or_static(byte_no, true);
 }
 
-
 void TemplateTable::fast_accessfield(TosState state) {
   transition(atos, state);
   Register Rcache  = G3_scratch;
@@ -2544,7 +2548,7 @@
   __ verify_oop(r);
 }
 
-void TemplateTable::putfield_or_static(int byte_no, bool is_static) {
+void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteControl rc) {
   transition(vtos, vtos);
   Register Rcache = G3_scratch;
   Register index  = G4_scratch;
@@ -2620,7 +2624,7 @@
       __ pop_i();
       pop_and_check_object(Rclass);
       __ st(Otos_i, Rclass, Roffset);
-      patch_bytecode(Bytecodes::_fast_iputfield, G3_scratch, G4_scratch, true, byte_no);
+      if (rc == may_rewrite) patch_bytecode(Bytecodes::_fast_iputfield, G3_scratch, G4_scratch, true, byte_no);
       __ ba(checkVolatile);
       __ delayed()->tst(Lscratch);
     }
@@ -2636,7 +2640,7 @@
       pop_and_check_object(Rclass);
       __ verify_oop(Otos_i);
       do_oop_store(_masm, Rclass, Roffset, 0, Otos_i, G1_scratch, _bs->kind(), false);
-      patch_bytecode(Bytecodes::_fast_aputfield, G3_scratch, G4_scratch, true, byte_no);
+      if (rc == may_rewrite) patch_bytecode(Bytecodes::_fast_aputfield, G3_scratch, G4_scratch, true, byte_no);
       __ ba(checkVolatile);
       __ delayed()->tst(Lscratch);
     }
@@ -2653,7 +2657,7 @@
     __ pop_i();
     if (!is_static) pop_and_check_object(Rclass);
     __ stb(Otos_i, Rclass, Roffset);
-    if (!is_static) {
+    if (!is_static && rc == may_rewrite) {
       patch_bytecode(Bytecodes::_fast_bputfield, G3_scratch, G4_scratch, true, byte_no);
     }
     __ ba(checkVolatile);
@@ -2670,7 +2674,7 @@
     __ pop_l();
     if (!is_static) pop_and_check_object(Rclass);
     __ st_long(Otos_l, Rclass, Roffset);
-    if (!is_static) {
+    if (!is_static && rc == may_rewrite) {
       patch_bytecode(Bytecodes::_fast_lputfield, G3_scratch, G4_scratch, true, byte_no);
     }
     __ ba(checkVolatile);
@@ -2687,7 +2691,7 @@
     __ pop_i();
     if (!is_static) pop_and_check_object(Rclass);
     __ sth(Otos_i, Rclass, Roffset);
-    if (!is_static) {
+    if (!is_static && rc == may_rewrite) {
       patch_bytecode(Bytecodes::_fast_cputfield, G3_scratch, G4_scratch, true, byte_no);
     }
     __ ba(checkVolatile);
@@ -2704,7 +2708,7 @@
     __ pop_i();
     if (!is_static) pop_and_check_object(Rclass);
     __ sth(Otos_i, Rclass, Roffset);
-    if (!is_static) {
+    if (!is_static && rc == may_rewrite) {
       patch_bytecode(Bytecodes::_fast_sputfield, G3_scratch, G4_scratch, true, byte_no);
     }
     __ ba(checkVolatile);
@@ -2721,7 +2725,7 @@
     __ pop_f();
     if (!is_static) pop_and_check_object(Rclass);
     __ stf(FloatRegisterImpl::S, Ftos_f, Rclass, Roffset);
-    if (!is_static) {
+    if (!is_static && rc == may_rewrite) {
       patch_bytecode(Bytecodes::_fast_fputfield, G3_scratch, G4_scratch, true, byte_no);
     }
     __ ba(checkVolatile);
@@ -2735,7 +2739,7 @@
     __ pop_d();
     if (!is_static) pop_and_check_object(Rclass);
     __ stf(FloatRegisterImpl::D, Ftos_d, Rclass, Roffset);
-    if (!is_static) {
+    if (!is_static && rc == may_rewrite) {
       patch_bytecode(Bytecodes::_fast_dputfield, G3_scratch, G4_scratch, true, byte_no);
     }
   }
@@ -2809,16 +2813,18 @@
   }
 }
 
-
 void TemplateTable::putfield(int byte_no) {
   putfield_or_static(byte_no, false);
 }
 
+void TemplateTable::nofast_putfield(int byte_no) {
+  putfield_or_static(byte_no, false, may_not_rewrite);
+}
+
 void TemplateTable::putstatic(int byte_no) {
   putfield_or_static(byte_no, true);
 }
 
-
 void TemplateTable::fast_xaccess(TosState state) {
   transition(vtos, state);
   Register Rcache = G3_scratch;
@@ -2971,7 +2977,9 @@
   __ br(Assembler::zero, false, Assembler::pt, notFinal);
   __ delayed()->and3(Rret, 0xFF, G4_scratch);      // gets number of parameters
 
-  patch_bytecode(Bytecodes::_fast_invokevfinal, Rscratch, Rtemp);
+  if (RewriteBytecodes && !UseSharedSpaces) {
+    patch_bytecode(Bytecodes::_fast_invokevfinal, Rscratch, Rtemp);
+  }
 
   invokevfinal_helper(Rscratch, Rret);
 
--- a/hotspot/src/cpu/x86/vm/templateTable_x86.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -543,8 +543,16 @@
 }
 
 void TemplateTable::iload() {
+  iload_internal();
+}
+
+void TemplateTable::nofast_iload() {
+  iload_internal(may_not_rewrite);
+}
+
+void TemplateTable::iload_internal(RewriteControl rc) {
   transition(vtos, itos);
-  if (RewriteFrequentPairs) {
+  if (RewriteFrequentPairs && rc == may_rewrite) {
     Label rewrite, done;
     const Register bc = LP64_ONLY(c_rarg3) NOT_LP64(rcx);
     LP64_ONLY(assert(rbx != bc, "register damaged"));
@@ -815,6 +823,14 @@
 }
 
 void TemplateTable::aload_0() {
+  aload_0_internal();
+}
+
+void TemplateTable::nofast_aload_0() {
+  aload_0_internal(may_not_rewrite);
+}
+
+void TemplateTable::aload_0_internal(RewriteControl rc) {
   transition(vtos, atos);
   // According to bytecode histograms, the pairs:
   //
@@ -837,7 +853,7 @@
   //   aload_0, iload_1
   // These bytecodes with a small amount of code are most profitable
   // to rewrite
-  if (RewriteFrequentPairs) {
+  if (RewriteFrequentPairs && rc == may_rewrite) {
     Label rewrite, done;
 
     const Register bc = LP64_ONLY(c_rarg3) NOT_LP64(rcx);
@@ -2491,29 +2507,21 @@
   assert_different_registers(Rcache, index, temp);
 
   Label resolved;
-    assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
-    __ get_cache_and_index_and_bytecode_at_bcp(Rcache, index, temp, byte_no, 1, index_size);
-    __ cmpl(temp, (int) bytecode());  // have we resolved this bytecode?
-    __ jcc(Assembler::equal, resolved);
+
+  Bytecodes::Code code = bytecode();
+  switch (code) {
+  case Bytecodes::_nofast_getfield: code = Bytecodes::_getfield; break;
+  case Bytecodes::_nofast_putfield: code = Bytecodes::_putfield; break;
+  }
+
+  assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
+  __ get_cache_and_index_and_bytecode_at_bcp(Rcache, index, temp, byte_no, 1, index_size);
+  __ cmpl(temp, code);  // have we resolved this bytecode?
+  __ jcc(Assembler::equal, resolved);
 
   // resolve first time through
-  address entry;
-  switch (bytecode()) {
-    case Bytecodes::_getstatic      : // fall through
-    case Bytecodes::_putstatic      : // fall through
-    case Bytecodes::_getfield       : // fall through
-    case Bytecodes::_putfield       : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_get_put);        break;
-    case Bytecodes::_invokevirtual  : // fall through
-    case Bytecodes::_invokespecial  : // fall through
-    case Bytecodes::_invokestatic   : // fall through
-    case Bytecodes::_invokeinterface: entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invoke);         break;
-    case Bytecodes::_invokehandle   : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokehandle);   break;
-    case Bytecodes::_invokedynamic  : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic);  break;
-    default:
-      fatal(err_msg("unexpected bytecode: %s", Bytecodes::name(bytecode())));
-      break;
-  }
-  __ movl(temp, (int)bytecode());
+  address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_from_cache);
+  __ movl(temp, code);
   __ call_VM(noreg, entry, temp);
   // Update registers with resolved info
   __ get_cache_and_index_at_bcp(Rcache, index, 1, index_size);
@@ -2628,7 +2636,7 @@
   __ verify_oop(r);
 }
 
-void TemplateTable::getfield_or_static(int byte_no, bool is_static) {
+void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteControl rc) {
   transition(vtos, vtos);
 
   const Register cache = rcx;
@@ -2660,7 +2668,7 @@
   __ load_signed_byte(rax, field);
   __ push(btos);
   // Rewrite bytecode to be faster
-  if (!is_static) {
+  if (!is_static && rc == may_rewrite) {
     patch_bytecode(Bytecodes::_fast_bgetfield, bc, rbx);
   }
   __ jmp(Done);
@@ -2671,7 +2679,7 @@
   // atos
   __ load_heap_oop(rax, field);
   __ push(atos);
-  if (!is_static) {
+  if (!is_static && rc == may_rewrite) {
     patch_bytecode(Bytecodes::_fast_agetfield, bc, rbx);
   }
   __ jmp(Done);
@@ -2683,7 +2691,7 @@
   __ movl(rax, field);
   __ push(itos);
   // Rewrite bytecode to be faster
-  if (!is_static) {
+  if (!is_static && rc == may_rewrite) {
     patch_bytecode(Bytecodes::_fast_igetfield, bc, rbx);
   }
   __ jmp(Done);
@@ -2695,7 +2703,7 @@
   __ load_unsigned_short(rax, field);
   __ push(ctos);
   // Rewrite bytecode to be faster
-  if (!is_static) {
+  if (!is_static && rc == may_rewrite) {
     patch_bytecode(Bytecodes::_fast_cgetfield, bc, rbx);
   }
   __ jmp(Done);
@@ -2707,7 +2715,7 @@
   __ load_signed_short(rax, field);
   __ push(stos);
   // Rewrite bytecode to be faster
-  if (!is_static) {
+  if (!is_static && rc == may_rewrite) {
     patch_bytecode(Bytecodes::_fast_sgetfield, bc, rbx);
   }
   __ jmp(Done);
@@ -2731,7 +2739,7 @@
 
   __ push(ltos);
   // Rewrite bytecode to be faster
-  LP64_ONLY(if (!is_static) patch_bytecode(Bytecodes::_fast_lgetfield, bc, rbx));
+  LP64_ONLY(if (!is_static && rc == may_rewrite) patch_bytecode(Bytecodes::_fast_lgetfield, bc, rbx));
   __ jmp(Done);
 
   __ bind(notLong);
@@ -2743,7 +2751,7 @@
   NOT_LP64(__ fld_s(field));
   __ push(ftos);
   // Rewrite bytecode to be faster
-  if (!is_static) {
+  if (!is_static && rc == may_rewrite) {
     patch_bytecode(Bytecodes::_fast_fgetfield, bc, rbx);
   }
   __ jmp(Done);
@@ -2758,7 +2766,7 @@
   NOT_LP64(__ fld_d(field));
   __ push(dtos);
   // Rewrite bytecode to be faster
-  if (!is_static) {
+  if (!is_static && rc == may_rewrite) {
     patch_bytecode(Bytecodes::_fast_dgetfield, bc, rbx);
   }
 #ifdef ASSERT
@@ -2779,6 +2787,10 @@
   getfield_or_static(byte_no, false);
 }
 
+void TemplateTable::nofast_getfield(int byte_no) {
+  getfield_or_static(byte_no, false, may_not_rewrite);
+}
+
 void TemplateTable::getstatic(int byte_no) {
   getfield_or_static(byte_no, true);
 }
@@ -2870,7 +2882,7 @@
   }
 }
 
-void TemplateTable::putfield_or_static(int byte_no, bool is_static) {
+void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteControl rc) {
   transition(vtos, vtos);
 
   const Register cache = rcx;
@@ -2911,7 +2923,7 @@
     __ pop(btos);
     if (!is_static) pop_and_check_object(obj);
     __ movb(field, rax);
-    if (!is_static) {
+    if (!is_static && rc == may_rewrite) {
       patch_bytecode(Bytecodes::_fast_bputfield, bc, rbx, true, byte_no);
     }
     __ jmp(Done);
@@ -2927,7 +2939,7 @@
     if (!is_static) pop_and_check_object(obj);
     // Store into the field
     do_oop_store(_masm, field, rax, _bs->kind(), false);
-    if (!is_static) {
+    if (!is_static && rc == may_rewrite) {
       patch_bytecode(Bytecodes::_fast_aputfield, bc, rbx, true, byte_no);
     }
     __ jmp(Done);
@@ -2942,7 +2954,7 @@
     __ pop(itos);
     if (!is_static) pop_and_check_object(obj);
     __ movl(field, rax);
-    if (!is_static) {
+    if (!is_static && rc == may_rewrite) {
       patch_bytecode(Bytecodes::_fast_iputfield, bc, rbx, true, byte_no);
     }
     __ jmp(Done);
@@ -2957,7 +2969,7 @@
     __ pop(ctos);
     if (!is_static) pop_and_check_object(obj);
     __ movw(field, rax);
-    if (!is_static) {
+    if (!is_static && rc == may_rewrite) {
       patch_bytecode(Bytecodes::_fast_cputfield, bc, rbx, true, byte_no);
     }
     __ jmp(Done);
@@ -2972,7 +2984,7 @@
     __ pop(stos);
     if (!is_static) pop_and_check_object(obj);
     __ movw(field, rax);
-    if (!is_static) {
+    if (!is_static && rc == may_rewrite) {
       patch_bytecode(Bytecodes::_fast_sputfield, bc, rbx, true, byte_no);
     }
     __ jmp(Done);
@@ -2988,7 +3000,7 @@
     __ pop(ltos);
     if (!is_static) pop_and_check_object(obj);
     __ movq(field, rax);
-    if (!is_static) {
+    if (!is_static && rc == may_rewrite) {
       patch_bytecode(Bytecodes::_fast_lputfield, bc, rbx, true, byte_no);
     }
     __ jmp(Done);
@@ -3035,7 +3047,7 @@
     if (!is_static) pop_and_check_object(obj);
     NOT_LP64( __ fstp_s(field);)
     LP64_ONLY( __ movflt(field, xmm0);)
-    if (!is_static) {
+    if (!is_static && rc == may_rewrite) {
       patch_bytecode(Bytecodes::_fast_fputfield, bc, rbx, true, byte_no);
     }
     __ jmp(Done);
@@ -3053,7 +3065,7 @@
     if (!is_static) pop_and_check_object(obj);
     NOT_LP64( __ fstp_d(field);)
     LP64_ONLY( __ movdbl(field, xmm0);)
-    if (!is_static) {
+    if (!is_static && rc == may_rewrite) {
       patch_bytecode(Bytecodes::_fast_dputfield, bc, rbx, true, byte_no);
     }
   }
@@ -3079,6 +3091,10 @@
   putfield_or_static(byte_no, false);
 }
 
+void TemplateTable::nofast_putfield(int byte_no) {
+  putfield_or_static(byte_no, false, may_not_rewrite);
+}
+
 void TemplateTable::putstatic(int byte_no) {
   putfield_or_static(byte_no, true);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 1998, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef CPU_X86_VM_TEMPLATETABLE_X86_HPP
+#define CPU_X86_VM_TEMPLATETABLE_X86_HPP
+
+  static void prepare_invoke(int byte_no,
+                             Register method,         // linked method (or i-klass)
+                             Register index = noreg,  // itable index, MethodType, etc.
+                             Register recv  = noreg,  // if caller wants to see it
+                             Register flags = noreg   // if caller wants to test it
+                             );
+  static void invokevirtual_helper(Register index, Register recv,
+                                   Register flags);
+  static void volatile_barrier(Assembler::Membar_mask_bits order_constraint);
+
+  // Helpers
+  static void index_check(Register array, Register index);
+  static void index_check_without_pop(Register array, Register index);
+
+#endif // CPU_X86_VM_TEMPLATETABLE_X86_HPP
--- a/hotspot/src/cpu/x86/vm/templateTable_x86_32.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 1998, 2012, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef CPU_X86_VM_TEMPLATETABLE_X86_32_HPP
-#define CPU_X86_VM_TEMPLATETABLE_X86_32_HPP
-
-  static void prepare_invoke(int byte_no,
-                             Register method,         // linked method (or i-klass)
-                             Register index = noreg,  // itable index, MethodType, etc.
-                             Register recv  = noreg,  // if caller wants to see it
-                             Register flags = noreg   // if caller wants to test it
-                             );
-  static void invokevirtual_helper(Register index, Register recv,
-                                   Register flags);
-  static void volatile_barrier(Assembler::Membar_mask_bits order_constraint);
-
-  // Helpers
-  static void index_check(Register array, Register index);
-  static void index_check_without_pop(Register array, Register index);
-
-#endif // CPU_X86_VM_TEMPLATETABLE_X86_32_HPP
--- a/hotspot/src/cpu/x86/vm/templateTable_x86_64.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2003, 2012, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef CPU_X86_VM_TEMPLATETABLE_X86_64_HPP
-#define CPU_X86_VM_TEMPLATETABLE_X86_64_HPP
-
-  static void prepare_invoke(int byte_no,
-                             Register method,         // linked method (or i-klass)
-                             Register index = noreg,  // itable index, MethodType, etc.
-                             Register recv  = noreg,  // if caller wants to see it
-                             Register flags = noreg   // if caller wants to test it
-                             );
-  static void invokevirtual_helper(Register index, Register recv,
-                                   Register flags);
-  static void volatile_barrier(Assembler::Membar_mask_bits order_constraint);
-
-  // Helpers
-  static void index_check(Register array, Register index);
-  static void index_check_without_pop(Register array, Register index);
-
-#endif // CPU_X86_VM_TEMPLATETABLE_X86_64_HPP
--- a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -379,15 +379,6 @@
   };
 };
 
-
-void VM_Version::get_cpu_info_wrapper() {
-  get_cpu_info_stub(&_cpuid_info);
-}
-
-#ifndef CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED
-  #define CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED(f) f()
-#endif
-
 void VM_Version::get_processor_features() {
 
   _cpu = 4; // 486 by default
@@ -401,9 +392,7 @@
   if (!Use486InstrsOnly) {
     // Get raw processor info
 
-    // Some platforms (like Win*) need a wrapper around here
-    // in order to properly handle SEGV for YMM registers test.
-    CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED(get_cpu_info_wrapper);
+    get_cpu_info_stub(&_cpuid_info);
 
     assert_is_initialized();
     _cpu = extended_cpu_family();
--- a/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -814,9 +814,9 @@
   }
 #endif // INCLUDE_ALL_GCS
 
-  // If G1 is not enabled then attempt to go through the accessor entry point
-  // Reference.get is an accessor
-  return generate_accessor_entry();
+  // If G1 is not enabled then attempt to go through the normal entry point
+  // Reference.get could be instrumented by jvmti
+  return generate_normal_entry(false);
 }
 
 address InterpreterGenerator::generate_native_entry(bool synchronized) {
--- a/hotspot/src/cpu/zero/vm/frame_zero.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/cpu/zero/vm/frame_zero.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -213,7 +213,7 @@
     valuebuf[buflen - 1] = '\0';
 
     // Print the result
-    st->print_cr(" " PTR_FORMAT ": %-21s = %s", addr, fieldbuf, valuebuf);
+    st->print_cr(" " PTR_FORMAT ": %-21s = %s", p2i(addr), fieldbuf, valuebuf);
   }
 }
 
--- a/hotspot/src/cpu/zero/vm/methodHandles_zero.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/cpu/zero/vm/methodHandles_zero.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2009, 2010, 2011 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -144,6 +144,7 @@
   oop recv = STACK_OBJECT(-numArgs);
   Klass* clazz = recv->klass();
   Klass* klass_part = InstanceKlass::cast(clazz);
+  ResourceMark rm(THREAD);
   klassVtable* vtable = klass_part->vtable();
   Method* vmtarget = vtable->method_at(vmindex);
 
--- a/hotspot/src/cpu/zero/vm/stubGenerator_zero.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/cpu/zero/vm/stubGenerator_zero.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2007, 2008, 2010 Red Hat, Inc.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2007, 2008, 2010, 2015 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -45,6 +45,18 @@
 #include "opto/runtime.hpp"
 #endif
 
+// For SafeFetch we need POSIX tls and setjmp
+#include <setjmp.h>
+#include <pthread.h>
+static pthread_key_t g_jmpbuf_key;
+
+// return the currently active jump buffer for this thread
+//  - if there is any, NULL otherwise. Called from
+//    zero signal handlers.
+extern sigjmp_buf* get_jmp_buf_for_continuation() {
+  return (sigjmp_buf*) pthread_getspecific(g_jmpbuf_key);
+}
+
 // Declaration and definition of StubGenerator (no .hpp file).
 // For a more detailed description of the stub routine structure
 // see the comment in stubRoutines.hpp
@@ -177,18 +189,56 @@
   }
 
   static int SafeFetch32(int *adr, int errValue) {
+
+    // set up a jump buffer; anchor the pointer to the jump buffer in tls; then
+    // do the pointer access. If pointer is invalid, we crash; in signal
+    // handler, we retrieve pointer to jmp buffer from tls, and jump back.
+    //
+    // Note: the jump buffer itself - which can get pretty large depending on
+    // the architecture - lives on the stack and that is fine, because we will
+    // not rewind the stack: either we crash, in which case signal handler
+    // frame is below us, or we don't crash, in which case it does not matter.
+    sigjmp_buf jb;
+    if (sigsetjmp(jb, 1)) {
+      // we crashed. clean up tls and return default value.
+      pthread_setspecific(g_jmpbuf_key, NULL);
+      return errValue;
+    } else {
+      // preparation phase
+      pthread_setspecific(g_jmpbuf_key, &jb);
+    }
+
     int value = errValue;
     value = *adr;
+
+    // all went well. clean tls.
+    pthread_setspecific(g_jmpbuf_key, NULL);
+
     return value;
   }
 
   static intptr_t SafeFetchN(intptr_t *adr, intptr_t errValue) {
+
+    sigjmp_buf jb;
+    if (sigsetjmp(jb, 1)) {
+      // we crashed. clean up tls and return default value.
+      pthread_setspecific(g_jmpbuf_key, NULL);
+      return errValue;
+    } else {
+      // preparation phase
+      pthread_setspecific(g_jmpbuf_key, &jb);
+    }
+
     intptr_t value = errValue;
     value = *adr;
+
+    // all went well. clean tls.
+    pthread_setspecific(g_jmpbuf_key, NULL);
+
     return value;
+
   }
 
-
   void generate_initial() {
     // Generates all stubs and initializes the entry points
 
@@ -241,6 +291,7 @@
     generate_arraycopy_stubs();
 
     // Safefetch stubs.
+    pthread_key_create(&g_jmpbuf_key, NULL);
     StubRoutines::_safefetch32_entry = CAST_FROM_FN_PTR(address, StubGenerator::SafeFetch32);
     StubRoutines::_safefetch32_fault_pc = NULL;
     StubRoutines::_safefetch32_continuation_pc = NULL;
--- a/hotspot/src/os/aix/vm/os_aix.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/os/aix/vm/os_aix.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -239,7 +239,6 @@
 static pid_t    _initial_pid       = 0;
 static int      SR_signum          = SIGUSR2; // Signal used to suspend/resume a thread (must be > SIGSEGV, see 4355769)
 static sigset_t SR_sigset;
-static pthread_mutex_t dl_mutex;              // Used to protect dlsym() calls.
 
 // This describes the state of multipage support of the underlying
 // OS. Note that this is of no interest to the outsize world and
@@ -315,19 +314,6 @@
   return Aix::physical_memory();
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// environment support
-
-bool os::getenv(const char* name, char* buf, int len) {
-  const char* val = ::getenv(name);
-  if (val != NULL && strlen(val) < (size_t)len) {
-    strcpy(buf, val);
-    return true;
-  }
-  if (len > 0) buf[0] = 0;  // return a null string
-  return false;
-}
-
 // Return true if user is running as root.
 
 bool os::have_special_privileges() {
@@ -1549,13 +1535,8 @@
   return NULL;
 }
 
-// Glibc-2.0 libdl is not MT safe. If you are building with any glibc,
-// chances are you might want to run the generated bits against glibc-2.0
-// libdl.so, so always use locking for any version of glibc.
 void* os::dll_lookup(void* handle, const char* name) {
-  pthread_mutex_lock(&dl_mutex);
   void* res = dlsym(handle, name);
-  pthread_mutex_unlock(&dl_mutex);
   return res;
 }
 
@@ -3534,7 +3515,6 @@
   Aix::_main_thread = pthread_self();
 
   initial_time_count = os::elapsed_counter();
-  pthread_mutex_init(&dl_mutex, NULL);
 
   // If the pagesize of the VM is greater than 8K determine the appropriate
   // number of initial guard pages. The user can change this with the
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/os/bsd/vm/os_bsd.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -190,20 +190,6 @@
   return Bsd::physical_memory();
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// environment support
-
-bool os::getenv(const char* name, char* buf, int len) {
-  const char* val = ::getenv(name);
-  if (val != NULL && strlen(val) < (size_t)len) {
-    strcpy(buf, val);
-    return true;
-  }
-  if (len > 0) buf[0] = 0;  // return a null string
-  return false;
-}
-
-
 // Return true if user is running as root.
 
 bool os::have_special_privileges() {
--- a/hotspot/src/os/linux/vm/os_linux.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/os/linux/vm/os_linux.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -158,9 +158,6 @@
 static int SR_signum = SIGUSR2;
 sigset_t SR_sigset;
 
-// Used to protect dlsym() calls
-static pthread_mutex_t dl_mutex;
-
 // Declarations
 static void unpackTime(timespec* absTime, bool isAbsolute, jlong time);
 
@@ -184,20 +181,6 @@
   return Linux::physical_memory();
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// environment support
-
-bool os::getenv(const char* name, char* buf, int len) {
-  const char* val = ::getenv(name);
-  if (val != NULL && strlen(val) < (size_t)len) {
-    strcpy(buf, val);
-    return true;
-  }
-  if (len > 0) buf[0] = 0;  // return a null string
-  return false;
-}
-
-
 // Return true if user is running as root.
 
 bool os::have_special_privileges() {
@@ -2039,14 +2022,8 @@
   return result;
 }
 
-// glibc-2.0 libdl is not MT safe.  If you are building with any glibc,
-// chances are you might want to run the generated bits against glibc-2.0
-// libdl.so, so always use locking for any version of glibc.
-//
 void* os::dll_lookup(void* handle, const char* name) {
-  pthread_mutex_lock(&dl_mutex);
   void* res = dlsym(handle, name);
-  pthread_mutex_unlock(&dl_mutex);
   return res;
 }
 
@@ -4655,8 +4632,6 @@
   }
   // else it defaults to CLOCK_REALTIME
 
-  pthread_mutex_init(&dl_mutex, NULL);
-
   // If the pagesize of the VM is greater than 8K determine the appropriate
   // number of initial guard pages.  The user can change this with the
   // command line arguments, if needed.
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -555,17 +555,6 @@
   return (bind_result == 0);
 }
 
-bool os::getenv(const char* name, char* buffer, int len) {
-  char* val = ::getenv(name);
-  if (val == NULL || strlen(val) + 1 > len) {
-    if (len > 0) buffer[0] = 0; // return a null string
-    return false;
-  }
-  strcpy(buffer, val);
-  return true;
-}
-
-
 // Return true if user is running as root.
 
 bool os::have_special_privileges() {
--- a/hotspot/src/os/windows/vm/os_windows.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/os/windows/vm/os_windows.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -153,11 +153,6 @@
 
 // Implementation of os
 
-bool os::getenv(const char* name, char* buffer, int len) {
-  int result = GetEnvironmentVariable(name, buffer, len);
-  return result > 0 && result < len;
-}
-
 bool os::unsetenv(const char* name) {
   assert(name != NULL, "Null pointer");
   return (SetEnvironmentVariable(name, NULL) == TRUE);
@@ -188,9 +183,13 @@
     char *dll_path;
     char *pslash;
     char *bin = "\\bin";
-    char home_dir[MAX_PATH];
-
-    if (!getenv("_ALT_JAVA_HOME_DIR", home_dir, MAX_PATH)) {
+    char home_dir[MAX_PATH + 1];
+    char *alt_home_dir = ::getenv("_ALT_JAVA_HOME_DIR");
+
+    if (alt_home_dir != NULL)  {
+      strncpy(home_dir, alt_home_dir, MAX_PATH + 1);
+      home_dir[MAX_PATH] = '\0';
+    } else {
       os::jvm_path(home_dir, sizeof(home_dir));
       // Found the full path to jvm.dll.
       // Now cut the path to <java_home>/jre if we can.
@@ -2696,17 +2695,6 @@
 }
 #endif
 
-void os::win32::call_test_func_with_wrapper(void (*funcPtr)(void)) {
-  // Install a win32 structured exception handler around the test
-  // function call so the VM can generate an error dump if needed.
-  __try {
-    (*funcPtr)();
-  } __except(topLevelExceptionFilter(
-                                     (_EXCEPTION_POINTERS*)_exception_info())) {
-    // Nothing to do.
-  }
-}
-
 // Virtual Memory
 
 int os::vm_page_size() { return os::win32::vm_page_size(); }
@@ -5930,4 +5918,3 @@
   UseNUMAInterleaving = old_use_numa_interleaving;
 }
 #endif // PRODUCT
-
--- a/hotspot/src/os/windows/vm/os_windows.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/os/windows/vm/os_windows.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, 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
@@ -115,8 +115,6 @@
   static address fast_jni_accessor_wrapper(BasicType);
 #endif
 
-  static void call_test_func_with_wrapper(void (*funcPtr)(void));
-
   // filter function to ignore faults on serializations page
   static LONG WINAPI serialize_fault_filter(struct _EXCEPTION_POINTERS* e);
 };
--- a/hotspot/src/os/windows/vm/os_windows.inline.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/os/windows/vm/os_windows.inline.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, 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
@@ -104,7 +104,4 @@
   win32::exit_process_or_thread(win32::EPT_PROCESS, num);
 }
 
-#define CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED(f) \
-        os::win32::call_test_func_with_wrapper(f)
-
 #endif // OS_WINDOWS_VM_OS_WINDOWS_INLINE_HPP
--- a/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -59,6 +59,10 @@
 #include "utilities/events.hpp"
 #include "utilities/vmError.hpp"
 
+// See stubGenerator_zero.cpp
+#include <setjmp.h>
+extern sigjmp_buf* get_jmp_buf_for_continuation();
+
 address os::current_stack_pointer() {
   address dummy = (address) &dummy;
   return dummy;
@@ -134,6 +138,14 @@
 
   SignalHandlerMark shm(t);
 
+  // handle SafeFetch faults
+  if (sig == SIGSEGV || sig == SIGBUS) {
+    sigjmp_buf* const pjb = get_jmp_buf_for_continuation();
+    if (pjb) {
+      siglongjmp(*pjb, 1);
+    }
+  }
+
   // Note: it's not uncommon that JNI code uses signal/sigset to
   // install then restore certain signal handler (e.g. to temporarily
   // block SIGPIPE, or have a SIGILL handler when detecting CPU
--- a/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -54,6 +54,10 @@
 #include "utilities/events.hpp"
 #include "utilities/vmError.hpp"
 
+// See stubGenerator_zero.cpp
+#include <setjmp.h>
+extern sigjmp_buf* get_jmp_buf_for_continuation();
+
 address os::current_stack_pointer() {
   address dummy = (address) &dummy;
   return dummy;
@@ -125,6 +129,14 @@
 
   SignalHandlerMark shm(t);
 
+  // handle SafeFetch faults
+  if (sig == SIGSEGV || sig == SIGBUS) {
+    sigjmp_buf* const pjb = get_jmp_buf_for_continuation();
+    if (pjb) {
+      siglongjmp(*pjb, 1);
+    }
+  }
+
   // Note: it's not uncommon that JNI code uses signal/sigset to
   // install then restore certain signal handler (e.g. to temporarily
   // block SIGPIPE, or have a SIGILL handler when detecting CPU
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -4838,20 +4838,21 @@
       }
     }
   } else { // not interface
-    if (is_initializer) {
-      if (is_static || is_final || is_synchronized || is_native ||
-          is_abstract || (major_gte_15 && is_bridge)) {
-        is_illegal = true;
-      }
-    } else { // not initializer
-      if (is_abstract) {
-        if ((is_final || is_native || is_private || is_static ||
-            (major_gte_15 && (is_synchronized || is_strict)))) {
+    if (has_illegal_visibility(flags)) {
+      is_illegal = true;
+    } else {
+      if (is_initializer) {
+        if (is_static || is_final || is_synchronized || is_native ||
+            is_abstract || (major_gte_15 && is_bridge)) {
           is_illegal = true;
         }
-      }
-      if (has_illegal_visibility(flags)) {
-        is_illegal = true;
+      } else { // not initializer
+        if (is_abstract) {
+          if ((is_final || is_native || is_private || is_static ||
+              (major_gte_15 && (is_synchronized || is_strict)))) {
+            is_illegal = true;
+          }
+        }
       }
     }
   }
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -1313,7 +1313,8 @@
 }
 
 static inline bool version_matches(Method* method, int version) {
-  return (method->constants()->version() == version && version < MAX_VERSION);
+  assert(version < MAX_VERSION, "version is too big");
+  return method != NULL && (method->constants()->version() == version);
 }
 
 static inline int get_line_number(Method* method, int bci) {
@@ -1343,6 +1344,7 @@
   typeArrayOop    _methods;
   typeArrayOop    _bcis;
   objArrayOop     _mirrors;
+  typeArrayOop    _cprefs; // needed to insulate method name against redefinition
   int             _index;
   No_Safepoint_Verifier _nsv;
 
@@ -1350,8 +1352,9 @@
 
   enum {
     trace_methods_offset = java_lang_Throwable::trace_methods_offset,
-    trace_bcis_offset = java_lang_Throwable::trace_bcis_offset,
+    trace_bcis_offset    = java_lang_Throwable::trace_bcis_offset,
     trace_mirrors_offset = java_lang_Throwable::trace_mirrors_offset,
+    trace_cprefs_offset  = java_lang_Throwable::trace_cprefs_offset,
     trace_next_offset    = java_lang_Throwable::trace_next_offset,
     trace_size           = java_lang_Throwable::trace_size,
     trace_chunk_size     = java_lang_Throwable::trace_chunk_size
@@ -1373,9 +1376,14 @@
     assert(mirrors != NULL, "mirror array should be initialized in backtrace");
     return mirrors;
   }
+  static typeArrayOop get_cprefs(objArrayHandle chunk) {
+    typeArrayOop cprefs = typeArrayOop(chunk->obj_at(trace_cprefs_offset));
+    assert(cprefs != NULL, "cprefs array should be initialized in backtrace");
+    return cprefs;
+  }
 
   // constructor for new backtrace
-  BacktraceBuilder(TRAPS): _methods(NULL), _bcis(NULL), _head(NULL), _mirrors(NULL) {
+  BacktraceBuilder(TRAPS): _methods(NULL), _bcis(NULL), _head(NULL), _mirrors(NULL), _cprefs(NULL) {
     expand(CHECK);
     _backtrace = _head;
     _index = 0;
@@ -1385,6 +1393,7 @@
     _methods = get_methods(backtrace);
     _bcis = get_bcis(backtrace);
     _mirrors = get_mirrors(backtrace);
+    _cprefs = get_cprefs(backtrace);
     assert(_methods->length() == _bcis->length() &&
            _methods->length() == _mirrors->length(),
            "method and source information arrays should match");
@@ -1410,17 +1419,22 @@
     objArrayOop mirrors = oopFactory::new_objectArray(trace_chunk_size, CHECK);
     objArrayHandle new_mirrors(THREAD, mirrors);
 
+    typeArrayOop cprefs = oopFactory::new_shortArray(trace_chunk_size, CHECK);
+    typeArrayHandle new_cprefs(THREAD, cprefs);
+
     if (!old_head.is_null()) {
       old_head->obj_at_put(trace_next_offset, new_head());
     }
     new_head->obj_at_put(trace_methods_offset, new_methods());
     new_head->obj_at_put(trace_bcis_offset, new_bcis());
     new_head->obj_at_put(trace_mirrors_offset, new_mirrors());
+    new_head->obj_at_put(trace_cprefs_offset, new_cprefs());
 
     _head    = new_head();
     _methods = new_methods();
     _bcis = new_bcis();
     _mirrors = new_mirrors();
+    _cprefs  = new_cprefs();
     _index = 0;
   }
 
@@ -1440,8 +1454,9 @@
       method = mhandle();
     }
 
-    _methods->short_at_put(_index, method->method_idnum());
+    _methods->short_at_put(_index, method->orig_method_idnum());
     _bcis->int_at_put(_index, merge_bci_and_version(bci, method->constants()->version()));
+    _cprefs->short_at_put(_index, method->name_index());
 
     // We need to save the mirrors in the backtrace to keep the class
     // from being unloaded while we still have this stack trace.
@@ -1454,27 +1469,26 @@
 
 // Print stack trace element to resource allocated buffer
 char* java_lang_Throwable::print_stack_element_to_buffer(Handle mirror,
-                                  int method_id, int version, int bci) {
+                                  int method_id, int version, int bci, int cpref) {
 
   // Get strings and string lengths
   InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(mirror()));
   const char* klass_name  = holder->external_name();
   int buf_len = (int)strlen(klass_name);
 
-  // The method id may point to an obsolete method, can't get more stack information
-  Method* method = holder->method_with_idnum(method_id);
-  if (method == NULL) {
-    char* buf = NEW_RESOURCE_ARRAY(char, buf_len + 64);
-    // This is what the java code prints in this case - added Redefined
-    sprintf(buf, "\tat %s.null (Redefined)", klass_name);
-    return buf;
-  }
-
-  char* method_name = method->name()->as_C_string();
+  Method* method = holder->method_with_orig_idnum(method_id, version);
+
+  // The method can be NULL if the requested class version is gone
+  Symbol* sym = (method != NULL) ? method->name() : holder->constants()->symbol_at(cpref);
+  char* method_name = sym->as_C_string();
   buf_len += (int)strlen(method_name);
 
+  // Use specific ik version as a holder since the mirror might
+  // refer to version that is now obsolete and no longer accessible
+  // via the previous versions list.
+  holder = holder->get_klass_version(version);
   char* source_file_name = NULL;
-  if (version_matches(method, version)) {
+  if (holder != NULL) {
     Symbol* source = holder->source_file_name();
     if (source != NULL) {
       source_file_name = source->as_C_string();
@@ -1516,17 +1530,18 @@
 }
 
 void java_lang_Throwable::print_stack_element(outputStream *st, Handle mirror,
-                                              int method_id, int version, int bci) {
+                                              int method_id, int version, int bci, int cpref) {
   ResourceMark rm;
-  char* buf = print_stack_element_to_buffer(mirror, method_id, version, bci);
+  char* buf = print_stack_element_to_buffer(mirror, method_id, version, bci, cpref);
   st->print_cr("%s", buf);
 }
 
 void java_lang_Throwable::print_stack_element(outputStream *st, methodHandle method, int bci) {
   Handle mirror = method->method_holder()->java_mirror();
-  int method_id = method->method_idnum();
+  int method_id = method->orig_method_idnum();
   int version = method->constants()->version();
-  print_stack_element(st, mirror, method_id, version, bci);
+  int cpref = method->name_index();
+  print_stack_element(st, mirror, method_id, version, bci, cpref);
 }
 
 const char* java_lang_Throwable::no_stack_trace_message() {
@@ -1551,6 +1566,7 @@
       typeArrayHandle methods (THREAD, BacktraceBuilder::get_methods(result));
       typeArrayHandle bcis (THREAD, BacktraceBuilder::get_bcis(result));
       objArrayHandle mirrors (THREAD, BacktraceBuilder::get_mirrors(result));
+      typeArrayHandle cprefs (THREAD, BacktraceBuilder::get_cprefs(result));
 
       int length = methods()->length();
       for (int index = 0; index < length; index++) {
@@ -1560,7 +1576,8 @@
         int method = methods->short_at(index);
         int version = version_at(bcis->int_at(index));
         int bci = bci_at(bcis->int_at(index));
-        print_stack_element(st, mirror, method, version, bci);
+        int cpref = cprefs->short_at(index);
+        print_stack_element(st, mirror, method, version, bci, cpref);
       }
       result = objArrayHandle(THREAD, objArrayOop(result->obj_at(trace_next_offset)));
     }
@@ -1837,29 +1854,30 @@
   if (chunk == NULL) {
     THROW_(vmSymbols::java_lang_IndexOutOfBoundsException(), NULL);
   }
-  // Get method id, bci, version and mirror from chunk
+  // Get method id, bci, version, mirror and cpref from chunk
   typeArrayOop methods = BacktraceBuilder::get_methods(chunk);
   typeArrayOop bcis = BacktraceBuilder::get_bcis(chunk);
   objArrayOop mirrors = BacktraceBuilder::get_mirrors(chunk);
+  typeArrayOop cprefs = BacktraceBuilder::get_cprefs(chunk);
 
   assert(methods != NULL && bcis != NULL && mirrors != NULL, "sanity check");
 
   int method = methods->short_at(chunk_index);
   int version = version_at(bcis->int_at(chunk_index));
   int bci = bci_at(bcis->int_at(chunk_index));
+  int cpref = cprefs->short_at(chunk_index);
   Handle mirror(THREAD, mirrors->obj_at(chunk_index));
 
   // Chunk can be partial full
   if (mirror.is_null()) {
     THROW_(vmSymbols::java_lang_IndexOutOfBoundsException(), NULL);
   }
-
-  oop element = java_lang_StackTraceElement::create(mirror, method, version, bci, CHECK_0);
+  oop element = java_lang_StackTraceElement::create(mirror, method, version, bci, cpref, CHECK_0);
   return element;
 }
 
 oop java_lang_StackTraceElement::create(Handle mirror, int method_id,
-                                        int version, int bci, TRAPS) {
+                                        int version, int bci, int cpref, TRAPS) {
   // Allocate java.lang.StackTraceElement instance
   Klass* k = SystemDictionary::StackTraceElement_klass();
   assert(k != NULL, "must be loaded in 1.4+");
@@ -1876,17 +1894,13 @@
   oop classname = StringTable::intern((char*) str, CHECK_0);
   java_lang_StackTraceElement::set_declaringClass(element(), classname);
 
-  Method* method = holder->method_with_idnum(method_id);
-  // Method on stack may be obsolete because it was redefined so cannot be
-  // found by idnum.
-  if (method == NULL) {
-    // leave name and fileName null
-    java_lang_StackTraceElement::set_lineNumber(element(), -1);
-    return element();
-  }
+  Method* method = holder->method_with_orig_idnum(method_id, version);
+
+  // The method can be NULL if the requested class version is gone
+  Symbol* sym = (method != NULL) ? method->name() : holder->constants()->symbol_at(cpref);
 
   // Fill in method name
-  oop methodname = StringTable::intern(method->name(), CHECK_0);
+  oop methodname = StringTable::intern(sym, CHECK_0);
   java_lang_StackTraceElement::set_methodName(element(), methodname);
 
   if (!version_matches(method, version)) {
@@ -1895,6 +1909,11 @@
     java_lang_StackTraceElement::set_lineNumber(element(), -1);
   } else {
     // Fill in source file name and line number.
+    // Use specific ik version as a holder since the mirror might
+    // refer to version that is now obsolete and no longer accessible
+    // via the previous versions list.
+    holder = holder->get_klass_version(version);
+    assert(holder != NULL, "sanity check");
     Symbol* source = holder->source_file_name();
     if (ShowHiddenFrames && source == NULL)
       source = vmSymbols::unknown_class_name();
@@ -1909,8 +1928,9 @@
 
 oop java_lang_StackTraceElement::create(methodHandle method, int bci, TRAPS) {
   Handle mirror (THREAD, method->method_holder()->java_mirror());
-  int method_id = method->method_idnum();
-  return create(mirror, method_id, method->constants()->version(), bci, THREAD);
+  int method_id = method->orig_method_idnum();
+  int cpref = method->name_index();
+  return create(mirror, method_id, method->constants()->version(), bci, cpref, THREAD);
 }
 
 void java_lang_reflect_AccessibleObject::compute_offsets() {
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/classfile/javaClasses.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -485,8 +485,9 @@
     trace_methods_offset = 0,
     trace_bcis_offset    = 1,
     trace_mirrors_offset = 2,
-    trace_next_offset    = 3,
-    trace_size           = 4,
+    trace_cprefs_offset  = 3,
+    trace_next_offset    = 4,
+    trace_size           = 5,
     trace_chunk_size     = 32
   };
 
@@ -497,7 +498,7 @@
   static int static_unassigned_stacktrace_offset;
 
   // Printing
-  static char* print_stack_element_to_buffer(Handle mirror, int method, int version, int bci);
+  static char* print_stack_element_to_buffer(Handle mirror, int method, int version, int bci, int cpref);
   // StackTrace (programmatic access, new since 1.4)
   static void clear_stacktrace(oop throwable);
   // No stack trace available
@@ -519,7 +520,7 @@
   static void set_message(oop throwable, oop value);
   static Symbol* detail_message(oop throwable);
   static void print_stack_element(outputStream *st, Handle mirror, int method,
-                                  int version, int bci);
+                                  int version, int bci, int cpref);
   static void print_stack_element(outputStream *st, methodHandle method, int bci);
   static void print_stack_usage(Handle stream);
 
@@ -1314,7 +1315,7 @@
   static void set_lineNumber(oop element, int value);
 
   // Create an instance of StackTraceElement
-  static oop create(Handle mirror, int method, int version, int bci, TRAPS);
+  static oop create(Handle mirror, int method, int version, int bci, int cpref, TRAPS);
   static oop create(methodHandle method, int bci, TRAPS);
 
   // Debugging
--- a/hotspot/src/share/vm/classfile/verifier.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/classfile/verifier.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -657,6 +657,7 @@
 
 
     bool this_uninit = false;  // Set to true when invokespecial <init> initialized 'this'
+    bool verified_exc_handlers = false;
 
     // Merge with the next instruction
     {
@@ -688,6 +689,18 @@
         }
       }
 
+      // Look for possible jump target in exception handlers and see if it
+      // matches current_frame.  Do this check here for astore*, dstore*,
+      // fstore*, istore*, and lstore* opcodes because they can change the type
+      // state by adding a local.  JVM Spec says that the incoming type state
+      // should be used for this check.  So, do the check here before a possible
+      // local is added to the type state.
+      if (Bytecodes::is_store_into_local(opcode) && bci >= ex_min && bci < ex_max) {
+        verify_exception_handler_targets(
+          bci, this_uninit, &current_frame, &stackmap_table, CHECK_VERIFY(this));
+        verified_exc_handlers = true;
+      }
+
       switch (opcode) {
         case Bytecodes::_nop :
           no_control_flow = false; break;
@@ -1669,9 +1682,13 @@
       }  // end switch
     }  // end Merge with the next instruction
 
-    // Look for possible jump target in exception handlers and see if it
-    // matches current_frame
-    if (bci >= ex_min && bci < ex_max) {
+    // Look for possible jump target in exception handlers and see if it matches
+    // current_frame.  Don't do this check if it has already been done (for
+    // ([a,d,f,i,l]store* opcodes).  This check cannot be done earlier because
+    // opcodes, such as invokespecial, may set the this_uninit flag.
+    assert(!(verified_exc_handlers && this_uninit),
+      "Exception handler targets got verified before this_uninit got set");
+    if (!verified_exc_handlers && bci >= ex_min && bci < ex_max) {
       verify_exception_handler_targets(
         bci, this_uninit, &current_frame, &stackmap_table, CHECK_VERIFY(this));
     }
@@ -2236,14 +2253,20 @@
 }
 
 // Look at the method's handlers.  If the bci is in the handler's try block
-// then check if the handler_pc is already on the stack.  If not, push it.
+// then check if the handler_pc is already on the stack.  If not, push it
+// unless the handler has already been scanned.
 void ClassVerifier::push_handlers(ExceptionTable* exhandlers,
+                                  GrowableArray<u4>* handler_list,
                                   GrowableArray<u4>* handler_stack,
                                   u4 bci) {
   int exlength = exhandlers->length();
   for(int x = 0; x < exlength; x++) {
     if (bci >= exhandlers->start_pc(x) && bci < exhandlers->end_pc(x)) {
-      handler_stack->append_if_missing(exhandlers->handler_pc(x));
+      u4 exhandler_pc = exhandlers->handler_pc(x);
+      if (!handler_list->contains(exhandler_pc)) {
+        handler_stack->append_if_missing(exhandler_pc);
+        handler_list->append(exhandler_pc);
+      }
     }
   }
 }
@@ -2261,6 +2284,10 @@
   GrowableArray<u4>* bci_stack = new GrowableArray<u4>(30);
   // Create stack for handlers for try blocks containing this handler.
   GrowableArray<u4>* handler_stack = new GrowableArray<u4>(30);
+  // Create list of handlers that have been pushed onto the handler_stack
+  // so that handlers embedded inside of their own TRY blocks only get
+  // scanned once.
+  GrowableArray<u4>* handler_list = new GrowableArray<u4>(30);
   // Create list of visited branch opcodes (goto* and if*).
   GrowableArray<u4>* visited_branches = new GrowableArray<u4>(30);
   ExceptionTable exhandlers(_method());
@@ -2279,7 +2306,7 @@
 
     // If the bytecode is in a TRY block, push its handlers so they
     // will get parsed.
-    push_handlers(&exhandlers, handler_stack, bci);
+    push_handlers(&exhandlers, handler_list, handler_stack, bci);
 
     switch (opcode) {
       case Bytecodes::_if_icmpeq:
--- a/hotspot/src/share/vm/classfile/verifier.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/classfile/verifier.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -305,9 +305,10 @@
     bool* this_uninit, constantPoolHandle cp, StackMapTable* stackmap_table,
     TRAPS);
 
-  // Used by ends_in_athrow() to push all handlers that contain bci onto
-  // the handler_stack, if the handler is not already on the stack.
+  // Used by ends_in_athrow() to push all handlers that contain bci onto the
+  // handler_stack, if the handler has not already been pushed on the stack.
   void push_handlers(ExceptionTable* exhandlers,
+                     GrowableArray<u4>* handler_list,
                      GrowableArray<u4>* handler_stack,
                      u4 bci);
 
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -559,6 +559,7 @@
   template(startRemoteAgent_name,                      "startRemoteManagementAgent")                              \
   template(startLocalAgent_name,                       "startLocalManagementAgent")                               \
   template(stopRemoteAgent_name,                       "stopRemoteManagementAgent")                               \
+  template(getAgentStatus_name,                        "getManagementAgentStatus")                                \
   template(java_lang_management_ThreadInfo_constructor_signature, "(Ljava/lang/Thread;ILjava/lang/Object;Ljava/lang/Thread;JJJJ[Ljava/lang/StackTraceElement;)V") \
   template(java_lang_management_ThreadInfo_with_locks_constructor_signature, "(Ljava/lang/Thread;ILjava/lang/Object;Ljava/lang/Thread;JJJJ[Ljava/lang/StackTraceElement;[Ljava/lang/Object;[I[Ljava/lang/Object;)V") \
   template(long_long_long_long_void_signature,         "(JJJJ)V")                                                 \
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/adaptiveFreeList.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/adaptiveFreeList.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -25,8 +25,8 @@
 #include "precompiled.hpp"
 #include "gc_implementation/concurrentMarkSweep/adaptiveFreeList.hpp"
 #include "gc_implementation/concurrentMarkSweep/freeChunk.hpp"
+#include "gc_interface/collectedHeap.hpp"
 #include "memory/freeBlockDictionary.hpp"
-#include "memory/sharedHeap.hpp"
 #include "runtime/globals.hpp"
 #include "runtime/mutex.hpp"
 #include "runtime/orderAccess.inline.hpp"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc_implementation/concurrentMarkSweep/cmsOopClosures.inline.hpp"
+#include "memory/iterator.inline.hpp"
+#include "memory/specialized_oop_closures.hpp"
+
+// Generate CMS specialized oop_oop_iterate functions.
+SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_CMS(ALL_KLASS_OOP_OOP_ITERATE_DEFN)
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -32,6 +32,7 @@
 #include "gc_interface/collectedHeap.inline.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/blockOffsetTable.inline.hpp"
+#include "memory/genCollectedHeap.hpp"
 #include "memory/resourceArea.hpp"
 #include "memory/space.inline.hpp"
 #include "memory/universe.inline.hpp"
@@ -673,10 +674,10 @@
                                                  HeapWord* bottom,              \
                                                  HeapWord* top,                 \
                                                  ClosureType* cl) {             \
-   bool is_par = SharedHeap::heap()->n_par_threads() > 0;                       \
+   bool is_par = GenCollectedHeap::heap()->n_par_threads() > 0;                 \
    if (is_par) {                                                                \
-     assert(SharedHeap::heap()->n_par_threads() ==                              \
-            SharedHeap::heap()->workers()->active_workers(), "Mismatch");       \
+     assert(GenCollectedHeap::heap()->n_par_threads() ==                        \
+            GenCollectedHeap::heap()->workers()->active_workers(), "Mismatch"); \
      walk_mem_region_with_cl_par(mr, bottom, top, cl);                          \
    } else {                                                                     \
      walk_mem_region_with_cl_nopar(mr, bottom, top, cl);                        \
@@ -1907,11 +1908,11 @@
   assert(chunk->is_free() && ffc->is_free(), "Error");
   _bt.split_block((HeapWord*)chunk, chunk->size(), new_size);
   if (rem_sz < SmallForDictionary) {
-    bool is_par = (SharedHeap::heap()->n_par_threads() > 0);
+    bool is_par = (GenCollectedHeap::heap()->n_par_threads() > 0);
     if (is_par) _indexedFreeListParLocks[rem_sz]->lock();
     assert(!is_par ||
-           (SharedHeap::heap()->n_par_threads() ==
-            SharedHeap::heap()->workers()->active_workers()), "Mismatch");
+           (GenCollectedHeap::heap()->n_par_threads() ==
+            GenCollectedHeap::heap()->workers()->active_workers()), "Mismatch");
     returnChunkToFreeList(ffc);
     split(size, rem_sz);
     if (is_par) _indexedFreeListParLocks[rem_sz]->unlock();
@@ -1982,7 +1983,7 @@
 
 bool CompactibleFreeListSpace::no_allocs_since_save_marks() {
   assert(_promoInfo.tracking(), "No preceding save_marks?");
-  assert(SharedHeap::heap()->n_par_threads() == 0,
+  assert(GenCollectedHeap::heap()->n_par_threads() == 0,
          "Shouldn't be called if using parallel gc.");
   return _promoInfo.noPromotions();
 }
@@ -1991,7 +1992,7 @@
                                                                             \
 void CompactibleFreeListSpace::                                             \
 oop_since_save_marks_iterate##nv_suffix(OopClosureType* blk) {              \
-  assert(SharedHeap::heap()->n_par_threads() == 0,                          \
+  assert(GenCollectedHeap::heap()->n_par_threads() == 0,                    \
          "Shouldn't be called (yet) during parallel part of gc.");          \
   _promoInfo.promoted_oops_iterate##nv_suffix(blk);                         \
   /*                                                                        \
@@ -2442,11 +2443,10 @@
   {
     VerifyAllOopsClosure cl(_collector, this, span, past_remark,
       _collector->markBitMap());
-    CollectedHeap* ch = Universe::heap();
 
     // Iterate over all oops in the heap. Uses the _no_header version
     // since we are not interested in following the klass pointers.
-    ch->oop_iterate_no_header(&cl);
+    GenCollectedHeap::heap()->oop_iterate_no_header(&cl);
   }
 
   if (VerifyObjectStartArray) {
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -28,7 +28,7 @@
 #include "gc_implementation/concurrentMarkSweep/adaptiveFreeList.hpp"
 #include "gc_implementation/concurrentMarkSweep/promotionInfo.hpp"
 #include "memory/binaryTreeDictionary.hpp"
-#include "memory/blockOffsetTable.inline.hpp"
+#include "memory/blockOffsetTable.hpp"
 #include "memory/freeList.hpp"
 #include "memory/space.hpp"
 
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -53,6 +53,7 @@
 #include "memory/padded.hpp"
 #include "memory/referencePolicy.hpp"
 #include "memory/resourceArea.hpp"
+#include "memory/strongRootsScope.hpp"
 #include "memory/tenuredGeneration.hpp"
 #include "oops/oop.inline.hpp"
 #include "prims/jvmtiExport.hpp"
@@ -64,6 +65,7 @@
 #include "runtime/vmThread.hpp"
 #include "services/memoryService.hpp"
 #include "services/runtimeService.hpp"
+#include "utilities/stack.inline.hpp"
 
 // statics
 CMSCollector* ConcurrentMarkSweepGeneration::_collector = NULL;
@@ -208,10 +210,6 @@
                                            use_adaptive_freelists,
                                            dictionaryChoice);
   NOT_PRODUCT(debug_cms_space = _cmsSpace;)
-  if (_cmsSpace == NULL) {
-    vm_exit_during_initialization(
-      "CompactibleFreeListSpace allocation failure");
-  }
   _cmsSpace->_gen = this;
 
   _gc_stats = new CMSGCStats();
@@ -230,14 +228,8 @@
     typedef CMSParGCThreadState* CMSParGCThreadStatePtr;
     _par_gc_thread_states =
       NEW_C_HEAP_ARRAY(CMSParGCThreadStatePtr, ParallelGCThreads, mtGC);
-    if (_par_gc_thread_states == NULL) {
-      vm_exit_during_initialization("Could not allocate par gc structs");
-    }
     for (uint i = 0; i < ParallelGCThreads; i++) {
       _par_gc_thread_states[i] = new CMSParGCThreadState(cmsSpace());
-      if (_par_gc_thread_states[i] == NULL) {
-        vm_exit_during_initialization("Could not allocate par gc structs");
-      }
     }
   } else {
     _par_gc_thread_states = NULL;
@@ -308,8 +300,6 @@
 
 AdaptiveSizePolicy* CMSCollector::size_policy() {
   GenCollectedHeap* gch = GenCollectedHeap::heap();
-  assert(gch->kind() == CollectedHeap::GenCollectedHeap,
-    "Wrong type of heap");
   return gch->gen_policy()->size_policy();
 }
 
@@ -586,11 +576,6 @@
         return;
       }
       _hash_seed = NEW_C_HEAP_ARRAY(int, num_queues, mtGC);
-      if (_hash_seed == NULL) {
-        warning("_hash_seed array allocation failure");
-        return;
-      }
-
       typedef Padded<OopTaskQueue> PaddedOopTaskQueue;
       for (i = 0; i < num_queues; i++) {
         PaddedOopTaskQueue *q = new PaddedOopTaskQueue();
@@ -633,12 +618,7 @@
     _eden_chunk_index = 0;
     _eden_chunk_capacity = (_young_gen->max_capacity()+CMSSamplingGrain)/CMSSamplingGrain;
     _eden_chunk_array = NEW_C_HEAP_ARRAY(HeapWord*, _eden_chunk_capacity, mtGC);
-    if (_eden_chunk_array == NULL) {
-      _eden_chunk_capacity = 0;
-      warning("GC/CMS: _eden_chunk_array allocation failure");
-    }
-  }
-  assert(_eden_chunk_array != NULL || _eden_chunk_capacity == 0, "Error");
+  }
 
   // Support for parallelizing survivor space rescan
   if ((CMSParallelRemarkEnabled && CMSParallelSurvivorRemarkEnabled) || CMSParallelInitialMarkEnabled) {
@@ -648,52 +628,15 @@
     _survivor_plab_array  = NEW_C_HEAP_ARRAY(ChunkArray, ParallelGCThreads, mtGC);
     _survivor_chunk_array = NEW_C_HEAP_ARRAY(HeapWord*, 2*max_plab_samples, mtGC);
     _cursor               = NEW_C_HEAP_ARRAY(size_t, ParallelGCThreads, mtGC);
-    if (_survivor_plab_array == NULL || _survivor_chunk_array == NULL
-        || _cursor == NULL) {
-      warning("Failed to allocate survivor plab/chunk array");
-      if (_survivor_plab_array  != NULL) {
-        FREE_C_HEAP_ARRAY(ChunkArray, _survivor_plab_array);
-        _survivor_plab_array = NULL;
-      }
-      if (_survivor_chunk_array != NULL) {
-        FREE_C_HEAP_ARRAY(HeapWord*, _survivor_chunk_array);
-        _survivor_chunk_array = NULL;
-      }
-      if (_cursor != NULL) {
-        FREE_C_HEAP_ARRAY(size_t, _cursor);
-        _cursor = NULL;
-      }
-    } else {
-      _survivor_chunk_capacity = 2*max_plab_samples;
-      for (uint i = 0; i < ParallelGCThreads; i++) {
-        HeapWord** vec = NEW_C_HEAP_ARRAY(HeapWord*, max_plab_samples, mtGC);
-        if (vec == NULL) {
-          warning("Failed to allocate survivor plab array");
-          for (int j = i; j > 0; j--) {
-            FREE_C_HEAP_ARRAY(HeapWord*, _survivor_plab_array[j-1].array());
-          }
-          FREE_C_HEAP_ARRAY(ChunkArray, _survivor_plab_array);
-          FREE_C_HEAP_ARRAY(HeapWord*, _survivor_chunk_array);
-          _survivor_plab_array = NULL;
-          _survivor_chunk_array = NULL;
-          _survivor_chunk_capacity = 0;
-          break;
-        } else {
-          ChunkArray* cur =
-            ::new (&_survivor_plab_array[i]) ChunkArray(vec,
-                                                        max_plab_samples);
-          assert(cur->end() == 0, "Should be 0");
-          assert(cur->array() == vec, "Should be vec");
-          assert(cur->capacity() == max_plab_samples, "Error");
-        }
-      }
-    }
-  }
-  assert(   (   _survivor_plab_array  != NULL
-             && _survivor_chunk_array != NULL)
-         || (   _survivor_chunk_capacity == 0
-             && _survivor_chunk_index == 0),
-         "Error");
+    _survivor_chunk_capacity = 2*max_plab_samples;
+    for (uint i = 0; i < ParallelGCThreads; i++) {
+      HeapWord** vec = NEW_C_HEAP_ARRAY(HeapWord*, max_plab_samples, mtGC);
+      ChunkArray* cur = ::new (&_survivor_plab_array[i]) ChunkArray(vec, max_plab_samples);
+      assert(cur->end() == 0, "Should be 0");
+      assert(cur->array() == vec, "Should be vec");
+      assert(cur->capacity() == max_plab_samples, "Error");
+    }
+  }
 
   NOT_PRODUCT(_overflow_counter = CMSMarkStackOverflowInterval;)
   _gc_counters = new CollectorCounters("CMS", 1);
@@ -1037,7 +980,7 @@
   assert_lock_strong(freelistLock());
 
 #ifndef PRODUCT
-  if (Universe::heap()->promotion_should_fail()) {
+  if (GenCollectedHeap::heap()->promotion_should_fail()) {
     return NULL;
   }
 #endif  // #ifndef PRODUCT
@@ -1114,7 +1057,7 @@
                                            oop old, markOop m,
                                            size_t word_sz) {
 #ifndef PRODUCT
-  if (Universe::heap()->promotion_should_fail()) {
+  if (GenCollectedHeap::heap()->promotion_should_fail()) {
     return NULL;
   }
 #endif  // #ifndef PRODUCT
@@ -2524,7 +2467,7 @@
   verification_mark_bm()->iterate(&vcl);
   if (vcl.failed()) {
     gclog_or_tty->print("Verification failed");
-    Universe::heap()->print_on(gclog_or_tty);
+    gch->print_on(gclog_or_tty);
     fatal("CMS: failed marking verification after remark");
   }
 }
@@ -3071,10 +3014,10 @@
       gch->set_par_threads(n_workers);
       initialize_sequential_subtasks_for_young_gen_rescan(n_workers);
       if (n_workers > 1) {
-        GenCollectedHeap::StrongRootsScope srs(gch);
+        StrongRootsScope srs;
         workers->run_task(&tsk);
       } else {
-        GenCollectedHeap::StrongRootsScope srs(gch);
+        StrongRootsScope srs;
         tsk.work(0);
       }
       gch->set_par_threads(0);
@@ -5169,11 +5112,11 @@
     // necessarily be so, since it's possible that we are doing
     // ST marking.
     ReferenceProcessorMTDiscoveryMutator mt(ref_processor(), true);
-    GenCollectedHeap::StrongRootsScope srs(gch);
+    StrongRootsScope srs;
     workers->run_task(&tsk);
   } else {
     ReferenceProcessorMTDiscoveryMutator mt(ref_processor(), false);
-    GenCollectedHeap::StrongRootsScope srs(gch);
+    StrongRootsScope srs;
     tsk.work(0);
   }
 
@@ -5241,7 +5184,7 @@
     verify_work_stacks_empty();
 
     gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
-    GenCollectedHeap::StrongRootsScope srs(gch);
+    StrongRootsScope srs;
 
     gch->gen_process_roots(_cmsGen->level(),
                            true,  // younger gens as roots
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -38,8 +38,8 @@
 #include "runtime/mutexLocker.hpp"
 #include "runtime/virtualspace.hpp"
 #include "services/memoryService.hpp"
-#include "utilities/bitMap.inline.hpp"
-#include "utilities/stack.inline.hpp"
+#include "utilities/bitMap.hpp"
+#include "utilities/stack.hpp"
 #include "utilities/taskqueue.hpp"
 #include "utilities/yieldingWorkgroup.hpp"
 
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -27,7 +27,7 @@
 
 #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp"
 #include "gc_implementation/shared/concurrentGCThread.hpp"
-#include "runtime/thread.inline.hpp"
+#include "runtime/thread.hpp"
 
 class ConcurrentMarkSweepGeneration;
 class CMSCollector;
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/promotionInfo.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/promotionInfo.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "memory/genOopClosures.hpp"
 #include "gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp"
 #include "gc_implementation/concurrentMarkSweep/promotionInfo.hpp"
 #include "oops/markOop.inline.hpp"
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, 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
@@ -62,7 +62,7 @@
     HandleMark hm;
     FreelistLocker x(_collector);
     MutexLockerEx  y(_collector->bitMapLock(), Mutex::_no_safepoint_check_flag);
-    Universe::heap()->prepare_for_verify();
+    GenCollectedHeap::heap()->prepare_for_verify();
     Universe::verify();
   }
 }
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -34,6 +34,7 @@
 #include "gc_implementation/g1/g1Log.hpp"
 #include "gc_implementation/g1/g1OopClosures.inline.hpp"
 #include "gc_implementation/g1/g1RemSet.hpp"
+#include "gc_implementation/g1/g1StringDedup.hpp"
 #include "gc_implementation/g1/heapRegion.inline.hpp"
 #include "gc_implementation/g1/heapRegionManager.inline.hpp"
 #include "gc_implementation/g1/heapRegionRemSet.hpp"
@@ -46,6 +47,7 @@
 #include "memory/genOopClosures.inline.hpp"
 #include "memory/referencePolicy.hpp"
 #include "memory/resourceArea.hpp"
+#include "memory/strongRootsScope.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/java.hpp"
@@ -115,7 +117,7 @@
 }
 
 size_t CMBitMap::compute_size(size_t heap_size) {
-  return heap_size / mark_distance();
+  return ReservedSpace::allocation_align_size_up(heap_size / mark_distance());
 }
 
 size_t CMBitMap::mark_distance() {
@@ -1325,7 +1327,7 @@
 
   if (VerifyDuringGC) {
     HandleMark hm;  // handle scope
-    Universe::heap()->prepare_for_verify();
+    g1h->prepare_for_verify();
     Universe::verify(VerifyOption_G1UsePrevMarking,
                      " VerifyDuringGC:(before)");
   }
@@ -1352,7 +1354,7 @@
     // Verify the heap w.r.t. the previous marking bitmap.
     if (VerifyDuringGC) {
       HandleMark hm;  // handle scope
-      Universe::heap()->prepare_for_verify();
+      g1h->prepare_for_verify();
       Universe::verify(VerifyOption_G1UsePrevMarking,
                        " VerifyDuringGC:(overflow)");
     }
@@ -1378,7 +1380,7 @@
 
     if (VerifyDuringGC) {
       HandleMark hm;  // handle scope
-      Universe::heap()->prepare_for_verify();
+      g1h->prepare_for_verify();
       Universe::verify(VerifyOption_G1UseNextMarking,
                        " VerifyDuringGC:(after)");
     }
@@ -1986,13 +1988,13 @@
 
   if (VerifyDuringGC) {
     HandleMark hm;  // handle scope
-    Universe::heap()->prepare_for_verify();
+    g1h->prepare_for_verify();
     Universe::verify(VerifyOption_G1UsePrevMarking,
                      " VerifyDuringGC:(before)");
   }
   g1h->check_bitmaps("Cleanup Start");
 
-  G1CollectorPolicy* g1p = G1CollectedHeap::heap()->g1_policy();
+  G1CollectorPolicy* g1p = g1h->g1_policy();
   g1p->record_concurrent_mark_cleanup_start();
 
   double start = os::elapsedTime();
@@ -2097,7 +2099,7 @@
 
   if (VerifyDuringGC) {
     HandleMark hm;  // handle scope
-    Universe::heap()->prepare_for_verify();
+    g1h->prepare_for_verify();
     Universe::verify(VerifyOption_G1UsePrevMarking,
                      " VerifyDuringGC:(after)");
   }
@@ -2650,7 +2652,7 @@
 
   g1h->ensure_parsability(false);
 
-  G1CollectedHeap::StrongRootsScope srs(g1h);
+  StrongRootsScope srs;
   // this is remark, so we'll use up all active threads
   uint active_workers = g1h->workers()->active_workers();
   if (active_workers == 0) {
@@ -3392,22 +3394,29 @@
 }
 #endif
 
-void CMTask::scan_object(oop obj) {
+template<bool scan>
+inline void CMTask::process_grey_object(oop obj) {
+  assert(scan || obj->is_typeArray(), "Skipping scan of grey non-typeArray");
   assert(_nextMarkBitMap->isMarked((HeapWord*) obj), "invariant");
 
   if (_cm->verbose_high()) {
-    gclog_or_tty->print_cr("[%u] we're scanning object "PTR_FORMAT,
+    gclog_or_tty->print_cr("[%u] processing grey object " PTR_FORMAT,
                            _worker_id, p2i((void*) obj));
   }
 
   size_t obj_size = obj->size();
   _words_scanned += obj_size;
 
-  obj->oop_iterate(_cm_oop_closure);
+  if (scan) {
+    obj->oop_iterate(_cm_oop_closure);
+  }
   statsOnly( ++_objs_scanned );
   check_limits();
 }
 
+template void CMTask::process_grey_object<true>(oop);
+template void CMTask::process_grey_object<false>(oop);
+
 // Closure for iteration over bitmaps
 class CMBitMapClosure : public BitMapClosure {
 private:
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -1100,6 +1100,12 @@
   void regular_clock_call();
   bool concurrent() { return _concurrent; }
 
+  // Test whether objAddr might have already been passed over by the
+  // mark bitmap scan, and so needs to be pushed onto the mark stack.
+  bool is_below_finger(HeapWord* objAddr, HeapWord* global_finger) const;
+
+  template<bool scan> void process_grey_object(oop obj);
+
 public:
   // It resets the task; it should be called right at the beginning of
   // a marking phase.
@@ -1152,7 +1158,7 @@
   inline void deal_with_reference(oop obj);
 
   // It scans an object and visits its children.
-  void scan_object(oop obj);
+  void scan_object(oop obj) { process_grey_object<true>(obj); }
 
   // It pushes an object on the local queue.
   inline void push(oop obj);
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -259,14 +259,35 @@
              ++_local_pushes );
 }
 
-// This determines whether the method below will check both the local
-// and global fingers when determining whether to push on the stack a
-// gray object (value 1) or whether it will only check the global one
-// (value 0). The tradeoffs are that the former will be a bit more
-// accurate and possibly push less on the stack, but it might also be
-// a little bit slower.
+inline bool CMTask::is_below_finger(HeapWord* objAddr,
+                                    HeapWord* global_finger) const {
+  // If objAddr is above the global finger, then the mark bitmap scan
+  // will find it later, and no push is needed.  Similarly, if we have
+  // a current region and objAddr is between the local finger and the
+  // end of the current region, then no push is needed.  The tradeoff
+  // of checking both vs only checking the global finger is that the
+  // local check will be more accurate and so result in fewer pushes,
+  // but may also be a little slower.
+  if (_finger != NULL) {
+    // We have a current region.
 
-#define _CHECK_BOTH_FINGERS_      1
+    // Finger and region values are all NULL or all non-NULL.  We
+    // use _finger to check since we immediately use its value.
+    assert(_curr_region != NULL, "invariant");
+    assert(_region_limit != NULL, "invariant");
+    assert(_region_limit <= global_finger, "invariant");
+
+    // True if objAddr is less than the local finger, or is between
+    // the region limit and the global finger.
+    if (objAddr < _finger) {
+      return true;
+    } else if (objAddr < _region_limit) {
+      return false;
+    } // Else check global finger.
+  }
+  // Check global finger.
+  return objAddr < global_finger;
+}
 
 inline void CMTask::deal_with_reference(oop obj) {
   if (_cm->verbose_high()) {
@@ -297,50 +318,43 @@
           // CAS done in CMBitMap::parMark() call in the routine above.
           HeapWord* global_finger = _cm->finger();
 
-#if _CHECK_BOTH_FINGERS_
-          // we will check both the local and global fingers
-
-          if (_finger != NULL && objAddr < _finger) {
-            if (_cm->verbose_high()) {
-              gclog_or_tty->print_cr("[%u] below the local finger ("PTR_FORMAT"), "
-                                     "pushing it", _worker_id, p2i(_finger));
+          // We only need to push a newly grey object on the mark
+          // stack if it is in a section of memory the mark bitmap
+          // scan has already examined.  Mark bitmap scanning
+          // maintains progress "fingers" for determining that.
+          //
+          // Notice that the global finger might be moving forward
+          // concurrently. This is not a problem. In the worst case, we
+          // mark the object while it is above the global finger and, by
+          // the time we read the global finger, it has moved forward
+          // past this object. In this case, the object will probably
+          // be visited when a task is scanning the region and will also
+          // be pushed on the stack. So, some duplicate work, but no
+          // correctness problems.
+          if (is_below_finger(objAddr, global_finger)) {
+            if (obj->is_typeArray()) {
+              // Immediately process arrays of primitive types, rather
+              // than pushing on the mark stack.  This keeps us from
+              // adding humongous objects to the mark stack that might
+              // be reclaimed before the entry is processed - see
+              // selection of candidates for eager reclaim of humongous
+              // objects.  The cost of the additional type test is
+              // mitigated by avoiding a trip through the mark stack,
+              // by only doing a bookkeeping update and avoiding the
+              // actual scan of the object - a typeArray contains no
+              // references, and the metadata is built-in.
+              process_grey_object<false>(obj);
+            } else {
+              if (_cm->verbose_high()) {
+                gclog_or_tty->print_cr("[%u] below a finger (local: " PTR_FORMAT
+                                       ", global: " PTR_FORMAT ") pushing "
+                                       PTR_FORMAT " on mark stack",
+                                       _worker_id, p2i(_finger),
+                                       p2i(global_finger), p2i(objAddr));
+              }
+              push(obj);
             }
-            push(obj);
-          } else if (_curr_region != NULL && objAddr < _region_limit) {
-            // do nothing
-          } else if (objAddr < global_finger) {
-            // Notice that the global finger might be moving forward
-            // concurrently. This is not a problem. In the worst case, we
-            // mark the object while it is above the global finger and, by
-            // the time we read the global finger, it has moved forward
-            // passed this object. In this case, the object will probably
-            // be visited when a task is scanning the region and will also
-            // be pushed on the stack. So, some duplicate work, but no
-            // correctness problems.
-
-            if (_cm->verbose_high()) {
-              gclog_or_tty->print_cr("[%u] below the global finger "
-                                     "("PTR_FORMAT"), pushing it",
-                                     _worker_id, p2i(global_finger));
-            }
-            push(obj);
-          } else {
-            // do nothing
           }
-#else // _CHECK_BOTH_FINGERS_
-          // we will only check the global finger
-
-          if (objAddr < global_finger) {
-            // see long comment above
-
-            if (_cm->verbose_high()) {
-              gclog_or_tty->print_cr("[%u] below the global finger "
-                                     "("PTR_FORMAT"), pushing it",
-                                     _worker_id, p2i(global_finger));
-            }
-            push(obj);
-          }
-#endif // _CHECK_BOTH_FINGERS_
         }
       }
     }
--- a/hotspot/src/share/vm/gc_implementation/g1/g1Allocator.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1Allocator.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -29,6 +29,9 @@
 #include "gc_implementation/g1/g1AllocRegion.hpp"
 #include "gc_implementation/g1/g1InCSetState.hpp"
 #include "gc_implementation/shared/parGCAllocBuffer.hpp"
+#include "gc_interface/collectedHeap.hpp"
+
+class EvacuationInfo;
 
 // Base class for G1 allocators.
 class G1Allocator : public CHeapObj<mtGC> {
--- a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, 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
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "gc_implementation/g1/g1CollectedHeap.hpp"
 #include "gc_implementation/g1/g1BlockOffsetTable.inline.hpp"
 #include "gc_implementation/g1/heapRegion.hpp"
 #include "memory/space.hpp"
@@ -303,9 +304,9 @@
   assert(blk_start <= threshold, "blk_start should be at or before threshold");
   assert(pointer_delta(threshold, blk_start) <= N_words,
          "offset should be <= BlockOffsetSharedArray::N");
-  assert(Universe::heap()->is_in_reserved(blk_start),
+  assert(G1CollectedHeap::heap()->is_in_reserved(blk_start),
          "reference must be into the heap");
-  assert(Universe::heap()->is_in_reserved(blk_end-1),
+  assert(G1CollectedHeap::heap()->is_in_reserved(blk_end-1),
          "limit must be within the heap");
   assert(threshold == _array->_reserved.start() + index*N_words,
          "index must agree with threshold");
@@ -458,7 +459,7 @@
 }
 
 HeapWord* G1BlockOffsetArrayContigSpace::initialize_threshold_raw() {
-  assert(!Universe::heap()->is_in_reserved(_array->_offset_array),
+  assert(!G1CollectedHeap::heap()->is_in_reserved(_array->_offset_array),
          "just checking");
   _next_offset_index = _array->index_for_raw(_bottom);
   _next_offset_index++;
@@ -468,7 +469,7 @@
 }
 
 void G1BlockOffsetArrayContigSpace::zero_bottom_entry_raw() {
-  assert(!Universe::heap()->is_in_reserved(_array->_offset_array),
+  assert(!G1CollectedHeap::heap()->is_in_reserved(_array->_offset_array),
          "just checking");
   size_t bottom_index = _array->index_for_raw(_bottom);
   assert(_array->address_for_index_raw(bottom_index) == _bottom,
@@ -477,7 +478,7 @@
 }
 
 HeapWord* G1BlockOffsetArrayContigSpace::initialize_threshold() {
-  assert(!Universe::heap()->is_in_reserved(_array->_offset_array),
+  assert(!G1CollectedHeap::heap()->is_in_reserved(_array->_offset_array),
          "just checking");
   _next_offset_index = _array->index_for(_bottom);
   _next_offset_index++;
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -70,6 +70,7 @@
 #include "runtime/orderAccess.inline.hpp"
 #include "runtime/vmThread.hpp"
 #include "utilities/globalDefinitions.hpp"
+#include "utilities/stack.inline.hpp"
 
 size_t G1CollectedHeap::_humongous_object_threshold_in_words = 0;
 
@@ -1728,7 +1729,7 @@
 
 
 G1CollectedHeap::G1CollectedHeap(G1CollectorPolicy* policy_) :
-  SharedHeap(),
+  CollectedHeap(),
   _g1_policy(policy_),
   _dirty_card_queue_set(false),
   _into_cset_dirty_card_queue_set(false),
@@ -1746,7 +1747,7 @@
   _secondary_free_list("Secondary Free List", new SecondaryFreeRegionListMtSafeChecker()),
   _old_set("Old Set", false /* humongous */, new OldRegionSetMtSafeChecker()),
   _humongous_set("Master Humongous Set", true /* humongous */, new HumongousRegionSetMtSafeChecker()),
-  _humongous_is_live(),
+  _humongous_reclaim_candidates(),
   _has_humongous_reclaim_candidates(false),
   _free_regions_coming(false),
   _young_list(new YoungList(this)),
@@ -1770,6 +1771,11 @@
 
   _g1h = this;
 
+  _workers = new FlexibleWorkGang("GC Thread", ParallelGCThreads,
+                          /* are_GC_task_threads */true,
+                          /* are_ConcurrentGC_threads */false);
+  _workers->initialize_workers();
+
   _allocator = G1Allocator::create_allocator(_g1h);
   _humongous_object_threshold_in_words = HeapRegion::GrainWords / 2;
 
@@ -1797,6 +1803,26 @@
   guarantee(_task_queues != NULL, "task_queues allocation failure.");
 }
 
+G1RegionToSpaceMapper* G1CollectedHeap::create_aux_memory_mapper(const char* description,
+                                                                 size_t size,
+                                                                 size_t translation_factor) {
+  size_t preferred_page_size = os::page_size_for_region_unaligned(size, 1);
+  // Allocate a new reserved space, preferring to use large pages.
+  ReservedSpace rs(size, preferred_page_size);
+  G1RegionToSpaceMapper* result  =
+    G1RegionToSpaceMapper::create_mapper(rs,
+                                         size,
+                                         rs.alignment(),
+                                         HeapRegion::GrainBytes,
+                                         translation_factor,
+                                         mtGC);
+  if (TracePageSizes) {
+    gclog_or_tty->print_cr("G1 '%s': pg_sz=" SIZE_FORMAT " base=" PTR_FORMAT " size=" SIZE_FORMAT " alignment=" SIZE_FORMAT " reqsize=" SIZE_FORMAT,
+                           description, preferred_page_size, p2i(rs.base()), rs.size(), rs.alignment(), size);
+  }
+  return result;
+}
+
 jint G1CollectedHeap::initialize() {
   CollectedHeap::pre_initialize();
   os::enable_vtime();
@@ -1864,57 +1890,35 @@
   ReservedSpace g1_rs = heap_rs.first_part(max_byte_size);
   G1RegionToSpaceMapper* heap_storage =
     G1RegionToSpaceMapper::create_mapper(g1_rs,
+                                         g1_rs.size(),
                                          UseLargePages ? os::large_page_size() : os::vm_page_size(),
                                          HeapRegion::GrainBytes,
                                          1,
                                          mtJavaHeap);
   heap_storage->set_mapping_changed_listener(&_listener);
 
-  // Reserve space for the block offset table. We do not support automatic uncommit
-  // for the card table at this time. BOT only.
-  ReservedSpace bot_rs(G1BlockOffsetSharedArray::compute_size(g1_rs.size() / HeapWordSize));
+  // Create storage for the BOT, card table, card counts table (hot card cache) and the bitmaps.
   G1RegionToSpaceMapper* bot_storage =
-    G1RegionToSpaceMapper::create_mapper(bot_rs,
-                                         os::vm_page_size(),
-                                         HeapRegion::GrainBytes,
-                                         G1BlockOffsetSharedArray::N_bytes,
-                                         mtGC);
+    create_aux_memory_mapper("Block offset table",
+                             G1BlockOffsetSharedArray::compute_size(g1_rs.size() / HeapWordSize),
+                             G1BlockOffsetSharedArray::N_bytes);
 
   ReservedSpace cardtable_rs(G1SATBCardTableLoggingModRefBS::compute_size(g1_rs.size() / HeapWordSize));
   G1RegionToSpaceMapper* cardtable_storage =
-    G1RegionToSpaceMapper::create_mapper(cardtable_rs,
-                                         os::vm_page_size(),
-                                         HeapRegion::GrainBytes,
-                                         G1BlockOffsetSharedArray::N_bytes,
-                                         mtGC);
-
-  // Reserve space for the card counts table.
-  ReservedSpace card_counts_rs(G1BlockOffsetSharedArray::compute_size(g1_rs.size() / HeapWordSize));
+    create_aux_memory_mapper("Card table",
+                             G1SATBCardTableLoggingModRefBS::compute_size(g1_rs.size() / HeapWordSize),
+                             G1BlockOffsetSharedArray::N_bytes);
+
   G1RegionToSpaceMapper* card_counts_storage =
-    G1RegionToSpaceMapper::create_mapper(card_counts_rs,
-                                         os::vm_page_size(),
-                                         HeapRegion::GrainBytes,
-                                         G1BlockOffsetSharedArray::N_bytes,
-                                         mtGC);
-
-  // Reserve space for prev and next bitmap.
+    create_aux_memory_mapper("Card counts table",
+                             G1BlockOffsetSharedArray::compute_size(g1_rs.size() / HeapWordSize),
+                             G1BlockOffsetSharedArray::N_bytes);
+
   size_t bitmap_size = CMBitMap::compute_size(g1_rs.size());
-
-  ReservedSpace prev_bitmap_rs(ReservedSpace::allocation_align_size_up(bitmap_size));
   G1RegionToSpaceMapper* prev_bitmap_storage =
-    G1RegionToSpaceMapper::create_mapper(prev_bitmap_rs,
-                                         os::vm_page_size(),
-                                         HeapRegion::GrainBytes,
-                                         CMBitMap::mark_distance(),
-                                         mtGC);
-
-  ReservedSpace next_bitmap_rs(ReservedSpace::allocation_align_size_up(bitmap_size));
+    create_aux_memory_mapper("Prev Bitmap", bitmap_size, CMBitMap::mark_distance());
   G1RegionToSpaceMapper* next_bitmap_storage =
-    G1RegionToSpaceMapper::create_mapper(next_bitmap_rs,
-                                         os::vm_page_size(),
-                                         HeapRegion::GrainBytes,
-                                         CMBitMap::mark_distance(),
-                                         mtGC);
+    create_aux_memory_mapper("Next Bitmap", bitmap_size, CMBitMap::mark_distance());
 
   _hrm.initialize(heap_storage, prev_bitmap_storage, next_bitmap_storage, bot_storage, cardtable_storage, card_counts_storage);
   g1_barrier_set()->initialize(cardtable_storage);
@@ -1937,8 +1941,14 @@
 
   _g1h = this;
 
-  _in_cset_fast_test.initialize(_hrm.reserved().start(), _hrm.reserved().end(), HeapRegion::GrainBytes);
-  _humongous_is_live.initialize(_hrm.reserved().start(), _hrm.reserved().end(), HeapRegion::GrainBytes);
+  {
+    HeapWord* start = _hrm.reserved().start();
+    HeapWord* end = _hrm.reserved().end();
+    size_t granularity = HeapRegion::GrainBytes;
+
+    _in_cset_fast_test.initialize(start, end, granularity);
+    _humongous_reclaim_candidates.initialize(start, end, granularity);
+  }
 
   // Create the ConcurrentMark data structure and thread.
   // (Must do this late, so that "max_regions" is defined.)
@@ -2026,15 +2036,15 @@
   }
 }
 
-void G1CollectedHeap::clear_humongous_is_live_table() {
-  guarantee(G1EagerReclaimHumongousObjects, "Should only be called if true");
-  _humongous_is_live.clear();
-}
-
 size_t G1CollectedHeap::conservative_max_heap_alignment() {
   return HeapRegion::max_region_size();
 }
 
+void G1CollectedHeap::post_initialize() {
+  CollectedHeap::post_initialize();
+  ref_processing_init();
+}
+
 void G1CollectedHeap::ref_processing_init() {
   // Reference processing in G1 currently works as follows:
   //
@@ -2071,7 +2081,6 @@
   //     * Discovery is atomic - i.e. not concurrent.
   //     * Reference discovery will not need a barrier.
 
-  SharedHeap::ref_processing_init();
   MemRegion mr = reserved_region();
 
   // Concurrent Mark ref processor
@@ -2128,6 +2137,7 @@
 }
 
 #ifndef PRODUCT
+
 class CheckGCTimeStampsHRClosure : public HeapRegionClosure {
 private:
   unsigned _gc_time_stamp;
@@ -2462,11 +2472,6 @@
   }
 };
 
-void G1CollectedHeap::oop_iterate(ExtendedOopClosure* cl) {
-  IterateOopClosureRegionClosure blk(cl);
-  heap_region_iterate(&blk);
-}
-
 // Iterates an ObjectClosure over all objects within a HeapRegion.
 
 class IterateObjectClosureRegionClosure: public HeapRegionClosure {
@@ -2486,23 +2491,6 @@
   heap_region_iterate(&blk);
 }
 
-// Calls a SpaceClosure on a HeapRegion.
-
-class SpaceClosureRegionClosure: public HeapRegionClosure {
-  SpaceClosure* _cl;
-public:
-  SpaceClosureRegionClosure(SpaceClosure* cl) : _cl(cl) {}
-  bool doHeapRegion(HeapRegion* r) {
-    _cl->do_space(r);
-    return false;
-  }
-};
-
-void G1CollectedHeap::space_iterate(SpaceClosure* cl) {
-  SpaceClosureRegionClosure blk(cl);
-  heap_region_iterate(&blk);
-}
-
 void G1CollectedHeap::heap_region_iterate(HeapRegionClosure* cl) const {
   _hrm.iterate(cl);
 }
@@ -2639,23 +2627,19 @@
   return result;
 }
 
-Space* G1CollectedHeap::space_containing(const void* addr) const {
-  return heap_region_containing(addr);
-}
-
 HeapWord* G1CollectedHeap::block_start(const void* addr) const {
-  Space* sp = space_containing(addr);
-  return sp->block_start(addr);
+  HeapRegion* hr = heap_region_containing(addr);
+  return hr->block_start(addr);
 }
 
 size_t G1CollectedHeap::block_size(const HeapWord* addr) const {
-  Space* sp = space_containing(addr);
-  return sp->block_size(addr);
+  HeapRegion* hr = heap_region_containing(addr);
+  return hr->block_size(addr);
 }
 
 bool G1CollectedHeap::block_is_obj(const HeapWord* addr) const {
-  Space* sp = space_containing(addr);
-  return sp->block_is_obj(addr);
+  HeapRegion* hr = heap_region_containing(addr);
+  return hr->block_is_obj(addr);
 }
 
 bool G1CollectedHeap::supports_tlab_allocation() const {
@@ -3336,8 +3320,8 @@
 #endif // PRODUCT
 
 G1CollectedHeap* G1CollectedHeap::heap() {
-  assert(_sh->kind() == CollectedHeap::G1CollectedHeap,
-         "not a garbage-first heap");
+  assert(_g1h != NULL, "Uninitialized access to G1CollectedHeap::heap()");
+  assert(_g1h->kind() == CollectedHeap::G1CollectedHeap, "Not a G1 heap");
   return _g1h;
 }
 
@@ -3434,12 +3418,6 @@
   return g1_rem_set()->cardsScanned();
 }
 
-bool G1CollectedHeap::humongous_region_is_always_live(uint index) {
-  HeapRegion* region = region_at(index);
-  assert(region->is_starts_humongous(), "Must start a humongous object");
-  return oop(region->bottom())->is_objArray() || !region->rem_set()->is_empty();
-}
-
 class RegisterHumongousWithInCSetFastTestClosure : public HeapRegionClosure {
  private:
   size_t _total_humongous;
@@ -3447,14 +3425,59 @@
 
   DirtyCardQueue _dcq;
 
-  bool humongous_region_is_candidate(uint index) {
-    HeapRegion* region = G1CollectedHeap::heap()->region_at(index);
-    assert(region->is_starts_humongous(), "Must start a humongous object");
+  // We don't nominate objects with many remembered set entries, on
+  // the assumption that such objects are likely still live.
+  bool is_remset_small(HeapRegion* region) const {
     HeapRegionRemSet* const rset = region->rem_set();
-    bool const allow_stale_refs = G1EagerReclaimHumongousObjectsWithStaleRefs;
-    return !oop(region->bottom())->is_objArray() &&
-           ((allow_stale_refs && rset->occupancy_less_or_equal_than(G1RSetSparseRegionEntries)) ||
-            (!allow_stale_refs && rset->is_empty()));
+    return G1EagerReclaimHumongousObjectsWithStaleRefs
+      ? rset->occupancy_less_or_equal_than(G1RSetSparseRegionEntries)
+      : rset->is_empty();
+  }
+
+  bool is_typeArray_region(HeapRegion* region) const {
+    return oop(region->bottom())->is_typeArray();
+  }
+
+  bool humongous_region_is_candidate(G1CollectedHeap* heap, HeapRegion* region) const {
+    assert(region->is_starts_humongous(), "Must start a humongous object");
+
+    // Candidate selection must satisfy the following constraints
+    // while concurrent marking is in progress:
+    //
+    // * In order to maintain SATB invariants, an object must not be
+    // reclaimed if it was allocated before the start of marking and
+    // has not had its references scanned.  Such an object must have
+    // its references (including type metadata) scanned to ensure no
+    // live objects are missed by the marking process.  Objects
+    // allocated after the start of concurrent marking don't need to
+    // be scanned.
+    //
+    // * An object must not be reclaimed if it is on the concurrent
+    // mark stack.  Objects allocated after the start of concurrent
+    // marking are never pushed on the mark stack.
+    //
+    // Nominating only objects allocated after the start of concurrent
+    // marking is sufficient to meet both constraints.  This may miss
+    // some objects that satisfy the constraints, but the marking data
+    // structures don't support efficiently performing the needed
+    // additional tests or scrubbing of the mark stack.
+    //
+    // However, we presently only nominate is_typeArray() objects.
+    // A humongous object containing references induces remembered
+    // set entries on other regions.  In order to reclaim such an
+    // object, those remembered sets would need to be cleaned up.
+    //
+    // We also treat is_typeArray() objects specially, allowing them
+    // to be reclaimed even if allocated before the start of
+    // concurrent mark.  For this we rely on mark stack insertion to
+    // exclude is_typeArray() objects, preventing reclaiming an object
+    // that is in the mark stack.  We also rely on the metadata for
+    // such objects to be built-in and so ensured to be kept live.
+    // Frequent allocation and drop of large binary blobs is an
+    // important use case for eager reclaim, and this special handling
+    // may reduce needed headroom.
+
+    return is_typeArray_region(region) && is_remset_small(region);
   }
 
  public:
@@ -3470,14 +3493,17 @@
     }
     G1CollectedHeap* g1h = G1CollectedHeap::heap();
 
-    uint region_idx = r->hrm_index();
-    bool is_candidate = humongous_region_is_candidate(region_idx);
-    // Is_candidate already filters out humongous object with large remembered sets.
-    // If we have a humongous object with a few remembered sets, we simply flush these
-    // remembered set entries into the DCQS. That will result in automatic
-    // re-evaluation of their remembered set entries during the following evacuation
-    // phase.
+    bool is_candidate = humongous_region_is_candidate(g1h, r);
+    uint rindex = r->hrm_index();
+    g1h->set_humongous_reclaim_candidate(rindex, is_candidate);
     if (is_candidate) {
+      _candidate_humongous++;
+      g1h->register_humongous_region_with_cset(rindex);
+      // Is_candidate already filters out humongous object with large remembered sets.
+      // If we have a humongous object with a few remembered sets, we simply flush these
+      // remembered set entries into the DCQS. That will result in automatic
+      // re-evaluation of their remembered set entries during the following evacuation
+      // phase.
       if (!r->rem_set()->is_empty()) {
         guarantee(r->rem_set()->occupancy_less_or_equal_than(G1RSetSparseRegionEntries),
                   "Found a not-small remembered set here. This is inconsistent with previous assumptions.");
@@ -3499,8 +3525,6 @@
         r->rem_set()->clear_locked();
       }
       assert(r->rem_set()->is_empty(), "At this point any humongous candidate remembered set must be empty.");
-      g1h->register_humongous_region_with_cset(region_idx);
-      _candidate_humongous++;
     }
     _total_humongous++;
 
@@ -3520,6 +3544,7 @@
   }
   double time = os::elapsed_counter();
 
+  // Collect reclaim candidate information and register candidates with cset.
   RegisterHumongousWithInCSetFastTestClosure cl;
   heap_region_iterate(&cl);
 
@@ -3529,10 +3554,6 @@
                                                                   cl.candidate_humongous());
   _has_humongous_reclaim_candidates = cl.candidate_humongous() > 0;
 
-  if (_has_humongous_reclaim_candidates || G1TraceEagerReclaimHumongousObjects) {
-    clear_humongous_is_live_table();
-  }
-
   // Finally flush all remembered set entries to re-check into the global DCQS.
   cl.flush_rem_set_entries();
 }
@@ -5994,11 +6015,11 @@
     // required because stale remembered sets might reference locations that
     // are currently allocated into.
     uint region_idx = r->hrm_index();
-    if (g1h->humongous_is_live(region_idx) ||
-        g1h->humongous_region_is_always_live(region_idx)) {
+    if (!g1h->is_humongous_reclaim_candidate(region_idx) ||
+        !r->rem_set()->is_empty()) {
 
       if (G1TraceEagerReclaimHumongousObjects) {
-        gclog_or_tty->print_cr("Live humongous region %u size "SIZE_FORMAT" start "PTR_FORMAT" length "UINT32_FORMAT" with remset "SIZE_FORMAT" code roots "SIZE_FORMAT" is marked %d live-other %d obj array %d",
+        gclog_or_tty->print_cr("Live humongous region %u size "SIZE_FORMAT" start "PTR_FORMAT" length "UINT32_FORMAT" with remset "SIZE_FORMAT" code roots "SIZE_FORMAT" is marked %d reclaim candidate %d type array %d",
                                region_idx,
                                obj->size()*HeapWordSize,
                                r->bottom(),
@@ -6006,20 +6027,21 @@
                                r->rem_set()->occupied(),
                                r->rem_set()->strong_code_roots_list_length(),
                                next_bitmap->isMarked(r->bottom()),
-                               g1h->humongous_is_live(region_idx),
-                               obj->is_objArray()
+                               g1h->is_humongous_reclaim_candidate(region_idx),
+                               obj->is_typeArray()
                               );
       }
 
       return false;
     }
 
-    guarantee(!obj->is_objArray(),
-              err_msg("Eagerly reclaiming object arrays is not supported, but the object "PTR_FORMAT" is.",
+    guarantee(obj->is_typeArray(),
+              err_msg("Only eagerly reclaiming type arrays is supported, but the object "
+                      PTR_FORMAT " is not.",
                       r->bottom()));
 
     if (G1TraceEagerReclaimHumongousObjects) {
-      gclog_or_tty->print_cr("Dead humongous region %u size "SIZE_FORMAT" start "PTR_FORMAT" length "UINT32_FORMAT" with remset "SIZE_FORMAT" code roots "SIZE_FORMAT" is marked %d live-other %d obj array %d",
+      gclog_or_tty->print_cr("Dead humongous region %u size "SIZE_FORMAT" start "PTR_FORMAT" length "UINT32_FORMAT" with remset "SIZE_FORMAT" code roots "SIZE_FORMAT" is marked %d reclaim candidate %d type array %d",
                              region_idx,
                              obj->size()*HeapWordSize,
                              r->bottom(),
@@ -6027,8 +6049,8 @@
                              r->rem_set()->occupied(),
                              r->rem_set()->strong_code_roots_list_length(),
                              next_bitmap->isMarked(r->bottom()),
-                             g1h->humongous_is_live(region_idx),
-                             obj->is_objArray()
+                             g1h->is_humongous_reclaim_candidate(region_idx),
+                             obj->is_typeArray()
                             );
     }
     // Need to clear mark bit of the humongous object if already set.
@@ -6163,8 +6185,6 @@
 }
 
 void G1CollectedHeap::set_region_short_lived_locked(HeapRegion* hr) {
-  assert(heap_lock_held_for_gc(),
-              "the heap lock should already be held by or for this thread");
   _young_list->push_region(hr);
 }
 
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -40,9 +40,9 @@
 #include "gc_implementation/g1/heapRegionSet.hpp"
 #include "gc_implementation/shared/hSpaceCounters.hpp"
 #include "gc_implementation/shared/parGCAllocBuffer.hpp"
+#include "gc_interface/collectedHeap.hpp"
 #include "memory/barrierSet.hpp"
 #include "memory/memRegion.hpp"
-#include "memory/sharedHeap.hpp"
 #include "utilities/stack.hpp"
 
 // A "G1CollectedHeap" is an implementation of a java heap for HotSpot.
@@ -76,6 +76,7 @@
 class EvacuationFailedInfo;
 class nmethod;
 class Ticks;
+class FlexibleWorkGang;
 
 typedef OverflowTaskQueue<StarTask, mtGC>         RefToScanQueue;
 typedef GenericTaskQueueSet<RefToScanQueue, mtGC> RefToScanQueueSet;
@@ -177,7 +178,7 @@
   virtual void on_commit(uint start_idx, size_t num_regions, bool zero_filled);
 };
 
-class G1CollectedHeap : public SharedHeap {
+class G1CollectedHeap : public CollectedHeap {
   friend class VM_CollectForMetadataAllocation;
   friend class VM_G1CollectForAllocation;
   friend class VM_G1CollectFull;
@@ -204,6 +205,8 @@
   // The one and only G1CollectedHeap, so static functions can find it.
   static G1CollectedHeap* _g1h;
 
+  FlexibleWorkGang* _workers;
+
   static size_t _humongous_object_threshold_in_words;
 
   // The secondary free list which contains regions that have been
@@ -217,7 +220,6 @@
   // It keeps track of the humongous regions.
   HeapRegionSet _humongous_set;
 
-  void clear_humongous_is_live_table();
   void eagerly_reclaim_humongous_regions();
 
   // The number of regions we could create by expansion.
@@ -287,22 +289,26 @@
   // Helper for monitoring and management support.
   G1MonitoringSupport* _g1mm;
 
-  // Records whether the region at the given index is kept live by roots or
-  // references from the young generation.
-  class HumongousIsLiveBiasedMappedArray : public G1BiasedMappedArray<bool> {
+  // Records whether the region at the given index is (still) a
+  // candidate for eager reclaim.  Only valid for humongous start
+  // regions; other regions have unspecified values.  Humongous start
+  // regions are initialized at start of collection pause, with
+  // candidates removed from the set as they are found reachable from
+  // roots or the young generation.
+  class HumongousReclaimCandidates : public G1BiasedMappedArray<bool> {
    protected:
     bool default_value() const { return false; }
    public:
     void clear() { G1BiasedMappedArray<bool>::clear(); }
-    void set_live(uint region) {
-      set_by_index(region, true);
+    void set_candidate(uint region, bool value) {
+      set_by_index(region, value);
     }
-    bool is_live(uint region) {
+    bool is_candidate(uint region) {
       return get_by_index(region);
     }
   };
 
-  HumongousIsLiveBiasedMappedArray _humongous_is_live;
+  HumongousReclaimCandidates _humongous_reclaim_candidates;
   // Stores whether during humongous object registration we found candidate regions.
   // If not, we can skip a few steps.
   bool _has_humongous_reclaim_candidates;
@@ -351,6 +357,12 @@
   // heap after a compaction.
   void print_hrm_post_compaction();
 
+  // Create a memory mapper for auxiliary data structures of the given size and
+  // translation factor.
+  static G1RegionToSpaceMapper* create_aux_memory_mapper(const char* description,
+                                                         size_t size,
+                                                         size_t translation_factor);
+
   double verify(bool guard, const char* msg);
   void verify_before_gc();
   void verify_after_gc();
@@ -605,6 +617,7 @@
   void enqueue_discovered_references(uint no_of_gc_workers);
 
 public:
+  FlexibleWorkGang* workers() const { return _workers; }
 
   G1Allocator* allocator() {
     return _allocator;
@@ -630,21 +643,18 @@
   inline AllocationContextStats& allocation_context_stats();
 
   // Do anything common to GC's.
-  virtual void gc_prologue(bool full);
-  virtual void gc_epilogue(bool full);
+  void gc_prologue(bool full);
+  void gc_epilogue(bool full);
 
+  // Modify the reclaim candidate set and test for presence.
+  // These are only valid for starts_humongous regions.
+  inline void set_humongous_reclaim_candidate(uint region, bool value);
+  inline bool is_humongous_reclaim_candidate(uint region);
+
+  // Remove from the reclaim candidate set.  Also remove from the
+  // collection set so that later encounters avoid the slow path.
   inline void set_humongous_is_live(oop obj);
 
-  bool humongous_is_live(uint region) {
-    return _humongous_is_live.is_live(region);
-  }
-
-  // Returns whether the given region (which must be a humongous (start) region)
-  // is to be considered conservatively live regardless of any other conditions.
-  bool humongous_region_is_always_live(uint index);
-  // Returns whether the given region (which must be a humongous (start) region)
-  // is considered a candidate for eager reclamation.
-  bool humongous_region_is_candidate(uint index);
   // Register the given region to be part of the collection set.
   inline void register_humongous_region_with_cset(uint index);
   // Register regions with humongous objects (actually on the start region) in
@@ -1000,11 +1010,14 @@
   // Return the (conservative) maximum heap alignment for any G1 heap
   static size_t conservative_max_heap_alignment();
 
+  // Does operations required after initialization has been done.
+  void post_initialize();
+
   // Initialize weak reference processing.
-  virtual void ref_processing_init();
+  void ref_processing_init();
 
   // Explicitly import set_par_threads into this scope
-  using SharedHeap::set_par_threads;
+  using CollectedHeap::set_par_threads;
   // Set _n_par_threads according to a policy TBD.
   void set_par_threads();
 
@@ -1251,10 +1264,6 @@
 
   // Iteration functions.
 
-  // Iterate over all the ref-containing fields of all objects, calling
-  // "cl.do_oop" on each.
-  virtual void oop_iterate(ExtendedOopClosure* cl);
-
   // Iterate over all objects, calling "cl.do_object" on each.
   virtual void object_iterate(ObjectClosure* cl);
 
@@ -1262,9 +1271,6 @@
     object_iterate(cl);
   }
 
-  // Iterate over all spaces in use in the heap, in ascending address order.
-  virtual void space_iterate(SpaceClosure* cl);
-
   // Iterate over heap regions, in address order, terminating the
   // iteration early if the "doHeapRegion" method returns "true".
   void heap_region_iterate(HeapRegionClosure* blk) const;
@@ -1307,10 +1313,6 @@
 
   HeapRegion* next_compaction_region(const HeapRegion* from) const;
 
-  // A CollectedHeap will contain some number of spaces.  This finds the
-  // space containing a given address, or else returns NULL.
-  virtual Space* space_containing(const void* addr) const;
-
   // Returns the HeapRegion that contains addr. addr must not be NULL.
   template <class T>
   inline HeapRegion* heap_region_containing_raw(const T addr) const;
@@ -1344,9 +1346,6 @@
   // the block is an object.
   virtual bool block_is_obj(const HeapWord* addr) const;
 
-  // Does this heap support heap inspection? (+PrintClassHistogram)
-  virtual bool supports_heap_inspection() const { return true; }
-
   // Section on thread-local allocation buffers (TLABs)
   // See CollectedHeap for semantics.
 
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -352,20 +352,30 @@
   return is_obj_ill(obj, heap_region_containing(obj));
 }
 
+inline void G1CollectedHeap::set_humongous_reclaim_candidate(uint region, bool value) {
+  assert(_hrm.at(region)->is_starts_humongous(), "Must start a humongous object");
+  _humongous_reclaim_candidates.set_candidate(region, value);
+}
+
+inline bool G1CollectedHeap::is_humongous_reclaim_candidate(uint region) {
+  assert(_hrm.at(region)->is_starts_humongous(), "Must start a humongous object");
+  return _humongous_reclaim_candidates.is_candidate(region);
+}
+
 inline void G1CollectedHeap::set_humongous_is_live(oop obj) {
   uint region = addr_to_region((HeapWord*)obj);
-  // We not only set the "live" flag in the humongous_is_live table, but also
+  // Clear the flag in the humongous_reclaim_candidates table.  Also
   // reset the entry in the _in_cset_fast_test table so that subsequent references
   // to the same humongous object do not go into the slow path again.
   // This is racy, as multiple threads may at the same time enter here, but this
   // is benign.
-  // During collection we only ever set the "live" flag, and only ever clear the
+  // During collection we only ever clear the "candidate" flag, and only ever clear the
   // entry in the in_cset_fast_table.
   // We only ever evaluate the contents of these tables (in the VM thread) after
   // having synchronized the worker threads with the VM thread, or in the same
   // thread (i.e. within the VM thread).
-  if (!_humongous_is_live.is_live(region)) {
-    _humongous_is_live.set_live(region);
+  if (is_humongous_reclaim_candidate(region)) {
+    set_humongous_reclaim_candidate(region, false);
     _in_cset_fast_test.clear_humongous(region);
   }
 }
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -1460,7 +1460,7 @@
   _max_survivor_regions = (uint) ceil(max_survivor_regions_d);
 
   _tenuring_threshold = _survivors_age_table.compute_tenuring_threshold(
-        HeapRegion::GrainWords * _max_survivor_regions);
+        HeapRegion::GrainWords * _max_survivor_regions, counters());
 }
 
 bool G1CollectorPolicy::force_initial_mark_if_outside_cycle(
--- a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015 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
@@ -263,7 +263,6 @@
   _gc_par_phases[SystemDictionaryRoots] = new WorkerDataArray<double>(max_gc_threads, "SystemDictionary Roots (ms)", true, G1Log::LevelFinest, 3);
   _gc_par_phases[CLDGRoots] = new WorkerDataArray<double>(max_gc_threads, "CLDG Roots (ms)", true, G1Log::LevelFinest, 3);
   _gc_par_phases[JVMTIRoots] = new WorkerDataArray<double>(max_gc_threads, "JVMTI Roots (ms)", true, G1Log::LevelFinest, 3);
-  _gc_par_phases[CodeCacheRoots] = new WorkerDataArray<double>(max_gc_threads, "CodeCache Roots (ms)", true, G1Log::LevelFinest, 3);
   _gc_par_phases[CMRefRoots] = new WorkerDataArray<double>(max_gc_threads, "CM RefProcessor Roots (ms)", true, G1Log::LevelFinest, 3);
   _gc_par_phases[WaitForStrongCLD] = new WorkerDataArray<double>(max_gc_threads, "Wait For Strong CLD (ms)", true, G1Log::LevelFinest, 3);
   _gc_par_phases[WeakCLDRoots] = new WorkerDataArray<double>(max_gc_threads, "Weak CLD Roots (ms)", true, G1Log::LevelFinest, 3);
--- a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015 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
@@ -51,7 +51,6 @@
     SystemDictionaryRoots,
     CLDGRoots,
     JVMTIRoots,
-    CodeCacheRoots,
     CMRefRoots,
     WaitForStrongCLD,
     WeakCLDRoots,
--- a/hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -29,7 +29,7 @@
 #include "gc_implementation/g1/g1CardCounts.hpp"
 #include "memory/allocation.hpp"
 #include "runtime/safepoint.hpp"
-#include "runtime/thread.inline.hpp"
+#include "runtime/thread.hpp"
 #include "utilities/globalDefinitions.hpp"
 
 class DirtyCardQueue;
@@ -123,7 +123,7 @@
   // Resets the hot card cache and discards the entries.
   void reset_hot_cache() {
     assert(SafepointSynchronize::is_at_safepoint(), "Should be at a safepoint");
-    assert(Thread::current()->is_VM_thread(), "Current thread should be the VMthread");
+    assert(Thread::current_noinline()->is_VM_thread(), "Current thread should be the VMthread");
     if (default_use_cache()) {
         reset_hot_cache_internal();
     }
--- a/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -61,9 +61,8 @@
                                       bool clear_all_softrefs) {
   assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint");
 
-  SharedHeap* sh = SharedHeap::heap();
 #ifdef ASSERT
-  if (sh->collector_policy()->should_clear_all_soft_refs()) {
+  if (G1CollectedHeap::heap()->collector_policy()->should_clear_all_soft_refs()) {
     assert(clear_all_softrefs, "Policy should have been checked earler");
   }
 #endif
@@ -102,11 +101,6 @@
   BiasedLocking::restore_marks();
   GenMarkSweep::deallocate_stacks();
 
-  // "free at last gc" is calculated from these.
-  // CHF: cheating for now!!!
-  //  Universe::set_heap_capacity_at_last_gc(Universe::heap()->capacity());
-  //  Universe::set_heap_used_at_last_gc(Universe::heap()->used());
-
   CodeCache::gc_epilogue();
   JvmtiExport::gc_epilogue();
 
@@ -168,12 +162,12 @@
   Klass::clean_weak_klass_links(&GenMarkSweep::is_alive);
 
   // Delete entries for dead interned string and clean up unreferenced symbols in symbol table.
-  G1CollectedHeap::heap()->unlink_string_and_symbol_table(&GenMarkSweep::is_alive);
+  g1h->unlink_string_and_symbol_table(&GenMarkSweep::is_alive);
 
   if (VerifyDuringGC) {
     HandleMark hm;  // handle scope
     COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact);
-    Universe::heap()->prepare_for_verify();
+    g1h->prepare_for_verify();
     // Note: we can verify only the heap here. When an object is
     // marked, the previous value of the mark word (including
     // identity hash values, ages, etc) is preserved, and the mark
@@ -187,7 +181,7 @@
     if (!VerifySilently) {
       gclog_or_tty->print(" VerifyDuringGC:(full)[Verifying ");
     }
-    Universe::heap()->verify(VerifySilently, VerifyOption_G1UseMarkWord);
+    g1h->verify(VerifySilently, VerifyOption_G1UseMarkWord);
     if (!VerifySilently) {
       gclog_or_tty->print_cr("]");
     }
--- a/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -25,7 +25,7 @@
 #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1MARKSWEEP_HPP
 #define SHARE_VM_GC_IMPLEMENTATION_G1_G1MARKSWEEP_HPP
 
-#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
+#include "gc_implementation/g1/g1CollectedHeap.hpp"
 #include "gc_implementation/g1/heapRegion.hpp"
 #include "memory/genMarkSweep.hpp"
 #include "memory/generation.hpp"
--- a/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -23,9 +23,12 @@
  */
 
 #include "precompiled.hpp"
+#include "gc_implementation/g1/g1_specialized_oop_closures.hpp"
 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
 #include "gc_implementation/g1/g1OopClosures.inline.hpp"
 #include "gc_implementation/g1/g1ParScanThreadState.hpp"
+#include "memory/iterator.inline.hpp"
+#include "utilities/stack.inline.hpp"
 
 G1ParCopyHelper::G1ParCopyHelper(G1CollectedHeap* g1,  G1ParScanThreadState* par_scan_state) :
   G1ParClosureSuper(g1, par_scan_state), _scanned_klass(NULL),
@@ -50,3 +53,6 @@
   assert(_worker_id < MAX2((uint)ParallelGCThreads, 1u),
          err_msg("The given worker id %u must be less than the number of threads %u", _worker_id, MAX2((uint)ParallelGCThreads, 1u)));
 }
+
+// Generate G1 specialized oop_oop_iterate functions.
+SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_G1(ALL_KLASS_OOP_OOP_ITERATE_DEFN)
--- a/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.inline.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.inline.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, 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
@@ -172,7 +172,7 @@
   oopDesc* o = obj;
 #endif // CHECK_UNHANDLED_OOPS
   assert((intptr_t)o % MinObjAlignmentInBytes == 0, "not oop aligned");
-  assert(Universe::heap()->is_in_reserved(obj), "must be in heap");
+  assert(_g1->is_in_reserved(obj), "must be in heap");
 #endif // ASSERT
 
   assert(_from != NULL, "from region must be non-NULL");
--- a/hotspot/src/share/vm/gc_implementation/g1/g1PageBasedVirtualSpace.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1PageBasedVirtualSpace.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, 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
@@ -44,37 +44,45 @@
 #endif
 #include "utilities/bitMap.inline.hpp"
 
-G1PageBasedVirtualSpace::G1PageBasedVirtualSpace() : _low_boundary(NULL),
-  _high_boundary(NULL), _committed(), _page_size(0), _special(false),
+G1PageBasedVirtualSpace::G1PageBasedVirtualSpace(ReservedSpace rs, size_t used_size, size_t page_size) :
+  _low_boundary(NULL), _high_boundary(NULL), _committed(), _page_size(0), _special(false),
   _dirty(), _executable(false) {
+  initialize_with_page_size(rs, used_size, page_size);
 }
 
-bool G1PageBasedVirtualSpace::initialize_with_granularity(ReservedSpace rs, size_t page_size) {
-  if (!rs.is_reserved()) {
-    return false;  // Allocation failed.
-  }
-  assert(_low_boundary == NULL, "VirtualSpace already initialized");
-  assert(page_size > 0, "Granularity must be non-zero.");
+void G1PageBasedVirtualSpace::initialize_with_page_size(ReservedSpace rs, size_t used_size, size_t page_size) {
+  guarantee(rs.is_reserved(), "Given reserved space must have been reserved already.");
+
+  vmassert(_low_boundary == NULL, "VirtualSpace already initialized");
+  vmassert(page_size > 0, "Page size must be non-zero.");
+
+  guarantee(is_ptr_aligned(rs.base(), page_size),
+            err_msg("Reserved space base " PTR_FORMAT " is not aligned to requested page size " SIZE_FORMAT, p2i(rs.base()), page_size));
+  guarantee(is_size_aligned(used_size, os::vm_page_size()),
+            err_msg("Given used reserved space size needs to be OS page size aligned (%d bytes) but is " SIZE_FORMAT, os::vm_page_size(), used_size));
+  guarantee(used_size <= rs.size(),
+            err_msg("Used size of reserved space " SIZE_FORMAT " bytes is smaller than reservation at " SIZE_FORMAT " bytes", used_size, rs.size()));
+  guarantee(is_size_aligned(rs.size(), page_size),
+            err_msg("Expected that the virtual space is size aligned, but " SIZE_FORMAT " is not aligned to page size " SIZE_FORMAT, rs.size(), page_size));
 
   _low_boundary  = rs.base();
-  _high_boundary = _low_boundary + rs.size();
+  _high_boundary = _low_boundary + used_size;
 
   _special = rs.special();
   _executable = rs.executable();
 
   _page_size = page_size;
 
-  assert(_committed.size() == 0, "virtual space initialized more than once");
-  uintx size_in_bits = rs.size() / page_size;
-  _committed.resize(size_in_bits, /* in_resource_area */ false);
+  vmassert(_committed.size() == 0, "virtual space initialized more than once");
+  BitMap::idx_t size_in_pages = rs.size() / page_size;
+  _committed.resize(size_in_pages, /* in_resource_area */ false);
   if (_special) {
-    _dirty.resize(size_in_bits, /* in_resource_area */ false);
+    _dirty.resize(size_in_pages, /* in_resource_area */ false);
   }
 
-  return true;
+  _tail_size = used_size % _page_size;
 }
 
-
 G1PageBasedVirtualSpace::~G1PageBasedVirtualSpace() {
   release();
 }
@@ -87,12 +95,18 @@
   _special                = false;
   _executable             = false;
   _page_size              = 0;
+  _tail_size              = 0;
   _committed.resize(0, false);
   _dirty.resize(0, false);
 }
 
 size_t G1PageBasedVirtualSpace::committed_size() const {
-  return _committed.count_one_bits() * _page_size;
+  size_t result = _committed.count_one_bits() * _page_size;
+  // The last page might not be in full.
+  if (is_last_page_partial() && _committed.at(_committed.size() - 1)) {
+    result -= _page_size - _tail_size;
+  }
+  return result;
 }
 
 size_t G1PageBasedVirtualSpace::reserved_size() const {
@@ -103,65 +117,134 @@
   return reserved_size() - committed_size();
 }
 
-uintptr_t G1PageBasedVirtualSpace::addr_to_page_index(char* addr) const {
+size_t G1PageBasedVirtualSpace::addr_to_page_index(char* addr) const {
   return (addr - _low_boundary) / _page_size;
 }
 
-bool G1PageBasedVirtualSpace::is_area_committed(uintptr_t start, size_t size_in_pages) const {
-  uintptr_t end = start + size_in_pages;
-  return _committed.get_next_zero_offset(start, end) >= end;
+bool G1PageBasedVirtualSpace::is_area_committed(size_t start_page, size_t size_in_pages) const {
+  size_t end_page = start_page + size_in_pages;
+  return _committed.get_next_zero_offset(start_page, end_page) >= end_page;
 }
 
-bool G1PageBasedVirtualSpace::is_area_uncommitted(uintptr_t start, size_t size_in_pages) const {
-  uintptr_t end = start + size_in_pages;
-  return _committed.get_next_one_offset(start, end) >= end;
+bool G1PageBasedVirtualSpace::is_area_uncommitted(size_t start_page, size_t size_in_pages) const {
+  size_t end_page = start_page + size_in_pages;
+  return _committed.get_next_one_offset(start_page, end_page) >= end_page;
 }
 
-char* G1PageBasedVirtualSpace::page_start(uintptr_t index) {
+char* G1PageBasedVirtualSpace::page_start(size_t index) const {
   return _low_boundary + index * _page_size;
 }
 
-size_t G1PageBasedVirtualSpace::byte_size_for_pages(size_t num) {
-  return num * _page_size;
+bool G1PageBasedVirtualSpace::is_after_last_page(size_t index) const {
+  guarantee(index <= _committed.size(),
+            err_msg("Given boundary page " SIZE_FORMAT " is beyond managed page count " SIZE_FORMAT, index, _committed.size()));
+  return index == _committed.size();
+}
+
+void G1PageBasedVirtualSpace::commit_preferred_pages(size_t start, size_t num_pages) {
+  vmassert(num_pages > 0, "No full pages to commit");
+  vmassert(start + num_pages <= _committed.size(),
+           err_msg("Tried to commit area from page " SIZE_FORMAT " to page " SIZE_FORMAT " "
+                   "that is outside of managed space of " SIZE_FORMAT " pages",
+                   start, start + num_pages, _committed.size()));
+
+  char* start_addr = page_start(start);
+  size_t size = num_pages * _page_size;
+
+  os::commit_memory_or_exit(start_addr, size, _page_size, _executable,
+                            err_msg("Failed to commit area from " PTR_FORMAT " to " PTR_FORMAT " of length " SIZE_FORMAT ".",
+                                    p2i(start_addr), p2i(start_addr + size), size));
+}
+
+void G1PageBasedVirtualSpace::commit_tail() {
+  vmassert(_tail_size > 0, "The size of the tail area must be > 0 when reaching here");
+
+  char* const aligned_end_address = (char*)align_ptr_down(_high_boundary, _page_size);
+  os::commit_memory_or_exit(aligned_end_address, _tail_size, os::vm_page_size(), _executable,
+                            err_msg("Failed to commit tail area from " PTR_FORMAT " to " PTR_FORMAT " of length " SIZE_FORMAT ".",
+                                    p2i(aligned_end_address), p2i(_high_boundary), _tail_size));
 }
 
-bool G1PageBasedVirtualSpace::commit(uintptr_t start, size_t size_in_pages) {
+void G1PageBasedVirtualSpace::commit_internal(size_t start_page, size_t end_page) {
+  guarantee(start_page < end_page,
+            err_msg("Given start page " SIZE_FORMAT " is larger or equal to end page " SIZE_FORMAT, start_page, end_page));
+  guarantee(end_page <= _committed.size(),
+            err_msg("Given end page " SIZE_FORMAT " is beyond end of managed page amount of " SIZE_FORMAT, end_page, _committed.size()));
+
+  size_t pages = end_page - start_page;
+  bool need_to_commit_tail = is_after_last_page(end_page) && is_last_page_partial();
+
+  // If we have to commit some (partial) tail area, decrease the amount of pages to avoid
+  // committing that in the full-page commit code.
+  if (need_to_commit_tail) {
+    pages--;
+  }
+
+  if (pages > 0) {
+    commit_preferred_pages(start_page, pages);
+  }
+
+  if (need_to_commit_tail) {
+    commit_tail();
+  }
+}
+
+char* G1PageBasedVirtualSpace::bounded_end_addr(size_t end_page) const {
+  return MIN2(_high_boundary, page_start(end_page));
+}
+
+void G1PageBasedVirtualSpace::pretouch_internal(size_t start_page, size_t end_page) {
+  guarantee(start_page < end_page,
+            err_msg("Given start page " SIZE_FORMAT " is larger or equal to end page " SIZE_FORMAT, start_page, end_page));
+
+  os::pretouch_memory(page_start(start_page), bounded_end_addr(end_page));
+}
+
+bool G1PageBasedVirtualSpace::commit(size_t start_page, size_t size_in_pages) {
   // We need to make sure to commit all pages covered by the given area.
-  guarantee(is_area_uncommitted(start, size_in_pages), "Specified area is not uncommitted");
+  guarantee(is_area_uncommitted(start_page, size_in_pages), "Specified area is not uncommitted");
 
   bool zero_filled = true;
-  uintptr_t end = start + size_in_pages;
+  size_t end_page = start_page + size_in_pages;
 
   if (_special) {
     // Check for dirty pages and update zero_filled if any found.
-    if (_dirty.get_next_one_offset(start,end) < end) {
+    if (_dirty.get_next_one_offset(start_page, end_page) < end_page) {
       zero_filled = false;
-      _dirty.clear_range(start, end);
+      _dirty.clear_range(start_page, end_page);
     }
   } else {
-    os::commit_memory_or_exit(page_start(start), byte_size_for_pages(size_in_pages), _executable,
-                              err_msg("Failed to commit pages from "SIZE_FORMAT" of length "SIZE_FORMAT, start, size_in_pages));
+    commit_internal(start_page, end_page);
   }
-  _committed.set_range(start, end);
+  _committed.set_range(start_page, end_page);
 
   if (AlwaysPreTouch) {
-    os::pretouch_memory(page_start(start), page_start(end));
+    pretouch_internal(start_page, end_page);
   }
   return zero_filled;
 }
 
-void G1PageBasedVirtualSpace::uncommit(uintptr_t start, size_t size_in_pages) {
-  guarantee(is_area_committed(start, size_in_pages), "checking");
+void G1PageBasedVirtualSpace::uncommit_internal(size_t start_page, size_t end_page) {
+  guarantee(start_page < end_page,
+            err_msg("Given start page " SIZE_FORMAT " is larger or equal to end page " SIZE_FORMAT, start_page, end_page));
 
+  char* start_addr = page_start(start_page);
+  os::uncommit_memory(start_addr, pointer_delta(bounded_end_addr(end_page), start_addr, sizeof(char)));
+}
+
+void G1PageBasedVirtualSpace::uncommit(size_t start_page, size_t size_in_pages) {
+  guarantee(is_area_committed(start_page, size_in_pages), "checking");
+
+  size_t end_page = start_page + size_in_pages;
   if (_special) {
     // Mark that memory is dirty. If committed again the memory might
     // need to be cleared explicitly.
-    _dirty.set_range(start, start + size_in_pages);
+    _dirty.set_range(start_page, end_page);
   } else {
-    os::uncommit_memory(page_start(start), byte_size_for_pages(size_in_pages));
+    uncommit_internal(start_page, end_page);
   }
 
-  _committed.clear_range(start, start + size_in_pages);
+  _committed.clear_range(start_page, end_page);
 }
 
 bool G1PageBasedVirtualSpace::contains(const void* p) const {
@@ -175,7 +258,8 @@
   out->cr();
   out->print_cr(" - committed: " SIZE_FORMAT, committed_size());
   out->print_cr(" - reserved:  " SIZE_FORMAT, reserved_size());
-  out->print_cr(" - [low_b, high_b]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]",  p2i(_low_boundary), p2i(_high_boundary));
+  out->print_cr(" - preferred page size: " SIZE_FORMAT, _page_size);
+  out->print_cr(" - [low_b, high_b]: [" PTR_FORMAT ", " PTR_FORMAT "]",  p2i(_low_boundary), p2i(_high_boundary));
 }
 
 void G1PageBasedVirtualSpace::print() {
--- a/hotspot/src/share/vm/gc_implementation/g1/g1PageBasedVirtualSpace.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1PageBasedVirtualSpace.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -34,6 +34,12 @@
 // granularity.
 // (De-)Allocation requests are always OS page aligned by passing a page index
 // and multiples of pages.
+// For systems that only commits of memory in a given size (always greater than
+// page size) the base address is required to be aligned to that page size.
+// The actual size requested need not be aligned to that page size, but the size
+// of the reservation passed may be rounded up to this page size. Any fragment
+// (less than the page size) of the actual size at the tail of the request will
+// be committed using OS small pages.
 // The implementation gives an error when trying to commit or uncommit pages that
 // have already been committed or uncommitted.
 class G1PageBasedVirtualSpace VALUE_OBJ_CLASS_SPEC {
@@ -43,7 +49,11 @@
   char* _low_boundary;
   char* _high_boundary;
 
-  // The commit/uncommit granularity in bytes.
+  // The size of the tail in bytes of the handled space that needs to be committed
+  // using small pages.
+  size_t _tail_size;
+
+  // The preferred page size used for commit/uncommit in bytes.
   size_t _page_size;
 
   // Bitmap used for verification of commit/uncommit operations.
@@ -62,30 +72,55 @@
   // Indicates whether the committed space should be executable.
   bool _executable;
 
+  // Helper function for committing memory. Commit the given memory range by using
+  // _page_size pages as much as possible and the remainder with small sized pages.
+  void commit_internal(size_t start_page, size_t end_page);
+  // Commit num_pages pages of _page_size size starting from start. All argument
+  // checking has been performed.
+  void commit_preferred_pages(size_t start_page, size_t end_page);
+  // Commit space at the high end of the space that needs to be committed with small
+  // sized pages.
+  void commit_tail();
+
+  // Uncommit the given memory range.
+  void uncommit_internal(size_t start_page, size_t end_page);
+
+  // Pretouch the given memory range.
+  void pretouch_internal(size_t start_page, size_t end_page);
+
   // Returns the index of the page which contains the given address.
   uintptr_t  addr_to_page_index(char* addr) const;
   // Returns the address of the given page index.
-  char*  page_start(uintptr_t index);
-  // Returns the byte size of the given number of pages.
-  size_t byte_size_for_pages(size_t num);
+  char*  page_start(size_t index) const;
+
+  // Is the given page index the last page?
+  bool is_last_page(size_t index) const { return index == (_committed.size() - 1); }
+  // Is the given page index the first after last page?
+  bool is_after_last_page(size_t index) const;
+  // Is the last page only partially covered by this space?
+  bool is_last_page_partial() const { return !is_ptr_aligned(_high_boundary, _page_size); }
+  // Returns the end address of the given page bounded by the reserved space.
+  char* bounded_end_addr(size_t end_page) const;
 
   // Returns true if the entire area is backed by committed memory.
-  bool is_area_committed(uintptr_t start, size_t size_in_pages) const;
+  bool is_area_committed(size_t start_page, size_t size_in_pages) const;
   // Returns true if the entire area is not backed by committed memory.
-  bool is_area_uncommitted(uintptr_t start, size_t size_in_pages) const;
+  bool is_area_uncommitted(size_t start_page, size_t size_in_pages) const;
 
+  void initialize_with_page_size(ReservedSpace rs, size_t used_size, size_t page_size);
  public:
 
   // Commit the given area of pages starting at start being size_in_pages large.
   // Returns true if the given area is zero filled upon completion.
-  bool commit(uintptr_t start, size_t size_in_pages);
+  bool commit(size_t start_page, size_t size_in_pages);
 
   // Uncommit the given area of pages starting at start being size_in_pages large.
-  void uncommit(uintptr_t start, size_t size_in_pages);
+  void uncommit(size_t start_page, size_t size_in_pages);
 
-  // Initialization
-  G1PageBasedVirtualSpace();
-  bool initialize_with_granularity(ReservedSpace rs, size_t page_size);
+  // Initialize the given reserved space with the given base address and the size
+  // actually used.
+  // Prefer to commit in page_size chunks.
+  G1PageBasedVirtualSpace(ReservedSpace rs, size_t used_size, size_t page_size);
 
   // Destruction
   ~G1PageBasedVirtualSpace();
--- a/hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -26,8 +26,10 @@
 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
 #include "gc_implementation/g1/g1OopClosures.inline.hpp"
 #include "gc_implementation/g1/g1ParScanThreadState.inline.hpp"
+#include "gc_implementation/g1/g1StringDedup.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/prefetch.inline.hpp"
+#include "utilities/stack.inline.hpp"
 
 G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, uint queue_num, ReferenceProcessor* rp)
   : _g1h(g1h),
--- a/hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.inline.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.inline.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, 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
@@ -63,7 +63,7 @@
   assert(has_partial_array_mask(p), "invariant");
   oop from_obj = clear_partial_array_mask(p);
 
-  assert(Universe::heap()->is_in_reserved(from_obj), "must be in heap.");
+  assert(_g1h->is_in_reserved(from_obj), "must be in heap.");
   assert(from_obj->is_objArray(), "must be obj array");
   objArrayOop from_obj_array = objArrayOop(from_obj);
   // The from-space object contains the real length.
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RegionToSpaceMapper.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RegionToSpaceMapper.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, 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
@@ -31,17 +31,16 @@
 #include "utilities/bitMap.inline.hpp"
 
 G1RegionToSpaceMapper::G1RegionToSpaceMapper(ReservedSpace rs,
-                                             size_t commit_granularity,
+                                             size_t used_size,
+                                             size_t page_size,
                                              size_t region_granularity,
                                              MemoryType type) :
-  _storage(),
-  _commit_granularity(commit_granularity),
+  _storage(rs, used_size, page_size),
   _region_granularity(region_granularity),
   _listener(NULL),
   _commit_map() {
-  guarantee(is_power_of_2(commit_granularity), "must be");
+  guarantee(is_power_of_2(page_size), "must be");
   guarantee(is_power_of_2(region_granularity), "must be");
-  _storage.initialize_with_granularity(rs, commit_granularity);
 
   MemTracker::record_virtual_memory_type((address)rs.base(), type);
 }
@@ -55,25 +54,26 @@
 
  public:
   G1RegionsLargerThanCommitSizeMapper(ReservedSpace rs,
-                                      size_t os_commit_granularity,
+                                      size_t actual_size,
+                                      size_t page_size,
                                       size_t alloc_granularity,
                                       size_t commit_factor,
                                       MemoryType type) :
-     G1RegionToSpaceMapper(rs, os_commit_granularity, alloc_granularity, type),
-    _pages_per_region(alloc_granularity / (os_commit_granularity * commit_factor)) {
+    G1RegionToSpaceMapper(rs, actual_size, page_size, alloc_granularity, type),
+    _pages_per_region(alloc_granularity / (page_size * commit_factor)) {
 
-    guarantee(alloc_granularity >= os_commit_granularity, "allocation granularity smaller than commit granularity");
+    guarantee(alloc_granularity >= page_size, "allocation granularity smaller than commit granularity");
     _commit_map.resize(rs.size() * commit_factor / alloc_granularity, /* in_resource_area */ false);
   }
 
-  virtual void commit_regions(uintptr_t start_idx, size_t num_regions) {
-    bool zero_filled = _storage.commit(start_idx * _pages_per_region, num_regions * _pages_per_region);
+  virtual void commit_regions(uint start_idx, size_t num_regions) {
+    bool zero_filled = _storage.commit((size_t)start_idx * _pages_per_region, num_regions * _pages_per_region);
     _commit_map.set_range(start_idx, start_idx + num_regions);
     fire_on_commit(start_idx, num_regions, zero_filled);
   }
 
-  virtual void uncommit_regions(uintptr_t start_idx, size_t num_regions) {
-    _storage.uncommit(start_idx * _pages_per_region, num_regions * _pages_per_region);
+  virtual void uncommit_regions(uint start_idx, size_t num_regions) {
+    _storage.uncommit((size_t)start_idx * _pages_per_region, num_regions * _pages_per_region);
     _commit_map.clear_range(start_idx, start_idx + num_regions);
   }
 };
@@ -98,22 +98,23 @@
 
  public:
   G1RegionsSmallerThanCommitSizeMapper(ReservedSpace rs,
-                                       size_t os_commit_granularity,
+                                       size_t actual_size,
+                                       size_t page_size,
                                        size_t alloc_granularity,
                                        size_t commit_factor,
                                        MemoryType type) :
-     G1RegionToSpaceMapper(rs, os_commit_granularity, alloc_granularity, type),
-    _regions_per_page((os_commit_granularity * commit_factor) / alloc_granularity), _refcounts() {
+    G1RegionToSpaceMapper(rs, actual_size, page_size, alloc_granularity, type),
+    _regions_per_page((page_size * commit_factor) / alloc_granularity), _refcounts() {
 
-    guarantee((os_commit_granularity * commit_factor) >= alloc_granularity, "allocation granularity smaller than commit granularity");
-    _refcounts.initialize((HeapWord*)rs.base(), (HeapWord*)(rs.base() + rs.size()), os_commit_granularity);
+    guarantee((page_size * commit_factor) >= alloc_granularity, "allocation granularity smaller than commit granularity");
+    _refcounts.initialize((HeapWord*)rs.base(), (HeapWord*)(rs.base() + align_size_up(rs.size(), page_size)), page_size);
     _commit_map.resize(rs.size() * commit_factor / alloc_granularity, /* in_resource_area */ false);
   }
 
-  virtual void commit_regions(uintptr_t start_idx, size_t num_regions) {
-    for (uintptr_t i = start_idx; i < start_idx + num_regions; i++) {
-      assert(!_commit_map.at(i), err_msg("Trying to commit storage at region "INTPTR_FORMAT" that is already committed", i));
-      uintptr_t idx = region_idx_to_page_idx(i);
+  virtual void commit_regions(uint start_idx, size_t num_regions) {
+    for (uint i = start_idx; i < start_idx + num_regions; i++) {
+      assert(!_commit_map.at(i), err_msg("Trying to commit storage at region %u that is already committed", i));
+      size_t idx = region_idx_to_page_idx(i);
       uint old_refcount = _refcounts.get_by_index(idx);
       bool zero_filled = false;
       if (old_refcount == 0) {
@@ -125,10 +126,10 @@
     }
   }
 
-  virtual void uncommit_regions(uintptr_t start_idx, size_t num_regions) {
-    for (uintptr_t i = start_idx; i < start_idx + num_regions; i++) {
-      assert(_commit_map.at(i), err_msg("Trying to uncommit storage at region "INTPTR_FORMAT" that is not committed", i));
-      uintptr_t idx = region_idx_to_page_idx(i);
+  virtual void uncommit_regions(uint start_idx, size_t num_regions) {
+    for (uint i = start_idx; i < start_idx + num_regions; i++) {
+      assert(_commit_map.at(i), err_msg("Trying to uncommit storage at region %u that is not committed", i));
+      size_t idx = region_idx_to_page_idx(i);
       uint old_refcount = _refcounts.get_by_index(idx);
       assert(old_refcount > 0, "must be");
       if (old_refcount == 1) {
@@ -147,14 +148,15 @@
 }
 
 G1RegionToSpaceMapper* G1RegionToSpaceMapper::create_mapper(ReservedSpace rs,
-                                                            size_t os_commit_granularity,
+                                                            size_t actual_size,
+                                                            size_t page_size,
                                                             size_t region_granularity,
                                                             size_t commit_factor,
                                                             MemoryType type) {
 
-  if (region_granularity >= (os_commit_granularity * commit_factor)) {
-    return new G1RegionsLargerThanCommitSizeMapper(rs, os_commit_granularity, region_granularity, commit_factor, type);
+  if (region_granularity >= (page_size * commit_factor)) {
+    return new G1RegionsLargerThanCommitSizeMapper(rs, actual_size, page_size, region_granularity, commit_factor, type);
   } else {
-    return new G1RegionsSmallerThanCommitSizeMapper(rs, os_commit_granularity, region_granularity, commit_factor, type);
+    return new G1RegionsSmallerThanCommitSizeMapper(rs, actual_size, page_size, region_granularity, commit_factor, type);
   }
 }
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RegionToSpaceMapper.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RegionToSpaceMapper.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -46,12 +46,12 @@
  protected:
   // Backing storage.
   G1PageBasedVirtualSpace _storage;
-  size_t _commit_granularity;
+
   size_t _region_granularity;
   // Mapping management
   BitMap _commit_map;
 
-  G1RegionToSpaceMapper(ReservedSpace rs, size_t commit_granularity, size_t region_granularity, MemoryType type);
+  G1RegionToSpaceMapper(ReservedSpace rs, size_t used_size, size_t page_size, size_t region_granularity, MemoryType type);
 
   void fire_on_commit(uint start_idx, size_t num_regions, bool zero_filled);
  public:
@@ -70,16 +70,20 @@
     return _commit_map.at(idx);
   }
 
-  virtual void commit_regions(uintptr_t start_idx, size_t num_regions = 1) = 0;
-  virtual void uncommit_regions(uintptr_t start_idx, size_t num_regions = 1) = 0;
+  virtual void commit_regions(uint start_idx, size_t num_regions = 1) = 0;
+  virtual void uncommit_regions(uint start_idx, size_t num_regions = 1) = 0;
 
   // Creates an appropriate G1RegionToSpaceMapper for the given parameters.
+  // The actual space to be used within the given reservation is given by actual_size.
+  // This is because some OSes need to round up the reservation size to guarantee
+  // alignment of page_size.
   // The byte_translation_factor defines how many bytes in a region correspond to
   // a single byte in the data structure this mapper is for.
   // Eg. in the card table, this value corresponds to the size a single card
-  // table entry corresponds to.
+  // table entry corresponds to in the heap.
   static G1RegionToSpaceMapper* create_mapper(ReservedSpace rs,
-                                              size_t os_commit_granularity,
+                                              size_t actual_size,
+                                              size_t page_size,
                                               size_t region_granularity,
                                               size_t byte_translation_factor,
                                               MemoryType type);
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -38,6 +38,7 @@
 #include "oops/oop.inline.hpp"
 #include "utilities/globalDefinitions.hpp"
 #include "utilities/intHisto.hpp"
+#include "utilities/stack.inline.hpp"
 
 #define CARD_REPEAT_HISTO 0
 
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.inline.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.inline.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, 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
@@ -57,7 +57,7 @@
   oopDesc* o = obj;
 #endif // CHECK_UNHANDLED_OOPS
   assert((intptr_t)o % MinObjAlignmentInBytes == 0, "not oop aligned");
-  assert(Universe::heap()->is_in_reserved(obj), "must be in heap");
+  assert(_g1->is_in_reserved(obj), "must be in heap");
 #endif // ASSERT
 
   assert(from == NULL || from->is_in_reserved(p), "p is not in from");
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RootProcessor.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RootProcessor.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -116,7 +116,7 @@
 G1RootProcessor::G1RootProcessor(G1CollectedHeap* g1h) :
     _g1h(g1h),
     _process_strong_tasks(new SubTasksDone(G1RP_PS_NumElements)),
-    _srs(g1h),
+    _srs(),
     _lock(Mutex::leaf, "G1 Root Scanning barrier lock", false, Monitor::_safepoint_check_never),
     _n_workers_discovered_strong_classes(0) {}
 
@@ -253,7 +253,8 @@
 
   {
     G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::ThreadRoots, worker_i);
-    Threads::possibly_parallel_oops_do(strong_roots, thread_stack_clds, strong_code);
+    bool is_par = _g1h->n_par_threads() > 0;
+    Threads::possibly_parallel_oops_do(is_par, strong_roots, thread_stack_clds, strong_code);
   }
 }
 
@@ -323,10 +324,6 @@
 void G1RootProcessor::scan_remembered_sets(G1ParPushHeapRSClosure* scan_rs,
                                            OopClosure* scan_non_heap_weak_roots,
                                            uint worker_i) {
-  G1GCPhaseTimes* phase_times = _g1h->g1_policy()->phase_times();
-  G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::CodeCacheRoots, worker_i);
-
-  // Now scan the complement of the collection set.
   G1CodeBlobClosure scavenge_cs_nmethods(scan_non_heap_weak_roots);
 
   _g1h->g1_rem_set()->oops_into_collection_set_do(scan_rs, &scavenge_cs_nmethods, worker_i);
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RootProcessor.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RootProcessor.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -26,7 +26,7 @@
 #define SHARE_VM_GC_IMPLEMENTATION_G1_ROOTPROCESSOR_HPP
 
 #include "memory/allocation.hpp"
-#include "memory/sharedHeap.hpp"
+#include "memory/strongRootsScope.hpp"
 #include "runtime/mutex.hpp"
 
 class CLDClosure;
@@ -46,7 +46,7 @@
 class G1RootProcessor : public StackObj {
   G1CollectedHeap* _g1h;
   SubTasksDone* _process_strong_tasks;
-  SharedHeap::StrongRootsScope _srs;
+  StrongRootsScope _srs;
 
   // Used to implement the Thread work barrier.
   Monitor _lock;
--- a/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -206,7 +206,7 @@
   if (new_val == NULL) return;
   // Otherwise, log it.
   G1SATBCardTableLoggingModRefBS* g1_bs =
-    barrier_set_cast<G1SATBCardTableLoggingModRefBS>(Universe::heap()->barrier_set());
+    barrier_set_cast<G1SATBCardTableLoggingModRefBS>(G1CollectedHeap::heap()->barrier_set());
   g1_bs->write_ref_field_work(field, new_val);
 }
 
--- a/hotspot/src/share/vm/gc_implementation/g1/g1StringDedupQueue.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1StringDedupQueue.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "classfile/javaClasses.inline.hpp"
+#include "gc_implementation/g1/g1CollectedHeap.hpp"
 #include "gc_implementation/g1/g1StringDedup.hpp"
 #include "gc_implementation/g1/g1StringDedupQueue.hpp"
 #include "memory/gcLocker.hpp"
@@ -163,7 +164,7 @@
     while (!iter.is_empty()) {
       oop obj = iter.next();
       if (obj != NULL) {
-        guarantee(Universe::heap()->is_in_reserved(obj), "Object must be on the heap");
+        guarantee(G1CollectedHeap::heap()->is_in_reserved(obj), "Object must be on the heap");
         guarantee(!obj->is_forwarded(), "Object must not be forwarded");
         guarantee(java_lang_String::is_instance(obj), "Object must be a String");
       }
--- a/hotspot/src/share/vm/gc_implementation/g1/g1StringDedupTable.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1StringDedupTable.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -27,6 +27,7 @@
 #include "classfile/javaClasses.inline.hpp"
 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
+#include "gc_implementation/g1/g1StringDedup.hpp"
 #include "gc_implementation/g1/g1StringDedupTable.hpp"
 #include "memory/gcLocker.hpp"
 #include "memory/padded.inline.hpp"
@@ -519,7 +520,7 @@
     while (*entry != NULL) {
       typeArrayOop value = (*entry)->obj();
       guarantee(value != NULL, "Object must not be NULL");
-      guarantee(Universe::heap()->is_in_reserved(value), "Object must be on the heap");
+      guarantee(G1CollectedHeap::heap()->is_in_reserved(value), "Object must be on the heap");
       guarantee(!value->is_forwarded(), "Object must not be forwarded");
       guarantee(value->is_typeArray(), "Object must be a typeArrayOop");
       unsigned int hash = hash_code(value);
--- a/hotspot/src/share/vm/gc_implementation/g1/g1StringDedupTable.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1StringDedupTable.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -29,6 +29,7 @@
 #include "runtime/mutexLocker.hpp"
 
 class G1StringDedupEntryCache;
+class G1StringDedupUnlinkOrOopsDoClosure;
 
 //
 // Table entry in the deduplication hashtable. Points weakly to the
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -31,7 +31,6 @@
 #include "gc_implementation/g1/survRateGroup.hpp"
 #include "gc_implementation/shared/ageTable.hpp"
 #include "gc_implementation/shared/spaceDecorator.hpp"
-#include "memory/space.inline.hpp"
 #include "memory/watermark.hpp"
 #include "utilities/macros.hpp"
 
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -330,8 +330,12 @@
         assert(!hrclaimer->is_region_claimed(ch_index),
                "Must not have been claimed yet because claiming of humongous continuation first claims the start region");
 
-        // There's no need to actually claim the continues humongous region, but we can do it in an assert as an extra precaution.
-        assert(hrclaimer->claim_region(ch_index), "We should always be able to claim the continuesHumongous part of the humongous object");
+        // Claim the region so no other worker tries to process the region. When a worker processes a
+        // starts_humongous region it may also process the associated continues_humongous regions.
+        // The continues_humongous regions can be changed to free regions. Unless this worker claims
+        // all of these regions, other workers might try claim and process these newly free regions.
+        bool claim_result = hrclaimer->claim_region(ch_index);
+        guarantee(claim_result, "We should always be able to claim the continuesHumongous part of the humongous object");
 
         bool res2 = blk->doHeapRegion(chr);
         if (res2) {
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -419,6 +419,7 @@
   ReservedSpace bot_rs(G1BlockOffsetSharedArray::compute_size(heap.word_size()));
   G1RegionToSpaceMapper* bot_storage =
     G1RegionToSpaceMapper::create_mapper(bot_rs,
+                                         bot_rs.size(),
                                          os::vm_page_size(),
                                          HeapRegion::GrainBytes,
                                          G1BlockOffsetSharedArray::N_bytes,
--- a/hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -25,8 +25,8 @@
 #include "precompiled.hpp"
 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
 #include "gc_implementation/g1/satbQueue.hpp"
+#include "gc_interface/collectedHeap.hpp"
 #include "memory/allocation.inline.hpp"
-#include "memory/sharedHeap.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/mutexLocker.hpp"
 #include "runtime/thread.hpp"
--- a/hotspot/src/share/vm/gc_implementation/g1/vmStructs_g1.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/vmStructs_g1.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -26,8 +26,8 @@
 #define SHARE_VM_GC_IMPLEMENTATION_G1_VMSTRUCTS_G1_HPP
 
 #include "gc_implementation/g1/heapRegion.hpp"
-#include "gc_implementation/g1/heapRegionManager.inline.hpp"
-#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
+#include "gc_implementation/g1/heapRegionManager.hpp"
+#include "gc_implementation/g1/g1CollectedHeap.hpp"
 
 #define VM_STRUCTS_G1(nonstatic_field, static_field)                          \
                                                                               \
@@ -70,7 +70,7 @@
                                                                               \
   declare_toplevel_type(G1HeapRegionTable)                                    \
                                                                               \
-  declare_type(G1CollectedHeap, SharedHeap)                                   \
+  declare_type(G1CollectedHeap, CollectedHeap)                                \
                                                                               \
   declare_type(G1OffsetTableContigSpace, CompactibleSpace)                    \
   declare_type(HeapRegion, G1OffsetTableContigSpace)                          \
--- a/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -225,15 +225,10 @@
 
 void VM_CGC_Operation::doit() {
   TraceCPUTime tcpu(G1Log::finer(), true, gclog_or_tty);
-  GCTraceTime t(_printGCMessage, G1Log::fine(), true, G1CollectedHeap::heap()->gc_timer_cm(), G1CollectedHeap::heap()->concurrent_mark()->concurrent_gc_id());
-  SharedHeap* sh = SharedHeap::heap();
-  // This could go away if CollectedHeap gave access to _gc_is_active...
-  if (sh != NULL) {
-    IsGCActiveMark x;
-    _cl->do_void();
-  } else {
-    _cl->do_void();
-  }
+  G1CollectedHeap* g1h = G1CollectedHeap::heap();
+  GCTraceTime t(_printGCMessage, G1Log::fine(), true, g1h->gc_timer_cm(), g1h->concurrent_mark()->concurrent_gc_id());
+  IsGCActiveMark x;
+  _cl->do_void();
 }
 
 bool VM_CGC_Operation::doit_prologue() {
@@ -244,14 +239,12 @@
   }
 
   Heap_lock->lock();
-  SharedHeap::heap()->_thread_holds_heap_lock_for_gc = true;
   return true;
 }
 
 void VM_CGC_Operation::doit_epilogue() {
   // Note the relative order of the unlocks must match that in
   // VM_GC_Operation::doit_epilogue()
-  SharedHeap::heap()->_thread_holds_heap_lock_for_gc = false;
   Heap_lock->unlock();
   if (_needs_pll) {
     release_and_notify_pending_list_lock();
--- a/hotspot/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -23,12 +23,12 @@
  */
 
 #include "precompiled.hpp"
+#include "gc_interface/collectedHeap.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/cardTableModRefBS.hpp"
 #include "memory/cardTableRS.hpp"
-#include "memory/sharedHeap.hpp"
+#include "memory/genCollectedHeap.hpp"
 #include "memory/space.inline.hpp"
-#include "memory/universe.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/java.hpp"
 #include "runtime/mutexLocker.hpp"
@@ -449,7 +449,7 @@
   // Do a dirty read here. If we pass the conditional then take the rare
   // event lock and do the read again in case some other thread had already
   // succeeded and done the resize.
-  int cur_collection = Universe::heap()->total_collections();
+  int cur_collection = GenCollectedHeap::heap()->total_collections();
   if (_last_LNC_resizing_collection[i] != cur_collection) {
     MutexLocker x(ParGCRareEvent_lock);
     if (_last_LNC_resizing_collection[i] != cur_collection) {
--- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -42,7 +42,7 @@
 #include "memory/generation.hpp"
 #include "memory/referencePolicy.hpp"
 #include "memory/resourceArea.hpp"
-#include "memory/sharedHeap.hpp"
+#include "memory/strongRootsScope.hpp"
 #include "memory/space.hpp"
 #include "oops/objArrayOop.hpp"
 #include "oops/oop.inline.hpp"
@@ -53,6 +53,7 @@
 #include "runtime/thread.inline.hpp"
 #include "utilities/copy.hpp"
 #include "utilities/globalDefinitions.hpp"
+#include "utilities/stack.inline.hpp"
 #include "utilities/workgroup.hpp"
 
 #ifdef _MSC_VER
@@ -117,7 +118,7 @@
 void ParScanThreadState::scan_partial_array_and_push_remainder(oop old) {
   assert(old->is_objArray(), "must be obj array");
   assert(old->is_forwarded(), "must be forwarded");
-  assert(Universe::heap()->is_in_reserved(old), "must be in heap.");
+  assert(GenCollectedHeap::heap()->is_in_reserved(old), "must be in heap.");
   assert(!old_gen()->is_in(old), "must be in young generation.");
 
   objArrayOop obj = objArrayOop(old->forwardee());
@@ -199,9 +200,9 @@
   for (size_t i = 0; i != num_take_elems; i++) {
     oop cur = of_stack->pop();
     oop obj_to_push = cur->forwardee();
-    assert(Universe::heap()->is_in_reserved(cur), "Should be in heap");
+    assert(GenCollectedHeap::heap()->is_in_reserved(cur), "Should be in heap");
     assert(!old_gen()->is_in_reserved(cur), "Should be in young gen");
-    assert(Universe::heap()->is_in_reserved(obj_to_push), "Should be in heap");
+    assert(GenCollectedHeap::heap()->is_in_reserved(obj_to_push), "Should be in heap");
     if (should_be_partially_scanned(obj_to_push, cur)) {
       assert(arrayOop(cur)->length() == 0, "entire array remaining to be scanned");
       obj_to_push = cur;
@@ -596,8 +597,6 @@
   // and handle marks.
   ResourceMark rm;
   HandleMark hm;
-  // We would need multiple old-gen queues otherwise.
-  assert(gch->n_gens() == 2, "Par young collection currently only works with one older gen.");
 
   ParScanThreadState& par_scan_state = _state_set->thread_state(worker_id);
   assert(_state_set->is_valid(worker_id), "Should not have been called");
@@ -697,7 +696,7 @@
 
   _par_cl->do_oop_nv(p);
 
-  if (Universe::heap()->is_in_reserved(p)) {
+  if (GenCollectedHeap::heap()->is_in_reserved(p)) {
     oop obj = oopDesc::load_decode_heap_oop_not_null(p);
     _rs->write_ref_field_gc_par(p, obj);
   }
@@ -724,7 +723,7 @@
 
   _cl->do_oop_nv(p);
 
-  if (Universe::heap()->is_in_reserved(p)) {
+  if (GenCollectedHeap::heap()->is_in_reserved(p)) {
     oop obj = oopDesc::load_decode_heap_oop_not_null(p);
     _rs->write_ref_field_gc_par(p, obj);
   }
@@ -823,8 +822,6 @@
 void ParNewRefProcTaskExecutor::execute(ProcessTask& task)
 {
   GenCollectedHeap* gch = GenCollectedHeap::heap();
-  assert(gch->kind() == CollectedHeap::GenCollectedHeap,
-         "not a generational heap");
   FlexibleWorkGang* workers = gch->workers();
   assert(workers != NULL, "Need parallel worker threads.");
   _state_set.reset(workers->active_workers(), _generation.promotion_failed());
@@ -899,7 +896,7 @@
     _gc_tracer.report_promotion_failed(_promotion_failed_info);
   }
   // Reset the PromotionFailureALot counters.
-  NOT_PRODUCT(Universe::heap()->reset_promotion_should_fail();)
+  NOT_PRODUCT(gch->reset_promotion_should_fail();)
 }
 
 void ParNewGeneration::collect(bool   full,
@@ -912,8 +909,6 @@
 
   _gc_timer->register_gc_start();
 
-  assert(gch->kind() == CollectedHeap::GenCollectedHeap,
-    "not a CMS generational heap");
   AdaptiveSizePolicy* size_policy = gch->gen_policy()->size_policy();
   FlexibleWorkGang* workers = gch->workers();
   assert(workers != NULL, "Need workgang for parallel work");
@@ -922,8 +917,6 @@
                                    workers->active_workers(),
                                    Threads::number_of_non_daemon_threads());
   workers->set_active_workers(active_workers);
-  assert(gch->n_gens() == 2,
-         "Par collection currently only works with single older gen.");
   _old_gen = gch->old_gen();
 
   // If the next generation is too full to accommodate worst-case promotion
@@ -974,10 +967,10 @@
   // in the multi-threaded case, but we special-case n=1 here to get
   // repeatable measurements of the 1-thread overhead of the parallel code.
   if (n_workers > 1) {
-    GenCollectedHeap::StrongRootsScope srs(gch);
+    StrongRootsScope srs;
     workers->run_task(&tsk);
   } else {
-    GenCollectedHeap::StrongRootsScope srs(gch);
+    StrongRootsScope srs;
     tsk.work(0);
   }
   thread_state_set.reset(0 /* Bad value in debug if not reset */,
@@ -1194,7 +1187,7 @@
   } else {
     // Is in to-space; do copying ourselves.
     Copy::aligned_disjoint_words((HeapWord*)old, (HeapWord*)new_obj, sz);
-    assert(Universe::heap()->is_in_reserved(new_obj), "illegal forwarding pointer value.");
+    assert(GenCollectedHeap::heap()->is_in_reserved(new_obj), "illegal forwarding pointer value.");
     forward_ptr = old->forward_to_atomic(new_obj);
     // Restore the mark word copied above.
     new_obj->set_mark(m);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "memory/iterator.inline.hpp"
+#include "memory/specialized_oop_closures.hpp"
+#include "gc_implementation/parNew/parOopClosures.inline.hpp"
+
+// Generate ParNew specialized oop_oop_iterate functions.
+SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_P(ALL_KLASS_OOP_OOP_ITERATE_DEFN);
--- a/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.inline.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.inline.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -70,7 +70,7 @@
 inline void ParScanClosure::do_oop_work(T* p,
                                         bool gc_barrier,
                                         bool root_scan) {
-  assert((!Universe::heap()->is_in_reserved(p) ||
+  assert((!GenCollectedHeap::heap()->is_in_reserved(p) ||
           generation()->is_in_reserved(p))
          && (generation()->level() == 0 || gc_barrier),
          "The gen must be right, and we must be doing the barrier "
@@ -82,7 +82,7 @@
 #ifndef PRODUCT
       if (_g->to()->is_in_reserved(obj)) {
         tty->print_cr("Scanning field (" PTR_FORMAT ") twice?", p2i(p));
-        GenCollectedHeap* gch =  (GenCollectedHeap*)Universe::heap();
+        GenCollectedHeap* gch = GenCollectedHeap::heap();
         Space* sp = gch->space_containing(p);
         oop obj = oop(sp->block_start(p));
         assert((HeapWord*)obj < (HeapWord*)p, "Error");
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSOldGen.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSOldGen.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, 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
@@ -89,7 +89,7 @@
   assert(virtual_space()->is_aligned(gen_size_limit()), "not aligned");
   assert(gen_size_limit() >= virtual_space()->committed_size(), "bad gen size");
 
-  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   size_t result =  gen_size_limit() - virtual_space()->committed_size();
   size_t result_aligned = align_size_down(result, heap->generation_alignment());
   return result_aligned;
@@ -101,7 +101,7 @@
     return uncommitted_bytes;
   }
 
-  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   const size_t gen_alignment = heap->generation_alignment();
   PSAdaptiveSizePolicy* policy = heap->size_policy();
   const size_t working_size =
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, 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
@@ -73,7 +73,7 @@
   size_t current_committed_size = virtual_space()->committed_size();
   assert((gen_size_limit() >= current_committed_size),
     "generation size limit is wrong");
-  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   size_t result =  gen_size_limit() - current_committed_size;
   size_t result_aligned = align_size_down(result, heap->generation_alignment());
   return result_aligned;
@@ -91,7 +91,7 @@
 
   if (eden_space()->is_empty()) {
     // Respect the minimum size for eden and for the young gen as a whole.
-    ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
+    ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
     const size_t eden_alignment = heap->space_alignment();
     const size_t gen_alignment = heap->generation_alignment();
 
@@ -128,7 +128,7 @@
 // If to_space is below from_space, to_space is not considered.
 // to_space can be.
 size_t ASPSYoungGen::available_to_live() {
-  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   const size_t alignment = heap->space_alignment();
 
   // Include any space that is committed but is not in eden.
@@ -292,7 +292,7 @@
 
   assert(eden_start < from_start, "Cannot push into from_space");
 
-  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   const size_t alignment = heap->space_alignment();
   const bool maintain_minimum =
     (requested_eden_size + 2 * requested_survivor_size) <= min_gen_size();
@@ -345,8 +345,6 @@
 
     // Does the optimal to-space overlap from-space?
     if (to_start < (char*)from_space()->end()) {
-      assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
-
       // Calculate the minimum offset possible for from_end
       size_t from_size =
         pointer_delta(from_space()->top(), from_start, sizeof(char));
@@ -509,9 +507,7 @@
   assert(from_space()->top() == old_from_top, "from top changed!");
 
   if (PrintAdaptiveSizePolicy) {
-    ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
-    assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
-
+    ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
     gclog_or_tty->print("AdaptiveSizePolicy::survivor space sizes: "
                   "collection: %d "
                   "(" SIZE_FORMAT ", " SIZE_FORMAT ") -> "
@@ -542,7 +538,7 @@
   }
   MemRegion cmr((HeapWord*)virtual_space()->low(),
                 (HeapWord*)virtual_space()->high());
-  Universe::heap()->barrier_set()->resize_covered_region(cmr);
+  ParallelScavengeHeap::heap()->barrier_set()->resize_covered_region(cmr);
 
   space_invariants();
 }
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -76,9 +76,7 @@
 
  public:
   CheckForUnmarkedObjects() {
-    ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
-    assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
-
+    ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
     _young_gen = heap->young_gen();
     _card_table = barrier_set_cast<CardTableExtension>(heap->barrier_set());
     // No point in asserting barrier set type here. Need to make CardTableExtension
@@ -325,9 +323,7 @@
 void CardTableExtension::verify_all_young_refs_imprecise() {
   CheckForUnmarkedObjects check;
 
-  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
-  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
-
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   PSOldGen* old_gen = heap->old_gen();
 
   old_gen->object_iterate(&check);
@@ -335,9 +331,7 @@
 
 // This should be called immediately after a scavenge, before mutators resume.
 void CardTableExtension::verify_all_young_refs_precise() {
-  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
-  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
-
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   PSOldGen* old_gen = heap->old_gen();
 
   CheckForPreciseMarks check(
@@ -351,7 +345,7 @@
 
 void CardTableExtension::verify_all_young_refs_precise_helper(MemRegion mr) {
   CardTableExtension* card_table =
-    barrier_set_cast<CardTableExtension>(Universe::heap()->barrier_set());
+    barrier_set_cast<CardTableExtension>(ParallelScavengeHeap::heap()->barrier_set());
 
   jbyte* bot = card_table->byte_for(mr.start());
   jbyte* top = card_table->byte_for(mr.end());
@@ -523,7 +517,7 @@
     cur_committed = new_committed;
   }
 #ifdef ASSERT
-  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   assert(cur_committed.start() ==
     (HeapWord*) align_size_up((uintptr_t) cur_committed.start(),
                               os::vm_page_size()),
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -78,13 +78,7 @@
 
   CardTableExtension* const barrier_set = new CardTableExtension(reserved_region());
   barrier_set->initialize();
-  _barrier_set = barrier_set;
-  oopDesc::set_bs(_barrier_set);
-  if (_barrier_set == NULL) {
-    vm_shutdown_during_initialization(
-      "Could not reserve enough space for barrier set");
-    return JNI_ENOMEM;
-  }
+  set_barrier_set(barrier_set);
 
   // Make up the generations
   // Calculate the maximum size that a generation can grow.  This
@@ -95,6 +89,7 @@
   double max_gc_pause_sec = ((double) MaxGCPauseMillis)/1000.0;
   double max_gc_minor_pause_sec = ((double) MaxGCMinorPauseMillis)/1000.0;
 
+  _psh = this;
   _gens = new AdjoiningGenerations(heap_rs, _collector_policy, generation_alignment());
 
   _old_gen = _gens->old_gen();
@@ -120,7 +115,6 @@
   // initialize the policy counters - 2 collectors, 3 generations
   _gc_policy_counters =
     new PSGCAdaptivePolicyCounters("ParScav:MSC", 2, 3, _size_policy);
-  _psh = this;
 
   // Set up the GCTaskManager
   _gc_task_manager = GCTaskManager::create(ParallelGCThreads);
@@ -176,27 +170,11 @@
 }
 
 bool ParallelScavengeHeap::is_in(const void* p) const {
-  if (young_gen()->is_in(p)) {
-    return true;
-  }
-
-  if (old_gen()->is_in(p)) {
-    return true;
-  }
-
-  return false;
+  return young_gen()->is_in(p) || old_gen()->is_in(p);
 }
 
 bool ParallelScavengeHeap::is_in_reserved(const void* p) const {
-  if (young_gen()->is_in_reserved(p)) {
-    return true;
-  }
-
-  if (old_gen()->is_in_reserved(p)) {
-    return true;
-  }
-
-  return false;
+  return young_gen()->is_in_reserved(p) || old_gen()->is_in_reserved(p);
 }
 
 bool ParallelScavengeHeap::is_scavengable(const void* addr) {
@@ -265,7 +243,7 @@
     // total_collections() value!
     {
       MutexLocker ml(Heap_lock);
-      gc_count = Universe::heap()->total_collections();
+      gc_count = total_collections();
 
       result = young_gen()->allocate(size);
       if (result != NULL) {
@@ -315,8 +293,7 @@
       // This prevents us from looping until time out on requests that can
       // not be satisfied.
       if (op.prologue_succeeded()) {
-        assert(Universe::heap()->is_in_or_null(op.result()),
-          "result not in heap");
+        assert(is_in_or_null(op.result()), "result not in heap");
 
         // If GC was locked out during VM operation then retry allocation
         // and/or stall as necessary.
@@ -426,7 +403,7 @@
 HeapWord* ParallelScavengeHeap::failed_mem_allocate(size_t size) {
   assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint");
   assert(Thread::current() == (Thread*)VMThread::vm_thread(), "should be in vm thread");
-  assert(!Universe::heap()->is_gc_active(), "not reentrant");
+  assert(!is_gc_active(), "not reentrant");
   assert(!Heap_lock->owned_by_self(), "this thread should not own the Heap_lock");
 
   // We assume that allocation in eden will fail unless we collect.
@@ -514,18 +491,14 @@
   {
     MutexLocker ml(Heap_lock);
     // This value is guarded by the Heap_lock
-    gc_count      = Universe::heap()->total_collections();
-    full_gc_count = Universe::heap()->total_full_collections();
+    gc_count      = total_collections();
+    full_gc_count = total_full_collections();
   }
 
   VM_ParallelGCSystemGC op(gc_count, full_gc_count, cause);
   VMThread::execute(&op);
 }
 
-void ParallelScavengeHeap::oop_iterate(ExtendedOopClosure* cl) {
-  Unimplemented();
-}
-
 void ParallelScavengeHeap::object_iterate(ObjectClosure* cl) {
   young_gen()->object_iterate(cl);
   old_gen()->object_iterate(cl);
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -32,8 +32,9 @@
 #include "gc_implementation/parallelScavenge/psYoungGen.hpp"
 #include "gc_implementation/shared/gcPolicyCounters.hpp"
 #include "gc_implementation/shared/gcWhen.hpp"
-#include "gc_interface/collectedHeap.inline.hpp"
+#include "gc_interface/collectedHeap.hpp"
 #include "memory/collectorPolicy.hpp"
+#include "memory/strongRootsScope.hpp"
 #include "utilities/ostream.hpp"
 
 class AdjoiningGenerations;
@@ -131,9 +132,6 @@
   // the young gen.
   virtual bool is_scavengable(const void* addr);
 
-  // Does this heap support heap inspection? (+PrintClassHistogram)
-  bool supports_heap_inspection() const { return true; }
-
   size_t max_capacity() const;
 
   // Whether p is in the allocated part of the heap
@@ -201,7 +199,6 @@
   // initializing stores to an object at this address.
   virtual bool can_elide_initializing_store_barrier(oop new_obj);
 
-  void oop_iterate(ExtendedOopClosure* cl);
   void object_iterate(ObjectClosure* cl);
   void safe_object_iterate(ObjectClosure* cl) { object_iterate(cl); }
 
@@ -238,7 +235,7 @@
   void gen_mangle_unused_area() PRODUCT_RETURN;
 
   // Call these in sequential code around the processing of strong roots.
-  class ParStrongRootsScope : public MarkingCodeBlobClosure::MarkScope {
+  class ParStrongRootsScope : public MarkScope {
    public:
     ParStrongRootsScope();
     ~ParStrongRootsScope();
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -41,13 +41,14 @@
 #include "runtime/thread.hpp"
 #include "runtime/vmThread.hpp"
 #include "services/management.hpp"
+#include "utilities/stack.inline.hpp"
 
 //
 // ThreadRootsMarkingTask
 //
 
 void ThreadRootsMarkingTask::do_it(GCTaskManager* manager, uint which) {
-  assert(Universe::heap()->is_gc_active(), "called outside gc");
+  assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc");
 
   ResourceMark rm;
 
@@ -78,7 +79,7 @@
 
 
 void MarkFromRootsTask::do_it(GCTaskManager* manager, uint which) {
-  assert(Universe::heap()->is_gc_active(), "called outside gc");
+  assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc");
 
   NOT_PRODUCT(GCTraceTime tm("MarkFromRootsTask",
     PrintGCDetails && TraceParallelOldGCTasks, true, NULL, PSParallelCompact::gc_tracer()->gc_id()));
@@ -149,7 +150,7 @@
 
 void RefProcTaskProxy::do_it(GCTaskManager* manager, uint which)
 {
-  assert(Universe::heap()->is_gc_active(), "called outside gc");
+  assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc");
 
   NOT_PRODUCT(GCTraceTime tm("RefProcTask",
     PrintGCDetails && TraceParallelOldGCTasks, true, NULL, PSParallelCompact::gc_tracer()->gc_id()));
@@ -167,7 +168,7 @@
 
 void RefProcTaskExecutor::execute(ProcessTask& task)
 {
-  ParallelScavengeHeap* heap = PSParallelCompact::gc_heap();
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   uint parallel_gc_threads = heap->gc_task_manager()->workers();
   uint active_gc_threads = heap->gc_task_manager()->active_workers();
   RegionTaskQueueSet* qset = ParCompactionManager::region_array();
@@ -188,7 +189,7 @@
 
 void RefProcTaskExecutor::execute(EnqueueTask& task)
 {
-  ParallelScavengeHeap* heap = PSParallelCompact::gc_heap();
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   uint parallel_gc_threads = heap->gc_task_manager()->workers();
   GCTaskQueue* q = GCTaskQueue::create();
   for(uint i=0; i<parallel_gc_threads; i++) {
@@ -205,7 +206,7 @@
   _terminator(t) {}
 
 void StealMarkingTask::do_it(GCTaskManager* manager, uint which) {
-  assert(Universe::heap()->is_gc_active(), "called outside gc");
+  assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc");
 
   NOT_PRODUCT(GCTraceTime tm("StealMarkingTask",
     PrintGCDetails && TraceParallelOldGCTasks, true, NULL, PSParallelCompact::gc_tracer()->gc_id()));
@@ -237,7 +238,7 @@
   _terminator(t) {}
 
 void StealRegionCompactionTask::do_it(GCTaskManager* manager, uint which) {
-  assert(Universe::heap()->is_gc_active(), "called outside gc");
+  assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc");
 
   NOT_PRODUCT(GCTraceTime tm("StealRegionCompactionTask",
     PrintGCDetails && TraceParallelOldGCTasks, true, NULL, PSParallelCompact::gc_tracer()->gc_id()));
@@ -319,7 +320,7 @@
 }
 
 void DrainStacksCompactionTask::do_it(GCTaskManager* manager, uint which) {
-  assert(Universe::heap()->is_gc_active(), "called outside gc");
+  assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc");
 
   NOT_PRODUCT(GCTraceTime tm("DrainStacksCompactionTask",
     PrintGCDetails && TraceParallelOldGCTasks, true, NULL, PSParallelCompact::gc_tracer()->gc_id()));
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -30,7 +30,10 @@
 #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
 #include "gc_implementation/parallelScavenge/psCompactionManager.inline.hpp"
 #include "gc_implementation/parallelScavenge/psOldGen.hpp"
-#include "gc_implementation/parallelScavenge/psParallelCompact.hpp"
+#include "gc_implementation/parallelScavenge/psParallelCompact.inline.hpp"
+#include "memory/iterator.inline.hpp"
+#include "oops/instanceKlass.inline.hpp"
+#include "oops/instanceMirrorKlass.inline.hpp"
 #include "oops/objArrayKlass.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/atomic.inline.hpp"
@@ -57,8 +60,7 @@
     _region_stack(NULL),
     _region_stack_index((uint)max_uintx) {
 
-  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
-  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
 
   _old_gen = heap->old_gen();
   _start_array = old_gen()->start_array();
@@ -174,6 +176,142 @@
   return _manager_array[index];
 }
 
+void InstanceKlass::oop_pc_follow_contents(oop obj, ParCompactionManager* cm) {
+  assert(obj != NULL, "can't follow the content of NULL object");
+
+  PSParallelCompact::follow_klass(cm, this);
+  // Only mark the header and let the scan of the meta-data mark
+  // everything else.
+
+  PSParallelCompact::MarkAndPushClosure cl(cm);
+  InstanceKlass::oop_oop_iterate_oop_maps<true>(obj, &cl);
+}
+
+void InstanceMirrorKlass::oop_pc_follow_contents(oop obj, ParCompactionManager* cm) {
+  InstanceKlass::oop_pc_follow_contents(obj, cm);
+
+  // Follow the klass field in the mirror.
+  Klass* klass = java_lang_Class::as_Klass(obj);
+  if (klass != NULL) {
+    // An anonymous class doesn't have its own class loader, so the call
+    // to follow_klass will mark and push its java mirror instead of the
+    // class loader. When handling the java mirror for an anonymous class
+    // we need to make sure its class loader data is claimed, this is done
+    // by calling follow_class_loader explicitly. For non-anonymous classes
+    // the call to follow_class_loader is made when the class loader itself
+    // is handled.
+    if (klass->oop_is_instance() && InstanceKlass::cast(klass)->is_anonymous()) {
+      PSParallelCompact::follow_class_loader(cm, klass->class_loader_data());
+    } else {
+      PSParallelCompact::follow_klass(cm, klass);
+    }
+  } else {
+    // If klass is NULL then this a mirror for a primitive type.
+    // We don't have to follow them, since they are handled as strong
+    // roots in Universe::oops_do.
+    assert(java_lang_Class::is_primitive(obj), "Sanity check");
+  }
+
+  PSParallelCompact::MarkAndPushClosure cl(cm);
+  oop_oop_iterate_statics<true>(obj, &cl);
+}
+
+void InstanceClassLoaderKlass::oop_pc_follow_contents(oop obj, ParCompactionManager* cm) {
+  InstanceKlass::oop_pc_follow_contents(obj, cm);
+
+  ClassLoaderData * const loader_data = java_lang_ClassLoader::loader_data(obj);
+  if (loader_data != NULL) {
+    PSParallelCompact::follow_class_loader(cm, loader_data);
+  }
+}
+
+template <class T>
+static void oop_pc_follow_contents_specialized(InstanceRefKlass* klass, oop obj, ParCompactionManager* cm) {
+  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
+  T heap_oop = oopDesc::load_heap_oop(referent_addr);
+  debug_only(
+    if(TraceReferenceGC && PrintGCDetails) {
+      gclog_or_tty->print_cr("InstanceRefKlass::oop_pc_follow_contents " PTR_FORMAT, p2i(obj));
+    }
+  )
+  if (!oopDesc::is_null(heap_oop)) {
+    oop referent = oopDesc::decode_heap_oop_not_null(heap_oop);
+    if (PSParallelCompact::mark_bitmap()->is_unmarked(referent) &&
+        PSParallelCompact::ref_processor()->discover_reference(obj, klass->reference_type())) {
+      // reference already enqueued, referent will be traversed later
+      klass->InstanceKlass::oop_pc_follow_contents(obj, cm);
+      debug_only(
+        if(TraceReferenceGC && PrintGCDetails) {
+          gclog_or_tty->print_cr("       Non NULL enqueued " PTR_FORMAT, p2i(obj));
+        }
+      )
+      return;
+    } else {
+      // treat referent as normal oop
+      debug_only(
+        if(TraceReferenceGC && PrintGCDetails) {
+          gclog_or_tty->print_cr("       Non NULL normal " PTR_FORMAT, p2i(obj));
+        }
+      )
+      PSParallelCompact::mark_and_push(cm, referent_addr);
+    }
+  }
+  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
+  if (ReferenceProcessor::pending_list_uses_discovered_field()) {
+    // Treat discovered as normal oop, if ref is not "active",
+    // i.e. if next is non-NULL.
+    T  next_oop = oopDesc::load_heap_oop(next_addr);
+    if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active"
+      T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
+      debug_only(
+        if(TraceReferenceGC && PrintGCDetails) {
+          gclog_or_tty->print_cr("   Process discovered as normal "
+                                 PTR_FORMAT, p2i(discovered_addr));
+        }
+      )
+      PSParallelCompact::mark_and_push(cm, discovered_addr);
+    }
+  } else {
+#ifdef ASSERT
+    // In the case of older JDKs which do not use the discovered
+    // field for the pending list, an inactive ref (next != NULL)
+    // must always have a NULL discovered field.
+    T next = oopDesc::load_heap_oop(next_addr);
+    oop discovered = java_lang_ref_Reference::discovered(obj);
+    assert(oopDesc::is_null(next) || oopDesc::is_null(discovered),
+           err_msg("Found an inactive reference " PTR_FORMAT " with a non-NULL discovered field",
+                   p2i(obj)));
+#endif
+  }
+  PSParallelCompact::mark_and_push(cm, next_addr);
+  klass->InstanceKlass::oop_pc_follow_contents(obj, cm);
+}
+
+
+void InstanceRefKlass::oop_pc_follow_contents(oop obj, ParCompactionManager* cm) {
+  if (UseCompressedOops) {
+    oop_pc_follow_contents_specialized<narrowOop>(this, obj, cm);
+  } else {
+    oop_pc_follow_contents_specialized<oop>(this, obj, cm);
+  }
+}
+
+void ObjArrayKlass::oop_pc_follow_contents(oop obj, ParCompactionManager* cm) {
+  PSParallelCompact::follow_klass(cm, this);
+
+  if (UseCompressedOops) {
+    oop_pc_follow_contents_specialized<narrowOop>(objArrayOop(obj), 0, cm);
+  } else {
+    oop_pc_follow_contents_specialized<oop>(objArrayOop(obj), 0, cm);
+  }
+}
+
+void TypeArrayKlass::oop_pc_follow_contents(oop obj, ParCompactionManager* cm) {
+  assert(obj->is_typeArray(),"must be a type array");
+  // Performance tweak: We skip iterating over the klass pointer since we
+  // know that Universe::TypeArrayKlass never moves.
+}
+
 void ParCompactionManager::follow_marking_stacks() {
   do {
     // Drain the overflow stack first, to allow stealing from the marking stack.
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.inline.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.inline.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -26,9 +26,11 @@
 #define SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSCOMPACTIONMANAGER_INLINE_HPP
 
 #include "gc_implementation/parallelScavenge/psCompactionManager.hpp"
-#include "gc_implementation/parallelScavenge/psParallelCompact.hpp"
-#include "oops/objArrayKlass.inline.hpp"
-#include "oops/oop.pcgc.inline.hpp"
+#include "gc_implementation/parallelScavenge/psParallelCompact.inline.hpp"
+#include "oops/objArrayOop.hpp"
+#include "oops/oop.inline.hpp"
+#include "utilities/debug.hpp"
+#include "utilities/globalDefinitions.hpp"
 
 void ParCompactionManager::push_objarray(oop obj, size_t index)
 {
@@ -49,16 +51,42 @@
 }
 
 inline void ParCompactionManager::follow_contents(oop obj) {
-  obj->follow_contents(this);
+  assert(PSParallelCompact::mark_bitmap()->is_marked(obj), "should be marked");
+  obj->pc_follow_contents(this);
+}
+
+template <class T>
+inline void oop_pc_follow_contents_specialized(objArrayOop obj, int index, ParCompactionManager* cm) {
+  const size_t len = size_t(obj->length());
+  const size_t beg_index = size_t(index);
+  assert(beg_index < len || len == 0, "index too large");
+
+  const size_t stride = MIN2(len - beg_index, ObjArrayMarkingStride);
+  const size_t end_index = beg_index + stride;
+  T* const base = (T*)obj->base();
+  T* const beg = base + beg_index;
+  T* const end = base + end_index;
+
+  // Push the non-NULL elements of the next stride on the marking stack.
+  for (T* e = beg; e < end; e++) {
+    PSParallelCompact::mark_and_push<T>(cm, e);
+  }
+
+  if (end_index < len) {
+    cm->push_objarray(obj, end_index); // Push the continuation.
+  }
 }
 
 inline void ParCompactionManager::follow_contents(objArrayOop obj, int index) {
-  ObjArrayKlass* k = (ObjArrayKlass*)obj->klass();
-  k->oop_follow_contents(this, obj, index);
+  if (UseCompressedOops) {
+    oop_pc_follow_contents_specialized<narrowOop>(obj, index, this);
+  } else {
+    oop_pc_follow_contents_specialized<oop>(obj, index, this);
+  }
 }
 
 inline void ParCompactionManager::update_contents(oop obj) {
-  obj->update_contents(this);
+  obj->pc_update_contents();
 }
 
 #endif // SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSCOMPACTIONMANAGER_INLINE_HPP
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -59,7 +59,7 @@
 CollectorCounters*  PSMarkSweep::_counters = NULL;
 
 void PSMarkSweep::initialize() {
-  MemRegion mr = Universe::heap()->reserved_region();
+  MemRegion mr = ParallelScavengeHeap::heap()->reserved_region();
   _ref_processor = new ReferenceProcessor(mr);     // a vanilla ref proc
   _counters = new CollectorCounters("PSMarkSweep", 1);
 }
@@ -81,9 +81,9 @@
 void PSMarkSweep::invoke(bool maximum_heap_compaction) {
   assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint");
   assert(Thread::current() == (Thread*)VMThread::vm_thread(), "should be in vm thread");
-  assert(!Universe::heap()->is_gc_active(), "not reentrant");
+  assert(!ParallelScavengeHeap::heap()->is_gc_active(), "not reentrant");
 
-  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   GCCause::Cause gc_cause = heap->gc_cause();
   PSAdaptiveSizePolicy* policy = heap->size_policy();
   IsGCActiveMark mark;
@@ -110,8 +110,7 @@
     return false;
   }
 
-  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
-  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   GCCause::Cause gc_cause = heap->gc_cause();
 
   _gc_timer->register_gc_start();
@@ -487,9 +486,7 @@
 }
 
 void PSMarkSweep::allocate_stacks() {
-  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
-  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
-
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   PSYoungGen* young_gen = heap->young_gen();
 
   MutableSpace* to_space = young_gen->to_space();
@@ -515,8 +512,7 @@
   GCTraceTime tm("phase 1", PrintGCDetails && Verbose, true, _gc_timer, _gc_tracer->gc_id());
   trace(" 1");
 
-  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
-  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
 
   // Need to clear claim bits before the tracing starts.
   ClassLoaderDataGraph::clear_claimed_marks();
@@ -582,9 +578,7 @@
   // phase2, phase3 and phase4, but the ValidateMarkSweep live oops
   // tracking expects us to do so. See comment under phase4.
 
-  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
-  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
-
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   PSOldGen* old_gen = heap->old_gen();
 
   // Begin compacting into the old gen
@@ -606,9 +600,7 @@
   GCTraceTime tm("phase 3", PrintGCDetails && Verbose, true, _gc_timer, _gc_tracer->gc_id());
   trace("3");
 
-  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
-  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
-
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   PSYoungGen* young_gen = heap->young_gen();
   PSOldGen* old_gen = heap->old_gen();
 
@@ -651,9 +643,7 @@
 
   // All pointers are now adjusted, move objects accordingly
 
-  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
-  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
-
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   PSYoungGen* young_gen = heap->young_gen();
   PSOldGen* old_gen = heap->old_gen();
 
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -38,15 +38,12 @@
 
 
 void PSMarkSweepDecorator::set_destination_decorator_tenured() {
-  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
-  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
-
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   _destination_decorator = heap->old_gen()->object_mark_sweep();
 }
 
 void PSMarkSweepDecorator::advance_destination_decorator() {
-  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
-  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
 
   assert(_destination_decorator != NULL, "Sanity");
 
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -107,20 +107,22 @@
     SpaceMangler::mangle_region(cmr);
   }
 
-  Universe::heap()->barrier_set()->resize_covered_region(cmr);
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
+  BarrierSet* bs = heap->barrier_set();
 
-  CardTableModRefBS* _ct =
-    barrier_set_cast<CardTableModRefBS>(Universe::heap()->barrier_set());
+  bs->resize_covered_region(cmr);
+
+  CardTableModRefBS* ct = barrier_set_cast<CardTableModRefBS>(bs);
 
   // Verify that the start and end of this generation is the start of a card.
   // If this wasn't true, a single card could span more than one generation,
   // which would cause problems when we commit/uncommit memory, and when we
   // clear and dirty cards.
-  guarantee(_ct->is_card_aligned(_reserved.start()), "generation must be card aligned");
-  if (_reserved.end() != Universe::heap()->reserved_region().end()) {
+  guarantee(ct->is_card_aligned(_reserved.start()), "generation must be card aligned");
+  if (_reserved.end() != heap->reserved_region().end()) {
     // Don't check at the very end of the heap as we'll assert that we're probing off
     // the end if we try.
-    guarantee(_ct->is_card_aligned(_reserved.end()), "generation must be card aligned");
+    guarantee(ct->is_card_aligned(_reserved.end()), "generation must be card aligned");
   }
 
   //
@@ -161,8 +163,7 @@
 }
 
 void PSOldGen::precompact() {
-  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
-  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
 
   // Reset start array first.
   start_array()->reset();
@@ -197,7 +198,7 @@
 
   // Allocations in the old generation need to be reported
   if (res != NULL) {
-    ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
+    ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
     heap->size_policy()->tenured_allocation(word_size);
   }
 
@@ -376,8 +377,7 @@
   }
 
   if (PrintAdaptiveSizePolicy) {
-    ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
-    assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
+    ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
     gclog_or_tty->print_cr("AdaptiveSizePolicy::old generation size: "
                   "collection: %d "
                   "(" SIZE_FORMAT ") -> (" SIZE_FORMAT ") ",
@@ -397,7 +397,7 @@
   size_t new_word_size = new_memregion.word_size();
 
   start_array()->set_covered_region(new_memregion);
-  Universe::heap()->barrier_set()->resize_covered_region(new_memregion);
+  ParallelScavengeHeap::heap()->barrier_set()->resize_covered_region(new_memregion);
 
   // ALWAYS do this last!!
   object_space()->initialize(new_memregion,
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -34,7 +34,7 @@
 #include "gc_implementation/parallelScavenge/psMarkSweep.hpp"
 #include "gc_implementation/parallelScavenge/psMarkSweepDecorator.hpp"
 #include "gc_implementation/parallelScavenge/psOldGen.hpp"
-#include "gc_implementation/parallelScavenge/psParallelCompact.hpp"
+#include "gc_implementation/parallelScavenge/psParallelCompact.inline.hpp"
 #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
 #include "gc_implementation/parallelScavenge/psScavenge.hpp"
 #include "gc_implementation/parallelScavenge/psYoungGen.hpp"
@@ -48,7 +48,10 @@
 #include "memory/gcLocker.inline.hpp"
 #include "memory/referencePolicy.hpp"
 #include "memory/referenceProcessor.hpp"
+#include "oops/instanceKlass.inline.hpp"
+#include "oops/instanceMirrorKlass.inline.hpp"
 #include "oops/methodData.hpp"
+#include "oops/objArrayKlass.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/atomic.inline.hpp"
 #include "runtime/fprofiler.hpp"
@@ -745,7 +748,7 @@
 
 HeapWord* ParallelCompactData::calc_new_pointer(HeapWord* addr) {
   assert(addr != NULL, "Should detect NULL oop earlier");
-  assert(PSParallelCompact::gc_heap()->is_in(addr), "not in heap");
+  assert(ParallelScavengeHeap::heap()->is_in(addr), "not in heap");
   assert(PSParallelCompact::mark_bitmap()->is_marked(addr), "not marked");
 
   // Region covering the object.
@@ -823,16 +826,8 @@
 PSParallelCompact::AdjustPointerClosure PSParallelCompact::_adjust_pointer_closure;
 PSParallelCompact::AdjustKlassClosure PSParallelCompact::_adjust_klass_closure;
 
-void PSParallelCompact::AdjustPointerClosure::do_oop(oop* p)       { adjust_pointer(p); }
-void PSParallelCompact::AdjustPointerClosure::do_oop(narrowOop* p) { adjust_pointer(p); }
-
 void PSParallelCompact::FollowStackClosure::do_void() { _compaction_manager->follow_marking_stacks(); }
 
-void PSParallelCompact::MarkAndPushClosure::do_oop(oop* p)       {
-  mark_and_push(_compaction_manager, p);
-}
-void PSParallelCompact::MarkAndPushClosure::do_oop(narrowOop* p) { mark_and_push(_compaction_manager, p); }
-
 void PSParallelCompact::FollowKlassClosure::do_klass(Klass* klass) {
   klass->oops_do(_mark_and_push_closure);
 }
@@ -841,9 +836,7 @@
 }
 
 void PSParallelCompact::post_initialize() {
-  ParallelScavengeHeap* heap = gc_heap();
-  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
-
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   MemRegion mr = heap->reserved_region();
   _ref_processor =
     new ReferenceProcessor(mr,            // span
@@ -860,8 +853,7 @@
 }
 
 bool PSParallelCompact::initialize() {
-  ParallelScavengeHeap* heap = gc_heap();
-  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   MemRegion mr = heap->reserved_region();
 
   // Was the old gen get allocated successfully?
@@ -895,7 +887,7 @@
 {
   memset(&_space_info, 0, sizeof(_space_info));
 
-  ParallelScavengeHeap* heap = gc_heap();
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   PSYoungGen* young_gen = heap->young_gen();
 
   _space_info[old_space_id].set_space(heap->old_gen()->object_space());
@@ -978,7 +970,7 @@
   // promotion failure does not swap spaces) because an unknown number of minor
   // collections will have swapped the spaces an unknown number of times.
   GCTraceTime tm("pre compact", print_phases(), true, &_gc_timer, _gc_tracer.gc_id());
-  ParallelScavengeHeap* heap = gc_heap();
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   _space_info[from_space_id].set_space(heap->young_gen()->from_space());
   _space_info[to_space_id].set_space(heap->young_gen()->to_space());
 
@@ -1033,7 +1025,7 @@
   MutableSpace* const from_space = _space_info[from_space_id].space();
   MutableSpace* const to_space   = _space_info[to_space_id].space();
 
-  ParallelScavengeHeap* heap = gc_heap();
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   bool eden_empty = eden_space->is_empty();
   if (!eden_empty) {
     eden_empty = absorb_live_data_from_eden(heap->size_policy(),
@@ -1971,7 +1963,7 @@
   assert(Thread::current() == (Thread*)VMThread::vm_thread(),
          "should be in vm thread");
 
-  ParallelScavengeHeap* heap = gc_heap();
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   GCCause::Cause gc_cause = heap->gc_cause();
   assert(!heap->is_gc_active(), "not reentrant");
 
@@ -1999,7 +1991,7 @@
     return false;
   }
 
-  ParallelScavengeHeap* heap = gc_heap();
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
 
   _gc_timer.register_gc_start();
   _gc_tracer.report_gc_start(heap->gc_cause(), _gc_timer.gc_start());
@@ -2352,7 +2344,7 @@
   // Recursively traverse all live objects and mark them
   GCTraceTime tm("marking phase", print_phases(), true, &_gc_timer, _gc_tracer.gc_id());
 
-  ParallelScavengeHeap* heap = gc_heap();
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   uint parallel_gc_threads = heap->gc_task_manager()->workers();
   uint active_gc_threads = heap->gc_task_manager()->active_workers();
   TaskQueueSetSuper* qset = ParCompactionManager::region_array();
@@ -2692,8 +2684,7 @@
   // trace("5");
   GCTraceTime tm("compaction phase", print_phases(), true, &_gc_timer, _gc_tracer.gc_id());
 
-  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
-  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   PSOldGen* old_gen = heap->old_gen();
   old_gen->start_array()->reset();
   uint parallel_gc_threads = heap->gc_task_manager()->workers();
@@ -2844,7 +2835,7 @@
 // heap, last_space_id is returned.  In debug mode it expects the address to be
 // in the heap and asserts such.
 PSParallelCompact::SpaceId PSParallelCompact::space_id(HeapWord* addr) {
-  assert(Universe::heap()->is_in_reserved(addr), "addr not in the heap");
+  assert(ParallelScavengeHeap::heap()->is_in_reserved(addr), "addr not in the heap");
 
   for (unsigned int id = old_space_id; id < last_space_id; ++id) {
     if (_space_info[id].space()->contains(addr)) {
@@ -3338,6 +3329,71 @@
   update_state(words);
 }
 
+void InstanceKlass::oop_pc_update_pointers(oop obj) {
+  oop_oop_iterate_oop_maps<true>(obj, PSParallelCompact::adjust_pointer_closure());
+}
+
+void InstanceMirrorKlass::oop_pc_update_pointers(oop obj) {
+  InstanceKlass::oop_pc_update_pointers(obj);
+
+  oop_oop_iterate_statics<true>(obj, PSParallelCompact::adjust_pointer_closure());
+}
+
+void InstanceClassLoaderKlass::oop_pc_update_pointers(oop obj) {
+  InstanceKlass::oop_pc_update_pointers(obj);
+}
+
+#ifdef ASSERT
+template <class T> static void trace_reference_gc(const char *s, oop obj,
+                                                  T* referent_addr,
+                                                  T* next_addr,
+                                                  T* discovered_addr) {
+  if(TraceReferenceGC && PrintGCDetails) {
+    gclog_or_tty->print_cr("%s obj " PTR_FORMAT, s, p2i(obj));
+    gclog_or_tty->print_cr("     referent_addr/* " PTR_FORMAT " / "
+                           PTR_FORMAT, p2i(referent_addr),
+                           referent_addr ? p2i(oopDesc::load_decode_heap_oop(referent_addr)) : NULL);
+    gclog_or_tty->print_cr("     next_addr/* " PTR_FORMAT " / "
+                           PTR_FORMAT, p2i(next_addr),
+                           next_addr ? p2i(oopDesc::load_decode_heap_oop(next_addr)) : NULL);
+    gclog_or_tty->print_cr("     discovered_addr/* " PTR_FORMAT " / "
+                           PTR_FORMAT, p2i(discovered_addr),
+                           discovered_addr ? p2i(oopDesc::load_decode_heap_oop(discovered_addr)) : NULL);
+  }
+}
+#endif
+
+template <class T>
+static void oop_pc_update_pointers_specialized(oop obj) {
+  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
+  PSParallelCompact::adjust_pointer(referent_addr);
+  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
+  PSParallelCompact::adjust_pointer(next_addr);
+  T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
+  PSParallelCompact::adjust_pointer(discovered_addr);
+  debug_only(trace_reference_gc("InstanceRefKlass::oop_update_ptrs", obj,
+                                referent_addr, next_addr, discovered_addr);)
+}
+
+void InstanceRefKlass::oop_pc_update_pointers(oop obj) {
+  InstanceKlass::oop_pc_update_pointers(obj);
+
+  if (UseCompressedOops) {
+    oop_pc_update_pointers_specialized<narrowOop>(obj);
+  } else {
+    oop_pc_update_pointers_specialized<oop>(obj);
+  }
+}
+
+void ObjArrayKlass::oop_pc_update_pointers(oop obj) {
+  assert(obj->is_objArray(), "obj must be obj array");
+  oop_oop_iterate_elements<true>(objArrayOop(obj), PSParallelCompact::adjust_pointer_closure());
+}
+
+void TypeArrayKlass::oop_pc_update_pointers(oop obj) {
+  assert(obj->is_typeArray(),"must be a type array");
+}
+
 ParMarkBitMapClosure::IterationStatus
 MoveAndUpdateClosure::do_addr(HeapWord* addr, size_t words) {
   assert(destination() != NULL, "sanity");
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -26,11 +26,12 @@
 #define SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSPARALLELCOMPACT_HPP
 
 #include "gc_implementation/parallelScavenge/objectStartArray.hpp"
+#include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
 #include "gc_implementation/parallelScavenge/parMarkBitMap.hpp"
 #include "gc_implementation/parallelScavenge/psCompactionManager.hpp"
 #include "gc_implementation/shared/collectorCounters.hpp"
 #include "gc_implementation/shared/mutableSpace.hpp"
-#include "memory/sharedHeap.hpp"
+#include "gc_interface/collectedHeap.hpp"
 #include "oops/oop.hpp"
 
 class ParallelScavengeHeap;
@@ -951,12 +952,14 @@
     virtual void do_void();
   };
 
-  class AdjustPointerClosure: public OopClosure {
+  class AdjustPointerClosure: public ExtendedOopClosure {
    public:
+    template <typename T> void do_oop_nv(T* p);
     virtual void do_oop(oop* p);
     virtual void do_oop(narrowOop* p);
-    // do not walk from thread stacks to the code cache on this phase
-    virtual void do_code_blob(CodeBlob* cb) const { }
+
+    // This closure provides its own oop verification code.
+    debug_only(virtual bool should_verify_oops() { return false; })
   };
 
   class AdjustKlassClosure : public KlassClosure {
@@ -1139,13 +1142,18 @@
   static void reset_millis_since_last_gc();
 
  public:
-  class MarkAndPushClosure: public OopClosure {
+  class MarkAndPushClosure: public ExtendedOopClosure {
    private:
     ParCompactionManager* _compaction_manager;
    public:
     MarkAndPushClosure(ParCompactionManager* cm) : _compaction_manager(cm) { }
+
+    template <typename T> void do_oop_nv(T* p);
     virtual void do_oop(oop* p);
     virtual void do_oop(narrowOop* p);
+
+    // This closure provides its own oop verification code.
+    debug_only(virtual bool should_verify_oops() { return false; })
   };
 
   // The one and only place to start following the classes.
@@ -1161,11 +1169,6 @@
 
   PSParallelCompact();
 
-  // Convenient accessor for Universe::heap().
-  static ParallelScavengeHeap* gc_heap() {
-    return (ParallelScavengeHeap*)Universe::heap();
-  }
-
   static void invoke(bool maximum_heap_compaction);
   static bool invoke_no_policy(bool maximum_heap_compaction);
 
@@ -1177,7 +1180,9 @@
   static bool initialize();
 
   // Closure accessors
-  static OopClosure* adjust_pointer_closure()      { return (OopClosure*)&_adjust_pointer_closure; }
+  static PSParallelCompact::AdjustPointerClosure* adjust_pointer_closure() {
+    return &_adjust_pointer_closure;
+  }
   static KlassClosure* adjust_klass_closure()      { return (KlassClosure*)&_adjust_klass_closure; }
   static BoolObjectClosure* is_alive_closure()     { return (BoolObjectClosure*)&_is_alive_closure; }
 
@@ -1333,39 +1338,6 @@
 }
 
 template <class T>
-inline void PSParallelCompact::mark_and_push(ParCompactionManager* cm, T* p) {
-  T heap_oop = oopDesc::load_heap_oop(p);
-  if (!oopDesc::is_null(heap_oop)) {
-    oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
-    if (mark_bitmap()->is_unmarked(obj) && mark_obj(obj)) {
-      cm->push(obj);
-    }
-  }
-}
-
-template <class T>
-inline void PSParallelCompact::adjust_pointer(T* p) {
-  T heap_oop = oopDesc::load_heap_oop(p);
-  if (!oopDesc::is_null(heap_oop)) {
-    oop obj     = oopDesc::decode_heap_oop_not_null(heap_oop);
-    oop new_obj = (oop)summary_data().calc_new_pointer(obj);
-    assert(new_obj != NULL,                    // is forwarding ptr?
-           "should be forwarded");
-    // Just always do the update unconditionally?
-    if (new_obj != NULL) {
-      assert(Universe::heap()->is_in_reserved(new_obj),
-             "should be in object space");
-      oopDesc::encode_store_heap_oop_not_null(p, new_obj);
-    }
-  }
-}
-
-inline void PSParallelCompact::follow_klass(ParCompactionManager* cm, Klass* klass) {
-  oop holder = klass->klass_holder();
-  PSParallelCompact::mark_and_push(cm, &holder);
-}
-
-template <class T>
 inline void PSParallelCompact::KeepAliveClosure::do_oop_work(T* p) {
   mark_and_push(_compaction_manager, p);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.inline.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSPARALLELCOMPACT_INLINE_HPP
+#define SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSPARALLELCOMPACT_INLINE_HPP
+
+#include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
+#include "gc_implementation/parallelScavenge/psCompactionManager.hpp"
+#include "gc_implementation/parallelScavenge/psParallelCompact.hpp"
+#include "gc_interface/collectedHeap.hpp"
+#include "oops/klass.hpp"
+#include "oops/oop.inline.hpp"
+
+template <typename T>
+inline void PSParallelCompact::mark_and_push(ParCompactionManager* cm, T* p) {
+  T heap_oop = oopDesc::load_heap_oop(p);
+  if (!oopDesc::is_null(heap_oop)) {
+    oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
+    assert(ParallelScavengeHeap::heap()->is_in(obj), "should be in heap");
+
+    if (mark_bitmap()->is_unmarked(obj) && mark_obj(obj)) {
+      cm->push(obj);
+    }
+  }
+}
+
+template <typename T>
+inline void PSParallelCompact::MarkAndPushClosure::do_oop_nv(T* p) {
+  mark_and_push(_compaction_manager, p);
+}
+
+inline void PSParallelCompact::MarkAndPushClosure::do_oop(oop* p)       { do_oop_nv(p); }
+inline void PSParallelCompact::MarkAndPushClosure::do_oop(narrowOop* p) { do_oop_nv(p); }
+
+inline void PSParallelCompact::follow_klass(ParCompactionManager* cm, Klass* klass) {
+  oop holder = klass->klass_holder();
+  mark_and_push(cm, &holder);
+}
+
+template <class T>
+inline void PSParallelCompact::adjust_pointer(T* p) {
+  T heap_oop = oopDesc::load_heap_oop(p);
+  if (!oopDesc::is_null(heap_oop)) {
+    oop obj     = oopDesc::decode_heap_oop_not_null(heap_oop);
+    assert(ParallelScavengeHeap::heap()->is_in(obj), "should be in heap");
+
+    oop new_obj = (oop)summary_data().calc_new_pointer(obj);
+    assert(new_obj != NULL,                    // is forwarding ptr?
+           "should be forwarded");
+    // Just always do the update unconditionally?
+    if (new_obj != NULL) {
+      assert(ParallelScavengeHeap::heap()->is_in_reserved(new_obj),
+             "should be in object space");
+      oopDesc::encode_store_heap_oop_not_null(p, new_obj);
+    }
+  }
+}
+
+template <typename T>
+void PSParallelCompact::AdjustPointerClosure::do_oop_nv(T* p) {
+  adjust_pointer(p);
+}
+
+inline void PSParallelCompact::AdjustPointerClosure::do_oop(oop* p)       { do_oop_nv(p); }
+inline void PSParallelCompact::AdjustPointerClosure::do_oop(narrowOop* p) { do_oop_nv(p); }
+
+#endif // SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSPARALLELCOMPACT_INLINE_HPP
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionLAB.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionLAB.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2015, 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
@@ -103,7 +103,7 @@
 }
 
 bool PSPromotionLAB::unallocate_object(HeapWord* obj, size_t obj_size) {
-  assert(Universe::heap()->is_in(obj), "Object outside heap");
+  assert(ParallelScavengeHeap::heap()->is_in(obj), "Object outside heap");
 
   if (contains(obj)) {
     HeapWord* object_end = obj + obj_size;
@@ -137,9 +137,7 @@
 #ifdef ASSERT
 
 bool PSYoungPromotionLAB::lab_is_valid(MemRegion lab) {
-  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
-  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
-
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   MutableSpace* to_space = heap->young_gen()->to_space();
   MemRegion used = to_space->used_region();
   if (used.contains(lab)) {
@@ -150,10 +148,9 @@
 }
 
 bool PSOldPromotionLAB::lab_is_valid(MemRegion lab) {
-  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
-  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
   assert(_start_array->covered_region().contains(lab), "Sanity");
 
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   PSOldGen* old_gen = heap->old_gen();
   MemRegion used = old_gen->object_space()->used_region();
 
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionLAB.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionLAB.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2015, 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
@@ -26,7 +26,7 @@
 #define SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSPROMOTIONLAB_HPP
 
 #include "gc_implementation/parallelScavenge/objectStartArray.hpp"
-#include "gc_interface/collectedHeap.inline.hpp"
+#include "gc_interface/collectedHeap.hpp"
 #include "memory/allocation.hpp"
 
 //
@@ -59,7 +59,7 @@
   // The shared initialize code invokes this.
   debug_only(virtual bool lab_is_valid(MemRegion lab) { return false; });
 
-  PSPromotionLAB() : _top(NULL), _bottom(NULL), _end(NULL) { }
+  PSPromotionLAB() : _top(NULL), _bottom(NULL), _end(NULL), _state(zero_size) { }
 
  public:
   // Filling and flushing.
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -32,6 +32,9 @@
 #include "memory/allocation.inline.hpp"
 #include "memory/memRegion.hpp"
 #include "memory/padded.inline.hpp"
+#include "oops/instanceKlass.inline.hpp"
+#include "oops/instanceMirrorKlass.inline.hpp"
+#include "oops/objArrayKlass.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "utilities/stack.inline.hpp"
 
@@ -41,8 +44,7 @@
 MutableSpace*                  PSPromotionManager::_young_space = NULL;
 
 void PSPromotionManager::initialize() {
-  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
-  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
 
   _old_gen = heap->old_gen();
   _young_space = heap->young_gen()->to_space();
@@ -85,8 +87,7 @@
 }
 
 void PSPromotionManager::pre_scavenge() {
-  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
-  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
 
   _young_space = heap->young_gen()->to_space();
 
@@ -129,7 +130,7 @@
 void
 PSPromotionManager::print_taskqueue_stats(outputStream* const out) {
   out->print_cr("== GC Tasks Stats, GC %3d",
-                Universe::heap()->total_collections());
+                ParallelScavengeHeap::heap()->total_collections());
 
   TaskQueueStats totals;
   out->print("thr "); TaskQueueStats::print_header(1, out); out->cr();
@@ -157,8 +158,7 @@
 #endif // TASKQUEUE_STATS
 
 PSPromotionManager::PSPromotionManager() {
-  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
-  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
 
   // We set the old lab's start array.
   _old_lab.set_start_array(old_gen()->start_array());
@@ -188,8 +188,7 @@
 
   // We need to get an assert in here to make sure the labs are always flushed.
 
-  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
-  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
 
   // Do not prefill the LAB's, save heap wastage!
   HeapWord* lab_base = young_space()->top();
@@ -210,8 +209,7 @@
   totally_drain = totally_drain || _totally_drain;
 
 #ifdef ASSERT
-  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
-  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   MutableSpace* to_space = heap->young_gen()->to_space();
   MutableSpace* old_space = heap->old_gen()->object_space();
 #endif /* ASSERT */
@@ -308,6 +306,118 @@
   }
 }
 
+class PushContentsClosure : public ExtendedOopClosure {
+  PSPromotionManager* _pm;
+ public:
+  PushContentsClosure(PSPromotionManager* pm) : _pm(pm) {}
+
+  template <typename T> void do_oop_nv(T* p) {
+    if (PSScavenge::should_scavenge(p)) {
+      _pm->claim_or_forward_depth(p);
+    }
+  }
+
+  virtual void do_oop(oop* p)       { do_oop_nv(p); }
+  virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
+
+  // Don't use the oop verification code in the oop_oop_iterate framework.
+  debug_only(virtual bool should_verify_oops() { return false; })
+};
+
+void InstanceKlass::oop_ps_push_contents(oop obj, PSPromotionManager* pm) {
+  PushContentsClosure cl(pm);
+  oop_oop_iterate_oop_maps_reverse<true>(obj, &cl);
+}
+
+void InstanceMirrorKlass::oop_ps_push_contents(oop obj, PSPromotionManager* pm) {
+    // Note that we don't have to follow the mirror -> klass pointer, since all
+    // klasses that are dirty will be scavenged when we iterate over the
+    // ClassLoaderData objects.
+
+  InstanceKlass::oop_ps_push_contents(obj, pm);
+
+  PushContentsClosure cl(pm);
+  oop_oop_iterate_statics<true>(obj, &cl);
+}
+
+void InstanceClassLoaderKlass::oop_ps_push_contents(oop obj, PSPromotionManager* pm) {
+  InstanceKlass::oop_ps_push_contents(obj, pm);
+
+  // This is called by the young collector. It will already have taken care of
+  // all class loader data. So, we don't have to follow the class loader ->
+  // class loader data link.
+}
+
+template <class T>
+static void oop_ps_push_contents_specialized(oop obj, InstanceRefKlass *klass, PSPromotionManager* pm) {
+  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
+  if (PSScavenge::should_scavenge(referent_addr)) {
+    ReferenceProcessor* rp = PSScavenge::reference_processor();
+    if (rp->discover_reference(obj, klass->reference_type())) {
+      // reference already enqueued, referent and next will be traversed later
+      klass->InstanceKlass::oop_ps_push_contents(obj, pm);
+      return;
+    } else {
+      // treat referent as normal oop
+      pm->claim_or_forward_depth(referent_addr);
+    }
+  }
+  // Treat discovered as normal oop, if ref is not "active",
+  // i.e. if next is non-NULL.
+  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
+  if (ReferenceProcessor::pending_list_uses_discovered_field()) {
+    T  next_oop = oopDesc::load_heap_oop(next_addr);
+    if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active"
+      T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
+      debug_only(
+        if(TraceReferenceGC && PrintGCDetails) {
+          gclog_or_tty->print_cr("   Process discovered as normal "
+                                 PTR_FORMAT, p2i(discovered_addr));
+        }
+      )
+      if (PSScavenge::should_scavenge(discovered_addr)) {
+        pm->claim_or_forward_depth(discovered_addr);
+      }
+    }
+  } else {
+#ifdef ASSERT
+    // In the case of older JDKs which do not use the discovered
+    // field for the pending list, an inactive ref (next != NULL)
+    // must always have a NULL discovered field.
+    oop next = oopDesc::load_decode_heap_oop(next_addr);
+    oop discovered = java_lang_ref_Reference::discovered(obj);
+    assert(oopDesc::is_null(next) || oopDesc::is_null(discovered),
+           err_msg("Found an inactive reference " PTR_FORMAT " with a non-NULL discovered field",
+                   p2i(obj)));
+#endif
+  }
+
+  // Treat next as normal oop;  next is a link in the reference queue.
+  if (PSScavenge::should_scavenge(next_addr)) {
+    pm->claim_or_forward_depth(next_addr);
+  }
+  klass->InstanceKlass::oop_ps_push_contents(obj, pm);
+}
+
+void InstanceRefKlass::oop_ps_push_contents(oop obj, PSPromotionManager* pm) {
+  if (UseCompressedOops) {
+    oop_ps_push_contents_specialized<narrowOop>(obj, this, pm);
+  } else {
+    oop_ps_push_contents_specialized<oop>(obj, this, pm);
+  }
+}
+
+void ObjArrayKlass::oop_ps_push_contents(oop obj, PSPromotionManager* pm) {
+  assert(obj->is_objArray(), "obj must be obj array");
+  PushContentsClosure cl(pm);
+  oop_oop_iterate_elements<true>(objArrayOop(obj), &cl);
+}
+
+void TypeArrayKlass::oop_ps_push_contents(oop obj, PSPromotionManager* pm) {
+  assert(obj->is_typeArray(),"must be a type array");
+  ShouldNotReachHere();
+}
+
 oop PSPromotionManager::oop_promotion_failed(oop obj, markOop obj_mark) {
   assert(_old_gen_is_full || PromotionFailureALot, "Sanity");
 
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -25,11 +25,12 @@
 #ifndef SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSPROMOTIONMANAGER_INLINE_HPP
 #define SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSPROMOTIONMANAGER_INLINE_HPP
 
+#include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
 #include "gc_implementation/parallelScavenge/psOldGen.hpp"
 #include "gc_implementation/parallelScavenge/psPromotionManager.hpp"
 #include "gc_implementation/parallelScavenge/psPromotionLAB.inline.hpp"
 #include "gc_implementation/parallelScavenge/psScavenge.hpp"
-#include "oops/oop.psgc.inline.hpp"
+#include "oops/oop.inline.hpp"
 
 inline PSPromotionManager* PSPromotionManager::manager_array(int index) {
   assert(_manager_array != NULL, "access of NULL manager_array");
@@ -57,9 +58,7 @@
 template <class T>
 inline void PSPromotionManager::claim_or_forward_depth(T* p) {
   assert(should_scavenge(p, true), "revisiting object?");
-  assert(Universe::heap()->kind() == CollectedHeap::ParallelScavengeHeap,
-         "Sanity");
-  assert(Universe::heap()->is_in(p), "pointer outside heap");
+  assert(ParallelScavengeHeap::heap()->is_in(p), "pointer outside heap");
 
   claim_or_forward_internal_depth(p);
 }
@@ -92,7 +91,7 @@
 }
 
 inline void PSPromotionManager::push_contents(oop obj) {
-  obj->push_contents(this);
+  obj->ps_push_contents(this);
 }
 //
 // This method is pretty bulky. It would be nice to split it up
@@ -150,7 +149,7 @@
     // Otherwise try allocating obj tenured
     if (new_obj == NULL) {
 #ifndef PRODUCT
-      if (Universe::heap()->promotion_should_fail()) {
+      if (ParallelScavengeHeap::heap()->promotion_should_fail()) {
         return oop_promotion_failed(o, test_mark);
       }
 #endif  // #ifndef PRODUCT
@@ -296,7 +295,7 @@
   // that are outside the heap. These pointers are either from roots
   // or from metadata.
   if ((!PSScavenge::is_obj_in_young((HeapWord*)p)) &&
-      Universe::heap()->is_in_reserved(p)) {
+      ParallelScavengeHeap::heap()->is_in_reserved(p)) {
     if (PSScavenge::is_obj_in_young(new_obj)) {
       PSScavenge::card_table()->inline_write_ref_field_gc(p, new_obj);
     }
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -87,8 +87,7 @@
 
 public:
   PSKeepAliveClosure(PSPromotionManager* pm) : _promotion_manager(pm) {
-    ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
-    assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
+    ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
     _to_space = heap->young_gen()->to_space();
 
     assert(_promotion_manager != NULL, "Sanity");
@@ -218,11 +217,9 @@
 bool PSScavenge::invoke() {
   assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint");
   assert(Thread::current() == (Thread*)VMThread::vm_thread(), "should be in vm thread");
-  assert(!Universe::heap()->is_gc_active(), "not reentrant");
+  assert(!ParallelScavengeHeap::heap()->is_gc_active(), "not reentrant");
 
-  ParallelScavengeHeap* const heap = (ParallelScavengeHeap*)Universe::heap();
-  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
-
+  ParallelScavengeHeap* const heap = ParallelScavengeHeap::heap();
   PSAdaptiveSizePolicy* policy = heap->size_policy();
   IsGCActiveMark mark;
 
@@ -273,9 +270,8 @@
     return false;
   }
 
-  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   GCCause::Cause gc_cause = heap->gc_cause();
-  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
 
   // Check for potential problems.
   if (!should_attempt_scavenge()) {
@@ -713,9 +709,7 @@
 // unforwarding markOops. It then restores any preserved mark oops,
 // and clears the _preserved_mark_stack.
 void PSScavenge::clean_up_failed_promotion() {
-  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
-  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
-
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   PSYoungGen* young_gen = heap->young_gen();
 
   {
@@ -742,7 +736,7 @@
   }
 
   // Reset the PromotionFailureALot counters.
-  NOT_PRODUCT(Universe::heap()->reset_promotion_should_fail();)
+  NOT_PRODUCT(heap->reset_promotion_should_fail();)
 }
 
 // This method is called whenever an attempt to promote an object
@@ -761,8 +755,7 @@
 }
 
 bool PSScavenge::should_attempt_scavenge() {
-  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
-  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   PSGCAdaptivePolicyCounters* counters = heap->gc_policy_counters();
 
   if (UsePerfData) {
@@ -838,9 +831,7 @@
                                                     MaxTenuringThreshold;
   }
 
-  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
-  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
-
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   PSYoungGen* young_gen = heap->young_gen();
   PSOldGen* old_gen = heap->old_gen();
 
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2015, 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
@@ -33,7 +33,7 @@
 #include "utilities/globalDefinitions.hpp"
 
 inline void PSScavenge::save_to_space_top_before_gc() {
-  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   _to_space_top_before_gc = heap->young_gen()->to_space()->top();
 }
 
@@ -56,7 +56,7 @@
 template <class T>
 inline bool PSScavenge::should_scavenge(T* p, bool check_to_space) {
   if (check_to_space) {
-    ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
+    ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
     return should_scavenge(p, heap->young_gen()->to_space());
   }
   return should_scavenge(p);
@@ -97,7 +97,6 @@
     ParallelScavengeHeap* psh = ParallelScavengeHeap::heap();
     assert(!psh->is_in_reserved(p), "GC barrier needed");
     if (PSScavenge::should_scavenge(p)) {
-      assert(!Universe::heap()->is_in_reserved(p), "Not from meta-data?");
       assert(PSScavenge::should_scavenge(p, true), "revisiting object?");
 
       oop o = *p;
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -47,7 +47,7 @@
 //
 
 void ScavengeRootsTask::do_it(GCTaskManager* manager, uint which) {
-  assert(Universe::heap()->is_gc_active(), "called outside gc");
+  assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc");
 
   PSPromotionManager* pm = PSPromotionManager::gc_thread_promotion_manager(which);
   PSScavengeRootsClosure roots_closure(pm);
@@ -118,7 +118,7 @@
 //
 
 void ThreadRootsTask::do_it(GCTaskManager* manager, uint which) {
-  assert(Universe::heap()->is_gc_active(), "called outside gc");
+  assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc");
 
   PSPromotionManager* pm = PSPromotionManager::gc_thread_promotion_manager(which);
   PSScavengeRootsClosure roots_closure(pm);
@@ -143,7 +143,7 @@
   _terminator(t) {}
 
 void StealTask::do_it(GCTaskManager* manager, uint which) {
-  assert(Universe::heap()->is_gc_active(), "called outside gc");
+  assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc");
 
   PSPromotionManager* pm =
     PSPromotionManager::gc_thread_promotion_manager(which);
@@ -181,10 +181,8 @@
 
   {
     PSPromotionManager* pm = PSPromotionManager::gc_thread_promotion_manager(which);
-
-    assert(Universe::heap()->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
     CardTableExtension* card_table =
-      barrier_set_cast<CardTableExtension>(Universe::heap()->barrier_set());
+      barrier_set_cast<CardTableExtension>(ParallelScavengeHeap::heap()->barrier_set());
 
     card_table->scavenge_contents_parallel(_gen->start_array(),
                                            _gen->object_space(),
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, 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
@@ -62,7 +62,7 @@
 
   MemRegion cmr((HeapWord*)virtual_space()->low(),
                 (HeapWord*)virtual_space()->high());
-  Universe::heap()->barrier_set()->resize_covered_region(cmr);
+  ParallelScavengeHeap::heap()->barrier_set()->resize_covered_region(cmr);
 
   if (ZapUnusedHeapArea) {
     // Mangle newly committed space immediately because it
@@ -103,7 +103,7 @@
                                            _max_gen_size, _virtual_space);
 
   // Compute maximum space sizes for performance counters
-  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   size_t alignment = heap->space_alignment();
   size_t size = virtual_space()->reserved_size();
 
@@ -153,8 +153,7 @@
 }
 
 void PSYoungGen::compute_initial_space_boundaries() {
-  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
-  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
 
   // Compute sizes
   size_t alignment = heap->space_alignment();
@@ -208,7 +207,7 @@
 
 #ifndef PRODUCT
 void PSYoungGen::space_invariants() {
-  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   const size_t alignment = heap->space_alignment();
 
   // Currently, our eden size cannot shrink to zero
@@ -494,7 +493,7 @@
   char* to_start   = (char*)to_space()->bottom();
   char* to_end     = (char*)to_space()->end();
 
-  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   const size_t alignment = heap->space_alignment();
   const bool maintain_minimum =
     (requested_eden_size + 2 * requested_survivor_size) <= min_gen_size();
@@ -546,8 +545,6 @@
 
     // Does the optimal to-space overlap from-space?
     if (to_start < (char*)from_space()->end()) {
-      assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
-
       // Calculate the minimum offset possible for from_end
       size_t from_size = pointer_delta(from_space()->top(), from_start, sizeof(char));
 
@@ -708,9 +705,7 @@
   assert(from_space()->top() == old_from_top, "from top changed!");
 
   if (PrintAdaptiveSizePolicy) {
-    ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
-    assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
-
+    ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
     gclog_or_tty->print("AdaptiveSizePolicy::survivor space sizes: "
                   "collection: %d "
                   "(" SIZE_FORMAT ", " SIZE_FORMAT ") -> "
@@ -843,7 +838,7 @@
 // from-space.
 size_t PSYoungGen::available_to_live() {
   size_t delta_in_survivor = 0;
-  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   const size_t space_alignment = heap->space_alignment();
   const size_t gen_alignment = heap->generation_alignment();
 
@@ -927,7 +922,7 @@
 
   MemRegion cmr((HeapWord*)virtual_space()->low(),
                 (HeapWord*)virtual_space()->high());
-  Universe::heap()->barrier_set()->resize_covered_region(cmr);
+  ParallelScavengeHeap::heap()->barrier_set()->resize_covered_region(cmr);
   space_invariants();
 }
 
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -41,8 +41,7 @@
 void VM_ParallelGCFailedAllocation::doit() {
   SvcGCMarker sgcm(SvcGCMarker::MINOR);
 
-  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
-  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "must be a ParallelScavengeHeap");
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
 
   GCCauseSetter gccs(heap, _gc_cause);
   _result = heap->failed_mem_allocate(_word_size);
@@ -63,9 +62,7 @@
 void VM_ParallelGCSystemGC::doit() {
   SvcGCMarker sgcm(SvcGCMarker::FULL);
 
-  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
-  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap,
-    "must be a ParallelScavengeHeap");
+  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
 
   GCCauseSetter gccs(heap, _gc_cause);
   if (_gc_cause == GCCause::_gc_locker || _gc_cause == GCCause::_wb_young_gc
--- a/hotspot/src/share/vm/gc_implementation/shared/ageTable.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/shared/ageTable.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -25,9 +25,9 @@
 #include "precompiled.hpp"
 #include "gc_implementation/shared/ageTable.hpp"
 #include "gc_implementation/shared/gcPolicyCounters.hpp"
+#include "gc_interface/collectedHeap.hpp"
 #include "memory/collectorPolicy.hpp"
 #include "memory/resourceArea.hpp"
-#include "memory/sharedHeap.hpp"
 #include "runtime/atomic.inline.hpp"
 #include "utilities/copy.hpp"
 
@@ -79,7 +79,7 @@
   }
 }
 
-uint ageTable::compute_tenuring_threshold(size_t survivor_capacity) {
+uint ageTable::compute_tenuring_threshold(size_t survivor_capacity, GCPolicyCounters* gc_counters) {
   size_t desired_survivor_size = (size_t)((((double) survivor_capacity)*TargetSurvivorRatio)/100);
   uint result;
 
@@ -126,9 +126,6 @@
       age++;
     }
     if (UsePerfData) {
-      SharedHeap* sh = SharedHeap::heap();
-      CollectorPolicy* policy = sh->collector_policy();
-      GCPolicyCounters* gc_counters = policy->counters();
       gc_counters->tenuring_threshold()->set_value(result);
       gc_counters->desired_survivor_size()->set_value(
         desired_survivor_size*oopSize);
--- a/hotspot/src/share/vm/gc_implementation/shared/ageTable.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/shared/ageTable.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -29,6 +29,8 @@
 #include "oops/oop.hpp"
 #include "runtime/perfData.hpp"
 
+class GCPolicyCounters;
+
 /* Copyright (c) 1992-2009 Oracle and/or its affiliates, and Stanford University.
    See the LICENSE file for license information. */
 
@@ -69,7 +71,7 @@
   void merge_par(ageTable* subTable);
 
   // calculate new tenuring threshold based on age information
-  uint compute_tenuring_threshold(size_t survivor_capacity);
+  uint compute_tenuring_threshold(size_t survivor_capacity, GCPolicyCounters* gc_counters);
 
  private:
   PerfVariable* _perf_sizes[table_size];
--- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -28,6 +28,8 @@
 #include "gc_implementation/shared/gcTrace.hpp"
 #include "gc_implementation/shared/markSweep.inline.hpp"
 #include "gc_interface/collectedHeap.inline.hpp"
+#include "oops/instanceKlass.inline.hpp"
+#include "oops/instanceMirrorKlass.inline.hpp"
 #include "oops/methodData.hpp"
 #include "oops/objArrayKlass.inline.hpp"
 #include "oops/oop.inline.hpp"
@@ -55,16 +57,183 @@
 CLDToOopClosure               MarkSweep::follow_cld_closure(&mark_and_push_closure);
 CLDToOopClosure               MarkSweep::adjust_cld_closure(&adjust_pointer_closure);
 
-void MarkSweep::MarkAndPushClosure::do_oop(oop* p)       { mark_and_push(p); }
-void MarkSweep::MarkAndPushClosure::do_oop(narrowOop* p) { mark_and_push(p); }
+template <typename T>
+void MarkSweep::MarkAndPushClosure::do_oop_nv(T* p)       { mark_and_push(p); }
+void MarkSweep::MarkAndPushClosure::do_oop(oop* p)        { do_oop_nv(p); }
+void MarkSweep::MarkAndPushClosure::do_oop(narrowOop* p)  { do_oop_nv(p); }
 
 void MarkSweep::follow_class_loader(ClassLoaderData* cld) {
   MarkSweep::follow_cld_closure.do_cld(cld);
 }
 
+void InstanceKlass::oop_ms_follow_contents(oop obj) {
+  assert(obj != NULL, "can't follow the content of NULL object");
+  MarkSweep::follow_klass(this);
+
+  oop_oop_iterate_oop_maps<true>(obj, &MarkSweep::mark_and_push_closure);
+}
+
+void InstanceMirrorKlass::oop_ms_follow_contents(oop obj) {
+  InstanceKlass::oop_ms_follow_contents(obj);
+
+  // Follow the klass field in the mirror
+  Klass* klass = java_lang_Class::as_Klass(obj);
+  if (klass != NULL) {
+    // An anonymous class doesn't have its own class loader, so the call
+    // to follow_klass will mark and push its java mirror instead of the
+    // class loader. When handling the java mirror for an anonymous class
+    // we need to make sure its class loader data is claimed, this is done
+    // by calling follow_class_loader explicitly. For non-anonymous classes
+    // the call to follow_class_loader is made when the class loader itself
+    // is handled.
+    if (klass->oop_is_instance() && InstanceKlass::cast(klass)->is_anonymous()) {
+      MarkSweep::follow_class_loader(klass->class_loader_data());
+    } else {
+      MarkSweep::follow_klass(klass);
+    }
+  } else {
+    // If klass is NULL then this a mirror for a primitive type.
+    // We don't have to follow them, since they are handled as strong
+    // roots in Universe::oops_do.
+    assert(java_lang_Class::is_primitive(obj), "Sanity check");
+  }
+
+  oop_oop_iterate_statics<true>(obj, &MarkSweep::mark_and_push_closure);
+}
+
+void InstanceClassLoaderKlass::oop_ms_follow_contents(oop obj) {
+  InstanceKlass::oop_ms_follow_contents(obj);
+
+  ClassLoaderData * const loader_data = java_lang_ClassLoader::loader_data(obj);
+
+  // We must NULL check here, since the class loader
+  // can be found before the loader data has been set up.
+  if(loader_data != NULL) {
+    MarkSweep::follow_class_loader(loader_data);
+  }
+}
+
+template <class T>
+static void oop_ms_follow_contents_specialized(InstanceRefKlass* klass, oop obj) {
+  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
+  T heap_oop = oopDesc::load_heap_oop(referent_addr);
+  debug_only(
+    if(TraceReferenceGC && PrintGCDetails) {
+      gclog_or_tty->print_cr("InstanceRefKlass::oop_ms_follow_contents_specialized " PTR_FORMAT, p2i(obj));
+    }
+  )
+  if (!oopDesc::is_null(heap_oop)) {
+    oop referent = oopDesc::decode_heap_oop_not_null(heap_oop);
+    if (!referent->is_gc_marked() &&
+        MarkSweep::ref_processor()->discover_reference(obj, klass->reference_type())) {
+      // reference was discovered, referent will be traversed later
+      klass->InstanceKlass::oop_ms_follow_contents(obj);
+      debug_only(
+        if(TraceReferenceGC && PrintGCDetails) {
+          gclog_or_tty->print_cr("       Non NULL enqueued " PTR_FORMAT, p2i(obj));
+        }
+      )
+      return;
+    } else {
+      // treat referent as normal oop
+      debug_only(
+        if(TraceReferenceGC && PrintGCDetails) {
+          gclog_or_tty->print_cr("       Non NULL normal " PTR_FORMAT, p2i(obj));
+        }
+      )
+      MarkSweep::mark_and_push(referent_addr);
+    }
+  }
+  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
+  if (ReferenceProcessor::pending_list_uses_discovered_field()) {
+    // Treat discovered as normal oop, if ref is not "active",
+    // i.e. if next is non-NULL.
+    T  next_oop = oopDesc::load_heap_oop(next_addr);
+    if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active"
+      T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
+      debug_only(
+        if(TraceReferenceGC && PrintGCDetails) {
+          gclog_or_tty->print_cr("   Process discovered as normal "
+                                 PTR_FORMAT, p2i(discovered_addr));
+        }
+      )
+      MarkSweep::mark_and_push(discovered_addr);
+    }
+  } else {
+#ifdef ASSERT
+    // In the case of older JDKs which do not use the discovered
+    // field for the pending list, an inactive ref (next != NULL)
+    // must always have a NULL discovered field.
+    oop next = oopDesc::load_decode_heap_oop(next_addr);
+    oop discovered = java_lang_ref_Reference::discovered(obj);
+    assert(oopDesc::is_null(next) || oopDesc::is_null(discovered),
+        err_msg("Found an inactive reference " PTR_FORMAT " with a non-NULL discovered field",
+            p2i(obj)));
+#endif
+  }
+  // treat next as normal oop.  next is a link in the reference queue.
+  debug_only(
+    if(TraceReferenceGC && PrintGCDetails) {
+      gclog_or_tty->print_cr("   Process next as normal " PTR_FORMAT, p2i(next_addr));
+    }
+  )
+  MarkSweep::mark_and_push(next_addr);
+  klass->InstanceKlass::oop_ms_follow_contents(obj);
+}
+
+void InstanceRefKlass::oop_ms_follow_contents(oop obj) {
+  if (UseCompressedOops) {
+    oop_ms_follow_contents_specialized<narrowOop>(this, obj);
+  } else {
+    oop_ms_follow_contents_specialized<oop>(this, obj);
+  }
+}
+
+template <class T>
+static void oop_ms_follow_contents_specialized(oop obj, int index) {
+  objArrayOop a = objArrayOop(obj);
+  const size_t len = size_t(a->length());
+  const size_t beg_index = size_t(index);
+  assert(beg_index < len || len == 0, "index too large");
+
+  const size_t stride = MIN2(len - beg_index, ObjArrayMarkingStride);
+  const size_t end_index = beg_index + stride;
+  T* const base = (T*)a->base();
+  T* const beg = base + beg_index;
+  T* const end = base + end_index;
+
+  // Push the non-NULL elements of the next stride on the marking stack.
+  for (T* e = beg; e < end; e++) {
+    MarkSweep::mark_and_push<T>(e);
+  }
+
+  if (end_index < len) {
+    MarkSweep::push_objarray(a, end_index); // Push the continuation.
+  }
+}
+
+void ObjArrayKlass::oop_ms_follow_contents(oop obj) {
+  assert (obj->is_array(), "obj must be array");
+  MarkSweep::follow_klass(this);
+  if (UseCompressedOops) {
+    oop_ms_follow_contents_specialized<narrowOop>(obj, 0);
+  } else {
+    oop_ms_follow_contents_specialized<oop>(obj, 0);
+  }
+}
+
+void TypeArrayKlass::oop_ms_follow_contents(oop obj) {
+  assert(obj->is_typeArray(),"must be a type array");
+  // Performance tweak: We skip iterating over the klass pointer since we
+  // know that Universe::TypeArrayKlass never moves.
+}
+
 void MarkSweep::follow_array(objArrayOop array, int index) {
-  ObjArrayKlass* k = (ObjArrayKlass*)array->klass();
-  k->oop_follow_contents(array, index);
+  if (UseCompressedOops) {
+    oop_ms_follow_contents_specialized<narrowOop>(array, index);
+  } else {
+    oop_ms_follow_contents_specialized<oop>(array, index);
+  }
 }
 
 void MarkSweep::follow_stack() {
@@ -112,8 +281,10 @@
 
 MarkSweep::AdjustPointerClosure MarkSweep::adjust_pointer_closure;
 
-void MarkSweep::AdjustPointerClosure::do_oop(oop* p)       { adjust_pointer(p); }
-void MarkSweep::AdjustPointerClosure::do_oop(narrowOop* p) { adjust_pointer(p); }
+template <typename T>
+void MarkSweep::AdjustPointerClosure::do_oop_nv(T* p)      { adjust_pointer(p); }
+void MarkSweep::AdjustPointerClosure::do_oop(oop* p)       { do_oop_nv(p); }
+void MarkSweep::AdjustPointerClosure::do_oop(narrowOop* p) { do_oop_nv(p); }
 
 void MarkSweep::adjust_marks() {
   assert( _preserved_oop_stack.size() == _preserved_mark_stack.size(),
@@ -175,3 +346,84 @@
 }
 
 #endif
+
+int InstanceKlass::oop_ms_adjust_pointers(oop obj) {
+  int size = size_helper();
+  oop_oop_iterate_oop_maps<true>(obj, &MarkSweep::adjust_pointer_closure);
+  return size;
+}
+
+int InstanceMirrorKlass::oop_ms_adjust_pointers(oop obj) {
+  int size = oop_size(obj);
+  InstanceKlass::oop_ms_adjust_pointers(obj);
+
+  oop_oop_iterate_statics<true>(obj, &MarkSweep::adjust_pointer_closure);
+  return size;
+}
+
+int InstanceClassLoaderKlass::oop_ms_adjust_pointers(oop obj) {
+  return InstanceKlass::oop_ms_adjust_pointers(obj);
+}
+
+#ifdef ASSERT
+template <class T> static void trace_reference_gc(const char *s, oop obj,
+                                                  T* referent_addr,
+                                                  T* next_addr,
+                                                  T* discovered_addr) {
+  if(TraceReferenceGC && PrintGCDetails) {
+    gclog_or_tty->print_cr("%s obj " PTR_FORMAT, s, p2i(obj));
+    gclog_or_tty->print_cr("     referent_addr/* " PTR_FORMAT " / "
+                           PTR_FORMAT, p2i(referent_addr),
+                           p2i(referent_addr ?
+                               (address)oopDesc::load_decode_heap_oop(referent_addr) : NULL));
+    gclog_or_tty->print_cr("     next_addr/* " PTR_FORMAT " / "
+                           PTR_FORMAT, p2i(next_addr),
+                           p2i(next_addr ? (address)oopDesc::load_decode_heap_oop(next_addr) : NULL));
+    gclog_or_tty->print_cr("     discovered_addr/* " PTR_FORMAT " / "
+                           PTR_FORMAT, p2i(discovered_addr),
+                           p2i(discovered_addr ?
+                               (address)oopDesc::load_decode_heap_oop(discovered_addr) : NULL));
+  }
+}
+#endif
+
+template <class T> void static adjust_object_specialized(oop obj) {
+  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
+  MarkSweep::adjust_pointer(referent_addr);
+  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
+  MarkSweep::adjust_pointer(next_addr);
+  T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
+  MarkSweep::adjust_pointer(discovered_addr);
+  debug_only(trace_reference_gc("InstanceRefKlass::oop_ms_adjust_pointers", obj,
+                                referent_addr, next_addr, discovered_addr);)
+}
+
+int InstanceRefKlass::oop_ms_adjust_pointers(oop obj) {
+  int size = size_helper();
+  InstanceKlass::oop_ms_adjust_pointers(obj);
+
+  if (UseCompressedOops) {
+    adjust_object_specialized<narrowOop>(obj);
+  } else {
+    adjust_object_specialized<oop>(obj);
+  }
+  return size;
+}
+
+int ObjArrayKlass::oop_ms_adjust_pointers(oop obj) {
+  assert(obj->is_objArray(), "obj must be obj array");
+  objArrayOop a = objArrayOop(obj);
+  // Get size before changing pointers.
+  // Don't call size() or oop_size() since that is a virtual call.
+  int size = a->object_size();
+  oop_oop_iterate_elements<true>(a, &MarkSweep::adjust_pointer_closure);
+  return size;
+}
+
+int TypeArrayKlass::oop_ms_adjust_pointers(oop obj) {
+  assert(obj->is_typeArray(), "must be a type array");
+  typeArrayOop t = typeArrayOop(obj);
+  // Performance tweak: We skip iterating over the klass pointer since we
+  // know that Universe::TypeArrayKlass never moves.
+  return t->object_size();
+}
--- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -60,8 +60,9 @@
     virtual void do_oop(narrowOop* p);
   };
 
-  class MarkAndPushClosure: public OopClosure {
+  class MarkAndPushClosure: public ExtendedOopClosure {
    public:
+    template <typename T> void do_oop_nv(T* p);
     virtual void do_oop(oop* p);
     virtual void do_oop(narrowOop* p);
   };
@@ -73,8 +74,12 @@
 
   class AdjustPointerClosure: public OopsInGenClosure {
    public:
+    template <typename T> void do_oop_nv(T* p);
     virtual void do_oop(oop* p);
     virtual void do_oop(narrowOop* p);
+
+    // This closure provides its own oop verification code.
+    debug_only(virtual bool should_verify_oops() { return false; })
   };
 
   // Used for java/lang/ref handling
--- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.inline.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/shared/markSweep.inline.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -28,11 +28,15 @@
 #include "gc_implementation/shared/markSweep.hpp"
 #include "gc_interface/collectedHeap.hpp"
 #include "oops/markOop.inline.hpp"
+#include "oops/instanceKlass.inline.hpp"
+#include "oops/instanceClassLoaderKlass.inline.hpp"
+#include "oops/instanceMirrorKlass.inline.hpp"
+#include "oops/instanceRefKlass.inline.hpp"
+#include "oops/objArrayKlass.inline.hpp"
 #include "utilities/stack.inline.hpp"
 #include "utilities/macros.hpp"
 #if INCLUDE_ALL_GCS
 #include "gc_implementation/g1/g1StringDedup.hpp"
-#include "gc_implementation/parallelScavenge/psParallelCompact.hpp"
 #endif // INCLUDE_ALL_GCS
 
 inline void MarkSweep::mark_object(oop obj) {
@@ -59,7 +63,9 @@
 }
 
 inline void MarkSweep::follow_object(oop obj) {
-  obj->follow_contents();
+  assert(obj->is_gc_marked(), "should be marked");
+
+  obj->ms_follow_contents();
 }
 
 template <class T> inline void MarkSweep::follow_root(T* p) {
@@ -95,13 +101,15 @@
 }
 
 inline int MarkSweep::adjust_pointers(oop obj) {
-  return obj->adjust_pointers();
+  return obj->ms_adjust_pointers();
 }
 
 template <class T> inline void MarkSweep::adjust_pointer(T* p) {
   T heap_oop = oopDesc::load_heap_oop(p);
   if (!oopDesc::is_null(heap_oop)) {
     oop obj     = oopDesc::decode_heap_oop_not_null(heap_oop);
+    assert(Universe::heap()->is_in(obj), "should be in heap");
+
     oop new_obj = oop(obj->mark()->decode_pointer());
     assert(new_obj != NULL ||                         // is forwarding ptr?
            obj->mark() == markOopDesc::prototype() || // not gc marked?
--- a/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -26,7 +26,7 @@
 #include "precompiled.hpp"
 #include "gc_implementation/shared/mutableNUMASpace.hpp"
 #include "gc_implementation/shared/spaceDecorator.hpp"
-#include "memory/sharedHeap.hpp"
+#include "gc_interface/collectedHeap.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/atomic.inline.hpp"
 #include "runtime/thread.inline.hpp"
--- a/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -116,8 +116,6 @@
     _prologue_succeeded = false;
   } else {
     _prologue_succeeded = true;
-    SharedHeap* sh = SharedHeap::heap();
-    if (sh != NULL) sh->_thread_holds_heap_lock_for_gc = true;
   }
   return _prologue_succeeded;
 }
@@ -126,22 +124,11 @@
 void VM_GC_Operation::doit_epilogue() {
   assert(Thread::current()->is_Java_thread(), "just checking");
   // Release the Heap_lock first.
-  SharedHeap* sh = SharedHeap::heap();
-  if (sh != NULL) sh->_thread_holds_heap_lock_for_gc = false;
   Heap_lock->unlock();
   release_and_notify_pending_list_lock();
 }
 
-bool VM_GC_HeapInspection::doit_prologue() {
-  if (Universe::heap()->supports_heap_inspection()) {
-    return VM_GC_Operation::doit_prologue();
-  } else {
-    return false;
-  }
-}
-
 bool VM_GC_HeapInspection::skip_operation() const {
-  assert(Universe::heap()->supports_heap_inspection(), "huh?");
   return false;
 }
 
--- a/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -150,7 +150,6 @@
   ~VM_GC_HeapInspection() {}
   virtual VMOp_Type type() const { return VMOp_GC_HeapInspection; }
   virtual bool skip_operation() const;
-  virtual bool doit_prologue();
   virtual void doit();
   void set_csv_format(bool value) {_csv_format = value;}
   void set_print_help(bool value) {_print_help = value;}
--- a/hotspot/src/share/vm/gc_interface/collectedHeap.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_interface/collectedHeap.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -220,6 +220,11 @@
   }
 }
 
+void CollectedHeap::set_barrier_set(BarrierSet* barrier_set) {
+  _barrier_set = barrier_set;
+  oopDesc::set_bs(_barrier_set);
+}
+
 void CollectedHeap::pre_initialize() {
   // Used for ReduceInitialCardMarks (when COMPILER2 is used);
   // otherwise remains unused.
--- a/hotspot/src/share/vm/gc_interface/collectedHeap.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_interface/collectedHeap.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -75,9 +75,8 @@
 
 //
 // CollectedHeap
-//   SharedHeap
-//     GenCollectedHeap
-//     G1CollectedHeap
+//   GenCollectedHeap
+//   G1CollectedHeap
 //   ParallelScavengeHeap
 //
 class CollectedHeap : public CHeapObj<mtInternal> {
@@ -205,7 +204,7 @@
   // In many heaps, there will be a need to perform some initialization activities
   // after the Universe is fully formed, but before general heap allocation is allowed.
   // This is the correct place to place such initialization methods.
-  virtual void post_initialize() = 0;
+  virtual void post_initialize();
 
   // Stop any onging concurrent work and prepare for exit.
   virtual void stop() {}
@@ -240,22 +239,11 @@
   }
 
   // Returns "TRUE" iff "p" points into the committed areas of the heap.
-  // Since this method can be expensive in general, we restrict its
-  // use to assertion checking only.
+  // This method can be expensive so avoid using it in performance critical
+  // code.
   virtual bool is_in(const void* p) const = 0;
 
-  bool is_in_or_null(const void* p) const {
-    return p == NULL || is_in(p);
-  }
-
-  bool is_in_place(Metadata** p) {
-    return !Universe::heap()->is_in(p);
-  }
-  bool is_in_place(oop* p) { return Universe::heap()->is_in(p); }
-  bool is_in_place(narrowOop* p) {
-    oop o = oopDesc::load_decode_heap_oop_not_null(p);
-    return Universe::heap()->is_in((const void*)o);
-  }
+  DEBUG_ONLY(bool is_in_or_null(const void* p) const { return p == NULL || is_in(p); })
 
   // Let's define some terms: a "closed" subset of a heap is one that
   //
@@ -451,9 +439,6 @@
   // remembered set.
   virtual void flush_deferred_store_barrier(JavaThread* thread);
 
-  // Does this heap support heap inspection (+PrintClassHistogram?)
-  virtual bool supports_heap_inspection() const = 0;
-
   // Perform a collection of the heap; intended for use in implementing
   // "System.gc".  This probably implies as full a collection as the
   // "CollectedHeap" supports.
@@ -470,6 +455,7 @@
 
   // Returns the barrier set for this heap
   BarrierSet* barrier_set() { return _barrier_set; }
+  void set_barrier_set(BarrierSet* barrier_set);
 
   // Returns "true" iff there is a stop-world GC in progress.  (I assume
   // that it should answer "false" for the concurrent part of a concurrent
@@ -497,12 +483,6 @@
   // Return the CollectorPolicy for the heap
   virtual CollectorPolicy* collector_policy() const = 0;
 
-  void oop_iterate_no_header(OopClosure* cl);
-
-  // Iterate over all the ref-containing fields of all objects, calling
-  // "cl.do_oop" on each.
-  virtual void oop_iterate(ExtendedOopClosure* cl) = 0;
-
   // Iterate over all objects, calling "cl.do_object" on each.
   virtual void object_iterate(ObjectClosure* cl) = 0;
 
--- a/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -236,12 +236,6 @@
   return (oop)obj;
 }
 
-inline void CollectedHeap::oop_iterate_no_header(OopClosure* cl) {
-  NoHeaderExtendedOopClosure no_header_cl(cl);
-  oop_iterate(&no_header_cl);
-}
-
-
 inline HeapWord* CollectedHeap::align_allocation_or_fail(HeapWord* addr,
                                                          HeapWord* end,
                                                          unsigned short alignment_in_bytes) {
--- a/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2015, 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
@@ -576,10 +576,10 @@
 /* 0xD8 */ &&opc_default,     &&opc_default,        &&opc_default,      &&opc_default,
 /* 0xDC */ &&opc_default,     &&opc_default,        &&opc_default,      &&opc_default,
 
-/* 0xE0 */ &&opc_default,     &&opc_default,        &&opc_default,      &&opc_default,
-/* 0xE4 */ &&opc_default,     &&opc_fast_aldc,      &&opc_fast_aldc_w,  &&opc_return_register_finalizer,
-/* 0xE8 */ &&opc_invokehandle,&&opc_default,        &&opc_default,      &&opc_default,
-/* 0xEC */ &&opc_default,     &&opc_default,        &&opc_default,      &&opc_default,
+/* 0xE0 */ &&opc_default,     &&opc_default,        &&opc_default,         &&opc_default,
+/* 0xE4 */ &&opc_default,     &&opc_fast_aldc,      &&opc_fast_aldc_w,     &&opc_return_register_finalizer,
+/* 0xE8 */ &&opc_invokehandle,&&opc_default,        &&opc_default,         &&opc_default,
+/* 0xEC */ &&opc_default,     &&opc_default,        &&opc_default,         &&opc_default,
 
 /* 0xF0 */ &&opc_default,     &&opc_default,        &&opc_default,      &&opc_default,
 /* 0xF4 */ &&opc_default,     &&opc_default,        &&opc_default,      &&opc_default,
@@ -1942,7 +1942,7 @@
 
           cache = cp->entry_at(index);
           if (!cache->is_resolved((Bytecodes::Code)opcode)) {
-            CALL_VM(InterpreterRuntime::resolve_get_put(THREAD, (Bytecodes::Code)opcode),
+            CALL_VM(InterpreterRuntime::resolve_from_cache(THREAD, (Bytecodes::Code)opcode),
                     handle_exception);
             cache = cp->entry_at(index);
           }
@@ -2040,7 +2040,7 @@
           u2 index = Bytes::get_native_u2(pc+1);
           ConstantPoolCacheEntry* cache = cp->entry_at(index);
           if (!cache->is_resolved((Bytecodes::Code)opcode)) {
-            CALL_VM(InterpreterRuntime::resolve_get_put(THREAD, (Bytecodes::Code)opcode),
+            CALL_VM(InterpreterRuntime::resolve_from_cache(THREAD, (Bytecodes::Code)opcode),
                     handle_exception);
             cache = cp->entry_at(index);
           }
@@ -2416,7 +2416,7 @@
         // This kind of CP cache entry does not need to match the flags byte, because
         // there is a 1-1 relation between bytecode type and CP entry type.
         if (! cache->is_resolved((Bytecodes::Code) opcode)) {
-          CALL_VM(InterpreterRuntime::resolve_invokedynamic(THREAD),
+          CALL_VM(InterpreterRuntime::resolve_from_cache(THREAD, (Bytecodes::Code)opcode),
                   handle_exception);
           cache = cp->constant_pool()->invokedynamic_cp_cache_entry_at(index);
         }
@@ -2447,7 +2447,7 @@
         ConstantPoolCacheEntry* cache = cp->entry_at(index);
 
         if (! cache->is_resolved((Bytecodes::Code) opcode)) {
-          CALL_VM(InterpreterRuntime::resolve_invokehandle(THREAD),
+          CALL_VM(InterpreterRuntime::resolve_from_cache(THREAD, (Bytecodes::Code)opcode),
                   handle_exception);
           cache = cp->entry_at(index);
         }
@@ -2480,7 +2480,7 @@
 
         ConstantPoolCacheEntry* cache = cp->entry_at(index);
         if (!cache->is_resolved((Bytecodes::Code)opcode)) {
-          CALL_VM(InterpreterRuntime::resolve_invoke(THREAD, (Bytecodes::Code)opcode),
+          CALL_VM(InterpreterRuntime::resolve_from_cache(THREAD, (Bytecodes::Code)opcode),
                   handle_exception);
           cache = cp->entry_at(index);
         }
@@ -2571,7 +2571,7 @@
         // out so c++ compiler has a chance for constant prop to fold everything possible away.
 
         if (!cache->is_resolved((Bytecodes::Code)opcode)) {
-          CALL_VM(InterpreterRuntime::resolve_invoke(THREAD, (Bytecodes::Code)opcode),
+          CALL_VM(InterpreterRuntime::resolve_from_cache(THREAD, (Bytecodes::Code)opcode),
                   handle_exception);
           cache = cp->entry_at(index);
         }
--- a/hotspot/src/share/vm/interpreter/bytecodes.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/interpreter/bytecodes.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -525,6 +525,12 @@
   def(_fast_aldc           , "fast_aldc"           , "bj"   , NULL    , T_OBJECT,   1, true,  _ldc   );
   def(_fast_aldc_w         , "fast_aldc_w"         , "bJJ"  , NULL    , T_OBJECT,   1, true,  _ldc_w );
 
+  def(_nofast_getfield     , "nofast_getfield"     , "bJJ"  , NULL    , T_ILLEGAL,  0, true,  _getfield       );
+  def(_nofast_putfield     , "nofast_putfield"     , "bJJ"  , NULL    , T_ILLEGAL, -2, true , _putfield       );
+
+  def(_nofast_aload_0      , "nofast_aload_0"      , "b"    , NULL    , T_ILLEGAL,  1, true , _aload_0        );
+  def(_nofast_iload        , "nofast_iload"        , "bi"   , NULL    , T_ILLEGAL,  1, false, _iload          );
+
   def(_shouldnotreachhere  , "_shouldnotreachhere" , "b"    , NULL    , T_VOID   ,  0, false);
 
   // compare can_trap information for each bytecode with the
--- a/hotspot/src/share/vm/interpreter/bytecodes.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/interpreter/bytecodes.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, 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
@@ -285,7 +285,20 @@
     // special handling of signature-polymorphic methods:
     _invokehandle         ,
 
-    _shouldnotreachhere,      // For debugging
+    // These bytecodes are rewritten at CDS dump time, so that we can prevent them from being
+    // rewritten at run time. This way, the ConstMethods can be placed in the CDS ReadOnly
+    // section, and RewriteByteCodes/RewriteFrequentPairs can rewrite non-CDS bytecodes
+    // at run time.
+    //
+    // Rewritten at CDS dump time to | Original bytecode
+    // _invoke_virtual rewritten on sparc, will be disabled if UseSharedSpaces turned on.
+    // ------------------------------+------------------
+    _nofast_getfield      ,          //  <- _getfield
+    _nofast_putfield      ,          //  <- _putfield
+    _nofast_aload_0       ,          //  <- _aload_0
+    _nofast_iload         ,          //  <- _iload
+
+    _shouldnotreachhere   ,          // For debugging
 
 
     number_of_codes
@@ -401,6 +414,7 @@
   static bool        is_astore      (Code code)    { return (code == _astore || code == _astore_0 || code == _astore_1
                                                                              || code == _astore_2 || code == _astore_3); }
 
+  static bool        is_store_into_local(Code code){ return (_istore <= code && code <= _astore_3); }
   static bool        is_const       (Code code)    { return (_aconst_null <= code && code <= _ldc2_w); }
   static bool        is_zero_const  (Code code)    { return (code == _aconst_null || code == _iconst_0
                                                            || code == _fconst_0 || code == _dconst_0); }
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -537,11 +537,13 @@
 // Fields
 //
 
-IRT_ENTRY(void, InterpreterRuntime::resolve_get_put(JavaThread* thread, Bytecodes::Code bytecode))
+void InterpreterRuntime::resolve_get_put(JavaThread* thread, Bytecodes::Code bytecode) {
+  Thread* THREAD = thread;
   // resolve field
   fieldDescriptor info;
   constantPoolHandle pool(thread, method(thread)->constants());
-  bool is_put    = (bytecode == Bytecodes::_putfield  || bytecode == Bytecodes::_putstatic);
+  bool is_put    = (bytecode == Bytecodes::_putfield  || bytecode == Bytecodes::_nofast_putfield ||
+                    bytecode == Bytecodes::_putstatic);
   bool is_static = (bytecode == Bytecodes::_getstatic || bytecode == Bytecodes::_putstatic);
 
   {
@@ -551,7 +553,8 @@
   } // end JvmtiHideSingleStepping
 
   // check if link resolution caused cpCache to be updated
-  if (already_resolved(thread)) return;
+  ConstantPoolCacheEntry* cp_cache_entry = cache_entry(thread);
+  if (cp_cache_entry->is_resolved(bytecode)) return;
 
   // compute auxiliary field attributes
   TosState state  = as_TosState(info.field_type());
@@ -579,7 +582,7 @@
     }
   }
 
-  cache_entry(thread)->set_field(
+  cp_cache_entry->set_field(
     get_code,
     put_code,
     info.field_holder(),
@@ -590,7 +593,7 @@
     info.access_flags().is_volatile(),
     pool->pool_holder()
   );
-IRT_END
+}
 
 
 //------------------------------------------------------------------------------------------------------------------------
@@ -685,7 +688,8 @@
   JvmtiExport::post_raw_breakpoint(thread, method, bcp);
 IRT_END
 
-IRT_ENTRY(void, InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes::Code bytecode)) {
+void InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes::Code bytecode) {
+  Thread* THREAD = thread;
   // extract receiver from the outgoing argument list if necessary
   Handle receiver(thread, NULL);
   if (bytecode == Bytecodes::_invokevirtual || bytecode == Bytecodes::_invokeinterface) {
@@ -709,7 +713,8 @@
   {
     JvmtiHideSingleStepping jhss(thread);
     LinkResolver::resolve_invoke(info, receiver, pool,
-                                 get_index_u2_cpcache(thread, bytecode), bytecode, CHECK);
+                                 get_index_u2_cpcache(thread, bytecode), bytecode,
+                                 CHECK);
     if (JvmtiExport::can_hotswap_or_post_breakpoint()) {
       int retry_count = 0;
       while (info.resolved_method()->is_old()) {
@@ -720,13 +725,15 @@
                   "Could not resolve to latest version of redefined method");
         // method is redefined in the middle of resolve so re-try.
         LinkResolver::resolve_invoke(info, receiver, pool,
-                                     get_index_u2_cpcache(thread, bytecode), bytecode, CHECK);
+                                     get_index_u2_cpcache(thread, bytecode), bytecode,
+                                     CHECK);
       }
     }
   } // end JvmtiHideSingleStepping
 
   // check if link resolution caused cpCache to be updated
-  if (already_resolved(thread)) return;
+  ConstantPoolCacheEntry* cp_cache_entry = cache_entry(thread);
+  if (cp_cache_entry->is_resolved(bytecode)) return;
 
   if (bytecode == Bytecodes::_invokeinterface) {
     if (TraceItables && Verbose) {
@@ -761,18 +768,18 @@
 #endif
   switch (info.call_kind()) {
   case CallInfo::direct_call:
-    cache_entry(thread)->set_direct_call(
+    cp_cache_entry->set_direct_call(
       bytecode,
       info.resolved_method());
     break;
   case CallInfo::vtable_call:
-    cache_entry(thread)->set_vtable_call(
+    cp_cache_entry->set_vtable_call(
       bytecode,
       info.resolved_method(),
       info.vtable_index());
     break;
   case CallInfo::itable_call:
-    cache_entry(thread)->set_itable_call(
+    cp_cache_entry->set_itable_call(
       bytecode,
       info.resolved_method(),
       info.itable_index());
@@ -780,30 +787,30 @@
   default:  ShouldNotReachHere();
   }
 }
-IRT_END
 
 
 // First time execution:  Resolve symbols, create a permanent MethodType object.
-IRT_ENTRY(void, InterpreterRuntime::resolve_invokehandle(JavaThread* thread)) {
+void InterpreterRuntime::resolve_invokehandle(JavaThread* thread) {
+  Thread* THREAD = thread;
   const Bytecodes::Code bytecode = Bytecodes::_invokehandle;
 
   // resolve method
   CallInfo info;
   constantPoolHandle pool(thread, method(thread)->constants());
-
   {
     JvmtiHideSingleStepping jhss(thread);
     LinkResolver::resolve_invoke(info, Handle(), pool,
-                                 get_index_u2_cpcache(thread, bytecode), bytecode, CHECK);
+                                 get_index_u2_cpcache(thread, bytecode), bytecode,
+                                 CHECK);
   } // end JvmtiHideSingleStepping
 
-  cache_entry(thread)->set_method_handle(pool, info);
+  ConstantPoolCacheEntry* cp_cache_entry = cache_entry(thread);
+  cp_cache_entry->set_method_handle(pool, info);
 }
-IRT_END
-
 
 // First time execution:  Resolve symbols, create a permanent CallSite object.
-IRT_ENTRY(void, InterpreterRuntime::resolve_invokedynamic(JavaThread* thread)) {
+void InterpreterRuntime::resolve_invokedynamic(JavaThread* thread) {
+  Thread* THREAD = thread;
   const Bytecodes::Code bytecode = Bytecodes::_invokedynamic;
 
   //TO DO: consider passing BCI to Java.
@@ -822,9 +829,37 @@
   ConstantPoolCacheEntry* cp_cache_entry = pool->invokedynamic_cp_cache_entry_at(index);
   cp_cache_entry->set_dynamic_call(pool, info);
 }
+
+// This function is the interface to the assembly code. It returns the resolved
+// cpCache entry.  This doesn't safepoint, but the helper routines safepoint.
+// This function will check for redefinition!
+IRT_ENTRY(void, InterpreterRuntime::resolve_from_cache(JavaThread* thread, Bytecodes::Code bytecode)) {
+  switch (bytecode) {
+  case Bytecodes::_getstatic:
+  case Bytecodes::_putstatic:
+  case Bytecodes::_getfield:
+  case Bytecodes::_putfield:
+    resolve_get_put(thread, bytecode);
+    break;
+  case Bytecodes::_invokevirtual:
+  case Bytecodes::_invokespecial:
+  case Bytecodes::_invokestatic:
+  case Bytecodes::_invokeinterface:
+    resolve_invoke(thread, bytecode);
+    break;
+  case Bytecodes::_invokehandle:
+    resolve_invokehandle(thread);
+    break;
+  case Bytecodes::_invokedynamic:
+    resolve_invokedynamic(thread);
+    break;
+  default:
+    fatal(err_msg("unexpected bytecode: %s", Bytecodes::name(bytecode)));
+    break;
+  }
+}
 IRT_END
 
-
 //------------------------------------------------------------------------------------------------------------------------
 // Miscellaneous
 
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, 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
@@ -52,7 +52,6 @@
     // pass method to avoid calling unsafe bcp_to_method (partial fix 4926272)
     return Bytecodes::code_at(method(thread), bcp(thread));
   }
-  static bool      already_resolved(JavaThread *thread) { return cache_entry(thread)->is_resolved(code(thread)); }
   static Bytecode  bytecode(JavaThread *thread)      { return Bytecode(method(thread), bcp(thread)); }
   static int       get_index_u1(JavaThread *thread, Bytecodes::Code bc)
                                                         { return bytecode(thread).get_index_u1(bc); }
@@ -117,9 +116,17 @@
   static void    note_no_trap(JavaThread* thread, Method *method, int trap_bci) {}
 #endif // CC_INTERP
 
+  static void resolve_from_cache(JavaThread* thread, Bytecodes::Code bytecode);
+ private:
   // Statics & fields
-  static void    resolve_get_put(JavaThread* thread, Bytecodes::Code bytecode);
+  static void resolve_get_put(JavaThread* thread, Bytecodes::Code bytecode);
 
+  // Calls
+  static void resolve_invoke(JavaThread* thread, Bytecodes::Code bytecode);
+  static void resolve_invokehandle (JavaThread* thread);
+  static void resolve_invokedynamic(JavaThread* thread);
+
+ public:
   // Synchronization
   static void    monitorenter(JavaThread* thread, BasicObjectLock* elem);
   static void    monitorexit (JavaThread* thread, BasicObjectLock* elem);
@@ -127,11 +134,6 @@
   static void    throw_illegal_monitor_state_exception(JavaThread* thread);
   static void    new_illegal_monitor_state_exception(JavaThread* thread);
 
-  // Calls
-  static void    resolve_invoke       (JavaThread* thread, Bytecodes::Code bytecode);
-  static void    resolve_invokehandle (JavaThread* thread);
-  static void    resolve_invokedynamic(JavaThread* thread);
-
   // Breakpoints
   static void _breakpoint(JavaThread* thread, Method* method, address bcp);
   static Bytecodes::Code get_original_bytecode_at(JavaThread* thread, Method* method, address bcp);
--- a/hotspot/src/share/vm/interpreter/linkResolver.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -777,11 +777,11 @@
                                  TRAPS) {
   assert(byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic ||
          byte == Bytecodes::_getfield  || byte == Bytecodes::_putfield  ||
+         byte == Bytecodes::_nofast_getfield  || byte == Bytecodes::_nofast_putfield  ||
          (byte == Bytecodes::_nop && !check_access), "bad field access bytecode");
 
   bool is_static = (byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic);
-  bool is_put    = (byte == Bytecodes::_putfield  || byte == Bytecodes::_putstatic);
-
+  bool is_put    = (byte == Bytecodes::_putfield  || byte == Bytecodes::_putstatic || byte == Bytecodes::_nofast_putfield);
   // Check if there's a resolved klass containing the field
   if (resolved_klass.is_null()) {
     ResourceMark rm(THREAD);
--- a/hotspot/src/share/vm/interpreter/rewriter.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/interpreter/rewriter.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -26,6 +26,7 @@
 #include "interpreter/bytecodes.hpp"
 #include "interpreter/interpreter.hpp"
 #include "interpreter/rewriter.hpp"
+#include "memory/metaspaceShared.hpp"
 #include "memory/gcLocker.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/generateOopMap.hpp"
@@ -167,12 +168,12 @@
   if (!reverse) {
     int cp_index = Bytes::get_Java_u2(p);
     if (_pool->tag_at(cp_index).is_interface_method()) {
-    int cache_index = add_invokespecial_cp_cache_entry(cp_index);
-    if (cache_index != (int)(jushort) cache_index) {
-      *invokespecial_error = true;
-    }
-    Bytes::put_native_u2(p, cache_index);
-  } else {
+      int cache_index = add_invokespecial_cp_cache_entry(cp_index);
+      if (cache_index != (int)(jushort) cache_index) {
+        *invokespecial_error = true;
+      }
+      Bytes::put_native_u2(p, cache_index);
+    } else {
       rewrite_member_reference(bcp, offset, reverse);
     }
   } else {
@@ -500,12 +501,14 @@
 }
 
 void Rewriter::rewrite(instanceKlassHandle klass, TRAPS) {
+  if (!DumpSharedSpaces) {
+    assert(!MetaspaceShared::is_in_shared_space(klass()), "archive methods must not be rewritten at run time");
+  }
   ResourceMark rm(THREAD);
   Rewriter     rw(klass, klass->constants(), klass->methods(), CHECK);
   // (That's all, folks.)
 }
 
-
 Rewriter::Rewriter(instanceKlassHandle klass, constantPoolHandle cpool, Array<Method*>* methods, TRAPS)
   : _klass(klass),
     _pool(cpool),
--- a/hotspot/src/share/vm/interpreter/templateTable.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/interpreter/templateTable.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -517,6 +517,12 @@
 
   def(Bytecodes::_invokehandle        , ubcp|disp|clvm|____, vtos, vtos, invokehandle        , f1_byte      );
 
+  def(Bytecodes::_nofast_getfield     , ubcp|____|clvm|____, vtos, vtos, nofast_getfield     , f1_byte      );
+  def(Bytecodes::_nofast_putfield     , ubcp|____|clvm|____, vtos, vtos, nofast_putfield     , f2_byte      );
+
+  def(Bytecodes::_nofast_aload_0      , ____|____|clvm|____, vtos, atos, nofast_aload_0      ,  _           );
+  def(Bytecodes::_nofast_iload        , ubcp|____|clvm|____, vtos, itos, nofast_iload        ,  _           );
+
   def(Bytecodes::_shouldnotreachhere   , ____|____|____|____, vtos, vtos, shouldnotreachhere ,  _           );
   // platform specific bytecodes
   pd_initialize();
--- a/hotspot/src/share/vm/interpreter/templateTable.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/interpreter/templateTable.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -82,6 +82,7 @@
   enum Operation { add, sub, mul, div, rem, _and, _or, _xor, shl, shr, ushr };
   enum Condition { equal, not_equal, less, less_equal, greater, greater_equal };
   enum CacheByte { f1_byte = 1, f2_byte = 2 };  // byte_no codes
+  enum RewriteControl { may_rewrite, may_not_rewrite };  // control for fast code under CDS
 
  private:
   static bool            _is_initialized;        // true if TemplateTable has been initialized
@@ -165,6 +166,10 @@
   static void dload(int n);
   static void aload(int n);
   static void aload_0();
+  static void nofast_aload_0();
+  static void nofast_iload();
+  static void iload_internal(RewriteControl rc = may_rewrite);
+  static void aload_0_internal(RewriteControl rc = may_rewrite);
 
   static void istore();
   static void lstore();
@@ -279,10 +284,13 @@
   static void invokehandle(int byte_no);
   static void fast_invokevfinal(int byte_no);
 
-  static void getfield_or_static(int byte_no, bool is_static);
-  static void putfield_or_static(int byte_no, bool is_static);
+  static void getfield_or_static(int byte_no, bool is_static, RewriteControl rc = may_rewrite);
+  static void putfield_or_static(int byte_no, bool is_static, RewriteControl rc = may_rewrite);
+
   static void getfield(int byte_no);
   static void putfield(int byte_no);
+  static void nofast_getfield(int byte_no);
+  static void nofast_putfield(int byte_no);
   static void getstatic(int byte_no);
   static void putstatic(int byte_no);
   static void pop_and_check_object(Register obj);
@@ -343,10 +351,8 @@
   // Platform specifics
 #if defined TEMPLATETABLE_MD_HPP
 # include TEMPLATETABLE_MD_HPP
-#elif defined TARGET_ARCH_MODEL_x86_32
-# include "templateTable_x86_32.hpp"
-#elif defined TARGET_ARCH_MODEL_x86_64
-# include "templateTable_x86_64.hpp"
+#elif defined (TARGET_ARCH_MODEL_x86_32) || defined (TARGET_ARCH_MODEL_x86_64)
+# include "templateTable_x86.hpp"
 #elif defined TARGET_ARCH_MODEL_sparc
 # include "templateTable_sparc.hpp"
 #elif defined TARGET_ARCH_MODEL_zero
--- a/hotspot/src/share/vm/memory/cardGeneration.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/memory/cardGeneration.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, 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
@@ -60,7 +60,7 @@
   // which would cause problems when we commit/uncommit memory, and when we
   // clear and dirty cards.
   guarantee(_rs->is_aligned(reserved_mr.start()), "generation must be card aligned");
-  if (reserved_mr.end() != Universe::heap()->reserved_region().end()) {
+  if (reserved_mr.end() != GenCollectedHeap::heap()->reserved_region().end()) {
     // Don't check at the very end of the heap as we'll assert that we're probing off
     // the end if we try.
     guarantee(_rs->is_aligned(reserved_mr.end()), "generation must be card aligned");
@@ -78,7 +78,7 @@
        heap_word_size(_virtual_space.committed_size());
     MemRegion mr(space()->bottom(), new_word_size);
     // Expand card table
-    Universe::heap()->barrier_set()->resize_covered_region(mr);
+    GenCollectedHeap::heap()->barrier_set()->resize_covered_region(mr);
     // Expand shared block offset array
     _bts->resize(new_word_size);
 
@@ -170,7 +170,7 @@
   _bts->resize(new_word_size);
   MemRegion mr(space()->bottom(), new_word_size);
   // Shrink the card table
-  Universe::heap()->barrier_set()->resize_covered_region(mr);
+  GenCollectedHeap::heap()->barrier_set()->resize_covered_region(mr);
 
   if (Verbose && PrintGC) {
     size_t new_mem_size = _virtual_space.committed_size();
--- a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -23,10 +23,11 @@
  */
 
 #include "precompiled.hpp"
+#include "gc_interface/collectedHeap.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/cardTableModRefBS.inline.hpp"
 #include "memory/cardTableRS.hpp"
-#include "memory/sharedHeap.hpp"
+#include "memory/genCollectedHeap.hpp"
 #include "memory/space.hpp"
 #include "memory/space.inline.hpp"
 #include "memory/universe.hpp"
@@ -450,21 +451,20 @@
     // This is an example of where n_par_threads() is used instead
     // of workers()->active_workers().  n_par_threads can be set to 0 to
     // turn off parallelism.  For example when this code is called as
-    // part of verification and SharedHeap::process_roots() is being
-    // used, then n_par_threads() may have been set to 0.  active_workers
-    // is not overloaded with the meaning that it is a switch to disable
-    // parallelism and so keeps the meaning of the number of
-    // active gc workers.  If parallelism has not been shut off by
-    // setting n_par_threads to 0, then n_par_threads should be
-    // equal to active_workers.  When a different mechanism for shutting
-    // off parallelism is used, then active_workers can be used in
+    // part of verification during root processing then n_par_threads()
+    // may have been set to 0. active_workers is not overloaded with
+    // the meaning that it is a switch to disable parallelism and so keeps
+    // the meaning of the number of active gc workers. If parallelism has
+    // not been shut off by setting n_par_threads to 0, then n_par_threads
+    // should be equal to active_workers.  When a different mechanism for
+    // shutting off parallelism is used, then active_workers can be used in
     // place of n_par_threads.
-    int n_threads =  SharedHeap::heap()->n_par_threads();
+    int n_threads =  GenCollectedHeap::heap()->n_par_threads();
     bool is_par = n_threads > 0;
     if (is_par) {
 #if INCLUDE_ALL_GCS
-      assert(SharedHeap::heap()->n_par_threads() ==
-             SharedHeap::heap()->workers()->active_workers(), "Mismatch");
+      assert(GenCollectedHeap::heap()->n_par_threads() ==
+             GenCollectedHeap::heap()->workers()->active_workers(), "Mismatch");
       non_clean_card_iterate_parallel_work(sp, mr, cl, ct, n_threads);
 #else  // INCLUDE_ALL_GCS
       fatal("Parallel gc not supported here.");
--- a/hotspot/src/share/vm/memory/cardTableRS.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/memory/cardTableRS.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, 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
@@ -38,16 +38,18 @@
   GenRemSet(),
   _cur_youngergen_card_val(youngergenP1_card)
 {
-  guarantee(Universe::heap()->kind() == CollectedHeap::GenCollectedHeap, "sanity");
   _ct_bs = new CardTableModRefBSForCTRS(whole_heap);
   _ct_bs->initialize();
   set_bs(_ct_bs);
-  _last_cur_val_in_gen = NEW_C_HEAP_ARRAY3(jbyte, GenCollectedHeap::max_gens + 1,
+  // max_gens is really GenCollectedHeap::heap()->gen_policy()->number_of_generations()
+  // (which is always 2, young & old), but GenCollectedHeap has not been initialized yet.
+  uint max_gens = 2;
+  _last_cur_val_in_gen = NEW_C_HEAP_ARRAY3(jbyte, max_gens + 1,
                          mtGC, CURRENT_PC, AllocFailStrategy::RETURN_NULL);
   if (_last_cur_val_in_gen == NULL) {
     vm_exit_during_initialization("Could not create last_cur_val_in_gen array.");
   }
-  for (int i = 0; i < GenCollectedHeap::max_gens + 1; i++) {
+  for (uint i = 0; i < max_gens + 1; i++) {
     _last_cur_val_in_gen[i] = clean_card_val();
   }
   _ct_bs->set_CTRS(this);
@@ -167,16 +169,20 @@
     // Cannot yet substitute active_workers for n_par_threads
     // in the case where parallelism is being turned off by
     // setting n_par_threads to 0.
-    _is_par = (SharedHeap::heap()->n_par_threads() > 0);
+    _is_par = (GenCollectedHeap::heap()->n_par_threads() > 0);
     assert(!_is_par ||
-           (SharedHeap::heap()->n_par_threads() ==
-            SharedHeap::heap()->workers()->active_workers()), "Mismatch");
+           (GenCollectedHeap::heap()->n_par_threads() ==
+            GenCollectedHeap::heap()->workers()->active_workers()), "Mismatch");
 }
 
 bool ClearNoncleanCardWrapper::is_word_aligned(jbyte* entry) {
   return (((intptr_t)entry) & (BytesPerWord-1)) == 0;
 }
 
+// The regions are visited in *decreasing* address order.
+// This order aids with imprecise card marking, where a dirty
+// card may cause scanning, and summarization marking, of objects
+// that extend onto subsequent cards.
 void ClearNoncleanCardWrapper::do_MemRegion(MemRegion mr) {
   assert(mr.word_size() > 0, "Error");
   assert(_ct->is_aligned(mr.start()), "mr.start() should be card aligned");
@@ -591,10 +597,6 @@
   // At present, we only know how to verify the card table RS for
   // generational heaps.
   VerifyCTGenClosure blk(this);
-  CollectedHeap* ch = Universe::heap();
-
-  if (ch->kind() == CollectedHeap::GenCollectedHeap) {
-    GenCollectedHeap::heap()->generation_iterate(&blk, false);
-    _ct_bs->verify();
-    }
-  }
+  GenCollectedHeap::heap()->generation_iterate(&blk, false);
+  _ct_bs->verify();
+}
--- a/hotspot/src/share/vm/memory/collectorPolicy.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/memory/collectorPolicy.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -669,7 +669,7 @@
       }
 
       // Read the gc count while the heap lock is held.
-      gc_count_before = Universe::heap()->total_collections();
+      gc_count_before = gch->total_collections();
     }
 
     VM_GenCollectForAllocation op(size, is_tlab, gc_count_before);
--- a/hotspot/src/share/vm/memory/defNewGeneration.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/memory/defNewGeneration.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -48,6 +48,9 @@
 #include "utilities/copy.hpp"
 #include "utilities/globalDefinitions.hpp"
 #include "utilities/stack.inline.hpp"
+#if INCLUDE_ALL_GCS
+#include "gc_implementation/parNew/parOopClosures.hpp"
+#endif
 
 //
 // DefNewGeneration functions.
@@ -190,7 +193,9 @@
 {
   MemRegion cmr((HeapWord*)_virtual_space.low(),
                 (HeapWord*)_virtual_space.high());
-  Universe::heap()->barrier_set()->resize_covered_region(cmr);
+  GenCollectedHeap* gch = GenCollectedHeap::heap();
+
+  gch->barrier_set()->resize_covered_region(cmr);
 
   _eden_space = new ContiguousSpace();
   _from_space = new ContiguousSpace();
@@ -202,13 +207,13 @@
   // Compute the maximum eden and survivor space sizes. These sizes
   // are computed assuming the entire reserved space is committed.
   // These values are exported as performance counters.
-  uintx alignment = GenCollectedHeap::heap()->collector_policy()->space_alignment();
+  uintx alignment = gch->collector_policy()->space_alignment();
   uintx size = _virtual_space.reserved_size();
   _max_survivor_size = compute_survivor_size(size, alignment);
   _max_eden_size = size - (2*_max_survivor_size);
 
   // allocate the performance counters
-  GenCollectorPolicy* gcp = (GenCollectorPolicy*) GenCollectedHeap::heap()->collector_policy();
+  GenCollectorPolicy* gcp = (GenCollectorPolicy*)gch->collector_policy();
 
   // Generation counters -- generation 0, 3 subspaces
   _gen_counters = new GenerationCounters("new", 0, 3,
@@ -378,8 +383,7 @@
 
   int next_level = level() + 1;
   GenCollectedHeap* gch = GenCollectedHeap::heap();
-  assert(next_level < gch->n_gens(),
-         "DefNewGeneration cannot be an oldest gen");
+  assert(next_level == 1, "DefNewGeneration must be a young gen");
 
   Generation* old_gen = gch->old_gen();
   size_t old_size = old_gen->capacity();
@@ -431,7 +435,7 @@
                              SpaceDecorator::DontMangle);
     MemRegion cmr((HeapWord*)_virtual_space.low(),
                   (HeapWord*)_virtual_space.high());
-    Universe::heap()->barrier_set()->resize_covered_region(cmr);
+    gch->barrier_set()->resize_covered_region(cmr);
     if (Verbose && PrintGC) {
       size_t new_size_after  = _virtual_space.committed_size();
       size_t eden_size_after = eden()->capacity();
@@ -550,8 +554,9 @@
 
 void DefNewGeneration::adjust_desired_tenuring_threshold() {
   // Set the desired survivor size to half the real survivor space
+  GCPolicyCounters* gc_counters = GenCollectedHeap::heap()->collector_policy()->counters();
   _tenuring_threshold =
-    age_table()->compute_tenuring_threshold(to()->capacity()/HeapWordSize);
+    age_table()->compute_tenuring_threshold(to()->capacity()/HeapWordSize, gc_counters);
 }
 
 void DefNewGeneration::collect(bool   full,
@@ -688,7 +693,7 @@
     gc_tracer.report_promotion_failed(_promotion_failed_info);
 
     // Reset the PromotionFailureALot counters.
-    NOT_PRODUCT(Universe::heap()->reset_promotion_should_fail();)
+    NOT_PRODUCT(gch->reset_promotion_should_fail();)
   }
   if (PrintGC && !PrintGCDetails) {
     gch->print_heap_change(gch_prev_used);
--- a/hotspot/src/share/vm/memory/defNewGeneration.inline.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/memory/defNewGeneration.inline.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -25,9 +25,9 @@
 #ifndef SHARE_VM_MEMORY_DEFNEWGENERATION_INLINE_HPP
 #define SHARE_VM_MEMORY_DEFNEWGENERATION_INLINE_HPP
 
-#include "gc_interface/collectedHeap.hpp"
 #include "memory/cardTableRS.hpp"
 #include "memory/defNewGeneration.hpp"
+#include "memory/genCollectedHeap.hpp"
 #include "memory/genOopClosures.inline.hpp"
 #include "memory/space.hpp"
 
@@ -60,7 +60,7 @@
   // We could check that p is also in an older generation, but
   // dirty cards in the youngest gen are never scanned, so the
   // extra check probably isn't worthwhile.
-  if (Universe::heap()->is_in_reserved(p)) {
+  if (GenCollectedHeap::heap()->is_in_reserved(p)) {
     oop obj = oopDesc::load_decode_heap_oop_not_null(p);
     _rs->inline_write_ref_field_gc(p, obj);
   }
@@ -84,7 +84,7 @@
   // we set a younger_gen card if we have an older->youngest
   // generation pointer.
   oop obj = oopDesc::load_decode_heap_oop_not_null(p);
-  if (((HeapWord*)obj < _boundary) && Universe::heap()->is_in_reserved(p)) {
+  if (((HeapWord*)obj < _boundary) && GenCollectedHeap::heap()->is_in_reserved(p)) {
     _rs->inline_write_ref_field_gc(p, obj);
   }
 }
--- a/hotspot/src/share/vm/memory/freeList.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/memory/freeList.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -23,10 +23,10 @@
  */
 
 #include "precompiled.hpp"
+#include "gc_interface/collectedHeap.hpp"
 #include "memory/freeBlockDictionary.hpp"
 #include "memory/freeList.hpp"
 #include "memory/metachunk.hpp"
-#include "memory/sharedHeap.hpp"
 #include "runtime/globals.hpp"
 #include "runtime/mutex.hpp"
 #include "runtime/vmThread.hpp"
--- a/hotspot/src/share/vm/memory/gcLocker.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/memory/gcLocker.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -23,9 +23,9 @@
  */
 
 #include "precompiled.hpp"
+#include "gc_interface/collectedHeap.hpp"
 #include "memory/gcLocker.inline.hpp"
 #include "memory/resourceArea.hpp"
-#include "memory/sharedHeap.hpp"
 #include "runtime/atomic.inline.hpp"
 #include "runtime/thread.inline.hpp"
 
--- a/hotspot/src/share/vm/memory/genCollectedHeap.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/memory/genCollectedHeap.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -39,7 +39,7 @@
 #include "memory/genOopClosures.inline.hpp"
 #include "memory/generationSpec.hpp"
 #include "memory/resourceArea.hpp"
-#include "memory/sharedHeap.hpp"
+#include "memory/strongRootsScope.hpp"
 #include "memory/space.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/biasedLocking.hpp"
@@ -50,9 +50,10 @@
 #include "runtime/vmThread.hpp"
 #include "services/management.hpp"
 #include "services/memoryService.hpp"
+#include "utilities/macros.hpp"
+#include "utilities/stack.inline.hpp"
 #include "utilities/vmError.hpp"
 #include "utilities/workgroup.hpp"
-#include "utilities/macros.hpp"
 #if INCLUDE_ALL_GCS
 #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp"
 #include "gc_implementation/concurrentMarkSweep/vmCMSOperations.hpp"
@@ -78,21 +79,27 @@
 };
 
 GenCollectedHeap::GenCollectedHeap(GenCollectorPolicy *policy) :
-  SharedHeap(),
+  CollectedHeap(),
   _rem_set(NULL),
   _gen_policy(policy),
   _process_strong_tasks(new SubTasksDone(GCH_PS_NumElements)),
   _full_collections_completed(0)
 {
   assert(policy != NULL, "Sanity check");
+  if (UseConcMarkSweepGC) {
+    _workers = new FlexibleWorkGang("GC Thread", ParallelGCThreads,
+                            /* are_GC_task_threads */true,
+                            /* are_ConcurrentGC_threads */false);
+    _workers->initialize_workers();
+  } else {
+    // Serial GC does not use workers.
+    _workers = NULL;
+  }
 }
 
 jint GenCollectedHeap::initialize() {
   CollectedHeap::pre_initialize();
 
-  _n_gens = gen_policy()->number_of_generations();
-  assert(_n_gens == 2, "There is no support for more than two generations");
-
   // While there are no constraints in the GC code that HeapWordSize
   // be any particular value, there are multiple other areas in the
   // system which believe this to be true (e.g. oop->object_size in some
@@ -166,7 +173,8 @@
 }
 
 void GenCollectedHeap::post_initialize() {
-  SharedHeap::post_initialize();
+  CollectedHeap::post_initialize();
+  ref_processing_init();
   GenCollectorPolicy *policy = (GenCollectorPolicy *)collector_policy();
   guarantee(policy->is_generation_policy(), "Illegal policy type");
   assert((_young_gen->kind() == Generation::DefNew) ||
@@ -185,7 +193,6 @@
 }
 
 void GenCollectedHeap::ref_processing_init() {
-  SharedHeap::ref_processing_init();
   _young_gen->ref_processor_init();
   _old_gen->ref_processor_init();
 }
@@ -200,8 +207,7 @@
 
 // Save the "used_region" for generations level and lower.
 void GenCollectedHeap::save_used_regions(int level) {
-  assert(level >= 0, "Illegal level parameter");
-  assert(level < _n_gens, "Illegal level parameter");
+  assert(level == 0 || level == 1, "Illegal level parameter");
   if (level == 1) {
     _old_gen->save_used_region();
   }
@@ -417,7 +423,6 @@
   assert(Heap_lock->is_locked(),
          "the requesting thread should have the Heap_lock");
   guarantee(!is_gc_active(), "collection is not reentrant");
-  assert(max_level < n_gens(), "sanity check");
 
   if (GC_locker::check_active_before_gc()) {
     return; // GC is disabled (e.g. JNI GetXXXCritical operation)
@@ -435,7 +440,7 @@
   {
     FlagSetting fl(_is_gc_active, true);
 
-    bool complete = full && (max_level == (n_gens()-1));
+    bool complete = full && (max_level == 1 /* old */);
     const char* gc_cause_prefix = complete ? "Full GC" : "GC";
     TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
     // The PrintGCDetails logging starts before we have incremented the GC id. We will do that later
@@ -507,7 +512,7 @@
     // Update "complete" boolean wrt what actually transpired --
     // for instance, a promotion failure could have led to
     // a whole heap collection.
-    complete = complete || (max_level_collected == n_gens() - 1);
+    complete = complete || (max_level_collected == 1 /* old */);
 
     if (complete) { // We did a "major" collection
       // FIXME: See comment at pre_full_gc_dump call
@@ -524,7 +529,7 @@
     }
 
     // Adjust generation sizes.
-    if (max_level_collected == 1) {
+    if (max_level_collected == 1 /* old */) {
       _old_gen->compute_new_size();
     }
     _young_gen->compute_new_size();
@@ -560,7 +565,8 @@
 }
 
 void GenCollectedHeap::set_par_threads(uint t) {
-  SharedHeap::set_par_threads(t);
+  assert(t == 0 || !UseSerialGC, "Cannot have parallel threads");
+  CollectedHeap::set_par_threads(t);
   set_n_termination(t);
 }
 
@@ -586,7 +592,7 @@
                                      CLDClosure* strong_cld_closure,
                                      CLDClosure* weak_cld_closure,
                                      CodeBlobClosure* code_roots) {
-  StrongRootsScope srs(this, activate_scope);
+  StrongRootsScope srs(activate_scope);
 
   // General roots.
   assert(Threads::thread_claim_parity() != 0, "must have called prologue code");
@@ -606,7 +612,8 @@
   // Only process code roots from thread stacks if we aren't visiting the entire CodeCache anyway
   CodeBlobClosure* roots_from_code_p = (so & SO_AllCodeCache) ? NULL : code_roots;
 
-  Threads::possibly_parallel_oops_do(strong_roots, roots_from_clds_p, roots_from_code_p);
+  bool is_par = n_par_threads() > 0;
+  Threads::possibly_parallel_oops_do(is_par, strong_roots, roots_from_clds_p, roots_from_code_p);
 
   if (!_process_strong_tasks->is_task_claimed(GCH_PS_Universe_oops_do)) {
     Universe::oops_do(strong_roots);
@@ -771,19 +778,19 @@
 #endif // INCLUDE_ALL_GCS
   } else if (cause == GCCause::_wb_young_gc) {
     // minor collection for WhiteBox API
-    collect(cause, 0);
+    collect(cause, 0 /* young */);
   } else {
 #ifdef ASSERT
   if (cause == GCCause::_scavenge_alot) {
     // minor collection only
-    collect(cause, 0);
+    collect(cause, 0 /* young */);
   } else {
     // Stop-the-world full collection
-    collect(cause, n_gens() - 1);
+    collect(cause, 1 /* old */);
   }
 #else
     // Stop-the-world full collection
-    collect(cause, n_gens() - 1);
+    collect(cause, 1 /* old */);
 #endif
   }
 }
@@ -798,7 +805,7 @@
 void GenCollectedHeap::collect_locked(GCCause::Cause cause) {
   // The caller has the Heap_lock
   assert(Heap_lock->owned_by_self(), "this thread should own the Heap_lock");
-  collect_locked(cause, n_gens() - 1);
+  collect_locked(cause, 1 /* old */);
 }
 
 // this is the private collection interface
@@ -854,7 +861,7 @@
 #endif // INCLUDE_ALL_GCS
 
 void GenCollectedHeap::do_full_collection(bool clear_all_soft_refs) {
-   do_full_collection(clear_all_soft_refs, _n_gens - 1);
+   do_full_collection(clear_all_soft_refs, 1 /* old */);
 }
 
 void GenCollectedHeap::do_full_collection(bool clear_all_soft_refs,
@@ -886,7 +893,7 @@
                   clear_all_soft_refs  /* clear_all_soft_refs */,
                   0                    /* size */,
                   false                /* is_tlab */,
-                  n_gens() - 1         /* max_level */);
+                  1  /* old */         /* max_level */);
   }
 }
 
@@ -899,17 +906,6 @@
 
 // Returns "TRUE" iff "p" points into the committed areas of the heap.
 bool GenCollectedHeap::is_in(const void* p) const {
-  #ifndef ASSERT
-  guarantee(VerifyBeforeGC      ||
-            VerifyDuringGC      ||
-            VerifyBeforeExit    ||
-            VerifyDuringStartup ||
-            PrintAssembly       ||
-            tty->count() != 0   ||   // already printing
-            VerifyAfterGC       ||
-    VMError::fatal_error_in_progress(), "too expensive");
-
-  #endif
   return _young_gen->is_in(p) || _old_gen->is_in(p);
 }
 
@@ -923,6 +919,11 @@
 }
 #endif
 
+void GenCollectedHeap::oop_iterate_no_header(OopClosure* cl) {
+  NoHeaderExtendedOopClosure no_header_cl(cl);
+  oop_iterate(&no_header_cl);
+}
+
 void GenCollectedHeap::oop_iterate(ExtendedOopClosure* cl) {
   _young_gen->oop_iterate(cl);
   _old_gen->oop_iterate(cl);
@@ -1092,11 +1093,6 @@
   }
 }
 
-void GenCollectedHeap::space_iterate(SpaceClosure* cl) {
-  _young_gen->space_iterate(cl, true);
-  _old_gen->space_iterate(cl, true);
-}
-
 bool GenCollectedHeap::is_maximal_no_gc() const {
   return _young_gen->is_maximal_no_gc() && _old_gen->is_maximal_no_gc();
 }
@@ -1112,9 +1108,7 @@
   return _gch;
 }
 
-
 void GenCollectedHeap::prepare_for_compaction() {
-  guarantee(_n_gens = 2, "Wrong number of generations");
   // Start by compacting into same gen.
   CompactPoint cp(_old_gen);
   _old_gen->prepare_for_compaction(&cp);
--- a/hotspot/src/share/vm/memory/genCollectedHeap.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/memory/genCollectedHeap.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -26,15 +26,16 @@
 #define SHARE_VM_MEMORY_GENCOLLECTEDHEAP_HPP
 
 #include "gc_implementation/shared/adaptiveSizePolicy.hpp"
+#include "gc_interface/collectedHeap.hpp"
 #include "memory/collectorPolicy.hpp"
 #include "memory/generation.hpp"
-#include "memory/sharedHeap.hpp"
 
 class SubTasksDone;
+class FlexibleWorkGang;
 
-// A "GenCollectedHeap" is a SharedHeap that uses generational
+// A "GenCollectedHeap" is a CollectedHeap that uses generational
 // collection.  It has two generations, young and old.
-class GenCollectedHeap : public SharedHeap {
+class GenCollectedHeap : public CollectedHeap {
   friend class GenCollectorPolicy;
   friend class Generation;
   friend class DefNewGeneration;
@@ -51,10 +52,6 @@
   friend class GCCauseSetter;
   friend class VMStructs;
 public:
-  enum SomeConstants {
-    max_gens = 10
-  };
-
   friend class VM_PopulateDumpSharedSpace;
 
  protected:
@@ -62,8 +59,6 @@
   static GenCollectedHeap* _gch;
 
  private:
-  int _n_gens;
-
   Generation* _young_gen;
   Generation* _old_gen;
 
@@ -93,6 +88,8 @@
   // In block contents verification, the number of header words to skip
   NOT_PRODUCT(static size_t _skip_header_HeapWords;)
 
+  FlexibleWorkGang* _workers;
+
 protected:
   // Helper functions for allocation
   HeapWord* attempt_allocation(size_t size,
@@ -125,6 +122,8 @@
 public:
   GenCollectedHeap(GenCollectorPolicy *policy);
 
+  FlexibleWorkGang* workers() const { return _workers; }
+
   GCStats* gc_stats(int level) const;
 
   // Returns JNI_OK on success
@@ -178,9 +177,6 @@
   HeapWord** top_addr() const;
   HeapWord** end_addr() const;
 
-  // Does this heap support heap inspection? (+PrintClassHistogram)
-  virtual bool supports_heap_inspection() const { return true; }
-
   // Perform a full collection of the heap; intended for use in implementing
   // "System.gc". This implies as full a collection as the CollectedHeap
   // supports. Caller does not hold the Heap_lock on entry.
@@ -223,6 +219,7 @@
   }
 
   // Iteration functions.
+  void oop_iterate_no_header(OopClosure* cl);
   void oop_iterate(ExtendedOopClosure* cl);
   void object_iterate(ObjectClosure* cl);
   void safe_object_iterate(ObjectClosure* cl);
@@ -331,7 +328,6 @@
     _old_gen->update_gc_stats(current_level, full);
   }
 
-  // Override.
   bool no_gc_in_progress() { return !is_gc_active(); }
 
   // Override.
@@ -363,18 +359,11 @@
   // If "old_to_young" determines the order.
   void generation_iterate(GenClosure* cl, bool old_to_young);
 
-  void space_iterate(SpaceClosure* cl);
-
   // Return "true" if all generations have reached the
   // maximal committed limit that they can reach, without a garbage
   // collection.
   virtual bool is_maximal_no_gc() const;
 
-  int n_gens() const {
-    assert(_n_gens == gen_policy()->number_of_generations(), "Sanity");
-    return _n_gens;
-  }
-
   // This function returns the "GenRemSet" object that allows us to scan
   // generations in a fully generational heap.
   GenRemSet* rem_set() { return _rem_set; }
@@ -531,8 +520,8 @@
   void record_gen_tops_before_GC() PRODUCT_RETURN;
 
 protected:
-  virtual void gc_prologue(bool full);
-  virtual void gc_epilogue(bool full);
+  void gc_prologue(bool full);
+  void gc_epilogue(bool full);
 };
 
 #endif // SHARE_VM_MEMORY_GENCOLLECTEDHEAP_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/memory/genOopClosures.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -0,0 +1,30 @@
+/* Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "memory/genOopClosures.inline.hpp"
+#include "memory/iterator.inline.hpp"
+#include "memory/specialized_oop_closures.hpp"
+
+// Generate Serial GC specialized oop_oop_iterate functions.
+SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_S(ALL_KLASS_OOP_OOP_ITERATE_DEFN)
--- a/hotspot/src/share/vm/memory/genOopClosures.inline.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/memory/genOopClosures.inline.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -31,7 +31,6 @@
 #include "memory/genOopClosures.hpp"
 #include "memory/genRemSet.hpp"
 #include "memory/generation.hpp"
-#include "memory/sharedHeap.hpp"
 #include "memory/space.hpp"
 
 inline OopsInGenClosure::OopsInGenClosure(Generation* gen) :
--- a/hotspot/src/share/vm/memory/generation.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/memory/generation.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -187,7 +187,7 @@
   assert(obj_size == (size_t)obj->size(), "bad obj_size passed in");
 
 #ifndef PRODUCT
-  if (Universe::heap()->promotion_should_fail()) {
+  if (GenCollectedHeap::heap()->promotion_should_fail()) {
     return NULL;
   }
 #endif  // #ifndef PRODUCT
--- a/hotspot/src/share/vm/memory/iterator.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/memory/iterator.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -23,8 +23,11 @@
  */
 
 #include "precompiled.hpp"
-#include "memory/iterator.hpp"
+#include "memory/iterator.inline.hpp"
+#include "memory/universe.hpp"
 #include "oops/oop.inline.hpp"
+#include "utilities/debug.hpp"
+#include "utilities/globalDefinitions.hpp"
 
 void KlassToOopClosure::do_klass(Klass* k) {
   assert(_oop_closure != NULL, "Not initialized?");
@@ -61,19 +64,18 @@
   }
 }
 
-MarkingCodeBlobClosure::MarkScope::MarkScope(bool activate)
-  : _active(activate)
-{
-  if (_active)  nmethod::oops_do_marking_prologue();
-}
-
-MarkingCodeBlobClosure::MarkScope::~MarkScope() {
-  if (_active)  nmethod::oops_do_marking_epilogue();
-}
-
 void MarkingCodeBlobClosure::do_code_blob(CodeBlob* cb) {
   nmethod* nm = cb->as_nmethod_or_null();
   if (nm != NULL && !nm->test_set_oops_do_mark()) {
     do_nmethod(nm);
   }
 }
+
+// Generate the *Klass::oop_oop_iterate functions for the base class
+// of the oop closures. These versions use the virtual do_oop calls,
+// instead of the devirtualized do_oop_nv version.
+ALL_KLASS_OOP_OOP_ITERATE_DEFN(ExtendedOopClosure,  _v)
+
+// Generate the *Klass::oop_oop_iterate functions
+// for the NoHeaderExtendedOopClosure helper class.
+ALL_KLASS_OOP_OOP_ITERATE_DEFN(NoHeaderExtendedOopClosure, _nv)
--- a/hotspot/src/share/vm/memory/iterator.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/memory/iterator.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -44,9 +44,7 @@
 class OopClosure : public Closure {
  public:
   virtual void do_oop(oop* o) = 0;
-  virtual void do_oop_v(oop* o) { do_oop(o); }
   virtual void do_oop(narrowOop* o) = 0;
-  virtual void do_oop_v(narrowOop* o) { do_oop(o); }
 };
 
 // ExtendedOopClosure adds extra code to be run during oop iterations.
@@ -74,11 +72,9 @@
   // Currently, only CMS and G1 need these.
 
   virtual bool do_metadata() { return do_metadata_nv(); }
-  bool do_metadata_v()       { return do_metadata(); }
   bool do_metadata_nv()      { return false; }
 
   virtual void do_klass(Klass* k)   { do_klass_nv(k); }
-  void do_klass_v(Klass* k)         { do_klass(k); }
   void do_klass_nv(Klass* k)        { ShouldNotReachHere(); }
 
   virtual void do_class_loader_data(ClassLoaderData* cld) { ShouldNotReachHere(); }
@@ -87,6 +83,14 @@
   // location without an intervening "major reset" (like the end of a GC).
   virtual bool idempotent() { return false; }
   virtual bool apply_to_weak_ref_discovered_field() { return false; }
+
+#ifdef ASSERT
+  // Default verification of each visited oop field.
+  template <typename T> void verify(T* p);
+
+  // Can be used by subclasses to turn off the default verification of oop fields.
+  virtual bool should_verify_oops() { return true; }
+#endif
 };
 
 // Wrapper closure only used to implement oop_iterate_no_header().
@@ -147,7 +151,6 @@
 };
 
 class CLDToKlassAndOopClosure : public CLDClosure {
-  friend class SharedHeap;
   friend class G1CollectedHeap;
  protected:
   OopClosure*   _oop_closure;
@@ -284,16 +287,6 @@
   // Called for each code blob, but at most once per unique blob.
 
   virtual void do_code_blob(CodeBlob* cb);
-
-  class MarkScope : public StackObj {
-  protected:
-    bool _active;
-  public:
-    MarkScope(bool activate = true);
-      // = { if (active) nmethod::oops_do_marking_prologue(); }
-    ~MarkScope();
-      // = { if (active) nmethod::oops_do_marking_epilogue(); }
-  };
 };
 
 // MonitorClosure is used for iterating over monitors in the monitors cache
@@ -364,16 +357,33 @@
   }
 };
 
+// The two class template specializations are used to dispatch calls
+// to the ExtendedOopClosure functions. If use_non_virtual_call is true,
+// the non-virtual versions are called (E.g. do_oop_nv), otherwise the
+// virtual versions are called (E.g. do_oop).
 
-// Helper defines for ExtendOopClosure
+template <bool use_non_virtual_call>
+class Devirtualizer {};
 
-#define if_do_metadata_checked(closure, nv_suffix)       \
-  /* Make sure the non-virtual and the virtual versions match. */     \
-  assert(closure->do_metadata##nv_suffix() == closure->do_metadata(), \
-      "Inconsistency in do_metadata");                                \
-  if (closure->do_metadata##nv_suffix())
+// Dispatches to the non-virtual functions.
+template <> class Devirtualizer<true> {
+ public:
+  template <class OopClosureType, typename T> static void do_oop(OopClosureType* closure, T* p);
+  template <class OopClosureType>             static void do_klass(OopClosureType* closure, Klass* k);
+  template <class OopClosureType>             static bool do_metadata(OopClosureType* closure);
+};
 
-#define assert_should_ignore_metadata(closure, nv_suffix)                                  \
-  assert(!closure->do_metadata##nv_suffix(), "Code to handle metadata is not implemented")
+// Dispatches to the virtual functions.
+template <> class Devirtualizer<false> {
+ public:
+  template <class OopClosureType, typename T> static void do_oop(OopClosureType* closure, T* p);
+  template <class OopClosureType>             static void do_klass(OopClosureType* closure, Klass* k);
+  template <class OopClosureType>             static bool do_metadata(OopClosureType* closure);
+};
+
+// Helper to convert the oop iterate macro suffixes into bool values that can be used by template functions.
+#define nvs_nv_to_bool true
+#define nvs_v_to_bool  false
+#define nvs_to_bool(nv_suffix) nvs##nv_suffix##_to_bool
 
 #endif // SHARE_VM_MEMORY_ITERATOR_HPP
--- a/hotspot/src/share/vm/memory/iterator.inline.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/memory/iterator.inline.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -28,6 +28,12 @@
 #include "classfile/classLoaderData.hpp"
 #include "memory/iterator.hpp"
 #include "oops/klass.hpp"
+#include "oops/instanceKlass.inline.hpp"
+#include "oops/instanceMirrorKlass.inline.hpp"
+#include "oops/instanceClassLoaderKlass.inline.hpp"
+#include "oops/instanceRefKlass.inline.hpp"
+#include "oops/objArrayKlass.inline.hpp"
+#include "oops/typeArrayKlass.inline.hpp"
 #include "utilities/debug.hpp"
 
 inline void MetadataAwareOopClosure::do_class_loader_data(ClassLoaderData* cld) {
@@ -44,4 +50,63 @@
 
 inline void MetadataAwareOopClosure::do_klass(Klass* k)       { do_klass_nv(k); }
 
+#ifdef ASSERT
+// This verification is applied to all visited oops.
+// The closures can turn is off by overriding should_verify_oops().
+template <typename T>
+void ExtendedOopClosure::verify(T* p) {
+  if (should_verify_oops()) {
+    T heap_oop = oopDesc::load_heap_oop(p);
+    if (!oopDesc::is_null(heap_oop)) {
+      oop o = oopDesc::decode_heap_oop_not_null(heap_oop);
+      assert(Universe::heap()->is_in_closed_subset(o),
+             err_msg("should be in closed *p " PTR_FORMAT " " PTR_FORMAT, p2i(p), p2i(o)));
+    }
+  }
+}
+#endif
+
+// Implementation of the non-virtual do_oop dispatch.
+
+template <class OopClosureType, typename T>
+inline void Devirtualizer<true>::do_oop(OopClosureType* closure, T* p) {
+  debug_only(closure->verify(p));
+  closure->do_oop_nv(p);
+}
+template <class OopClosureType>
+inline void Devirtualizer<true>::do_klass(OopClosureType* closure, Klass* k) {
+  closure->do_klass_nv(k);
+}
+template <class OopClosureType>
+inline bool Devirtualizer<true>::do_metadata(OopClosureType* closure) {
+  // Make sure the non-virtual and the virtual versions match.
+  assert(closure->do_metadata_nv() == closure->do_metadata(), "Inconsistency in do_metadata");
+  return closure->do_metadata_nv();
+}
+
+// Implementation of the virtual do_oop dispatch.
+
+template <class OopClosureType, typename T>
+void Devirtualizer<false>::do_oop(OopClosureType* closure, T* p) {
+  debug_only(closure->verify(p));
+  closure->do_oop(p);
+}
+template <class OopClosureType>
+void Devirtualizer<false>::do_klass(OopClosureType* closure, Klass* k) {
+  closure->do_klass(k);
+}
+template <class OopClosureType>
+bool Devirtualizer<false>::do_metadata(OopClosureType* closure) {
+  return closure->do_metadata();
+}
+
+// The list of all "specializable" oop_oop_iterate function definitions.
+#define ALL_KLASS_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix)                  \
+  ALL_INSTANCE_KLASS_OOP_OOP_ITERATE_DEFN(             OopClosureType, nv_suffix)  \
+  ALL_INSTANCE_REF_KLASS_OOP_OOP_ITERATE_DEFN(         OopClosureType, nv_suffix)  \
+  ALL_INSTANCE_MIRROR_KLASS_OOP_OOP_ITERATE_DEFN(      OopClosureType, nv_suffix)  \
+  ALL_INSTANCE_CLASS_LOADER_KLASS_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix)  \
+  ALL_OBJ_ARRAY_KLASS_OOP_OOP_ITERATE_DEFN(            OopClosureType, nv_suffix)  \
+  ALL_TYPE_ARRAY_KLASS_OOP_OOP_ITERATE_DEFN(           OopClosureType, nv_suffix)
+
 #endif // SHARE_VM_MEMORY_ITERATOR_INLINE_HPP
--- a/hotspot/src/share/vm/memory/metaspaceShared.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -30,6 +30,8 @@
 #include "classfile/symbolTable.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "code/codeCache.hpp"
+#include "interpreter/bytecodes.hpp"
+#include "interpreter/bytecodeStream.hpp"
 #include "memory/filemap.hpp"
 #include "memory/gcLocker.hpp"
 #include "memory/metaspace.hpp"
@@ -104,15 +106,33 @@
   }
 }
 
-// Walk all methods in the class list and assign a fingerprint.
-// so that this part of the ConstMethod* is read only.
-static void calculate_fingerprints() {
+static void rewrite_nofast_bytecode(Method* method) {
+  RawBytecodeStream bcs(method);
+  while (!bcs.is_last_bytecode()) {
+    Bytecodes::Code opcode = bcs.raw_next();
+    switch (opcode) {
+    case Bytecodes::_getfield:      *bcs.bcp() = Bytecodes::_nofast_getfield;      break;
+    case Bytecodes::_putfield:      *bcs.bcp() = Bytecodes::_nofast_putfield;      break;
+    case Bytecodes::_aload_0:       *bcs.bcp() = Bytecodes::_nofast_aload_0;       break;
+    case Bytecodes::_iload:         *bcs.bcp() = Bytecodes::_nofast_iload;         break;
+    default: break;
+    }
+  }
+}
+
+// Walk all methods in the class list to ensure that they won't be modified at
+// run time. This includes:
+// [1] Rewrite all bytecodes as needed, so that the ConstMethod* will not be modified
+//     at run time by RewriteBytecodes/RewriteFrequentPairs
+// [2] Assign a fingerprint, so one doesn't need to be assigned at run-time.
+static void rewrite_nofast_bytecodes_and_calculate_fingerprints() {
   for (int i = 0; i < _global_klass_objects->length(); i++) {
     Klass* k = _global_klass_objects->at(i);
     if (k->oop_is_instance()) {
       InstanceKlass* ik = InstanceKlass::cast(k);
       for (int i = 0; i < ik->methods()->length(); i++) {
         Method* m = ik->methods()->at(i);
+        rewrite_nofast_bytecode(m);
         Fingerprinter fp(m);
         // The side effect of this call sets method's fingerprint field.
         fp.fingerprint();
@@ -476,9 +496,10 @@
     tty->print_cr("    type array classes = %5d", num_type_array);
   }
 
-  // Update all the fingerprints in the shared methods.
-  tty->print("Calculating fingerprints ... ");
-  calculate_fingerprints();
+
+  // Ensure the ConstMethods won't be modified at run-time
+  tty->print("Updating ConstMethods ... ");
+  rewrite_nofast_bytecodes_and_calculate_fingerprints();
   tty->print_cr("done. ");
 
   // Remove all references outside the metadata
--- a/hotspot/src/share/vm/memory/sharedHeap.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-/*
- * Copyright (c) 2000, 2015, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "classfile/stringTable.hpp"
-#include "classfile/systemDictionary.hpp"
-#include "code/codeCache.hpp"
-#include "gc_interface/collectedHeap.inline.hpp"
-#include "memory/sharedHeap.hpp"
-#include "oops/oop.inline.hpp"
-#include "runtime/atomic.inline.hpp"
-#include "runtime/fprofiler.hpp"
-#include "runtime/java.hpp"
-#include "utilities/copy.hpp"
-#include "utilities/workgroup.hpp"
-
-SharedHeap* SharedHeap::_sh;
-
-SharedHeap::SharedHeap() :
-  CollectedHeap(),
-  _workers(NULL)
-{
-  _sh = this;  // ch is static, should be set only once.
-  if (UseConcMarkSweepGC || UseG1GC) {
-    _workers = new FlexibleWorkGang("GC Thread", ParallelGCThreads,
-                            /* are_GC_task_threads */true,
-                            /* are_ConcurrentGC_threads */false);
-    if (_workers == NULL) {
-      vm_exit_during_initialization("Failed necessary allocation.");
-    } else {
-      _workers->initialize_workers();
-    }
-  }
-}
-
-bool SharedHeap::heap_lock_held_for_gc() {
-  Thread* t = Thread::current();
-  return    Heap_lock->owned_by_self()
-         || (   (t->is_GC_task_thread() ||  t->is_VM_thread())
-             && _thread_holds_heap_lock_for_gc);
-}
-
-void SharedHeap::set_par_threads(uint t) {
-  assert(t == 0 || !UseSerialGC, "Cannot have parallel threads");
-  _n_par_threads = t;
-}
-
-SharedHeap::StrongRootsScope::StrongRootsScope(SharedHeap* heap, bool activate)
-  : MarkScope(activate), _sh(heap)
-{
-  if (_active) {
-    Threads::change_thread_claim_parity();
-    // Zero the claimed high water mark in the StringTable
-    StringTable::clear_parallel_claimed_index();
-  }
-}
-
-SharedHeap::StrongRootsScope::~StrongRootsScope() {
-  Threads::assert_all_threads_claimed();
-}
-
-void SharedHeap::set_barrier_set(BarrierSet* bs) {
-  _barrier_set = bs;
-  // Cached barrier set for fast access in oops
-  oopDesc::set_bs(bs);
-}
-
-void SharedHeap::post_initialize() {
-  CollectedHeap::post_initialize();
-  ref_processing_init();
-}
-
-void SharedHeap::ref_processing_init() {}
--- a/hotspot/src/share/vm/memory/sharedHeap.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,213 +0,0 @@
-/*
- * Copyright (c) 2000, 2015, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_MEMORY_SHAREDHEAP_HPP
-#define SHARE_VM_MEMORY_SHAREDHEAP_HPP
-
-#include "gc_interface/collectedHeap.hpp"
-#include "memory/generation.hpp"
-
-// A "SharedHeap" is an implementation of a java heap for HotSpot.  This
-// is an abstract class: there may be many different kinds of heaps.  This
-// class defines the functions that a heap must implement, and contains
-// infrastructure common to all heaps.
-
-class Generation;
-class BarrierSet;
-class GenRemSet;
-class Space;
-class SpaceClosure;
-class OopClosure;
-class OopsInGenClosure;
-class ObjectClosure;
-class SubTasksDone;
-class WorkGang;
-class FlexibleWorkGang;
-class CollectorPolicy;
-class KlassClosure;
-
-// Note on use of FlexibleWorkGang's for GC.
-// There are three places where task completion is determined.
-// In
-//    1) ParallelTaskTerminator::offer_termination() where _n_threads
-//    must be set to the correct value so that count of workers that
-//    have offered termination will exactly match the number
-//    working on the task.  Tasks such as those derived from GCTask
-//    use ParallelTaskTerminator's.  Tasks that want load balancing
-//    by work stealing use this method to gauge completion.
-//    2) SubTasksDone has a variable _n_threads that is used in
-//    all_tasks_completed() to determine completion.  all_tasks_complete()
-//    counts the number of tasks that have been done and then reset
-//    the SubTasksDone so that it can be used again.  When the number of
-//    tasks is set to the number of GC workers, then _n_threads must
-//    be set to the number of active GC workers. G1RootProcessor and
-//    GenCollectedHeap have SubTasksDone.
-//    3) SequentialSubTasksDone has an _n_threads that is used in
-//    a way similar to SubTasksDone and has the same dependency on the
-//    number of active GC workers.  CompactibleFreeListSpace and Space
-//    have SequentialSubTasksDone's.
-//
-// Examples of using SubTasksDone and SequentialSubTasksDone:
-//  G1RootProcessor and GenCollectedHeap::process_roots() use
-//  SubTasksDone* _process_strong_tasks to claim tasks for workers
-//
-//  GenCollectedHeap::gen_process_roots() calls
-//      rem_set()->younger_refs_iterate()
-//  to scan the card table and which eventually calls down into
-//  CardTableModRefBS::par_non_clean_card_iterate_work().  This method
-//  uses SequentialSubTasksDone* _pst to claim tasks.
-//  Both SubTasksDone and SequentialSubTasksDone call their method
-//  all_tasks_completed() to count the number of GC workers that have
-//  finished their work.  That logic is "when all the workers are
-//  finished the tasks are finished".
-//
-//  The pattern that appears  in the code is to set _n_threads
-//  to a value > 1 before a task that you would like executed in parallel
-//  and then to set it to 0 after that task has completed.  A value of
-//  0 is a "special" value in set_n_threads() which translates to
-//  setting _n_threads to 1.
-//
-//  Some code uses _n_termination to decide if work should be done in
-//  parallel.  The notorious possibly_parallel_oops_do() in threads.cpp
-//  is an example of such code.  Look for variable "is_par" for other
-//  examples.
-//
-//  The active_workers is not reset to 0 after a parallel phase.  It's
-//  value may be used in later phases and in one instance at least
-//  (the parallel remark) it has to be used (the parallel remark depends
-//  on the partitioning done in the previous parallel scavenge).
-
-class SharedHeap : public CollectedHeap {
-  friend class VMStructs;
-
-  friend class VM_GC_Operation;
-  friend class VM_CGC_Operation;
-
-protected:
-  // There should be only a single instance of "SharedHeap" in a program.
-  // This is enforced with the protected constructor below, which will also
-  // set the static pointer "_sh" to that instance.
-  static SharedHeap* _sh;
-
-  // If we're doing parallel GC, use this gang of threads.
-  FlexibleWorkGang* _workers;
-
-  // Full initialization is done in a concrete subtype's "initialize"
-  // function.
-  SharedHeap();
-
-  // Returns true if the calling thread holds the heap lock,
-  // or the calling thread is a par gc thread and the heap_lock is held
-  // by the vm thread doing a gc operation.
-  bool heap_lock_held_for_gc();
-  // True if the heap_lock is held by the a non-gc thread invoking a gc
-  // operation.
-  bool _thread_holds_heap_lock_for_gc;
-
-public:
-  static SharedHeap* heap() { return _sh; }
-
-  void set_barrier_set(BarrierSet* bs);
-
-  // Does operations required after initialization has been done.
-  virtual void post_initialize();
-
-  // Initialization of ("weak") reference processing support
-  virtual void ref_processing_init();
-
-  // Iteration functions.
-  void oop_iterate(ExtendedOopClosure* cl) = 0;
-
-  // Iterate over all spaces in use in the heap, in an undefined order.
-  virtual void space_iterate(SpaceClosure* cl) = 0;
-
-  // A SharedHeap will contain some number of spaces.  This finds the
-  // space whose reserved area contains the given address, or else returns
-  // NULL.
-  virtual Space* space_containing(const void* addr) const = 0;
-
-  bool no_gc_in_progress() { return !is_gc_active(); }
-
-  // Note, the below comment needs to be updated to reflect the changes
-  // introduced by JDK-8076225. This should be done as part of JDK-8076289.
-  //
-  //Some collectors will perform "process_strong_roots" in parallel.
-  // Such a call will involve claiming some fine-grained tasks, such as
-  // scanning of threads.  To make this process simpler, we provide the
-  // "strong_roots_parity()" method.  Collectors that start parallel tasks
-  // whose threads invoke "process_strong_roots" must
-  // call "change_strong_roots_parity" in sequential code starting such a
-  // task.  (This also means that a parallel thread may only call
-  // process_strong_roots once.)
-  //
-  // For calls to process_roots by sequential code, the parity is
-  // updated automatically.
-  //
-  // The idea is that objects representing fine-grained tasks, such as
-  // threads, will contain a "parity" field.  A task will is claimed in the
-  // current "process_roots" call only if its parity field is the
-  // same as the "strong_roots_parity"; task claiming is accomplished by
-  // updating the parity field to the strong_roots_parity with a CAS.
-  //
-  // If the client meats this spec, then strong_roots_parity() will have
-  // the following properties:
-  //   a) to return a different value than was returned before the last
-  //      call to change_strong_roots_parity, and
-  //   c) to never return a distinguished value (zero) with which such
-  //      task-claiming variables may be initialized, to indicate "never
-  //      claimed".
- public:
-
-  // Call these in sequential code around process_roots.
-  // strong_roots_prologue calls change_strong_roots_parity, if
-  // parallel tasks are enabled.
-  class StrongRootsScope : public MarkingCodeBlobClosure::MarkScope {
-    SharedHeap*   _sh;
-
-   public:
-    StrongRootsScope(SharedHeap* heap, bool activate = true);
-    ~StrongRootsScope();
-  };
-
- private:
-
- public:
-  FlexibleWorkGang* workers() const { return _workers; }
-
-  // The functions below are helper functions that a subclass of
-  // "SharedHeap" can use in the implementation of its virtual
-  // functions.
-
-public:
-
-  // Do anything common to GC's.
-  virtual void gc_prologue(bool full) = 0;
-  virtual void gc_epilogue(bool full) = 0;
-
-  // Sets the number of parallel threads that will be doing tasks
-  // (such as process roots) subsequently.
-  virtual void set_par_threads(uint t);
-};
-
-#endif // SHARE_VM_MEMORY_SHAREDHEAP_HPP
--- a/hotspot/src/share/vm/memory/space.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/memory/space.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -31,6 +31,7 @@
 #include "memory/blockOffsetTable.inline.hpp"
 #include "memory/defNewGeneration.hpp"
 #include "memory/genCollectedHeap.hpp"
+#include "memory/genOopClosures.inline.hpp"
 #include "memory/space.hpp"
 #include "memory/space.inline.hpp"
 #include "memory/universe.inline.hpp"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/memory/strongRootsScope.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "classfile/stringTable.hpp"
+#include "code/nmethod.hpp"
+#include "memory/strongRootsScope.hpp"
+#include "runtime/thread.hpp"
+
+MarkScope::MarkScope(bool activate) : _active(activate) {
+  if (_active) {
+    nmethod::oops_do_marking_prologue();
+  }
+}
+
+MarkScope::~MarkScope() {
+  if (_active) {
+    nmethod::oops_do_marking_epilogue();
+  }
+}
+
+StrongRootsScope::StrongRootsScope(bool activate) : MarkScope(activate) {
+  if (_active) {
+    Threads::change_thread_claim_parity();
+    // Zero the claimed high water mark in the StringTable
+    StringTable::clear_parallel_claimed_index();
+  }
+}
+
+StrongRootsScope::~StrongRootsScope() {
+  Threads::assert_all_threads_claimed();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/memory/strongRootsScope.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_MEMORY_STRONGROOTSSCOPE_HPP
+#define SHARE_VM_MEMORY_STRONGROOTSSCOPE_HPP
+
+#include "memory/allocation.hpp"
+
+class MarkScope : public StackObj {
+ protected:
+  bool _active;
+ public:
+  MarkScope(bool activate = true);
+  ~MarkScope();
+};
+
+// Sets up and tears down the required state for parallel root processing.
+
+class StrongRootsScope : public MarkScope {
+ public:
+  StrongRootsScope(bool activate = true);
+  ~StrongRootsScope();
+};
+
+#endif // SHARE_VM_MEMORY_STRONGROOTSSCOPE_HPP
--- a/hotspot/src/share/vm/memory/tenuredGeneration.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/memory/tenuredGeneration.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -36,6 +36,9 @@
 #include "oops/oop.inline.hpp"
 #include "runtime/java.hpp"
 #include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
+#include "gc_implementation/parNew/parOopClosures.hpp"
+#endif
 
 TenuredGeneration::TenuredGeneration(ReservedSpace rs,
                                      size_t initial_byte_size, int level,
--- a/hotspot/src/share/vm/oops/constMethod.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/oops/constMethod.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -32,7 +32,6 @@
 // processes in a read-only section with Class Data Sharing (CDS).  It's important
 // that this class doesn't have virtual functions because the vptr cannot be shared
 // with CDS.
-//   (*)RewriteByteCodes and RewriteFrequentPairs is an exception but turned off in CDS
 //
 // Note that most applications load thousands of methods, so keeping the size of this
 // structure small has a big impact on footprint.
--- a/hotspot/src/share/vm/oops/instanceClassLoaderKlass.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,146 +0,0 @@
-/*
- * Copyright (c) 2011, 2015, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "classfile/javaClasses.hpp"
-#include "classfile/systemDictionary.hpp"
-#include "gc_implementation/shared/markSweep.inline.hpp"
-#include "gc_interface/collectedHeap.inline.hpp"
-#include "memory/genOopClosures.inline.hpp"
-#include "memory/iterator.inline.hpp"
-#include "memory/oopFactory.hpp"
-#include "memory/specialized_oop_closures.hpp"
-#include "oops/instanceKlass.hpp"
-#include "oops/instanceClassLoaderKlass.hpp"
-#include "oops/instanceMirrorKlass.hpp"
-#include "oops/instanceOop.hpp"
-#include "oops/oop.inline.hpp"
-#include "oops/symbol.hpp"
-#include "runtime/handles.inline.hpp"
-#include "utilities/macros.hpp"
-#if INCLUDE_ALL_GCS
-#include "gc_implementation/parNew/parOopClosures.inline.hpp"
-#include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
-#endif // INCLUDE_ALL_GCS
-
-// Macro to define InstanceClassLoaderKlass::oop_oop_iterate for virtual/nonvirtual for
-// all closures.  Macros calling macros above for each oop size.
-// Since ClassLoader objects have only a pointer to the loader_data, they are not
-// compressed nor does the pointer move.
-
-#define InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix)\
-                                                                                \
-int InstanceClassLoaderKlass::                                                  \
-oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure) {                  \
-  /* Get size before changing pointers */                                       \
-  int size = InstanceKlass::oop_oop_iterate##nv_suffix(obj, closure);           \
-                                                                                \
-  if_do_metadata_checked(closure, nv_suffix) {                                  \
-    ClassLoaderData* cld = java_lang_ClassLoader::loader_data(obj);             \
-    /* cld can be null if we have a non-registered class loader. */             \
-    if (cld != NULL) {                                                          \
-      closure->do_class_loader_data(cld);                                       \
-    }                                                                           \
-  }                                                                             \
-                                                                                \
-  return size;                                                                  \
-}
-
-#if INCLUDE_ALL_GCS
-#define InstanceClassLoaderKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix) \
-                                                                                \
-int InstanceClassLoaderKlass::                                                  \
-oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* closure) {        \
-  /* Get size before changing pointers */                                       \
-  int size = InstanceKlass::oop_oop_iterate_backwards##nv_suffix(obj, closure); \
-  return size;                                                                  \
-}
-#endif // INCLUDE_ALL_GCS
-
-
-#define InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix)      \
-                                                                                \
-int InstanceClassLoaderKlass::                                                  \
-oop_oop_iterate##nv_suffix##_m(oop obj,                                         \
-                               OopClosureType* closure,                         \
-                               MemRegion mr) {                                  \
-  int size = InstanceKlass::oop_oop_iterate##nv_suffix##_m(obj, closure, mr);   \
-                                                                                \
-  if_do_metadata_checked(closure, nv_suffix) {                                  \
-    if (mr.contains(obj)) {                                                     \
-      ClassLoaderData* cld = java_lang_ClassLoader::loader_data(obj);           \
-      /* cld can be null if we have a non-registered class loader. */           \
-      if (cld != NULL) {                                                        \
-        closure->do_class_loader_data(cld);                                     \
-      }                                                                         \
-    }                                                                           \
-  }                                                                             \
-                                                                                \
-  return size;                                                                  \
-}
-
-ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN)
-ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN)
-#if INCLUDE_ALL_GCS
-ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceClassLoaderKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
-ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceClassLoaderKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
-#endif // INCLUDE_ALL_GCS
-ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN_m)
-ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN_m)
-
-void InstanceClassLoaderKlass::oop_follow_contents(oop obj) {
-  InstanceKlass::oop_follow_contents(obj);
-  ClassLoaderData * const loader_data = java_lang_ClassLoader::loader_data(obj);
-
-  // We must NULL check here, since the class loader
-  // can be found before the loader data has been set up.
-  if(loader_data != NULL) {
-    MarkSweep::follow_class_loader(loader_data);
-  }
-}
-
-#if INCLUDE_ALL_GCS
-void InstanceClassLoaderKlass::oop_follow_contents(ParCompactionManager* cm,
-        oop obj) {
-  InstanceKlass::oop_follow_contents(cm, obj);
-  ClassLoaderData * const loader_data = java_lang_ClassLoader::loader_data(obj);
-  if (loader_data != NULL) {
-    PSParallelCompact::follow_class_loader(cm, loader_data);
-  }
-}
-
-void InstanceClassLoaderKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
-  InstanceKlass::oop_push_contents(pm, obj);
-
-  // This is called by the young collector. It will already have taken care of
-  // all class loader data. So, we don't have to follow the class loader ->
-  // class loader data link.
-}
-
-int InstanceClassLoaderKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
-  InstanceKlass::oop_update_pointers(cm, obj);
-  return size_helper();
-}
-#endif // INCLUDE_ALL_GCS
-
--- a/hotspot/src/share/vm/oops/instanceClassLoaderKlass.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/oops/instanceClassLoaderKlass.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -48,34 +48,60 @@
 
   InstanceClassLoaderKlass() { assert(DumpSharedSpaces || UseSharedSpaces, "only for CDS"); }
 
-  // Iterators
-  int oop_oop_iterate(oop obj, ExtendedOopClosure* blk) {
-    return oop_oop_iterate_v(obj, blk);
-  }
-  int oop_oop_iterate_m(oop obj, ExtendedOopClosure* blk, MemRegion mr) {
-    return oop_oop_iterate_v_m(obj, blk, mr);
-  }
+  // GC specific object visitors
+  //
+  // Mark Sweep
+  void oop_ms_follow_contents(oop obj);
+  int  oop_ms_adjust_pointers(oop obj);
+#if INCLUDE_ALL_GCS
+  // Parallel Scavenge
+  void oop_ps_push_contents(  oop obj, PSPromotionManager* pm);
+  // Parallel Compact
+  void oop_pc_follow_contents(oop obj, ParCompactionManager* cm);
+  void oop_pc_update_pointers(oop obj);
+#endif
+
+  // Oop fields (and metadata) iterators
+  //  [nv = true]  Use non-virtual calls to do_oop_nv.
+  //  [nv = false] Use virtual calls to do_oop.
+  //
+  // The InstanceClassLoaderKlass iterators also visit the CLD pointer (or mirror of anonymous klasses.)
 
-#define InstanceClassLoaderKlass_OOP_OOP_ITERATE_DECL(OopClosureType, nv_suffix)                \
-  int oop_oop_iterate##nv_suffix(oop obj, OopClosureType* blk);                         \
+ private:
+  // Forward iteration
+  // Iterate over the oop fields and metadata.
+  template <bool nv, class OopClosureType>
+  inline int oop_oop_iterate(oop obj, OopClosureType* closure);
+
+#if INCLUDE_ALL_GCS
+  // Reverse iteration
+  // Iterate over the oop fields and metadata.
+  template <bool nv, class OopClosureType>
+  inline int oop_oop_iterate_reverse(oop obj, OopClosureType* closure);
+#endif
+
+  // Bounded range iteration
+  // Iterate over the oop fields and metadata.
+  template <bool nv, class OopClosureType>
+  inline int oop_oop_iterate_bounded(oop obj, OopClosureType* closure, MemRegion mr);
+
+ public:
+
+#define InstanceClassLoaderKlass_OOP_OOP_ITERATE_DECL(OopClosureType, nv_suffix)   \
+  int oop_oop_iterate##nv_suffix(oop obj, OopClosureType* blk);                    \
   int oop_oop_iterate##nv_suffix##_m(oop obj, OopClosureType* blk, MemRegion mr);
 
   ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceClassLoaderKlass_OOP_OOP_ITERATE_DECL)
   ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceClassLoaderKlass_OOP_OOP_ITERATE_DECL)
 
 #if INCLUDE_ALL_GCS
-#define InstanceClassLoaderKlass_OOP_OOP_ITERATE_BACKWARDS_DECL(OopClosureType, nv_suffix)      \
+#define InstanceClassLoaderKlass_OOP_OOP_ITERATE_BACKWARDS_DECL(OopClosureType, nv_suffix)  \
   int oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* blk);
 
   ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceClassLoaderKlass_OOP_OOP_ITERATE_BACKWARDS_DECL)
   ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceClassLoaderKlass_OOP_OOP_ITERATE_BACKWARDS_DECL)
 #endif // INCLUDE_ALL_GCS
 
-    // Garbage collection
-  void oop_follow_contents(oop obj);
-
-  // Parallel Scavenge and Parallel Old
-  PARALLEL_GC_DECLS
 };
 
 #endif // SHARE_VM_OOPS_INSTANCECLASSLOADERKLASS_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/oops/instanceClassLoaderKlass.inline.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_OOPS_INSTANCECLASSLOADERKLASS_INLINE_HPP
+#define SHARE_VM_OOPS_INSTANCECLASSLOADERKLASS_INLINE_HPP
+
+#include "classfile/javaClasses.hpp"
+#include "oops/instanceClassLoaderKlass.hpp"
+#include "oops/instanceKlass.inline.hpp"
+#include "oops/oop.inline.hpp"
+#include "utilities/debug.hpp"
+#include "utilities/globalDefinitions.hpp"
+#include "utilities/macros.hpp"
+
+template <bool nv, class OopClosureType>
+inline int InstanceClassLoaderKlass::oop_oop_iterate(oop obj, OopClosureType* closure) {
+  int size = InstanceKlass::oop_oop_iterate<nv>(obj, closure);
+
+  if (Devirtualizer<nv>::do_metadata(closure)) {
+    ClassLoaderData* cld = java_lang_ClassLoader::loader_data(obj);
+    // cld can be null if we have a non-registered class loader.
+    if (cld != NULL) {
+      closure->do_class_loader_data(cld);
+    }
+  }
+
+  return size;
+}
+
+#if INCLUDE_ALL_GCS
+template <bool nv, class OopClosureType>
+inline int InstanceClassLoaderKlass::oop_oop_iterate_reverse(oop obj, OopClosureType* closure) {
+  int size = InstanceKlass::oop_oop_iterate_reverse<nv>(obj, closure);
+
+  assert(!Devirtualizer<nv>::do_metadata(closure),
+      "Code to handle metadata is not implemented");
+
+  return size;
+}
+#endif // INCLUDE_ALL_GCS
+
+
+template <bool nv, class OopClosureType>
+inline int InstanceClassLoaderKlass::oop_oop_iterate_bounded(oop obj, OopClosureType* closure, MemRegion mr) {
+  int size = InstanceKlass::oop_oop_iterate_bounded<nv>(obj, closure, mr);
+
+  if (Devirtualizer<nv>::do_metadata(closure)) {
+    if (mr.contains(obj)) {
+      ClassLoaderData* cld = java_lang_ClassLoader::loader_data(obj);
+      // cld can be null if we have a non-registered class loader.
+      if (cld != NULL) {
+        closure->do_class_loader_data(cld);
+      }
+    }
+  }
+
+  return size;
+}
+
+
+#define InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix)              \
+                                                                                              \
+int InstanceClassLoaderKlass::oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure) {  \
+  return oop_oop_iterate<nvs_to_bool(nv_suffix)>(obj, closure);                               \
+}
+
+#if INCLUDE_ALL_GCS
+#define InstanceClassLoaderKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix)              \
+                                                                                                        \
+int InstanceClassLoaderKlass::oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* closure) {  \
+  return oop_oop_iterate_reverse<nvs_to_bool(nv_suffix)>(obj, closure);                                 \
+}
+#else
+#define InstanceClassLoaderKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix)
+#endif
+
+
+#define InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix)                              \
+                                                                                                                \
+int InstanceClassLoaderKlass::oop_oop_iterate##nv_suffix##_m(oop obj, OopClosureType* closure, MemRegion mr) {  \
+  return oop_oop_iterate_bounded<nvs_to_bool(nv_suffix)>(obj, closure, mr);                                     \
+}
+
+#define ALL_INSTANCE_CLASS_LOADER_KLASS_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix)  \
+  InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN(          OopClosureType, nv_suffix)     \
+  InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN_m(        OopClosureType, nv_suffix)     \
+  InstanceClassLoaderKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix)
+
+#endif // SHARE_VM_OOPS_INSTANCECLASSLOADERKLASS_INLINE_HPP
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -28,12 +28,10 @@
 #include "classfile/verifier.hpp"
 #include "classfile/vmSymbols.hpp"
 #include "compiler/compileBroker.hpp"
-#include "gc_implementation/shared/markSweep.inline.hpp"
 #include "gc_interface/collectedHeap.inline.hpp"
 #include "interpreter/oopMapCache.hpp"
 #include "interpreter/rewriter.hpp"
 #include "jvmtifiles/jvmti.h"
-#include "memory/genOopClosures.inline.hpp"
 #include "memory/heapInspection.hpp"
 #include "memory/iterator.inline.hpp"
 #include "memory/metadataFactory.hpp"
@@ -41,7 +39,7 @@
 #include "memory/specialized_oop_closures.hpp"
 #include "oops/fieldStreams.hpp"
 #include "oops/instanceClassLoaderKlass.hpp"
-#include "oops/instanceKlass.hpp"
+#include "oops/instanceKlass.inline.hpp"
 #include "oops/instanceMirrorKlass.hpp"
 #include "oops/instanceOop.hpp"
 #include "oops/klass.inline.hpp"
@@ -64,17 +62,6 @@
 #include "services/threadService.hpp"
 #include "utilities/dtrace.hpp"
 #include "utilities/macros.hpp"
-#if INCLUDE_ALL_GCS
-#include "gc_implementation/concurrentMarkSweep/cmsOopClosures.inline.hpp"
-#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
-#include "gc_implementation/g1/g1OopClosures.inline.hpp"
-#include "gc_implementation/g1/g1RemSet.inline.hpp"
-#include "gc_implementation/g1/heapRegionManager.inline.hpp"
-#include "gc_implementation/parNew/parOopClosures.inline.hpp"
-#include "gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp"
-#include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
-#include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
-#endif // INCLUDE_ALL_GCS
 #ifdef COMPILER1
 #include "c1/c1_Compiler.hpp"
 #endif
@@ -716,23 +703,6 @@
 
     // Set up method entry points for compiler and interpreter    .
     m->link_method(m, CHECK);
-
-    // This is for JVMTI and unrelated to relocator but the last thing we do
-#ifdef ASSERT
-    if (StressMethodComparator) {
-      ResourceMark rm(THREAD);
-      static int nmc = 0;
-      for (int j = i; j >= 0 && j >= i-4; j--) {
-        if ((++nmc % 1000) == 0)  tty->print_cr("Have run MethodComparator %d times...", nmc);
-        bool z = MethodComparator::methods_EMCP(m(),
-                   methods()->at(j));
-        if (j == i && !z) {
-          tty->print("MethodComparator FAIL: "); m->print(); m->print_codes();
-          assert(z, "method must compare equal to itself");
-        }
-      }
-    }
-#endif //ASSERT
   }
 }
 
@@ -2010,288 +1980,6 @@
 }
 #endif //PRODUCT
 
-
-// Garbage collection
-
-#ifdef ASSERT
-template <class T> void assert_is_in(T *p) {
-  T heap_oop = oopDesc::load_heap_oop(p);
-  if (!oopDesc::is_null(heap_oop)) {
-    oop o = oopDesc::decode_heap_oop_not_null(heap_oop);
-    assert(Universe::heap()->is_in(o), "should be in heap");
-  }
-}
-template <class T> void assert_is_in_closed_subset(T *p) {
-  T heap_oop = oopDesc::load_heap_oop(p);
-  if (!oopDesc::is_null(heap_oop)) {
-    oop o = oopDesc::decode_heap_oop_not_null(heap_oop);
-    assert(Universe::heap()->is_in_closed_subset(o),
-           err_msg("should be in closed *p " INTPTR_FORMAT " " INTPTR_FORMAT, (address)p, (address)o));
-  }
-}
-template <class T> void assert_is_in_reserved(T *p) {
-  T heap_oop = oopDesc::load_heap_oop(p);
-  if (!oopDesc::is_null(heap_oop)) {
-    oop o = oopDesc::decode_heap_oop_not_null(heap_oop);
-    assert(Universe::heap()->is_in_reserved(o), "should be in reserved");
-  }
-}
-template <class T> void assert_nothing(T *p) {}
-
-#else
-template <class T> void assert_is_in(T *p) {}
-template <class T> void assert_is_in_closed_subset(T *p) {}
-template <class T> void assert_is_in_reserved(T *p) {}
-template <class T> void assert_nothing(T *p) {}
-#endif // ASSERT
-
-//
-// Macros that iterate over areas of oops which are specialized on type of
-// oop pointer either narrow or wide, depending on UseCompressedOops
-//
-// Parameters are:
-//   T         - type of oop to point to (either oop or narrowOop)
-//   start_p   - starting pointer for region to iterate over
-//   count     - number of oops or narrowOops to iterate over
-//   do_oop    - action to perform on each oop (it's arbitrary C code which
-//               makes it more efficient to put in a macro rather than making
-//               it a template function)
-//   assert_fn - assert function which is template function because performance
-//               doesn't matter when enabled.
-#define InstanceKlass_SPECIALIZED_OOP_ITERATE( \
-  T, start_p, count, do_oop,                \
-  assert_fn)                                \
-{                                           \
-  T* p         = (T*)(start_p);             \
-  T* const end = p + (count);               \
-  while (p < end) {                         \
-    (assert_fn)(p);                         \
-    do_oop;                                 \
-    ++p;                                    \
-  }                                         \
-}
-
-#define InstanceKlass_SPECIALIZED_OOP_REVERSE_ITERATE( \
-  T, start_p, count, do_oop,                \
-  assert_fn)                                \
-{                                           \
-  T* const start = (T*)(start_p);           \
-  T*       p     = start + (count);         \
-  while (start < p) {                       \
-    --p;                                    \
-    (assert_fn)(p);                         \
-    do_oop;                                 \
-  }                                         \
-}
-
-#define InstanceKlass_SPECIALIZED_BOUNDED_OOP_ITERATE( \
-  T, start_p, count, low, high,             \
-  do_oop, assert_fn)                        \
-{                                           \
-  T* const l = (T*)(low);                   \
-  T* const h = (T*)(high);                  \
-  assert(mask_bits((intptr_t)l, sizeof(T)-1) == 0 && \
-         mask_bits((intptr_t)h, sizeof(T)-1) == 0,   \
-         "bounded region must be properly aligned"); \
-  T* p       = (T*)(start_p);               \
-  T* end     = p + (count);                 \
-  if (p < l) p = l;                         \
-  if (end > h) end = h;                     \
-  while (p < end) {                         \
-    (assert_fn)(p);                         \
-    do_oop;                                 \
-    ++p;                                    \
-  }                                         \
-}
-
-
-// The following macros call specialized macros, passing either oop or
-// narrowOop as the specialization type.  These test the UseCompressedOops
-// flag.
-#define InstanceKlass_OOP_MAP_ITERATE(obj, do_oop, assert_fn)            \
-{                                                                        \
-  /* Compute oopmap block range. The common case                         \
-     is nonstatic_oop_map_size == 1. */                                  \
-  OopMapBlock* map           = start_of_nonstatic_oop_maps();            \
-  OopMapBlock* const end_map = map + nonstatic_oop_map_count();          \
-  if (UseCompressedOops) {                                               \
-    while (map < end_map) {                                              \
-      InstanceKlass_SPECIALIZED_OOP_ITERATE(narrowOop,                   \
-        obj->obj_field_addr<narrowOop>(map->offset()), map->count(),     \
-        do_oop, assert_fn)                                               \
-      ++map;                                                             \
-    }                                                                    \
-  } else {                                                               \
-    while (map < end_map) {                                              \
-      InstanceKlass_SPECIALIZED_OOP_ITERATE(oop,                         \
-        obj->obj_field_addr<oop>(map->offset()), map->count(),           \
-        do_oop, assert_fn)                                               \
-      ++map;                                                             \
-    }                                                                    \
-  }                                                                      \
-}
-
-#define InstanceKlass_OOP_MAP_REVERSE_ITERATE(obj, do_oop, assert_fn)    \
-{                                                                        \
-  OopMapBlock* const start_map = start_of_nonstatic_oop_maps();          \
-  OopMapBlock* map             = start_map + nonstatic_oop_map_count();  \
-  if (UseCompressedOops) {                                               \
-    while (start_map < map) {                                            \
-      --map;                                                             \
-      InstanceKlass_SPECIALIZED_OOP_REVERSE_ITERATE(narrowOop,           \
-        obj->obj_field_addr<narrowOop>(map->offset()), map->count(),     \
-        do_oop, assert_fn)                                               \
-    }                                                                    \
-  } else {                                                               \
-    while (start_map < map) {                                            \
-      --map;                                                             \
-      InstanceKlass_SPECIALIZED_OOP_REVERSE_ITERATE(oop,                 \
-        obj->obj_field_addr<oop>(map->offset()), map->count(),           \
-        do_oop, assert_fn)                                               \
-    }                                                                    \
-  }                                                                      \
-}
-
-#define InstanceKlass_BOUNDED_OOP_MAP_ITERATE(obj, low, high, do_oop,    \
-                                              assert_fn)                 \
-{                                                                        \
-  /* Compute oopmap block range. The common case is                      \
-     nonstatic_oop_map_size == 1, so we accept the                       \
-     usually non-existent extra overhead of examining                    \
-     all the maps. */                                                    \
-  OopMapBlock* map           = start_of_nonstatic_oop_maps();            \
-  OopMapBlock* const end_map = map + nonstatic_oop_map_count();          \
-  if (UseCompressedOops) {                                               \
-    while (map < end_map) {                                              \
-      InstanceKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(narrowOop,           \
-        obj->obj_field_addr<narrowOop>(map->offset()), map->count(),     \
-        low, high,                                                       \
-        do_oop, assert_fn)                                               \
-      ++map;                                                             \
-    }                                                                    \
-  } else {                                                               \
-    while (map < end_map) {                                              \
-      InstanceKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(oop,                 \
-        obj->obj_field_addr<oop>(map->offset()), map->count(),           \
-        low, high,                                                       \
-        do_oop, assert_fn)                                               \
-      ++map;                                                             \
-    }                                                                    \
-  }                                                                      \
-}
-
-void InstanceKlass::oop_follow_contents(oop obj) {
-  assert(obj != NULL, "can't follow the content of NULL object");
-  MarkSweep::follow_klass(obj->klass());
-  InstanceKlass_OOP_MAP_ITERATE( \
-    obj, \
-    MarkSweep::mark_and_push(p), \
-    assert_is_in_closed_subset)
-}
-
-#if INCLUDE_ALL_GCS
-void InstanceKlass::oop_follow_contents(ParCompactionManager* cm,
-                                        oop obj) {
-  assert(obj != NULL, "can't follow the content of NULL object");
-  PSParallelCompact::follow_klass(cm, obj->klass());
-  // Only mark the header and let the scan of the meta-data mark
-  // everything else.
-  InstanceKlass_OOP_MAP_ITERATE( \
-    obj, \
-    PSParallelCompact::mark_and_push(cm, p), \
-    assert_is_in)
-}
-#endif // INCLUDE_ALL_GCS
-
-// closure's do_metadata() method dictates whether the given closure should be
-// applied to the klass ptr in the object header.
-
-#define InstanceKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix)        \
-                                                                             \
-int InstanceKlass::oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure) { \
-  /* header */                                                          \
-  if_do_metadata_checked(closure, nv_suffix) {                          \
-    closure->do_klass##nv_suffix(obj->klass());                         \
-  }                                                                     \
-  InstanceKlass_OOP_MAP_ITERATE(                                        \
-    obj,                                                                \
-    (closure)->do_oop##nv_suffix(p),                                    \
-    assert_is_in_closed_subset)                                         \
-  return size_helper();                                                 \
-}
-
-#if INCLUDE_ALL_GCS
-#define InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix) \
-                                                                                \
-int InstanceKlass::oop_oop_iterate_backwards##nv_suffix(oop obj,                \
-                                              OopClosureType* closure) {        \
-  assert_should_ignore_metadata(closure, nv_suffix);                            \
-                                                                                \
-  /* instance variables */                                                      \
-  InstanceKlass_OOP_MAP_REVERSE_ITERATE(                                        \
-    obj,                                                                        \
-    (closure)->do_oop##nv_suffix(p),                                            \
-    assert_is_in_closed_subset)                                                 \
-   return size_helper();                                                        \
-}
-#endif // INCLUDE_ALL_GCS
-
-#define InstanceKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix) \
-                                                                        \
-int InstanceKlass::oop_oop_iterate##nv_suffix##_m(oop obj,              \
-                                                  OopClosureType* closure, \
-                                                  MemRegion mr) {          \
-  if_do_metadata_checked(closure, nv_suffix) {                           \
-    if (mr.contains(obj)) {                                              \
-      closure->do_klass##nv_suffix(obj->klass());                        \
-    }                                                                    \
-  }                                                                      \
-  InstanceKlass_BOUNDED_OOP_MAP_ITERATE(                                 \
-    obj, mr.start(), mr.end(),                                           \
-    (closure)->do_oop##nv_suffix(p),                                     \
-    assert_is_in_closed_subset)                                          \
-  return size_helper();                                                  \
-}
-
-ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceKlass_OOP_OOP_ITERATE_DEFN)
-ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceKlass_OOP_OOP_ITERATE_DEFN)
-ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceKlass_OOP_OOP_ITERATE_DEFN_m)
-ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceKlass_OOP_OOP_ITERATE_DEFN_m)
-#if INCLUDE_ALL_GCS
-ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
-ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
-#endif // INCLUDE_ALL_GCS
-
-int InstanceKlass::oop_adjust_pointers(oop obj) {
-  int size = size_helper();
-  InstanceKlass_OOP_MAP_ITERATE( \
-    obj, \
-    MarkSweep::adjust_pointer(p), \
-    assert_is_in)
-  return size;
-}
-
-#if INCLUDE_ALL_GCS
-void InstanceKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
-  InstanceKlass_OOP_MAP_REVERSE_ITERATE( \
-    obj, \
-    if (PSScavenge::should_scavenge(p)) { \
-      pm->claim_or_forward_depth(p); \
-    }, \
-    assert_nothing )
-}
-
-int InstanceKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
-  int size = size_helper();
-  InstanceKlass_OOP_MAP_ITERATE( \
-    obj, \
-    PSParallelCompact::adjust_pointer(p), \
-    assert_is_in)
-  return size;
-}
-
-#endif // INCLUDE_ALL_GCS
-
 void InstanceKlass::clean_implementors_list(BoolObjectClosure* is_alive) {
   assert(class_loader_data()->is_alive(is_alive), "this klass should be live");
   if (is_interface()) {
@@ -3769,6 +3457,37 @@
   return m;
 }
 
+
+Method* InstanceKlass::method_with_orig_idnum(int idnum) {
+  if (idnum >= methods()->length()) {
+    return NULL;
+  }
+  Method* m = methods()->at(idnum);
+  if (m != NULL && m->orig_method_idnum() == idnum) {
+    return m;
+  }
+  // Obsolete method idnum does not match the original idnum
+  for (int index = 0; index < methods()->length(); ++index) {
+    m = methods()->at(index);
+    if (m->orig_method_idnum() == idnum) {
+      return m;
+    }
+  }
+  // None found, return null for the caller to handle.
+  return NULL;
+}
+
+
+Method* InstanceKlass::method_with_orig_idnum(int idnum, int version) {
+  InstanceKlass* holder = get_klass_version(version);
+  if (holder == NULL) {
+    return NULL; // The version of klass is gone, no method is found
+  }
+  Method* method = holder->method_with_orig_idnum(idnum);
+  return method;
+}
+
+
 jint InstanceKlass::get_cached_class_file_len() {
   return VM_RedefineClasses::get_cached_class_file_len(_cached_class_file);
 }
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -330,6 +330,8 @@
   Array<Method*>* methods() const          { return _methods; }
   void set_methods(Array<Method*>* a)      { _methods = a; }
   Method* method_with_idnum(int idnum);
+  Method* method_with_orig_idnum(int idnum);
+  Method* method_with_orig_idnum(int idnum, int version);
 
   // method ordering
   Array<int>* method_ordering() const     { return _method_ordering; }
@@ -625,6 +627,15 @@
 
   InstanceKlass* previous_versions() const { return _previous_versions; }
 
+  InstanceKlass* get_klass_version(int version) {
+    for (InstanceKlass* ik = this; ik != NULL; ik = ik->previous_versions()) {
+      if (ik->constants()->version() == version) {
+        return ik;
+      }
+    }
+    return NULL;
+  }
+
   bool has_been_redefined() const {
     return (_misc_flags & _misc_has_been_redefined) != 0;
   }
@@ -958,10 +969,6 @@
   void adjust_default_methods(InstanceKlass* holder, bool* trace_name_printed);
 #endif // INCLUDE_JVMTI
 
-  // Garbage collection
-  void oop_follow_contents(oop obj);
-  int  oop_adjust_pointers(oop obj);
-
   void clean_implementors_list(BoolObjectClosure* is_alive);
   void clean_method_data(BoolObjectClosure* is_alive);
   void clean_dependent_nmethods();
@@ -985,32 +992,108 @@
   static void notify_unload_class(InstanceKlass* ik);
   static void release_C_heap_structures(InstanceKlass* ik);
 
-  // Parallel Scavenge and Parallel Old
-  PARALLEL_GC_DECLS
-
   // Naming
   const char* signature_name() const;
 
-  // Iterators
-  int oop_oop_iterate(oop obj, ExtendedOopClosure* blk) {
-    return oop_oop_iterate_v(obj, blk);
-  }
+  // GC specific object visitors
+  //
+  // Mark Sweep
+  void oop_ms_follow_contents(oop obj);
+  int  oop_ms_adjust_pointers(oop obj);
+#if INCLUDE_ALL_GCS
+  // Parallel Scavenge
+  void oop_ps_push_contents(  oop obj, PSPromotionManager* pm);
+  // Parallel Compact
+  void oop_pc_follow_contents(oop obj, ParCompactionManager* cm);
+  void oop_pc_update_pointers(oop obj);
+#endif
+
+  // Oop fields (and metadata) iterators
+  //  [nv = true]  Use non-virtual calls to do_oop_nv.
+  //  [nv = false] Use virtual calls to do_oop.
+  //
+  // The InstanceKlass iterators also visits the Object's klass.
+
+  // Forward iteration
+ public:
+  // Iterate over all oop fields in the oop maps.
+  template <bool nv, class OopClosureType>
+  inline void oop_oop_iterate_oop_maps(oop obj, OopClosureType* closure);
+
+ protected:
+  // Iterate over all oop fields and metadata.
+  template <bool nv, class OopClosureType>
+  inline int oop_oop_iterate(oop obj, OopClosureType* closure);
+
+ private:
+  // Iterate over all oop fields in the oop maps.
+  // Specialized for [T = oop] or [T = narrowOop].
+  template <bool nv, typename T, class OopClosureType>
+  inline void oop_oop_iterate_oop_maps_specialized(oop obj, OopClosureType* closure);
+
+  // Iterate over all oop fields in one oop map.
+  template <bool nv, typename T, class OopClosureType>
+  inline void oop_oop_iterate_oop_map(OopMapBlock* map, oop obj, OopClosureType* closure);
+
 
-  int oop_oop_iterate_m(oop obj, ExtendedOopClosure* blk, MemRegion mr) {
-    return oop_oop_iterate_v_m(obj, blk, mr);
-  }
+  // Reverse iteration
+#if INCLUDE_ALL_GCS
+ public:
+  // Iterate over all oop fields in the oop maps.
+  template <bool nv, class OopClosureType>
+  inline void oop_oop_iterate_oop_maps_reverse(oop obj, OopClosureType* closure);
+
+ protected:
+  // Iterate over all oop fields and metadata.
+  template <bool nv, class OopClosureType>
+  inline int oop_oop_iterate_reverse(oop obj, OopClosureType* closure);
+
+ private:
+  // Iterate over all oop fields in the oop maps.
+  // Specialized for [T = oop] or [T = narrowOop].
+  template <bool nv, typename T, class OopClosureType>
+  inline void oop_oop_iterate_oop_maps_specialized_reverse(oop obj, OopClosureType* closure);
+
+  // Iterate over all oop fields in one oop map.
+  template <bool nv, typename T, class OopClosureType>
+  inline void oop_oop_iterate_oop_map_reverse(OopMapBlock* map, oop obj, OopClosureType* closure);
+#endif
+
 
-#define InstanceKlass_OOP_OOP_ITERATE_DECL(OopClosureType, nv_suffix)      \
-  int  oop_oop_iterate##nv_suffix(oop obj, OopClosureType* blk);           \
-  int  oop_oop_iterate##nv_suffix##_m(oop obj, OopClosureType* blk,        \
-                                      MemRegion mr);
+  // Bounded range iteration
+ public:
+  // Iterate over all oop fields in the oop maps.
+  template <bool nv, class OopClosureType>
+  inline void oop_oop_iterate_oop_maps_bounded(oop obj, OopClosureType* closure, MemRegion mr);
+
+ protected:
+  // Iterate over all oop fields and metadata.
+  template <bool nv, class OopClosureType>
+  inline int oop_oop_iterate_bounded(oop obj, OopClosureType* closure, MemRegion mr);
+
+ private:
+  // Iterate over all oop fields in the oop maps.
+  // Specialized for [T = oop] or [T = narrowOop].
+  template <bool nv, typename T, class OopClosureType>
+  inline void oop_oop_iterate_oop_maps_specialized_bounded(oop obj, OopClosureType* closure, MemRegion mr);
+
+  // Iterate over all oop fields in one oop map.
+  template <bool nv, typename T, class OopClosureType>
+  inline void oop_oop_iterate_oop_map_bounded(OopMapBlock* map, oop obj, OopClosureType* closure, MemRegion mr);
+
+
+ public:
+
+#define InstanceKlass_OOP_OOP_ITERATE_DECL(OopClosureType, nv_suffix)                   \
+  int  oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure);                    \
+  int  oop_oop_iterate##nv_suffix##_m(oop obj, OopClosureType* closure, MemRegion mr);
 
   ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceKlass_OOP_OOP_ITERATE_DECL)
   ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceKlass_OOP_OOP_ITERATE_DECL)
 
 #if INCLUDE_ALL_GCS
-#define InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DECL(OopClosureType, nv_suffix) \
-  int  oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* blk);
+#define InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DECL(OopClosureType, nv_suffix)  \
+  int  oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* closure);
 
   ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DECL)
   ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DECL)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/oops/instanceKlass.inline.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_OOPS_INSTANCEKLASS_INLINE_HPP
+#define SHARE_VM_OOPS_INSTANCEKLASS_INLINE_HPP
+
+#include "memory/iterator.hpp"
+#include "oops/instanceKlass.hpp"
+#include "oops/oop.inline.hpp"
+#include "utilities/debug.hpp"
+#include "utilities/globalDefinitions.hpp"
+#include "utilities/macros.hpp"
+
+// The iteration over the oops in objects is a hot path in the GC code.
+// By force inlining the following functions, we get similar GC performance
+// as the previous macro based implementation.
+#ifdef TARGET_COMPILER_visCPP
+#define INLINE __forceinline
+#else
+#define INLINE inline
+#endif
+
+template <bool nv, typename T, class OopClosureType>
+INLINE void InstanceKlass::oop_oop_iterate_oop_map(OopMapBlock* map, oop obj, OopClosureType* closure) {
+  T* p         = (T*)obj->obj_field_addr<T>(map->offset());
+  T* const end = p + map->count();
+
+  for (; p < end; ++p) {
+    Devirtualizer<nv>::do_oop(closure, p);
+  }
+}
+
+#if INCLUDE_ALL_GCS
+template <bool nv, typename T, class OopClosureType>
+INLINE void InstanceKlass::oop_oop_iterate_oop_map_reverse(OopMapBlock* map, oop obj, OopClosureType* closure) {
+  T* const start = (T*)obj->obj_field_addr<T>(map->offset());
+  T*       p     = start + map->count();
+
+  while (start < p) {
+    --p;
+    Devirtualizer<nv>::do_oop(closure, p);
+  }
+}
+#endif
+
+template <bool nv, typename T, class OopClosureType>
+INLINE void InstanceKlass::oop_oop_iterate_oop_map_bounded(OopMapBlock* map, oop obj, OopClosureType* closure, MemRegion mr) {
+  T* p   = (T*)obj->obj_field_addr<T>(map->offset());
+  T* end = p + map->count();
+
+  T* const l   = (T*)mr.start();
+  T* const h   = (T*)mr.end();
+  assert(mask_bits((intptr_t)l, sizeof(T)-1) == 0 &&
+         mask_bits((intptr_t)h, sizeof(T)-1) == 0,
+         "bounded region must be properly aligned");
+
+  if (p < l) {
+    p = l;
+  }
+  if (end > h) {
+    end = h;
+  }
+
+  for (;p < end; ++p) {
+    Devirtualizer<nv>::do_oop(closure, p);
+  }
+}
+
+template <bool nv, typename T, class OopClosureType>
+INLINE void InstanceKlass::oop_oop_iterate_oop_maps_specialized(oop obj, OopClosureType* closure) {
+  OopMapBlock* map           = start_of_nonstatic_oop_maps();
+  OopMapBlock* const end_map = map + nonstatic_oop_map_count();
+
+  for (; map < end_map; ++map) {
+    oop_oop_iterate_oop_map<nv, T>(map, obj, closure);
+  }
+}
+
+#if INCLUDE_ALL_GCS
+template <bool nv, typename T, class OopClosureType>
+INLINE void InstanceKlass::oop_oop_iterate_oop_maps_specialized_reverse(oop obj, OopClosureType* closure) {
+  OopMapBlock* const start_map = start_of_nonstatic_oop_maps();
+  OopMapBlock* map             = start_map + nonstatic_oop_map_count();
+
+  while (start_map < map) {
+    --map;
+    oop_oop_iterate_oop_map_reverse<nv, T>(map, obj, closure);
+  }
+}
+#endif
+
+template <bool nv, typename T, class OopClosureType>
+INLINE void InstanceKlass::oop_oop_iterate_oop_maps_specialized_bounded(oop obj, OopClosureType* closure, MemRegion mr) {
+  OopMapBlock* map           = start_of_nonstatic_oop_maps();
+  OopMapBlock* const end_map = map + nonstatic_oop_map_count();
+
+  for (;map < end_map; ++map) {
+    oop_oop_iterate_oop_map_bounded<nv, T>(map, obj, closure, mr);
+  }
+}
+
+template <bool nv, class OopClosureType>
+INLINE void InstanceKlass::oop_oop_iterate_oop_maps(oop obj, OopClosureType* closure) {
+  if (UseCompressedOops) {
+    oop_oop_iterate_oop_maps_specialized<nv, narrowOop>(obj, closure);
+  } else {
+    oop_oop_iterate_oop_maps_specialized<nv, oop>(obj, closure);
+  }
+}
+
+#if INCLUDE_ALL_GCS
+template <bool nv, class OopClosureType>
+INLINE void InstanceKlass::oop_oop_iterate_oop_maps_reverse(oop obj, OopClosureType* closure) {
+  if (UseCompressedOops) {
+    oop_oop_iterate_oop_maps_specialized_reverse<nv, narrowOop>(obj, closure);
+  } else {
+    oop_oop_iterate_oop_maps_specialized_reverse<nv, oop>(obj, closure);
+  }
+}
+#endif
+
+template <bool nv, class OopClosureType>
+INLINE void InstanceKlass::oop_oop_iterate_oop_maps_bounded(oop obj, OopClosureType* closure, MemRegion mr) {
+  if (UseCompressedOops) {
+    oop_oop_iterate_oop_maps_specialized_bounded<nv, narrowOop>(obj, closure, mr);
+  } else {
+    oop_oop_iterate_oop_maps_specialized_bounded<nv, oop>(obj, closure, mr);
+  }
+}
+
+template <bool nv, class OopClosureType>
+INLINE int InstanceKlass::oop_oop_iterate(oop obj, OopClosureType* closure) {
+  if (Devirtualizer<nv>::do_metadata(closure)) {
+    Devirtualizer<nv>::do_klass(closure, this);
+  }
+
+  oop_oop_iterate_oop_maps<nv>(obj, closure);
+
+  return size_helper();
+}
+
+#if INCLUDE_ALL_GCS
+template <bool nv, class OopClosureType>
+INLINE int InstanceKlass::oop_oop_iterate_reverse(oop obj, OopClosureType* closure) {
+  assert(!Devirtualizer<nv>::do_metadata(closure),
+      "Code to handle metadata is not implemented");
+
+  oop_oop_iterate_oop_maps_reverse<nv>(obj, closure);
+
+  return size_helper();
+}
+#endif
+
+template <bool nv, class OopClosureType>
+INLINE int InstanceKlass::oop_oop_iterate_bounded(oop obj, OopClosureType* closure, MemRegion mr) {
+  if (Devirtualizer<nv>::do_metadata(closure)) {
+    if (mr.contains(obj)) {
+      Devirtualizer<nv>::do_klass(closure, this);
+    }
+  }
+
+  oop_oop_iterate_oop_maps_bounded<nv>(obj, closure, mr);
+
+  return size_helper();
+}
+
+#undef INLINE
+
+
+#define InstanceKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix)              \
+int InstanceKlass::oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure) {  \
+  return oop_oop_iterate<nvs_to_bool(nv_suffix)>(obj, closure);                    \
+}
+
+#if INCLUDE_ALL_GCS
+#define InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix)              \
+int InstanceKlass::oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* closure) {  \
+  return oop_oop_iterate_reverse<nvs_to_bool(nv_suffix)>(obj, closure);                      \
+}
+#else
+#define InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix)
+#endif
+
+#define InstanceKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix)                              \
+int InstanceKlass::oop_oop_iterate##nv_suffix##_m(oop obj, OopClosureType* closure, MemRegion mr) {  \
+  return oop_oop_iterate_bounded<nvs_to_bool(nv_suffix)>(obj, closure, mr);                          \
+}
+
+#define ALL_INSTANCE_KLASS_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix)  \
+  InstanceKlass_OOP_OOP_ITERATE_DEFN(          OopClosureType, nv_suffix)   \
+  InstanceKlass_OOP_OOP_ITERATE_DEFN_m(        OopClosureType, nv_suffix)   \
+  InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix)
+
+#endif // SHARE_VM_OOPS_INSTANCEKLASS_INLINE_HPP
--- a/hotspot/src/share/vm/oops/instanceMirrorKlass.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/oops/instanceMirrorKlass.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -25,9 +25,7 @@
 #include "precompiled.hpp"
 #include "classfile/javaClasses.hpp"
 #include "classfile/systemDictionary.hpp"
-#include "gc_implementation/shared/markSweep.inline.hpp"
 #include "gc_interface/collectedHeap.inline.hpp"
-#include "memory/genOopClosures.inline.hpp"
 #include "memory/iterator.inline.hpp"
 #include "memory/oopFactory.hpp"
 #include "memory/specialized_oop_closures.hpp"
@@ -38,313 +36,9 @@
 #include "oops/symbol.hpp"
 #include "runtime/handles.inline.hpp"
 #include "utilities/macros.hpp"
-#if INCLUDE_ALL_GCS
-#include "gc_implementation/concurrentMarkSweep/cmsOopClosures.inline.hpp"
-#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
-#include "gc_implementation/g1/g1OopClosures.inline.hpp"
-#include "gc_implementation/g1/g1RemSet.inline.hpp"
-#include "gc_implementation/g1/heapRegionManager.inline.hpp"
-#include "gc_implementation/parNew/parOopClosures.inline.hpp"
-#include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
-#include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
-#endif // INCLUDE_ALL_GCS
 
 int InstanceMirrorKlass::_offset_of_static_fields = 0;
 
-#ifdef ASSERT
-template <class T> void assert_is_in(T *p) {
-  T heap_oop = oopDesc::load_heap_oop(p);
-  if (!oopDesc::is_null(heap_oop)) {
-    oop o = oopDesc::decode_heap_oop_not_null(heap_oop);
-    assert(Universe::heap()->is_in(o), "should be in heap");
-  }
-}
-template <class T> void assert_is_in_closed_subset(T *p) {
-  T heap_oop = oopDesc::load_heap_oop(p);
-  if (!oopDesc::is_null(heap_oop)) {
-    oop o = oopDesc::decode_heap_oop_not_null(heap_oop);
-    assert(Universe::heap()->is_in_closed_subset(o), "should be in closed");
-  }
-}
-template <class T> void assert_is_in_reserved(T *p) {
-  T heap_oop = oopDesc::load_heap_oop(p);
-  if (!oopDesc::is_null(heap_oop)) {
-    oop o = oopDesc::decode_heap_oop_not_null(heap_oop);
-    assert(Universe::heap()->is_in_reserved(o), "should be in reserved");
-  }
-}
-template <class T> void assert_nothing(T *p) {}
-
-#else
-template <class T> void assert_is_in(T *p) {}
-template <class T> void assert_is_in_closed_subset(T *p) {}
-template <class T> void assert_is_in_reserved(T *p) {}
-template <class T> void assert_nothing(T *p) {}
-#endif // ASSERT
-
-#define InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE( \
-  T, start_p, count, do_oop,                         \
-  assert_fn)                                         \
-{                                                    \
-  T* p         = (T*)(start_p);                      \
-  T* const end = p + (count);                        \
-  while (p < end) {                                  \
-    (assert_fn)(p);                                  \
-    do_oop;                                          \
-    ++p;                                             \
-  }                                                  \
-}
-
-#define InstanceMirrorKlass_SPECIALIZED_BOUNDED_OOP_ITERATE( \
-  T, start_p, count, low, high,                              \
-  do_oop, assert_fn)                                         \
-{                                                            \
-  T* const l = (T*)(low);                                    \
-  T* const h = (T*)(high);                                   \
-  assert(mask_bits((intptr_t)l, sizeof(T)-1) == 0 &&         \
-         mask_bits((intptr_t)h, sizeof(T)-1) == 0,           \
-         "bounded region must be properly aligned");         \
-  T* p       = (T*)(start_p);                                \
-  T* end     = p + (count);                                  \
-  if (p < l) p = l;                                          \
-  if (end > h) end = h;                                      \
-  while (p < end) {                                          \
-    (assert_fn)(p);                                          \
-    do_oop;                                                  \
-    ++p;                                                     \
-  }                                                          \
-}
-
-
-#define InstanceMirrorKlass_OOP_ITERATE(start_p, count,    \
-                                  do_oop, assert_fn)       \
-{                                                          \
-  if (UseCompressedOops) {                                 \
-    InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE(narrowOop, \
-      start_p, count,                                      \
-      do_oop, assert_fn)                                   \
-  } else {                                                 \
-    InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE(oop,       \
-      start_p, count,                                      \
-      do_oop, assert_fn)                                   \
-  }                                                        \
-}
-
-// The following macros call specialized macros, passing either oop or
-// narrowOop as the specialization type.  These test the UseCompressedOops
-// flag.
-#define InstanceMirrorKlass_BOUNDED_OOP_ITERATE(start_p, count, low, high, \
-                                          do_oop, assert_fn)               \
-{                                                                          \
-  if (UseCompressedOops) {                                                 \
-    InstanceMirrorKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(narrowOop,         \
-      start_p, count,                                                      \
-      low, high,                                                           \
-      do_oop, assert_fn)                                                   \
-  } else {                                                                 \
-    InstanceMirrorKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(oop,               \
-      start_p, count,                                                      \
-      low, high,                                                           \
-      do_oop, assert_fn)                                                   \
-  }                                                                        \
-}
-
-
-void InstanceMirrorKlass::oop_follow_contents(oop obj) {
-  InstanceKlass::oop_follow_contents(obj);
-
-  // Follow the klass field in the mirror.
-  Klass* klass = java_lang_Class::as_Klass(obj);
-  if (klass != NULL) {
-    // An anonymous class doesn't have its own class loader, so the call
-    // to follow_klass will mark and push its java mirror instead of the
-    // class loader. When handling the java mirror for an anonymous class
-    // we need to make sure its class loader data is claimed, this is done
-    // by calling follow_class_loader explicitly. For non-anonymous classes
-    // the call to follow_class_loader is made when the class loader itself
-    // is handled.
-    if (klass->oop_is_instance() && InstanceKlass::cast(klass)->is_anonymous()) {
-      MarkSweep::follow_class_loader(klass->class_loader_data());
-    } else {
-      MarkSweep::follow_klass(klass);
-    }
-  } else {
-    // If klass is NULL then this a mirror for a primitive type.
-    // We don't have to follow them, since they are handled as strong
-    // roots in Universe::oops_do.
-    assert(java_lang_Class::is_primitive(obj), "Sanity check");
-  }
-
-  InstanceMirrorKlass_OOP_ITERATE(                                                    \
-    start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj),        \
-    MarkSweep::mark_and_push(p),                                                      \
-    assert_is_in_closed_subset)
-}
-
-#if INCLUDE_ALL_GCS
-void InstanceMirrorKlass::oop_follow_contents(ParCompactionManager* cm,
-                                              oop obj) {
-  InstanceKlass::oop_follow_contents(cm, obj);
-
-  // Follow the klass field in the mirror.
-  Klass* klass = java_lang_Class::as_Klass(obj);
-  if (klass != NULL) {
-    // An anonymous class doesn't have its own class loader, so the call
-    // to follow_klass will mark and push its java mirror instead of the
-    // class loader. When handling the java mirror for an anonymous class
-    // we need to make sure its class loader data is claimed, this is done
-    // by calling follow_class_loader explicitly. For non-anonymous classes
-    // the call to follow_class_loader is made when the class loader itself
-    // is handled.
-    if (klass->oop_is_instance() && InstanceKlass::cast(klass)->is_anonymous()) {
-      PSParallelCompact::follow_class_loader(cm, klass->class_loader_data());
-    } else {
-      PSParallelCompact::follow_klass(cm, klass);
-    }
-  } else {
-    // If klass is NULL then this a mirror for a primitive type.
-    // We don't have to follow them, since they are handled as strong
-    // roots in Universe::oops_do.
-    assert(java_lang_Class::is_primitive(obj), "Sanity check");
-  }
-
-  InstanceMirrorKlass_OOP_ITERATE(                                                    \
-    start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj),        \
-    PSParallelCompact::mark_and_push(cm, p),                                          \
-    assert_is_in)
-}
-#endif // INCLUDE_ALL_GCS
-
-int InstanceMirrorKlass::oop_adjust_pointers(oop obj) {
-  int size = oop_size(obj);
-  InstanceKlass::oop_adjust_pointers(obj);
-
-  InstanceMirrorKlass_OOP_ITERATE(                                                    \
-    start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj),        \
-    MarkSweep::adjust_pointer(p),                                                     \
-    assert_nothing)
-  return size;
-}
-
-#define InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(T, nv_suffix)                \
-  InstanceMirrorKlass_OOP_ITERATE(                                                    \
-    start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj),        \
-      (closure)->do_oop##nv_suffix(p),                                                \
-    assert_is_in_closed_subset)                                                       \
-  return oop_size(obj);                                                               \
-
-#define InstanceMirrorKlass_BOUNDED_SPECIALIZED_OOP_ITERATE(T, nv_suffix, mr)         \
-  InstanceMirrorKlass_BOUNDED_OOP_ITERATE(                                            \
-    start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj),        \
-    mr.start(), mr.end(),                                                             \
-      (closure)->do_oop##nv_suffix(p),                                                \
-    assert_is_in_closed_subset)                                                       \
-  return oop_size(obj);                                                               \
-
-
-// Macro to define InstanceMirrorKlass::oop_oop_iterate for virtual/nonvirtual for
-// all closures.  Macros calling macros above for each oop size.
-
-#define InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix)           \
-                                                                                      \
-int InstanceMirrorKlass::                                                             \
-oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure) {                        \
-  /* Get size before changing pointers */                                             \
-  InstanceKlass::oop_oop_iterate##nv_suffix(obj, closure);                            \
-                                                                                      \
-  if_do_metadata_checked(closure, nv_suffix) {                                        \
-    Klass* klass = java_lang_Class::as_Klass(obj);                                    \
-    /* We'll get NULL for primitive mirrors. */                                       \
-    if (klass != NULL) {                                                              \
-      closure->do_klass##nv_suffix(klass);                                            \
-    }                                                                                 \
-  }                                                                                   \
-                                                                                      \
-  if (UseCompressedOops) {                                                            \
-    InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(narrowOop, nv_suffix);           \
-  } else {                                                                            \
-    InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(oop, nv_suffix);                 \
-  }                                                                                   \
-}
-
-#if INCLUDE_ALL_GCS
-#define InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix) \
-                                                                                      \
-int InstanceMirrorKlass::                                                             \
-oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* closure) {              \
-  /* Get size before changing pointers */                                             \
-  InstanceKlass::oop_oop_iterate_backwards##nv_suffix(obj, closure);                  \
-                                                                                      \
-  if (UseCompressedOops) {                                                            \
-    InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(narrowOop, nv_suffix);           \
-  } else {                                                                            \
-    InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(oop, nv_suffix);                 \
-  }                                                                                   \
-}
-#endif // INCLUDE_ALL_GCS
-
-
-#define InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix)         \
-                                                                                      \
-int InstanceMirrorKlass::                                                             \
-oop_oop_iterate##nv_suffix##_m(oop obj,                                               \
-                               OopClosureType* closure,                               \
-                               MemRegion mr) {                                        \
-  InstanceKlass::oop_oop_iterate##nv_suffix##_m(obj, closure, mr);                    \
-                                                                                      \
-  if_do_metadata_checked(closure, nv_suffix) {                                        \
-    if (mr.contains(obj)) {                                                           \
-      Klass* klass = java_lang_Class::as_Klass(obj);                                  \
-      /* We'll get NULL for primitive mirrors. */                                     \
-      if (klass != NULL) {                                                            \
-        closure->do_klass##nv_suffix(klass);                                          \
-      }                                                                               \
-    }                                                                                 \
-  }                                                                                   \
-                                                                                      \
-  if (UseCompressedOops) {                                                            \
-    InstanceMirrorKlass_BOUNDED_SPECIALIZED_OOP_ITERATE(narrowOop, nv_suffix, mr);    \
-  } else {                                                                            \
-    InstanceMirrorKlass_BOUNDED_SPECIALIZED_OOP_ITERATE(oop, nv_suffix, mr);          \
-  }                                                                                   \
-}
-
-ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN)
-ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN)
-#if INCLUDE_ALL_GCS
-ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
-ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
-#endif // INCLUDE_ALL_GCS
-ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN_m)
-ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN_m)
-
-#if INCLUDE_ALL_GCS
-void InstanceMirrorKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
-  // Note that we don't have to follow the mirror -> klass pointer, since all
-  // klasses that are dirty will be scavenged when we iterate over the
-  // ClassLoaderData objects.
-
-  InstanceKlass::oop_push_contents(pm, obj);
-  InstanceMirrorKlass_OOP_ITERATE(                                            \
-    start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj),\
-    if (PSScavenge::should_scavenge(p)) {                                     \
-      pm->claim_or_forward_depth(p);                                          \
-    },                                                                        \
-    assert_nothing )
-}
-
-int InstanceMirrorKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
-  int size = oop_size(obj);
-  InstanceKlass::oop_update_pointers(cm, obj);
-
-  InstanceMirrorKlass_OOP_ITERATE(                                            \
-    start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj),\
-    PSParallelCompact::adjust_pointer(p),                                     \
-    assert_nothing)
-  return size;
-}
-#endif // INCLUDE_ALL_GCS
-
 int InstanceMirrorKlass::instance_size(KlassHandle k) {
   if (k() != NULL && k->oop_is_instance()) {
     return align_object_size(size_helper() + InstanceKlass::cast(k())->static_field_size());
--- a/hotspot/src/share/vm/oops/instanceMirrorKlass.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/oops/instanceMirrorKlass.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -88,19 +88,66 @@
   // allocation
   instanceOop allocate_instance(KlassHandle k, TRAPS);
 
-  // Garbage collection
-  int  oop_adjust_pointers(oop obj);
-  void oop_follow_contents(oop obj);
+  // GC specific object visitors
+  //
+  // Mark Sweep
+  void oop_ms_follow_contents(oop obj);
+  int  oop_ms_adjust_pointers(oop obj);
+#if INCLUDE_ALL_GCS
+  // Parallel Scavenge
+  void oop_ps_push_contents(  oop obj, PSPromotionManager* pm);
+  // Parallel Compact
+  void oop_pc_follow_contents(oop obj, ParCompactionManager* cm);
+  void oop_pc_update_pointers(oop obj);
+#endif
 
-  // Parallel Scavenge and Parallel Old
-  PARALLEL_GC_DECLS
+  // Oop fields (and metadata) iterators
+  //  [nv = true]  Use non-virtual calls to do_oop_nv.
+  //  [nv = false] Use virtual calls to do_oop.
+  //
+  // The InstanceMirrorKlass iterators also visit the hidden Klass pointer.
+
+ public:
+  // Iterate over the static fields.
+  template <bool nv, class OopClosureType>
+  inline void oop_oop_iterate_statics(oop obj, OopClosureType* closure);
+
+ private:
+  // Iterate over the static fields.
+  // Specialized for [T = oop] or [T = narrowOop].
+  template <bool nv, typename T, class OopClosureType>
+  inline void oop_oop_iterate_statics_specialized(oop obj, OopClosureType* closure);
 
-  int oop_oop_iterate(oop obj, ExtendedOopClosure* blk) {
-    return oop_oop_iterate_v(obj, blk);
-  }
-  int oop_oop_iterate_m(oop obj, ExtendedOopClosure* blk, MemRegion mr) {
-    return oop_oop_iterate_v_m(obj, blk, mr);
-  }
+  // Forward iteration
+  // Iterate over the oop fields and metadata.
+  template <bool nv, class OopClosureType>
+  inline int oop_oop_iterate(oop obj, OopClosureType* closure);
+
+
+  // Reverse iteration
+#if INCLUDE_ALL_GCS
+  // Iterate over the oop fields and metadata.
+  template <bool nv, class OopClosureType>
+  inline int oop_oop_iterate_reverse(oop obj, OopClosureType* closure);
+#endif
+
+
+  // Bounded range iteration
+  // Iterate over the oop fields and metadata.
+  template <bool nv, class OopClosureType>
+  inline int oop_oop_iterate_bounded(oop obj, OopClosureType* closure, MemRegion mr);
+
+  // Iterate over the static fields.
+  template <bool nv, class OopClosureType>
+  inline void oop_oop_iterate_statics_bounded(oop obj, OopClosureType* closure, MemRegion mr);
+
+  // Iterate over the static fields.
+  // Specialized for [T = oop] or [T = narrowOop].
+  template <bool nv, typename T, class OopClosureType>
+  inline void oop_oop_iterate_statics_specialized_bounded(oop obj, OopClosureType* closure, MemRegion mr);
+
+
+ public:
 
 #define InstanceMirrorKlass_OOP_OOP_ITERATE_DECL(OopClosureType, nv_suffix)           \
   int oop_oop_iterate##nv_suffix(oop obj, OopClosureType* blk);                       \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/oops/instanceMirrorKlass.inline.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -0,0 +1,164 @@
+/* Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_OOPS_INSTANCEMIRRORKLASS_INLINE_HPP
+#define SHARE_VM_OOPS_INSTANCEMIRRORKLASS_INLINE_HPP
+
+#include "classfile/javaClasses.hpp"
+#include "oops/instanceKlass.inline.hpp"
+#include "oops/instanceMirrorKlass.hpp"
+#include "oops/oop.inline.hpp"
+#include "utilities/debug.hpp"
+#include "utilities/globalDefinitions.hpp"
+#include "utilities/macros.hpp"
+
+template <bool nv, typename T, class OopClosureType>
+void InstanceMirrorKlass::oop_oop_iterate_statics_specialized(oop obj, OopClosureType* closure) {
+  T* p         = (T*)start_of_static_fields(obj);
+  T* const end = p + java_lang_Class::static_oop_field_count(obj);
+
+  for (; p < end; ++p) {
+    Devirtualizer<nv>::do_oop(closure, p);
+  }
+}
+
+template <bool nv, class OopClosureType>
+void InstanceMirrorKlass::oop_oop_iterate_statics(oop obj, OopClosureType* closure) {
+  if (UseCompressedOops) {
+    oop_oop_iterate_statics_specialized<nv, narrowOop>(obj, closure);
+  } else {
+    oop_oop_iterate_statics_specialized<nv, oop>(obj, closure);
+  }
+}
+
+template <bool nv, class OopClosureType>
+int InstanceMirrorKlass::oop_oop_iterate(oop obj, OopClosureType* closure) {
+  InstanceKlass::oop_oop_iterate<nv>(obj, closure);
+
+  if (Devirtualizer<nv>::do_metadata(closure)) {
+    Klass* klass = java_lang_Class::as_Klass(obj);
+    // We'll get NULL for primitive mirrors.
+    if (klass != NULL) {
+      Devirtualizer<nv>::do_klass(closure, klass);
+    }
+  }
+
+  oop_oop_iterate_statics<nv>(obj, closure);
+
+  return oop_size(obj);
+}
+
+#if INCLUDE_ALL_GCS
+template <bool nv, class OopClosureType>
+int InstanceMirrorKlass::oop_oop_iterate_reverse(oop obj, OopClosureType* closure) {
+  InstanceKlass::oop_oop_iterate_reverse<nv>(obj, closure);
+
+  InstanceMirrorKlass::oop_oop_iterate_statics<nv>(obj, closure);
+
+  return oop_size(obj);
+}
+#endif
+
+template <bool nv, typename T, class OopClosureType>
+void InstanceMirrorKlass::oop_oop_iterate_statics_specialized_bounded(oop obj,
+                                                                     OopClosureType* closure,
+                                                                     MemRegion mr) {
+  T* p   = (T*)start_of_static_fields(obj);
+  T* end = p + java_lang_Class::static_oop_field_count(obj);
+
+  T* const l   = (T*)mr.start();
+  T* const h   = (T*)mr.end();
+  assert(mask_bits((intptr_t)l, sizeof(T)-1) == 0 &&
+         mask_bits((intptr_t)h, sizeof(T)-1) == 0,
+         "bounded region must be properly aligned");
+
+  if (p < l) {
+    p = l;
+  }
+  if (end > h) {
+    end = h;
+  }
+
+  for (;p < end; ++p) {
+    Devirtualizer<nv>::do_oop(closure, p);
+  }
+}
+
+template <bool nv, class OopClosureType>
+void InstanceMirrorKlass::oop_oop_iterate_statics_bounded(oop obj, OopClosureType* closure, MemRegion mr) {
+  if (UseCompressedOops) {
+    oop_oop_iterate_statics_specialized_bounded<nv, narrowOop>(obj, closure, mr);
+  } else {
+    oop_oop_iterate_statics_specialized_bounded<nv, oop>(obj, closure, mr);
+  }
+}
+
+template <bool nv, class OopClosureType>
+int InstanceMirrorKlass::oop_oop_iterate_bounded(oop obj, OopClosureType* closure, MemRegion mr) {
+  InstanceKlass::oop_oop_iterate_bounded<nv>(obj, closure, mr);
+
+  if (Devirtualizer<nv>::do_metadata(closure)) {
+    if (mr.contains(obj)) {
+      Klass* klass = java_lang_Class::as_Klass(obj);
+      // We'll get NULL for primitive mirrors.
+      if (klass != NULL) {
+        Devirtualizer<nv>::do_klass(closure, klass);
+      }
+    }
+  }
+
+  oop_oop_iterate_statics_bounded<nv>(obj, closure, mr);
+
+  return oop_size(obj);
+}
+
+
+#define InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix)              \
+                                                                                         \
+int InstanceMirrorKlass::oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure) {  \
+  return oop_oop_iterate<nvs_to_bool(nv_suffix)>(obj, closure);                          \
+}
+
+#if INCLUDE_ALL_GCS
+#define InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix)              \
+                                                                                                   \
+int InstanceMirrorKlass::oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* closure) {  \
+  return oop_oop_iterate_reverse<nvs_to_bool(nv_suffix)>(obj, closure);                            \
+}
+#else
+#define InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix)
+#endif
+
+
+#define InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix)                              \
+                                                                                                           \
+int InstanceMirrorKlass::oop_oop_iterate##nv_suffix##_m(oop obj, OopClosureType* closure, MemRegion mr) {  \
+  return oop_oop_iterate_bounded<nvs_to_bool(nv_suffix)>(obj, closure, mr);                                \
+}
+
+#define ALL_INSTANCE_MIRROR_KLASS_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix)  \
+  InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN(          OopClosureType, nv_suffix)    \
+  InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN_m(        OopClosureType, nv_suffix)    \
+  InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix)
+
+#endif // SHARE_VM_OOPS_INSTANCEMIRRORKLASS_INLINE_HPP
--- a/hotspot/src/share/vm/oops/instanceRefKlass.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/oops/instanceRefKlass.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -25,421 +25,16 @@
 #include "precompiled.hpp"
 #include "classfile/javaClasses.hpp"
 #include "classfile/systemDictionary.hpp"
-#include "gc_implementation/shared/markSweep.inline.hpp"
-#include "gc_interface/collectedHeap.hpp"
 #include "gc_interface/collectedHeap.inline.hpp"
 #include "memory/genCollectedHeap.hpp"
-#include "memory/genOopClosures.inline.hpp"
 #include "memory/specialized_oop_closures.hpp"
-#include "oops/instanceRefKlass.hpp"
+#include "oops/instanceRefKlass.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "utilities/preserveException.hpp"
 #include "utilities/macros.hpp"
-#if INCLUDE_ALL_GCS
-#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
-#include "gc_implementation/g1/g1OopClosures.inline.hpp"
-#include "gc_implementation/g1/g1RemSet.inline.hpp"
-#include "gc_implementation/g1/heapRegionManager.inline.hpp"
-#include "gc_implementation/parNew/parOopClosures.inline.hpp"
-#include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
-#include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
-#endif // INCLUDE_ALL_GCS
 
 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
 
-template <class T>
-void specialized_oop_follow_contents(InstanceRefKlass* ref, oop obj) {
-  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
-  T heap_oop = oopDesc::load_heap_oop(referent_addr);
-  debug_only(
-    if(TraceReferenceGC && PrintGCDetails) {
-      gclog_or_tty->print_cr("InstanceRefKlass::oop_follow_contents " INTPTR_FORMAT, (void *)obj);
-    }
-  )
-  if (!oopDesc::is_null(heap_oop)) {
-    oop referent = oopDesc::decode_heap_oop_not_null(heap_oop);
-    if (!referent->is_gc_marked() &&
-        MarkSweep::ref_processor()->discover_reference(obj, ref->reference_type())) {
-      // reference was discovered, referent will be traversed later
-      ref->InstanceKlass::oop_follow_contents(obj);
-      debug_only(
-        if(TraceReferenceGC && PrintGCDetails) {
-          gclog_or_tty->print_cr("       Non NULL enqueued " INTPTR_FORMAT, (void *)obj);
-        }
-      )
-      return;
-    } else {
-      // treat referent as normal oop
-      debug_only(
-        if(TraceReferenceGC && PrintGCDetails) {
-          gclog_or_tty->print_cr("       Non NULL normal " INTPTR_FORMAT, (void *)obj);
-        }
-      )
-      MarkSweep::mark_and_push(referent_addr);
-    }
-  }
-  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
-  if (ReferenceProcessor::pending_list_uses_discovered_field()) {
-    // Treat discovered as normal oop, if ref is not "active",
-    // i.e. if next is non-NULL.
-    T  next_oop = oopDesc::load_heap_oop(next_addr);
-    if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active"
-      T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
-      debug_only(
-        if(TraceReferenceGC && PrintGCDetails) {
-          gclog_or_tty->print_cr("   Process discovered as normal "
-                                 INTPTR_FORMAT, discovered_addr);
-        }
-      )
-      MarkSweep::mark_and_push(discovered_addr);
-    }
-  } else {
-#ifdef ASSERT
-    // In the case of older JDKs which do not use the discovered
-    // field for the pending list, an inactive ref (next != NULL)
-    // must always have a NULL discovered field.
-    oop next = oopDesc::load_decode_heap_oop(next_addr);
-    oop discovered = java_lang_ref_Reference::discovered(obj);
-    assert(oopDesc::is_null(next) || oopDesc::is_null(discovered),
-           err_msg("Found an inactive reference " PTR_FORMAT " with a non-NULL discovered field",
-                   (oopDesc*)obj));
-#endif
-  }
-  // treat next as normal oop.  next is a link in the reference queue.
-  debug_only(
-    if(TraceReferenceGC && PrintGCDetails) {
-      gclog_or_tty->print_cr("   Process next as normal " INTPTR_FORMAT, next_addr);
-    }
-  )
-  MarkSweep::mark_and_push(next_addr);
-  ref->InstanceKlass::oop_follow_contents(obj);
-}
-
-void InstanceRefKlass::oop_follow_contents(oop obj) {
-  if (UseCompressedOops) {
-    specialized_oop_follow_contents<narrowOop>(this, obj);
-  } else {
-    specialized_oop_follow_contents<oop>(this, obj);
-  }
-}
-
-#if INCLUDE_ALL_GCS
-template <class T>
-void specialized_oop_follow_contents(InstanceRefKlass* ref,
-                                     ParCompactionManager* cm,
-                                     oop obj) {
-  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
-  T heap_oop = oopDesc::load_heap_oop(referent_addr);
-  debug_only(
-    if(TraceReferenceGC && PrintGCDetails) {
-      gclog_or_tty->print_cr("InstanceRefKlass::oop_follow_contents " INTPTR_FORMAT, (void *)obj);
-    }
-  )
-  if (!oopDesc::is_null(heap_oop)) {
-    oop referent = oopDesc::decode_heap_oop_not_null(heap_oop);
-    if (PSParallelCompact::mark_bitmap()->is_unmarked(referent) &&
-        PSParallelCompact::ref_processor()->
-          discover_reference(obj, ref->reference_type())) {
-      // reference already enqueued, referent will be traversed later
-      ref->InstanceKlass::oop_follow_contents(cm, obj);
-      debug_only(
-        if(TraceReferenceGC && PrintGCDetails) {
-          gclog_or_tty->print_cr("       Non NULL enqueued " INTPTR_FORMAT, (void *)obj);
-        }
-      )
-      return;
-    } else {
-      // treat referent as normal oop
-      debug_only(
-        if(TraceReferenceGC && PrintGCDetails) {
-          gclog_or_tty->print_cr("       Non NULL normal " INTPTR_FORMAT, (void *)obj);
-        }
-      )
-      PSParallelCompact::mark_and_push(cm, referent_addr);
-    }
-  }
-  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
-  if (ReferenceProcessor::pending_list_uses_discovered_field()) {
-    // Treat discovered as normal oop, if ref is not "active",
-    // i.e. if next is non-NULL.
-    T  next_oop = oopDesc::load_heap_oop(next_addr);
-    if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active"
-      T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
-      debug_only(
-        if(TraceReferenceGC && PrintGCDetails) {
-          gclog_or_tty->print_cr("   Process discovered as normal "
-                                 INTPTR_FORMAT, discovered_addr);
-        }
-      )
-      PSParallelCompact::mark_and_push(cm, discovered_addr);
-    }
-  } else {
-#ifdef ASSERT
-    // In the case of older JDKs which do not use the discovered
-    // field for the pending list, an inactive ref (next != NULL)
-    // must always have a NULL discovered field.
-    T next = oopDesc::load_heap_oop(next_addr);
-    oop discovered = java_lang_ref_Reference::discovered(obj);
-    assert(oopDesc::is_null(next) || oopDesc::is_null(discovered),
-           err_msg("Found an inactive reference " PTR_FORMAT " with a non-NULL discovered field",
-                   (oopDesc*)obj));
-#endif
-  }
-  PSParallelCompact::mark_and_push(cm, next_addr);
-  ref->InstanceKlass::oop_follow_contents(cm, obj);
-}
-
-void InstanceRefKlass::oop_follow_contents(ParCompactionManager* cm,
-                                           oop obj) {
-  if (UseCompressedOops) {
-    specialized_oop_follow_contents<narrowOop>(this, cm, obj);
-  } else {
-    specialized_oop_follow_contents<oop>(this, cm, obj);
-  }
-}
-#endif // INCLUDE_ALL_GCS
-
-#ifdef ASSERT
-template <class T> void trace_reference_gc(const char *s, oop obj,
-                                           T* referent_addr,
-                                           T* next_addr,
-                                           T* discovered_addr) {
-  if(TraceReferenceGC && PrintGCDetails) {
-    gclog_or_tty->print_cr("%s obj " INTPTR_FORMAT, s, (address)obj);
-    gclog_or_tty->print_cr("     referent_addr/* " INTPTR_FORMAT " / "
-         INTPTR_FORMAT, referent_addr,
-         referent_addr ?
-           (address)oopDesc::load_decode_heap_oop(referent_addr) : NULL);
-    gclog_or_tty->print_cr("     next_addr/* " INTPTR_FORMAT " / "
-         INTPTR_FORMAT, next_addr,
-         next_addr ? (address)oopDesc::load_decode_heap_oop(next_addr) : NULL);
-    gclog_or_tty->print_cr("     discovered_addr/* " INTPTR_FORMAT " / "
-         INTPTR_FORMAT, discovered_addr,
-         discovered_addr ?
-           (address)oopDesc::load_decode_heap_oop(discovered_addr) : NULL);
-  }
-}
-#endif
-
-template <class T> void specialized_oop_adjust_pointers(InstanceRefKlass *ref, oop obj) {
-  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
-  MarkSweep::adjust_pointer(referent_addr);
-  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
-  MarkSweep::adjust_pointer(next_addr);
-  T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
-  MarkSweep::adjust_pointer(discovered_addr);
-  debug_only(trace_reference_gc("InstanceRefKlass::oop_adjust_pointers", obj,
-                                referent_addr, next_addr, discovered_addr);)
-}
-
-int InstanceRefKlass::oop_adjust_pointers(oop obj) {
-  int size = size_helper();
-  InstanceKlass::oop_adjust_pointers(obj);
-
-  if (UseCompressedOops) {
-    specialized_oop_adjust_pointers<narrowOop>(this, obj);
-  } else {
-    specialized_oop_adjust_pointers<oop>(this, obj);
-  }
-  return size;
-}
-
-#define InstanceRefKlass_SPECIALIZED_OOP_ITERATE(T, nv_suffix, contains)        \
-  T* disc_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);             \
-  if (closure->apply_to_weak_ref_discovered_field()) {                          \
-    closure->do_oop##nv_suffix(disc_addr);                                      \
-  }                                                                             \
-                                                                                \
-  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);           \
-  T heap_oop = oopDesc::load_heap_oop(referent_addr);                           \
-  ReferenceProcessor* rp = closure->_ref_processor;                             \
-  if (!oopDesc::is_null(heap_oop)) {                                            \
-    oop referent = oopDesc::decode_heap_oop_not_null(heap_oop);                 \
-    if (!referent->is_gc_marked() && (rp != NULL) &&                            \
-        rp->discover_reference(obj, reference_type())) {                        \
-      return size;                                                              \
-    } else if (contains(referent_addr)) {                                       \
-      /* treat referent as normal oop */                                        \
-      closure->do_oop##nv_suffix(referent_addr);                                \
-    }                                                                           \
-  }                                                                             \
-  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);                   \
-  if (ReferenceProcessor::pending_list_uses_discovered_field()) {               \
-    T next_oop  = oopDesc::load_heap_oop(next_addr);                            \
-    /* Treat discovered as normal oop, if ref is not "active" (next non-NULL) */\
-    if (!oopDesc::is_null(next_oop) && contains(disc_addr)) {                   \
-        /* i.e. ref is not "active" */                                          \
-      debug_only(                                                               \
-        if(TraceReferenceGC && PrintGCDetails) {                                \
-          gclog_or_tty->print_cr("   Process discovered as normal "             \
-                                 INTPTR_FORMAT, disc_addr);                     \
-        }                                                                       \
-      )                                                                         \
-      closure->do_oop##nv_suffix(disc_addr);                                    \
-    }                                                                           \
-  } else {                                                                      \
-    /* In the case of older JDKs which do not use the discovered field for  */  \
-    /* the pending list, an inactive ref (next != NULL) must always have a  */  \
-    /* NULL discovered field. */                                                \
-    debug_only(                                                                 \
-      T next_oop = oopDesc::load_heap_oop(next_addr);                           \
-      T disc_oop = oopDesc::load_heap_oop(disc_addr);                           \
-      assert(oopDesc::is_null(next_oop) || oopDesc::is_null(disc_oop),          \
-           err_msg("Found an inactive reference " PTR_FORMAT " with a non-NULL" \
-                   "discovered field", (oopDesc*)obj));                                   \
-    )                                                                           \
-  }                                                                             \
-  /* treat next as normal oop */                                                \
-  if (contains(next_addr)) {                                                    \
-    closure->do_oop##nv_suffix(next_addr);                                      \
-  }                                                                             \
-  return size;                                                                  \
-
-
-template <class T> bool contains(T *t) { return true; }
-
-// Macro to define InstanceRefKlass::oop_oop_iterate for virtual/nonvirtual for
-// all closures.  Macros calling macros above for each oop size.
-
-#define InstanceRefKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix)        \
-                                                                                \
-int InstanceRefKlass::                                                          \
-oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure) {                  \
-  /* Get size before changing pointers */                                       \
-  int size = InstanceKlass::oop_oop_iterate##nv_suffix(obj, closure);           \
-                                                                                \
-  if (UseCompressedOops) {                                                      \
-    InstanceRefKlass_SPECIALIZED_OOP_ITERATE(narrowOop, nv_suffix, contains);   \
-  } else {                                                                      \
-    InstanceRefKlass_SPECIALIZED_OOP_ITERATE(oop, nv_suffix, contains);         \
-  }                                                                             \
-}
-
-#if INCLUDE_ALL_GCS
-#define InstanceRefKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix) \
-                                                                                \
-int InstanceRefKlass::                                                          \
-oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* closure) {        \
-  /* Get size before changing pointers */                                       \
-  int size = InstanceKlass::oop_oop_iterate_backwards##nv_suffix(obj, closure); \
-                                                                                \
-  if (UseCompressedOops) {                                                      \
-    InstanceRefKlass_SPECIALIZED_OOP_ITERATE(narrowOop, nv_suffix, contains);   \
-  } else {                                                                      \
-    InstanceRefKlass_SPECIALIZED_OOP_ITERATE(oop, nv_suffix, contains);         \
-  }                                                                             \
-}
-#endif // INCLUDE_ALL_GCS
-
-
-#define InstanceRefKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix)      \
-                                                                                \
-int InstanceRefKlass::                                                          \
-oop_oop_iterate##nv_suffix##_m(oop obj,                                         \
-                               OopClosureType* closure,                         \
-                               MemRegion mr) {                                  \
-  int size = InstanceKlass::oop_oop_iterate##nv_suffix##_m(obj, closure, mr);   \
-  if (UseCompressedOops) {                                                      \
-    InstanceRefKlass_SPECIALIZED_OOP_ITERATE(narrowOop, nv_suffix, mr.contains); \
-  } else {                                                                      \
-    InstanceRefKlass_SPECIALIZED_OOP_ITERATE(oop, nv_suffix, mr.contains);      \
-  }                                                                             \
-}
-
-ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceRefKlass_OOP_OOP_ITERATE_DEFN)
-ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceRefKlass_OOP_OOP_ITERATE_DEFN)
-#if INCLUDE_ALL_GCS
-ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceRefKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
-ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceRefKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
-#endif // INCLUDE_ALL_GCS
-ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceRefKlass_OOP_OOP_ITERATE_DEFN_m)
-ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceRefKlass_OOP_OOP_ITERATE_DEFN_m)
-
-#if INCLUDE_ALL_GCS
-template <class T>
-void specialized_oop_push_contents(InstanceRefKlass *ref,
-                                   PSPromotionManager* pm, oop obj) {
-  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
-  if (PSScavenge::should_scavenge(referent_addr)) {
-    ReferenceProcessor* rp = PSScavenge::reference_processor();
-    if (rp->discover_reference(obj, ref->reference_type())) {
-      // reference already enqueued, referent and next will be traversed later
-      ref->InstanceKlass::oop_push_contents(pm, obj);
-      return;
-    } else {
-      // treat referent as normal oop
-      pm->claim_or_forward_depth(referent_addr);
-    }
-  }
-  // Treat discovered as normal oop, if ref is not "active",
-  // i.e. if next is non-NULL.
-  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
-  if (ReferenceProcessor::pending_list_uses_discovered_field()) {
-    T  next_oop = oopDesc::load_heap_oop(next_addr);
-    if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active"
-      T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
-      debug_only(
-        if(TraceReferenceGC && PrintGCDetails) {
-          gclog_or_tty->print_cr("   Process discovered as normal "
-                                 INTPTR_FORMAT, discovered_addr);
-        }
-      )
-      if (PSScavenge::should_scavenge(discovered_addr)) {
-        pm->claim_or_forward_depth(discovered_addr);
-      }
-    }
-  } else {
-#ifdef ASSERT
-    // In the case of older JDKs which do not use the discovered
-    // field for the pending list, an inactive ref (next != NULL)
-    // must always have a NULL discovered field.
-    oop next = oopDesc::load_decode_heap_oop(next_addr);
-    oop discovered = java_lang_ref_Reference::discovered(obj);
-    assert(oopDesc::is_null(next) || oopDesc::is_null(discovered),
-           err_msg("Found an inactive reference " PTR_FORMAT " with a non-NULL discovered field",
-                   (oopDesc*)obj));
-#endif
-  }
-
-  // Treat next as normal oop;  next is a link in the reference queue.
-  if (PSScavenge::should_scavenge(next_addr)) {
-    pm->claim_or_forward_depth(next_addr);
-  }
-  ref->InstanceKlass::oop_push_contents(pm, obj);
-}
-
-void InstanceRefKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
-  if (UseCompressedOops) {
-    specialized_oop_push_contents<narrowOop>(this, pm, obj);
-  } else {
-    specialized_oop_push_contents<oop>(this, pm, obj);
-  }
-}
-
-template <class T>
-void specialized_oop_update_pointers(InstanceRefKlass *ref,
-                                    ParCompactionManager* cm, oop obj) {
-  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
-  PSParallelCompact::adjust_pointer(referent_addr);
-  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
-  PSParallelCompact::adjust_pointer(next_addr);
-  T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
-  PSParallelCompact::adjust_pointer(discovered_addr);
-  debug_only(trace_reference_gc("InstanceRefKlass::oop_update_ptrs", obj,
-                                referent_addr, next_addr, discovered_addr);)
-}
-
-int InstanceRefKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
-  InstanceKlass::oop_update_pointers(cm, obj);
-  if (UseCompressedOops) {
-    specialized_oop_update_pointers<narrowOop>(this, cm, obj);
-  } else {
-    specialized_oop_update_pointers<oop>(this, cm, obj);
-  }
-  return size_helper();
-}
-#endif // INCLUDE_ALL_GCS
-
 void InstanceRefKlass::update_nonstatic_oop_maps(Klass* k) {
   // Clear the nonstatic oop-map entries corresponding to referent
   // and nextPending field.  They are treated specially by the
@@ -483,12 +78,6 @@
   InstanceKlass::oop_verify_on(obj, st);
   // Verify referent field
   oop referent = java_lang_ref_Reference::referent(obj);
-
-  // We should make this general to all heaps
-  GenCollectedHeap* gch = NULL;
-  if (Universe::heap()->kind() == CollectedHeap::GenCollectedHeap)
-    gch = GenCollectedHeap::heap();
-
   if (referent != NULL) {
     guarantee(referent->is_oop(), "referent field heap failed");
   }
--- a/hotspot/src/share/vm/oops/instanceRefKlass.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/oops/instanceRefKlass.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -64,30 +64,71 @@
     return (InstanceRefKlass*) k;
   }
 
-  // Garbage collection
-  int  oop_adjust_pointers(oop obj);
-  void oop_follow_contents(oop obj);
+  // GC specific object visitors
+  //
+  // Mark Sweep
+  void oop_ms_follow_contents(oop obj);
+  int  oop_ms_adjust_pointers(oop obj);
+#if INCLUDE_ALL_GCS
+  // Parallel Scavenge
+  void oop_ps_push_contents(  oop obj, PSPromotionManager* pm);
+  // Parallel Compact
+  void oop_pc_follow_contents(oop obj, ParCompactionManager* cm);
+  void oop_pc_update_pointers(oop obj);
+#endif
 
-  // Parallel Scavenge and Parallel Old
-  PARALLEL_GC_DECLS
+  // Oop fields (and metadata) iterators
+  //  [nv = true]  Use non-virtual calls to do_oop_nv.
+  //  [nv = false] Use virtual calls to do_oop.
+  //
+  // The InstanceRefKlass iterators also support reference processing.
+
+
+  // Forward iteration
+private:
+  // Iterate over all oop fields and metadata.
+  template <bool nv, class OopClosureType>
+  inline int oop_oop_iterate(oop obj, OopClosureType* closure);
 
-  int oop_oop_iterate(oop obj, ExtendedOopClosure* blk) {
-    return oop_oop_iterate_v(obj, blk);
-  }
-  int oop_oop_iterate_m(oop obj, ExtendedOopClosure* blk, MemRegion mr) {
-    return oop_oop_iterate_v_m(obj, blk, mr);
-  }
+  // Reverse iteration
+#if INCLUDE_ALL_GCS
+  // Iterate over all oop fields and metadata.
+  template <bool nv, class OopClosureType>
+  inline int oop_oop_iterate_reverse(oop obj, OopClosureType* closure);
+#endif // INCLUDE_ALL_GCS
+
+  // Bounded range iteration
+  // Iterate over all oop fields and metadata.
+  template <bool nv, class OopClosureType>
+  inline int oop_oop_iterate_bounded(oop obj, OopClosureType* closure, MemRegion mr);
+
+  // Reference processing part of the iterators.
 
-#define InstanceRefKlass_OOP_OOP_ITERATE_DECL(OopClosureType, nv_suffix)                \
-  int oop_oop_iterate##nv_suffix(oop obj, OopClosureType* blk);                         \
-  int oop_oop_iterate##nv_suffix##_m(oop obj, OopClosureType* blk, MemRegion mr);
+  // Specialized for [T = oop] or [T = narrowOop].
+  template <bool nv, typename T, class OopClosureType, class Contains>
+  inline void oop_oop_iterate_ref_processing_specialized(oop obj, OopClosureType* closure, Contains& contains);
+
+  // Only perform reference processing if the referent object is within mr.
+  template <bool nv, class OopClosureType>
+  inline void oop_oop_iterate_ref_processing_bounded(oop obj, OopClosureType* closure, MemRegion mr);
+
+  // Reference processing
+  template <bool nv, class OopClosureType>
+  inline void oop_oop_iterate_ref_processing(oop obj, OopClosureType* closure);
+
+
+ public:
+
+#define InstanceRefKlass_OOP_OOP_ITERATE_DECL(OopClosureType, nv_suffix)               \
+  int oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure);                    \
+  int oop_oop_iterate##nv_suffix##_m(oop obj, OopClosureType* closure, MemRegion mr);
 
   ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceRefKlass_OOP_OOP_ITERATE_DECL)
   ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceRefKlass_OOP_OOP_ITERATE_DECL)
 
 #if INCLUDE_ALL_GCS
-#define InstanceRefKlass_OOP_OOP_ITERATE_BACKWARDS_DECL(OopClosureType, nv_suffix)      \
-  int oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* blk);
+#define InstanceRefKlass_OOP_OOP_ITERATE_BACKWARDS_DECL(OopClosureType, nv_suffix)     \
+  int oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* closure);
 
   ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceRefKlass_OOP_OOP_ITERATE_BACKWARDS_DECL)
   ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceRefKlass_OOP_OOP_ITERATE_BACKWARDS_DECL)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/oops/instanceRefKlass.inline.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_OOPS_INSTANCEREFKLASS_INLINE_HPP
+#define SHARE_VM_OOPS_INSTANCEREFKLASS_INLINE_HPP
+
+#include "classfile/javaClasses.hpp"
+#include "memory/referenceProcessor.hpp"
+#include "oops/instanceRefKlass.hpp"
+#include "oops/instanceKlass.inline.hpp"
+#include "oops/oop.inline.hpp"
+#include "utilities/debug.hpp"
+#include "utilities/globalDefinitions.hpp"
+#include "utilities/macros.hpp"
+
+template <bool nv, typename T, class OopClosureType, class Contains>
+void InstanceRefKlass::oop_oop_iterate_ref_processing_specialized(oop obj, OopClosureType* closure, Contains& contains) {
+  T* disc_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
+  if (closure->apply_to_weak_ref_discovered_field()) {
+    Devirtualizer<nv>::do_oop(closure, disc_addr);
+  }
+
+  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
+  T heap_oop = oopDesc::load_heap_oop(referent_addr);
+  ReferenceProcessor* rp = closure->_ref_processor;
+  if (!oopDesc::is_null(heap_oop)) {
+    oop referent = oopDesc::decode_heap_oop_not_null(heap_oop);
+    if (!referent->is_gc_marked() && (rp != NULL) &&
+        rp->discover_reference(obj, reference_type())) {
+      return;
+    } else if (contains(referent_addr)) {
+      // treat referent as normal oop
+      Devirtualizer<nv>::do_oop(closure, referent_addr);
+    }
+  }
+  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
+  if (ReferenceProcessor::pending_list_uses_discovered_field()) {
+    T next_oop  = oopDesc::load_heap_oop(next_addr);
+    // Treat discovered as normal oop, if ref is not "active" (next non-NULL)
+    if (!oopDesc::is_null(next_oop) && contains(disc_addr)) {
+      // i.e. ref is not "active"
+      debug_only(
+        if(TraceReferenceGC && PrintGCDetails) {
+          gclog_or_tty->print_cr("   Process discovered as normal "
+                                 PTR_FORMAT, p2i(disc_addr));
+        }
+      )
+      Devirtualizer<nv>::do_oop(closure, disc_addr);
+    }
+  } else {
+    // In the case of older JDKs which do not use the discovered field for
+    // the pending list, an inactive ref (next != NULL) must always have a
+    // NULL discovered field.
+    debug_only(
+      T next_oop = oopDesc::load_heap_oop(next_addr);
+      T disc_oop = oopDesc::load_heap_oop(disc_addr);
+      assert(oopDesc::is_null(next_oop) || oopDesc::is_null(disc_oop),
+           err_msg("Found an inactive reference " PTR_FORMAT " with a non-NULL"
+                   "discovered field", p2i(obj)));
+    )
+  }
+  // treat next as normal oop
+  if (contains(next_addr)) {
+    Devirtualizer<nv>::do_oop(closure, next_addr);
+  }
+}
+
+class AlwaysContains {
+ public:
+  template <typename T> bool operator()(T* p) const { return true; }
+};
+
+template <bool nv, class OopClosureType>
+void InstanceRefKlass::oop_oop_iterate_ref_processing(oop obj, OopClosureType* closure) {
+  AlwaysContains always_contains;
+  if (UseCompressedOops) {
+    oop_oop_iterate_ref_processing_specialized<nv, narrowOop>(obj, closure, always_contains);
+  } else {
+    oop_oop_iterate_ref_processing_specialized<nv, oop>(obj, closure, always_contains);
+  }
+}
+
+class MrContains {
+  const MemRegion _mr;
+ public:
+  MrContains(MemRegion mr) : _mr(mr) {}
+  template <typename T> bool operator()(T* p) const { return _mr.contains(p); }
+};
+
+template <bool nv, class OopClosureType>
+void InstanceRefKlass::oop_oop_iterate_ref_processing_bounded(oop obj, OopClosureType* closure, MemRegion mr) {
+  const MrContains contains(mr);
+  if (UseCompressedOops) {
+    oop_oop_iterate_ref_processing_specialized<nv, narrowOop>(obj, closure, contains);
+  } else {
+    oop_oop_iterate_ref_processing_specialized<nv, oop>(obj, closure, contains);
+  }
+}
+
+template <bool nv, class OopClosureType>
+int InstanceRefKlass::oop_oop_iterate(oop obj, OopClosureType* closure) {
+  // Get size before changing pointers
+  int size = InstanceKlass::oop_oop_iterate<nv>(obj, closure);
+
+  oop_oop_iterate_ref_processing<nv>(obj, closure);
+
+  return size;
+}
+
+#if INCLUDE_ALL_GCS
+template <bool nv, class OopClosureType>
+int InstanceRefKlass::
+oop_oop_iterate_reverse(oop obj, OopClosureType* closure) {
+  // Get size before changing pointers
+  int size = InstanceKlass::oop_oop_iterate_reverse<nv>(obj, closure);
+
+  oop_oop_iterate_ref_processing<nv>(obj, closure);
+
+  return size;
+}
+#endif // INCLUDE_ALL_GCS
+
+
+template <bool nv, class OopClosureType>
+int InstanceRefKlass::oop_oop_iterate_bounded(oop obj, OopClosureType* closure, MemRegion mr) {
+  // Get size before changing pointers
+  int size = InstanceKlass::oop_oop_iterate_bounded<nv>(obj, closure, mr);
+
+  oop_oop_iterate_ref_processing_bounded<nv>(obj, closure, mr);
+
+  return size;
+}
+
+// Macro to define InstanceRefKlass::oop_oop_iterate for virtual/nonvirtual for
+// all closures.  Macros calling macros above for each oop size.
+
+#define InstanceRefKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix)              \
+                                                                                      \
+int InstanceRefKlass::oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure) {  \
+  return oop_oop_iterate<nvs_to_bool(nv_suffix)>(obj, closure);                       \
+}
+
+#if INCLUDE_ALL_GCS
+#define InstanceRefKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix)              \
+                                                                                                \
+int InstanceRefKlass::oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* closure) {  \
+  return oop_oop_iterate_reverse<nvs_to_bool(nv_suffix)>(obj, closure);                         \
+}
+#else
+#define InstanceRefKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix)
+#endif
+
+
+#define InstanceRefKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix)                              \
+                                                                                                        \
+int InstanceRefKlass::oop_oop_iterate##nv_suffix##_m(oop obj, OopClosureType* closure, MemRegion mr) {  \
+  return oop_oop_iterate_bounded<nvs_to_bool(nv_suffix)>(obj, closure, mr);                             \
+}
+
+#define ALL_INSTANCE_REF_KLASS_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix)  \
+  InstanceRefKlass_OOP_OOP_ITERATE_DEFN(          OopClosureType, nv_suffix)    \
+  InstanceRefKlass_OOP_OOP_ITERATE_DEFN_m(        OopClosureType, nv_suffix)    \
+  InstanceRefKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix)
+
+
+#endif // SHARE_VM_OOPS_INSTANCEREFKLASS_INLINE_HPP
--- a/hotspot/src/share/vm/oops/klass.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/oops/klass.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -27,7 +27,6 @@
 #include "classfile/dictionary.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
-#include "gc_implementation/shared/markSweep.inline.hpp"
 #include "gc_interface/collectedHeap.inline.hpp"
 #include "memory/heapInspection.hpp"
 #include "memory/metadataFactory.hpp"
@@ -43,9 +42,6 @@
 #include "utilities/stack.inline.hpp"
 #if INCLUDE_ALL_GCS
 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
-#include "gc_implementation/parallelScavenge/psParallelCompact.hpp"
-#include "gc_implementation/parallelScavenge/psPromotionManager.hpp"
-#include "gc_implementation/parallelScavenge/psScavenge.hpp"
 #endif // INCLUDE_ALL_GCS
 
 void Klass::set_name(Symbol* n) {
--- a/hotspot/src/share/vm/oops/klass.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/oops/klass.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -25,21 +25,14 @@
 #ifndef SHARE_VM_OOPS_KLASS_HPP
 #define SHARE_VM_OOPS_KLASS_HPP
 
-#include "memory/genOopClosures.hpp"
 #include "memory/iterator.hpp"
 #include "memory/memRegion.hpp"
 #include "memory/specialized_oop_closures.hpp"
-#include "oops/klassPS.hpp"
 #include "oops/metadata.hpp"
 #include "oops/oop.hpp"
 #include "trace/traceMacros.hpp"
 #include "utilities/accessFlags.hpp"
 #include "utilities/macros.hpp"
-#if INCLUDE_ALL_GCS
-#include "gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp"
-#include "gc_implementation/g1/g1OopClosures.hpp"
-#include "gc_implementation/parNew/parOopClosures.hpp"
-#endif // INCLUDE_ALL_GCS
 
 //
 // A Klass provides:
@@ -61,6 +54,7 @@
 class ClassLoaderData;
 class klassVtable;
 class ParCompactionManager;
+class PSPromotionManager;
 class KlassSizeStats;
 class fieldDescriptor;
 
@@ -478,13 +472,6 @@
   //     and the package separators as '/'.
   virtual const char* signature_name() const;
 
-  // garbage collection support
-  virtual void oop_follow_contents(oop obj) = 0;
-  virtual int  oop_adjust_pointers(oop obj) = 0;
-
-  // Parallel Scavenge and Parallel Old
-  PARALLEL_GC_DECLS_PV
-
   // type testing operations
  protected:
   virtual bool oop_is_instance_slow()       const { return false; }
@@ -581,60 +568,35 @@
     clean_weak_klass_links(is_alive, false /* clean_alive_klasses */);
   }
 
-  // iterators
-  virtual int oop_oop_iterate(oop obj, ExtendedOopClosure* blk) = 0;
-  virtual int oop_oop_iterate_v(oop obj, ExtendedOopClosure* blk) {
-    return oop_oop_iterate(obj, blk);
-  }
+  // GC specific object visitors
+  //
+  // Mark Sweep
+  virtual void oop_ms_follow_contents(oop obj) = 0;
+  virtual int  oop_ms_adjust_pointers(oop obj) = 0;
+#if INCLUDE_ALL_GCS
+  // Parallel Scavenge
+  virtual void oop_ps_push_contents(  oop obj, PSPromotionManager* pm)   = 0;
+  // Parallel Compact
+  virtual void oop_pc_follow_contents(oop obj, ParCompactionManager* cm) = 0;
+  virtual void oop_pc_update_pointers(oop obj) = 0;
+#endif
+
+  // Iterators specialized to particular subtypes
+  // of ExtendedOopClosure, to avoid closure virtual calls.
+#define Klass_OOP_OOP_ITERATE_DECL(OopClosureType, nv_suffix)                                      \
+  virtual int oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure) = 0;                    \
+  /* Iterates "closure" over all the oops in "obj" (of type "this") within "mr". */                \
+  virtual int oop_oop_iterate##nv_suffix##_m(oop obj, OopClosureType* closure, MemRegion mr) = 0;
+
+  ALL_OOP_OOP_ITERATE_CLOSURES_1(Klass_OOP_OOP_ITERATE_DECL)
+  ALL_OOP_OOP_ITERATE_CLOSURES_2(Klass_OOP_OOP_ITERATE_DECL)
 
 #if INCLUDE_ALL_GCS
-  // In case we don't have a specialized backward scanner use forward
-  // iteration.
-  virtual int oop_oop_iterate_backwards_v(oop obj, ExtendedOopClosure* blk) {
-    return oop_oop_iterate_v(obj, blk);
-  }
-#endif // INCLUDE_ALL_GCS
-
-  // Iterates "blk" over all the oops in "obj" (of type "this") within "mr".
-  // (I don't see why the _m should be required, but without it the Solaris
-  // C++ gives warning messages about overridings of the "oop_oop_iterate"
-  // defined above "hiding" this virtual function.  (DLD, 6/20/00)) */
-  virtual int oop_oop_iterate_m(oop obj, ExtendedOopClosure* blk, MemRegion mr) = 0;
-  virtual int oop_oop_iterate_v_m(oop obj, ExtendedOopClosure* blk, MemRegion mr) {
-    return oop_oop_iterate_m(obj, blk, mr);
-  }
+#define Klass_OOP_OOP_ITERATE_BACKWARDS_DECL(OopClosureType, nv_suffix)                    \
+  virtual int oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* closure) = 0;
 
-  // Versions of the above iterators specialized to particular subtypes
-  // of OopClosure, to avoid closure virtual calls.
-#define Klass_OOP_OOP_ITERATE_DECL(OopClosureType, nv_suffix)                \
-  virtual int oop_oop_iterate##nv_suffix(oop obj, OopClosureType* blk) {     \
-    /* Default implementation reverts to general version. */                 \
-    return oop_oop_iterate(obj, blk);                                        \
-  }                                                                          \
-                                                                             \
-  /* Iterates "blk" over all the oops in "obj" (of type "this") within "mr". \
-     (I don't see why the _m should be required, but without it the Solaris  \
-     C++ gives warning messages about overridings of the "oop_oop_iterate"   \
-     defined above "hiding" this virtual function.  (DLD, 6/20/00)) */       \
-  virtual int oop_oop_iterate##nv_suffix##_m(oop obj,                        \
-                                             OopClosureType* blk,            \
-                                             MemRegion mr) {                 \
-    return oop_oop_iterate_m(obj, blk, mr);                                  \
-  }
-
-  SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_1(Klass_OOP_OOP_ITERATE_DECL)
-  SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_2(Klass_OOP_OOP_ITERATE_DECL)
-
-#if INCLUDE_ALL_GCS
-#define Klass_OOP_OOP_ITERATE_BACKWARDS_DECL(OopClosureType, nv_suffix)      \
-  virtual int oop_oop_iterate_backwards##nv_suffix(oop obj,                  \
-                                                   OopClosureType* blk) {    \
-    /* Default implementation reverts to general version. */                 \
-    return oop_oop_iterate_backwards_v(obj, blk);                            \
-  }
-
-  SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_1(Klass_OOP_OOP_ITERATE_BACKWARDS_DECL)
-  SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_2(Klass_OOP_OOP_ITERATE_BACKWARDS_DECL)
+  ALL_OOP_OOP_ITERATE_CLOSURES_1(Klass_OOP_OOP_ITERATE_BACKWARDS_DECL)
+  ALL_OOP_OOP_ITERATE_CLOSURES_2(Klass_OOP_OOP_ITERATE_BACKWARDS_DECL)
 #endif // INCLUDE_ALL_GCS
 
   virtual void array_klasses_do(void f(Klass* k)) {}
--- a/hotspot/src/share/vm/oops/klassPS.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2007, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_OOPS_KLASSPS_HPP
-#define SHARE_VM_OOPS_KLASSPS_HPP
-
-  // Expands to Parallel Scavenge and Parallel Old declarations
-
-#include "utilities/macros.hpp"
-
-#if INCLUDE_ALL_GCS
-#define PARALLEL_GC_DECLS \
-  virtual void oop_push_contents(PSPromotionManager* pm, oop obj);          \
-  /* Parallel Old GC support                                                \
-                                                                            \
-   The 2-arg version of oop_update_pointers is for objects that are         \
-   known not to cross chunk boundaries.  The 4-arg version is for           \
-   objects that do (or may) cross chunk boundaries; it updates only those   \
-   oops that are in the region [beg_addr, end_addr).  */                    \
-  virtual void oop_follow_contents(ParCompactionManager* cm, oop obj);      \
-  virtual int  oop_update_pointers(ParCompactionManager* cm, oop obj);
-
-// Pure virtual version for klass.hpp
-#define PARALLEL_GC_DECLS_PV \
-  virtual void oop_push_contents(PSPromotionManager* pm, oop obj) = 0;      \
-  virtual void oop_follow_contents(ParCompactionManager* cm, oop obj) = 0;  \
-  virtual int  oop_update_pointers(ParCompactionManager* cm, oop obj) = 0;
-#else  // INCLUDE_ALL_GCS
-#define PARALLEL_GC_DECLS
-#define PARALLEL_GC_DECLS_PV
-#endif // INCLUDE_ALL_GCS
-
-#endif // SHARE_VM_OOPS_KLASSPS_HPP
--- a/hotspot/src/share/vm/oops/objArrayKlass.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/oops/objArrayKlass.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -26,9 +26,7 @@
 #include "classfile/symbolTable.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
-#include "gc_implementation/shared/markSweep.inline.hpp"
 #include "gc_interface/collectedHeap.inline.hpp"
-#include "memory/genOopClosures.inline.hpp"
 #include "memory/iterator.inline.hpp"
 #include "memory/metadataFactory.hpp"
 #include "memory/resourceArea.hpp"
@@ -45,17 +43,6 @@
 #include "runtime/orderAccess.inline.hpp"
 #include "utilities/copy.hpp"
 #include "utilities/macros.hpp"
-#if INCLUDE_ALL_GCS
-#include "gc_implementation/concurrentMarkSweep/cmsOopClosures.inline.hpp"
-#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
-#include "gc_implementation/g1/g1OopClosures.inline.hpp"
-#include "gc_implementation/g1/g1RemSet.inline.hpp"
-#include "gc_implementation/g1/heapRegionManager.inline.hpp"
-#include "gc_implementation/parNew/parOopClosures.inline.hpp"
-#include "gc_implementation/parallelScavenge/psCompactionManager.hpp"
-#include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
-#include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
-#endif // INCLUDE_ALL_GCS
 
 ObjArrayKlass* ObjArrayKlass::allocate(ClassLoaderData* loader_data, int n, KlassHandle klass_handle, Symbol* name, TRAPS) {
   assert(ObjArrayKlass::header_size() <= InstanceKlass::header_size(),
@@ -410,179 +397,6 @@
   bottom_klass()->initialize(THREAD);  // dispatches to either InstanceKlass or TypeArrayKlass
 }
 
-#define ObjArrayKlass_SPECIALIZED_OOP_ITERATE(T, a, p, do_oop) \
-{                                   \
-  T* p         = (T*)(a)->base();   \
-  T* const end = p + (a)->length(); \
-  while (p < end) {                 \
-    do_oop;                         \
-    p++;                            \
-  }                                 \
-}
-
-#define ObjArrayKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(T, a, p, low, high, do_oop) \
-{                                   \
-  T* const l = (T*)(low);           \
-  T* const h = (T*)(high);          \
-  T* p       = (T*)(a)->base();     \
-  T* end     = p + (a)->length();   \
-  if (p < l) p = l;                 \
-  if (end > h) end = h;             \
-  while (p < end) {                 \
-    do_oop;                         \
-    ++p;                            \
-  }                                 \
-}
-
-#define ObjArrayKlass_OOP_ITERATE(a, p, do_oop)      \
-  if (UseCompressedOops) {                           \
-    ObjArrayKlass_SPECIALIZED_OOP_ITERATE(narrowOop, \
-      a, p, do_oop)                                  \
-  } else {                                           \
-    ObjArrayKlass_SPECIALIZED_OOP_ITERATE(oop,       \
-      a, p, do_oop)                                  \
-  }
-
-#define ObjArrayKlass_BOUNDED_OOP_ITERATE(a, p, low, high, do_oop) \
-  if (UseCompressedOops) {                                   \
-    ObjArrayKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(narrowOop, \
-      a, p, low, high, do_oop)                               \
-  } else {                                                   \
-    ObjArrayKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(oop,       \
-      a, p, low, high, do_oop)                               \
-  }
-
-void ObjArrayKlass::oop_follow_contents(oop obj) {
-  assert (obj->is_array(), "obj must be array");
-  MarkSweep::follow_klass(obj->klass());
-  if (UseCompressedOops) {
-    objarray_follow_contents<narrowOop>(obj, 0);
-  } else {
-    objarray_follow_contents<oop>(obj, 0);
-  }
-}
-
-#if INCLUDE_ALL_GCS
-void ObjArrayKlass::oop_follow_contents(ParCompactionManager* cm,
-                                        oop obj) {
-  assert(obj->is_array(), "obj must be array");
-  PSParallelCompact::follow_klass(cm, obj->klass());
-  if (UseCompressedOops) {
-    objarray_follow_contents<narrowOop>(cm, obj, 0);
-  } else {
-    objarray_follow_contents<oop>(cm, obj, 0);
-  }
-}
-#endif // INCLUDE_ALL_GCS
-
-#define ObjArrayKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix)           \
-                                                                                \
-int ObjArrayKlass::oop_oop_iterate##nv_suffix(oop obj,                          \
-                                              OopClosureType* closure) {        \
-  assert (obj->is_array(), "obj must be array");                                \
-  objArrayOop a = objArrayOop(obj);                                             \
-  /* Get size before changing pointers. */                                      \
-  /* Don't call size() or oop_size() since that is a virtual call. */           \
-  int size = a->object_size();                                                  \
-  if_do_metadata_checked(closure, nv_suffix) {                                  \
-    closure->do_klass##nv_suffix(obj->klass());                                 \
-  }                                                                             \
-  ObjArrayKlass_OOP_ITERATE(a, p, (closure)->do_oop##nv_suffix(p))              \
-  return size;                                                                  \
-}
-
-#define ObjArrayKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix)         \
-                                                                                \
-int ObjArrayKlass::oop_oop_iterate##nv_suffix##_m(oop obj,                      \
-                                                  OopClosureType* closure,      \
-                                                  MemRegion mr) {               \
-  assert(obj->is_array(), "obj must be array");                                 \
-  objArrayOop a  = objArrayOop(obj);                                            \
-  /* Get size before changing pointers. */                                      \
-  /* Don't call size() or oop_size() since that is a virtual call */            \
-  int size = a->object_size();                                                  \
-  if_do_metadata_checked(closure, nv_suffix) {                                  \
-    /* SSS: Do we need to pass down mr here? */                                 \
-    closure->do_klass##nv_suffix(a->klass());                                   \
-  }                                                                             \
-  ObjArrayKlass_BOUNDED_OOP_ITERATE(                                            \
-    a, p, mr.start(), mr.end(), (closure)->do_oop##nv_suffix(p))                \
-  return size;                                                                  \
-}
-
-// Like oop_oop_iterate but only iterates over a specified range and only used
-// for objArrayOops.
-#define ObjArrayKlass_OOP_OOP_ITERATE_DEFN_r(OopClosureType, nv_suffix)         \
-                                                                                \
-int ObjArrayKlass::oop_oop_iterate_range##nv_suffix(oop obj,                    \
-                                                  OopClosureType* closure,      \
-                                                  int start, int end) {         \
-  assert(obj->is_array(), "obj must be array");                                 \
-  objArrayOop a  = objArrayOop(obj);                                            \
-  /* Get size before changing pointers. */                                      \
-  /* Don't call size() or oop_size() since that is a virtual call */            \
-  int size = a->object_size();                                                  \
-  if (UseCompressedOops) {                                                      \
-    HeapWord* low = start == 0 ? (HeapWord*)a : (HeapWord*)a->obj_at_addr<narrowOop>(start);\
-    /* this might be wierd if end needs to be aligned on HeapWord boundary */   \
-    HeapWord* high = (HeapWord*)((narrowOop*)a->base() + end);                  \
-    MemRegion mr(low, high);                                                    \
-    if_do_metadata_checked(closure, nv_suffix) {                                \
-      /* SSS: Do we need to pass down mr here? */                               \
-      closure->do_klass##nv_suffix(a->klass());                                 \
-    }                                                                           \
-    ObjArrayKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(narrowOop,                    \
-      a, p, low, high, (closure)->do_oop##nv_suffix(p))                         \
-  } else {                                                                      \
-    HeapWord* low = start == 0 ? (HeapWord*)a : (HeapWord*)a->obj_at_addr<oop>(start);  \
-    HeapWord* high = (HeapWord*)((oop*)a->base() + end);                        \
-    MemRegion mr(low, high);                                                    \
-    if_do_metadata_checked(closure, nv_suffix) {                                \
-      /* SSS: Do we need to pass down mr here? */                               \
-      closure->do_klass##nv_suffix(a->klass());                                 \
-    }                                                                           \
-    ObjArrayKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(oop,                          \
-      a, p, low, high, (closure)->do_oop##nv_suffix(p))                         \
-  }                                                                             \
-  return size;                                                                  \
-}
-
-ALL_OOP_OOP_ITERATE_CLOSURES_1(ObjArrayKlass_OOP_OOP_ITERATE_DEFN)
-ALL_OOP_OOP_ITERATE_CLOSURES_2(ObjArrayKlass_OOP_OOP_ITERATE_DEFN)
-ALL_OOP_OOP_ITERATE_CLOSURES_1(ObjArrayKlass_OOP_OOP_ITERATE_DEFN_m)
-ALL_OOP_OOP_ITERATE_CLOSURES_2(ObjArrayKlass_OOP_OOP_ITERATE_DEFN_m)
-ALL_OOP_OOP_ITERATE_CLOSURES_1(ObjArrayKlass_OOP_OOP_ITERATE_DEFN_r)
-ALL_OOP_OOP_ITERATE_CLOSURES_2(ObjArrayKlass_OOP_OOP_ITERATE_DEFN_r)
-
-int ObjArrayKlass::oop_adjust_pointers(oop obj) {
-  assert(obj->is_objArray(), "obj must be obj array");
-  objArrayOop a = objArrayOop(obj);
-  // Get size before changing pointers.
-  // Don't call size() or oop_size() since that is a virtual call.
-  int size = a->object_size();
-  ObjArrayKlass_OOP_ITERATE(a, p, MarkSweep::adjust_pointer(p))
-  return size;
-}
-
-#if INCLUDE_ALL_GCS
-void ObjArrayKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
-  assert(obj->is_objArray(), "obj must be obj array");
-  ObjArrayKlass_OOP_ITERATE( \
-    objArrayOop(obj), p, \
-    if (PSScavenge::should_scavenge(p)) { \
-      pm->claim_or_forward_depth(p); \
-    })
-}
-
-int ObjArrayKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
-  assert (obj->is_objArray(), "obj must be obj array");
-  objArrayOop a = objArrayOop(obj);
-  int size = a->object_size();
-  ObjArrayKlass_OOP_ITERATE(a, p, PSParallelCompact::adjust_pointer(p))
-  return size;
-}
-#endif // INCLUDE_ALL_GCS
-
 // JVM support
 
 jint ObjArrayKlass::compute_modifier_flags(TRAPS) const {
--- a/hotspot/src/share/vm/oops/objArrayKlass.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/oops/objArrayKlass.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -26,7 +26,6 @@
 #define SHARE_VM_OOPS_OBJARRAYKLASS_HPP
 
 #include "classfile/classLoaderData.hpp"
-#include "memory/specialized_oop_closures.hpp"
 #include "oops/arrayKlass.hpp"
 #include "utilities/macros.hpp"
 
@@ -103,28 +102,67 @@
   // Initialization (virtual from Klass)
   void initialize(TRAPS);
 
-  // Garbage collection
-  void oop_follow_contents(oop obj);
-  inline void oop_follow_contents(oop obj, int index);
-  template <class T> inline void objarray_follow_contents(oop obj, int index);
-
-  int  oop_adjust_pointers(oop obj);
-
-  // Parallel Scavenge and Parallel Old
-  PARALLEL_GC_DECLS
+  // GC specific object visitors
+  //
+  // Mark Sweep
+  void oop_ms_follow_contents(oop obj);
+  int  oop_ms_adjust_pointers(oop obj);
 #if INCLUDE_ALL_GCS
-  inline void oop_follow_contents(ParCompactionManager* cm, oop obj, int index);
-  template <class T> inline void
-    objarray_follow_contents(ParCompactionManager* cm, oop obj, int index);
-#endif // INCLUDE_ALL_GCS
+  // Parallel Scavenge
+  void oop_ps_push_contents(  oop obj, PSPromotionManager* pm);
+  // Parallel Compact
+  void oop_pc_follow_contents(oop obj, ParCompactionManager* cm);
+  void oop_pc_update_pointers(oop obj);
+#endif
+
+  // Oop fields (and metadata) iterators
+  //  [nv = true]  Use non-virtual calls to do_oop_nv.
+  //  [nv = false] Use virtual calls to do_oop.
+  //
+  // The ObjArrayKlass iterators also visits the Object's klass.
+
+ private:
+
+  // Iterate over oop elements and metadata.
+  template <bool nv, typename OopClosureType>
+  inline int oop_oop_iterate(oop obj, OopClosureType* closure);
+
+  // Iterate over oop elements within mr, and metadata.
+  template <bool nv, typename OopClosureType>
+  inline int oop_oop_iterate_bounded(oop obj, OopClosureType* closure, MemRegion mr);
+
+  // Iterate over oop elements with indices within [start, end), and metadata.
+  template <bool nv, class OopClosureType>
+  inline int oop_oop_iterate_range(oop obj, OopClosureType* closure, int start, int end);
 
-  // Iterators
-  int oop_oop_iterate(oop obj, ExtendedOopClosure* blk) {
-    return oop_oop_iterate_v(obj, blk);
-  }
-  int oop_oop_iterate_m(oop obj, ExtendedOopClosure* blk, MemRegion mr) {
-    return oop_oop_iterate_v_m(obj, blk, mr);
-  }
+  // Iterate over oop elements within [start, end), and metadata.
+  // Specialized for [T = oop] or [T = narrowOop].
+  template <bool nv, typename T, class OopClosureType>
+  inline void oop_oop_iterate_range_specialized(objArrayOop a, OopClosureType* closure, int start, int end);
+
+ public:
+  // Iterate over all oop elements.
+  template <bool nv, class OopClosureType>
+  inline void oop_oop_iterate_elements(objArrayOop a, OopClosureType* closure);
+
+ private:
+  // Iterate over all oop elements.
+  // Specialized for [T = oop] or [T = narrowOop].
+  template <bool nv, typename T, class OopClosureType>
+  inline void oop_oop_iterate_elements_specialized(objArrayOop a, OopClosureType* closure);
+
+  // Iterate over all oop elements with indices within mr.
+  template <bool nv, class OopClosureType>
+  inline void oop_oop_iterate_elements_bounded(objArrayOop a, OopClosureType* closure, MemRegion mr);
+
+  // Iterate over oop elements within [low, high)..
+  // Specialized for [T = oop] or [T = narrowOop].
+  template <bool nv, typename T, class OopClosureType>
+  inline void oop_oop_iterate_elements_specialized_bounded(objArrayOop a, OopClosureType* closure, void* low, void* high);
+
+
+ public:
+
 #define ObjArrayKlass_OOP_OOP_ITERATE_DECL(OopClosureType, nv_suffix)   \
   int oop_oop_iterate##nv_suffix(oop obj, OopClosureType* blk);         \
   int oop_oop_iterate##nv_suffix##_m(oop obj, OopClosureType* blk,      \
@@ -135,6 +173,14 @@
   ALL_OOP_OOP_ITERATE_CLOSURES_1(ObjArrayKlass_OOP_OOP_ITERATE_DECL)
   ALL_OOP_OOP_ITERATE_CLOSURES_2(ObjArrayKlass_OOP_OOP_ITERATE_DECL)
 
+#if INCLUDE_ALL_GCS
+#define ObjArrayKlass_OOP_OOP_ITERATE_BACKWARDS_DECL(OopClosureType, nv_suffix) \
+  int  oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* blk);
+
+  ALL_OOP_OOP_ITERATE_CLOSURES_1(ObjArrayKlass_OOP_OOP_ITERATE_BACKWARDS_DECL)
+  ALL_OOP_OOP_ITERATE_CLOSURES_2(ObjArrayKlass_OOP_OOP_ITERATE_BACKWARDS_DECL)
+#endif // INCLUDE_ALL_GCS
+
   // JVM support
   jint compute_modifier_flags(TRAPS) const;
 
--- a/hotspot/src/share/vm/oops/objArrayKlass.inline.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/oops/objArrayKlass.inline.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2015, 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
@@ -25,78 +25,165 @@
 #ifndef SHARE_VM_OOPS_OBJARRAYKLASS_INLINE_HPP
 #define SHARE_VM_OOPS_OBJARRAYKLASS_INLINE_HPP
 
-#include "gc_implementation/shared/markSweep.inline.hpp"
+#include "memory/memRegion.hpp"
+#include "memory/iterator.inline.hpp"
 #include "oops/objArrayKlass.hpp"
+#include "oops/objArrayOop.inline.hpp"
+#include "oops/oop.inline.hpp"
 #include "utilities/macros.hpp"
-#if INCLUDE_ALL_GCS
-#include "gc_implementation/parallelScavenge/psCompactionManager.inline.hpp"
-#include "gc_implementation/parallelScavenge/psParallelCompact.hpp"
-#endif // INCLUDE_ALL_GCS
+
+template <bool nv, typename T, class OopClosureType>
+void ObjArrayKlass::oop_oop_iterate_elements_specialized(objArrayOop a, OopClosureType* closure) {
+  T* p         = (T*)a->base();
+  T* const end = p + a->length();
+
+  for (;p < end; p++) {
+    Devirtualizer<nv>::do_oop(closure, p);
+  }
+}
+
+template <bool nv, typename T, class OopClosureType>
+void ObjArrayKlass::oop_oop_iterate_elements_specialized_bounded(
+    objArrayOop a, OopClosureType* closure, void* low, void* high) {
+
+  T* const l = (T*)low;
+  T* const h = (T*)high;
+
+  T* p   = (T*)a->base();
+  T* end = p + a->length();
 
-void ObjArrayKlass::oop_follow_contents(oop obj, int index) {
+  if (p < l) {
+    p = l;
+  }
+  if (end > h) {
+    end = h;
+  }
+
+  for (;p < end; ++p) {
+    Devirtualizer<nv>::do_oop(closure, p);
+  }
+}
+
+template <bool nv, class OopClosureType>
+void ObjArrayKlass::oop_oop_iterate_elements(objArrayOop a, OopClosureType* closure) {
   if (UseCompressedOops) {
-    objarray_follow_contents<narrowOop>(obj, index);
+    oop_oop_iterate_elements_specialized<nv, narrowOop>(a, closure);
   } else {
-    objarray_follow_contents<oop>(obj, index);
+    oop_oop_iterate_elements_specialized<nv, oop>(a, closure);
+  }
+}
+
+template <bool nv, class OopClosureType>
+void ObjArrayKlass::oop_oop_iterate_elements_bounded(objArrayOop a, OopClosureType* closure, MemRegion mr) {
+  if (UseCompressedOops) {
+    oop_oop_iterate_elements_specialized_bounded<nv, narrowOop>(a, closure, mr.start(), mr.end());
+  } else {
+    oop_oop_iterate_elements_specialized_bounded<nv, oop>(a, closure, mr.start(), mr.end());
   }
 }
 
-template <class T>
-void ObjArrayKlass::objarray_follow_contents(oop obj, int index) {
+template <bool nv, typename OopClosureType>
+int ObjArrayKlass::oop_oop_iterate(oop obj, OopClosureType* closure) {
+  assert (obj->is_array(), "obj must be array");
   objArrayOop a = objArrayOop(obj);
-  const size_t len = size_t(a->length());
-  const size_t beg_index = size_t(index);
-  assert(beg_index < len || len == 0, "index too large");
+
+  // Get size before changing pointers.
+  // Don't call size() or oop_size() since that is a virtual call.
+  int size = a->object_size();
+  if (Devirtualizer<nv>::do_metadata(closure)) {
+    Devirtualizer<nv>::do_klass(closure, obj->klass());
+  }
+
+  oop_oop_iterate_elements<nv>(a, closure);
 
-  const size_t stride = MIN2(len - beg_index, ObjArrayMarkingStride);
-  const size_t end_index = beg_index + stride;
-  T* const base = (T*)a->base();
-  T* const beg = base + beg_index;
-  T* const end = base + end_index;
+  return size;
+}
 
-  // Push the non-NULL elements of the next stride on the marking stack.
-  for (T* e = beg; e < end; e++) {
-    MarkSweep::mark_and_push<T>(e);
+template <bool nv, typename OopClosureType>
+int ObjArrayKlass::oop_oop_iterate_bounded(oop obj, OopClosureType* closure, MemRegion mr) {
+  assert(obj->is_array(), "obj must be array");
+  objArrayOop a  = objArrayOop(obj);
+
+  // Get size before changing pointers.
+  // Don't call size() or oop_size() since that is a virtual call
+  int size = a->object_size();
+
+  if (Devirtualizer<nv>::do_metadata(closure)) {
+    Devirtualizer<nv>::do_klass(closure, a->klass());
   }
 
-  if (end_index < len) {
-    MarkSweep::push_objarray(a, end_index); // Push the continuation.
+  oop_oop_iterate_elements_bounded<nv>(a, closure, mr);
+
+  return size;
+}
+
+template <bool nv, typename T, class OopClosureType>
+void ObjArrayKlass::oop_oop_iterate_range_specialized(objArrayOop a, OopClosureType* closure, int start, int end) {
+  if (Devirtualizer<nv>::do_metadata(closure)) {
+    Devirtualizer<nv>::do_klass(closure, a->klass());
   }
+
+  T* low = start == 0 ? cast_from_oop<T*>(a) : a->obj_at_addr<T>(start);
+  T* high = (T*)a->base() + end;
+
+  oop_oop_iterate_elements_specialized_bounded<nv, T>(a, closure, low, high);
+}
+
+// Like oop_oop_iterate but only iterates over a specified range and only used
+// for objArrayOops.
+template <bool nv, class OopClosureType>
+int ObjArrayKlass::oop_oop_iterate_range(oop obj, OopClosureType* closure, int start, int end) {
+  assert(obj->is_array(), "obj must be array");
+  objArrayOop a  = objArrayOop(obj);
+
+  // Get size before changing pointers.
+  // Don't call size() or oop_size() since that is a virtual call
+  int size = a->object_size();
+
+  if (UseCompressedOops) {
+    oop_oop_iterate_range_specialized<nv, narrowOop>(a, closure, start, end);
+  } else {
+    oop_oop_iterate_range_specialized<nv, oop>(a, closure, start, end);
+  }
+
+  return size;
+}
+
+
+#define ObjArrayKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix)              \
+                                                                                   \
+int ObjArrayKlass::oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure) {  \
+  return oop_oop_iterate<nvs_to_bool(nv_suffix)>(obj, closure);                    \
 }
 
 #if INCLUDE_ALL_GCS
-void ObjArrayKlass::oop_follow_contents(ParCompactionManager* cm, oop obj,
-                                        int index) {
-  if (UseCompressedOops) {
-    objarray_follow_contents<narrowOop>(cm, obj, index);
-  } else {
-    objarray_follow_contents<oop>(cm, obj, index);
-  }
+#define ObjArrayKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix)              \
+int ObjArrayKlass::oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* closure) {  \
+  /* No reverse implementation ATM. */                                                       \
+  return oop_oop_iterate<nvs_to_bool(nv_suffix)>(obj, closure);                              \
+}
+#else
+#define ObjArrayKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix)
+#endif
+
+#define ObjArrayKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix)                              \
+                                                                                                     \
+int ObjArrayKlass::oop_oop_iterate##nv_suffix##_m(oop obj, OopClosureType* closure, MemRegion mr) {  \
+  return oop_oop_iterate_bounded<nvs_to_bool(nv_suffix)>(obj, closure, mr);                          \
 }
 
-template <class T>
-void ObjArrayKlass::objarray_follow_contents(ParCompactionManager* cm, oop obj,
-                                             int index) {
-  objArrayOop a = objArrayOop(obj);
-  const size_t len = size_t(a->length());
-  const size_t beg_index = size_t(index);
-  assert(beg_index < len || len == 0, "index too large");
+#define ObjArrayKlass_OOP_OOP_ITERATE_DEFN_r(OopClosureType, nv_suffix)                                      \
+                                                                                                             \
+int ObjArrayKlass::oop_oop_iterate_range##nv_suffix(oop obj, OopClosureType* closure, int start, int end) {  \
+  return oop_oop_iterate_range<nvs_to_bool(nv_suffix)>(obj, closure, start, end);                            \
+}
+
 
-  const size_t stride = MIN2(len - beg_index, ObjArrayMarkingStride);
-  const size_t end_index = beg_index + stride;
-  T* const base = (T*)a->base();
-  T* const beg = base + beg_index;
-  T* const end = base + end_index;
+#define ALL_OBJ_ARRAY_KLASS_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix)  \
+  ObjArrayKlass_OOP_OOP_ITERATE_DEFN(          OopClosureType, nv_suffix)    \
+  ObjArrayKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix)    \
+  ObjArrayKlass_OOP_OOP_ITERATE_DEFN_m(        OopClosureType, nv_suffix)    \
+  ObjArrayKlass_OOP_OOP_ITERATE_DEFN_r(        OopClosureType, nv_suffix)
 
-  // Push the non-NULL elements of the next stride on the marking stack.
-  for (T* e = beg; e < end; e++) {
-    PSParallelCompact::mark_and_push<T>(cm, e);
-  }
-
-  if (end_index < len) {
-    cm->push_objarray(a, end_index); // Push the continuation.
-  }
-}
-#endif // INCLUDE_ALL_GCS
 
 #endif // SHARE_VM_OOPS_OBJARRAYKLASS_INLINE_HPP
--- a/hotspot/src/share/vm/oops/oop.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/oops/oop.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -298,19 +298,6 @@
 
   // garbage collection
   bool is_gc_marked() const;
-  // Apply "MarkSweep::mark_and_push" to (the address of) every non-NULL
-  // reference field in "this".
-  void follow_contents(void);
-
-#if INCLUDE_ALL_GCS
-  // Parallel Scavenge
-  void push_contents(PSPromotionManager* pm);
-
-  // Parallel Old
-  void update_contents(ParCompactionManager* cm);
-
-  void follow_contents(ParCompactionManager* cm);
-#endif // INCLUDE_ALL_GCS
 
   bool is_scavengable() const;
 
@@ -334,9 +321,6 @@
   uint age() const;
   void incr_age();
 
-  // Adjust all pointers in this object to point at it's forwarded location and
-  // return the size of this oop.  This is used by the MarkSweep collector.
-  int adjust_pointers();
 
   // mark-sweep support
   void follow_body(int begin, int end);
@@ -345,6 +329,22 @@
   static BarrierSet* bs()            { return _bs; }
   static void set_bs(BarrierSet* bs) { _bs = bs; }
 
+  // Garbage Collection support
+
+  // Mark Sweep
+  void ms_follow_contents();
+  // Adjust all pointers in this object to point at it's forwarded location and
+  // return the size of this oop.  This is used by the MarkSweep collector.
+  int  ms_adjust_pointers();
+#if INCLUDE_ALL_GCS
+  // Parallel Compact
+  void pc_follow_contents(ParCompactionManager* pc);
+  void pc_update_contents();
+  // Parallel Scavenge
+  void ps_push_contents(PSPromotionManager* pm);
+#endif
+
+
   // iterators, returns size of object
 #define OOP_ITERATE_DECL(OopClosureType, nv_suffix)                      \
   int oop_iterate(OopClosureType* blk);                                  \
--- a/hotspot/src/share/vm/oops/oop.inline.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/oops/oop.inline.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -26,13 +26,11 @@
 #define SHARE_VM_OOPS_OOP_INLINE_HPP
 
 #include "gc_implementation/shared/ageTable.hpp"
-#include "gc_implementation/shared/markSweep.inline.hpp"
 #include "gc_interface/collectedHeap.inline.hpp"
 #include "memory/barrierSet.inline.hpp"
 #include "memory/cardTableModRefBS.hpp"
 #include "memory/genCollectedHeap.hpp"
 #include "memory/generation.hpp"
-#include "memory/specialized_oop_closures.hpp"
 #include "oops/arrayKlass.hpp"
 #include "oops/arrayOop.hpp"
 #include "oops/klass.inline.hpp"
@@ -592,11 +590,6 @@
 }
 #endif // PRODUCT
 
-inline void oopDesc::follow_contents(void) {
-  assert (is_gc_marked(), "should be marked");
-  klass()->oop_follow_contents(this);
-}
-
 inline bool oopDesc::is_scavengable() const {
   return Universe::heap()->is_scavengable(this);
 }
@@ -706,21 +699,49 @@
   }
 }
 
-inline int oopDesc::adjust_pointers() {
+inline void oopDesc::ms_follow_contents() {
+  klass()->oop_ms_follow_contents(this);
+}
+
+inline int oopDesc::ms_adjust_pointers() {
   debug_only(int check_size = size());
-  int s = klass()->oop_adjust_pointers(this);
+  int s = klass()->oop_ms_adjust_pointers(this);
   assert(s == check_size, "should be the same");
   return s;
 }
 
-#define OOP_ITERATE_DEFN(OopClosureType, nv_suffix)                        \
-                                                                           \
-inline int oopDesc::oop_iterate(OopClosureType* blk) {                     \
-  return klass()->oop_oop_iterate##nv_suffix(this, blk);               \
-}                                                                          \
-                                                                           \
-inline int oopDesc::oop_iterate(OopClosureType* blk, MemRegion mr) {       \
-  return klass()->oop_oop_iterate##nv_suffix##_m(this, blk, mr);       \
+#if INCLUDE_ALL_GCS
+inline void oopDesc::pc_follow_contents(ParCompactionManager* cm) {
+  klass()->oop_pc_follow_contents(this, cm);
+}
+
+inline void oopDesc::pc_update_contents() {
+  Klass* k = klass();
+  if (!k->oop_is_typeArray()) {
+    // It might contain oops beyond the header, so take the virtual call.
+    k->oop_pc_update_pointers(this);
+  }
+  // Else skip it.  The TypeArrayKlass in the header never needs scavenging.
+}
+
+inline void oopDesc::ps_push_contents(PSPromotionManager* pm) {
+  Klass* k = klass();
+  if (!k->oop_is_typeArray()) {
+    // It might contain oops beyond the header, so take the virtual call.
+    k->oop_ps_push_contents(this, pm);
+  }
+  // Else skip it.  The TypeArrayKlass in the header never needs scavenging.
+}
+#endif
+
+#define OOP_ITERATE_DEFN(OopClosureType, nv_suffix)                   \
+                                                                      \
+inline int oopDesc::oop_iterate(OopClosureType* blk) {                \
+  return klass()->oop_oop_iterate##nv_suffix(this, blk);              \
+}                                                                     \
+                                                                      \
+inline int oopDesc::oop_iterate(OopClosureType* blk, MemRegion mr) {  \
+  return klass()->oop_oop_iterate##nv_suffix##_m(this, blk, mr);      \
 }
 
 
@@ -736,18 +757,21 @@
   return oop_iterate(&cl, mr);
 }
 
-ALL_OOP_OOP_ITERATE_CLOSURES_1(OOP_ITERATE_DEFN)
-ALL_OOP_OOP_ITERATE_CLOSURES_2(OOP_ITERATE_DEFN)
+#if INCLUDE_ALL_GCS
+#define OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix)       \
+                                                                    \
+inline int oopDesc::oop_iterate_backwards(OopClosureType* blk) {    \
+  return klass()->oop_oop_iterate_backwards##nv_suffix(this, blk);  \
+}
+#else
+#define OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix)
+#endif
 
-#if INCLUDE_ALL_GCS
-#define OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix)              \
-                                                                           \
-inline int oopDesc::oop_iterate_backwards(OopClosureType* blk) {           \
-  return klass()->oop_oop_iterate_backwards##nv_suffix(this, blk);     \
-}
+#define ALL_OOPDESC_OOP_ITERATE(OopClosureType, nv_suffix)  \
+  OOP_ITERATE_DEFN(OopClosureType, nv_suffix)               \
+  OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix)
 
-ALL_OOP_OOP_ITERATE_CLOSURES_1(OOP_ITERATE_BACKWARDS_DEFN)
-ALL_OOP_OOP_ITERATE_CLOSURES_2(OOP_ITERATE_BACKWARDS_DEFN)
-#endif // INCLUDE_ALL_GCS
+ALL_OOP_OOP_ITERATE_CLOSURES_1(ALL_OOPDESC_OOP_ITERATE)
+ALL_OOP_OOP_ITERATE_CLOSURES_2(ALL_OOPDESC_OOP_ITERATE)
 
 #endif // SHARE_VM_OOPS_OOP_INLINE_HPP
--- a/hotspot/src/share/vm/oops/oop.pcgc.inline.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2005, 2015, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_OOPS_OOP_PCGC_INLINE_HPP
-#define SHARE_VM_OOPS_OOP_PCGC_INLINE_HPP
-
-#include "runtime/atomic.inline.hpp"
-#include "utilities/macros.hpp"
-#if INCLUDE_ALL_GCS
-#include "gc_implementation/parNew/parNewGeneration.hpp"
-#include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
-#include "gc_implementation/parallelScavenge/psCompactionManager.hpp"
-#include "gc_implementation/parallelScavenge/psParallelCompact.hpp"
-#include "gc_implementation/parallelScavenge/psScavenge.hpp"
-#endif // INCLUDE_ALL_GCS
-
-inline void oopDesc::update_contents(ParCompactionManager* cm) {
-  // The klass field must be updated before anything else
-  // can be done.
-  DEBUG_ONLY(Klass* original_klass = klass());
-
-  Klass* new_klass = klass();
-  if (!new_klass->oop_is_typeArray()) {
-    // It might contain oops beyond the header, so take the virtual call.
-    new_klass->oop_update_pointers(cm, this);
-  }
-  // Else skip it.  The TypeArrayKlass in the header never needs scavenging.
-}
-
-inline void oopDesc::follow_contents(ParCompactionManager* cm) {
-  assert (PSParallelCompact::mark_bitmap()->is_marked(this),
-    "should be marked");
-  klass()->oop_follow_contents(cm, this);
-}
-
-#endif // SHARE_VM_OOPS_OOP_PCGC_INLINE_HPP
--- a/hotspot/src/share/vm/oops/oop.psgc.inline.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2002, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_OOPS_OOP_PSGC_INLINE_HPP
-#define SHARE_VM_OOPS_OOP_PSGC_INLINE_HPP
-
-#include "utilities/macros.hpp"
-#if INCLUDE_ALL_GCS
-#include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
-#include "gc_implementation/parallelScavenge/psScavenge.hpp"
-#endif // INCLUDE_ALL_GCS
-
-// ParallelScavengeHeap methods
-
-inline void oopDesc::push_contents(PSPromotionManager* pm) {
-  Klass* k = klass();
-  if (!k->oop_is_typeArray()) {
-    // It might contain oops beyond the header, so take the virtual call.
-    k->oop_push_contents(pm, this);
-  }
-  // Else skip it.  The TypeArrayKlass in the header never needs scavenging.
-}
-
-#endif // SHARE_VM_OOPS_OOP_PSGC_INLINE_HPP
--- a/hotspot/src/share/vm/oops/typeArrayKlass.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/oops/typeArrayKlass.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -36,7 +36,7 @@
 #include "oops/klass.inline.hpp"
 #include "oops/objArrayKlass.hpp"
 #include "oops/oop.inline.hpp"
-#include "oops/typeArrayKlass.hpp"
+#include "oops/typeArrayKlass.inline.hpp"
 #include "oops/typeArrayOop.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/orderAccess.inline.hpp"
@@ -204,57 +204,6 @@
   return t->object_size();
 }
 
-void TypeArrayKlass::oop_follow_contents(oop obj) {
-  assert(obj->is_typeArray(),"must be a type array");
-  // Performance tweak: We skip iterating over the klass pointer since we
-  // know that Universe::TypeArrayKlass never moves.
-}
-
-#if INCLUDE_ALL_GCS
-void TypeArrayKlass::oop_follow_contents(ParCompactionManager* cm, oop obj) {
-  assert(obj->is_typeArray(),"must be a type array");
-  // Performance tweak: We skip iterating over the klass pointer since we
-  // know that Universe::TypeArrayKlass never moves.
-}
-#endif // INCLUDE_ALL_GCS
-
-int TypeArrayKlass::oop_adjust_pointers(oop obj) {
-  assert(obj->is_typeArray(),"must be a type array");
-  typeArrayOop t = typeArrayOop(obj);
-  // Performance tweak: We skip iterating over the klass pointer since we
-  // know that Universe::TypeArrayKlass never moves.
-  return t->object_size();
-}
-
-int TypeArrayKlass::oop_oop_iterate(oop obj, ExtendedOopClosure* blk) {
-  assert(obj->is_typeArray(),"must be a type array");
-  typeArrayOop t = typeArrayOop(obj);
-  // Performance tweak: We skip iterating over the klass pointer since we
-  // know that Universe::TypeArrayKlass never moves.
-  return t->object_size();
-}
-
-int TypeArrayKlass::oop_oop_iterate_m(oop obj, ExtendedOopClosure* blk, MemRegion mr) {
-  assert(obj->is_typeArray(),"must be a type array");
-  typeArrayOop t = typeArrayOop(obj);
-  // Performance tweak: We skip iterating over the klass pointer since we
-  // know that Universe::TypeArrayKlass never moves.
-  return t->object_size();
-}
-
-#if INCLUDE_ALL_GCS
-void TypeArrayKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
-  ShouldNotReachHere();
-  assert(obj->is_typeArray(),"must be a type array");
-}
-
-int
-TypeArrayKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
-  assert(obj->is_typeArray(),"must be a type array");
-  return typeArrayOop(obj)->object_size();
-}
-#endif // INCLUDE_ALL_GCS
-
 void TypeArrayKlass::initialize(TRAPS) {
   // Nothing to do. Having this function is handy since objArrayKlasses can be
   // initialized by calling initialize on their bottom_klass, see ObjArrayKlass::initialize
--- a/hotspot/src/share/vm/oops/typeArrayKlass.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/oops/typeArrayKlass.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -72,16 +72,46 @@
   // Copying
   void  copy_array(arrayOop s, int src_pos, arrayOop d, int dst_pos, int length, TRAPS);
 
-  // Iteration
-  int oop_oop_iterate(oop obj, ExtendedOopClosure* blk);
-  int oop_oop_iterate_m(oop obj, ExtendedOopClosure* blk, MemRegion mr);
+  // GC specific object visitors
+  //
+  // Mark Sweep
+  void oop_ms_follow_contents(oop obj);
+  int  oop_ms_adjust_pointers(oop obj);
+#if INCLUDE_ALL_GCS
+  // Parallel Scavenge
+  void oop_ps_push_contents(  oop obj, PSPromotionManager* pm);
+  // Parallel Compact
+  void oop_pc_follow_contents(oop obj, ParCompactionManager* cm);
+  void oop_pc_update_pointers(oop obj);
+#endif
+
+  // Oop iterators. Since there are no oops in TypeArrayKlasses,
+  // these functions only return the size of the object.
+
+ private:
+  // The implementation used by all oop_oop_iterate functions in TypeArrayKlasses.
+  inline int oop_oop_iterate_impl(oop obj, ExtendedOopClosure* closure);
 
-  // Garbage collection
-  void oop_follow_contents(oop obj);
-  int  oop_adjust_pointers(oop obj);
+ public:
+
+#define TypeArrayKlass_OOP_OOP_ITERATE_DECL(OopClosureType, nv_suffix)    \
+  int oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure);       \
+  int oop_oop_iterate##nv_suffix##_m(oop obj, OopClosureType* closure,    \
+                                     MemRegion mr);                       \
+  int oop_oop_iterate_range##nv_suffix(oop obj, OopClosureType* closure,  \
+                                     int start, int end);
 
-  // Parallel Scavenge and Parallel Old
-  PARALLEL_GC_DECLS
+  ALL_OOP_OOP_ITERATE_CLOSURES_1(TypeArrayKlass_OOP_OOP_ITERATE_DECL)
+  ALL_OOP_OOP_ITERATE_CLOSURES_2(TypeArrayKlass_OOP_OOP_ITERATE_DECL)
+
+#if INCLUDE_ALL_GCS
+#define TypeArrayKlass_OOP_OOP_ITERATE_BACKWARDS_DECL(OopClosureType, nv_suffix)  \
+  int  oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* closure);
+
+  ALL_OOP_OOP_ITERATE_CLOSURES_1(TypeArrayKlass_OOP_OOP_ITERATE_BACKWARDS_DECL)
+  ALL_OOP_OOP_ITERATE_CLOSURES_2(TypeArrayKlass_OOP_OOP_ITERATE_BACKWARDS_DECL)
+#endif // INCLUDE_ALL_GCS
+
 
  protected:
   // Find n'th dimensional array
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/oops/typeArrayKlass.inline.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 1997, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_OOPS_TYPEARRAYKLASS_INLINE_HPP
+#define SHARE_VM_OOPS_TYPEARRAYKLASS_INLINE_HPP
+
+#include "oops/oop.inline.hpp"
+#include "oops/typeArrayKlass.hpp"
+#include "oops/typeArrayOop.hpp"
+
+class ExtendedOopClosure;
+
+inline int TypeArrayKlass::oop_oop_iterate_impl(oop obj, ExtendedOopClosure* closure) {
+  assert(obj->is_typeArray(),"must be a type array");
+  typeArrayOop t = typeArrayOop(obj);
+  // Performance tweak: We skip iterating over the klass pointer since we
+  // know that Universe::TypeArrayKlass never moves.
+  return t->object_size();
+}
+
+#define TypeArrayKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix)  \
+                                                                        \
+int TypeArrayKlass::                                                    \
+oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure) {          \
+  return oop_oop_iterate_impl(obj, closure);                            \
+}
+
+#if INCLUDE_ALL_GCS
+#define TypeArrayKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix)  \
+                                                                                  \
+int TypeArrayKlass::                                                              \
+oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* closure) {          \
+  return oop_oop_iterate_impl(obj, closure);                                      \
+}
+#else
+#define TypeArrayKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix)
+#endif
+
+
+#define TypeArrayKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix)          \
+                                                                                  \
+int TypeArrayKlass::                                                              \
+oop_oop_iterate##nv_suffix##_m(oop obj, OopClosureType* closure, MemRegion mr) {  \
+  return oop_oop_iterate_impl(obj, closure);                                      \
+}
+
+#define ALL_TYPE_ARRAY_KLASS_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix)  \
+  TypeArrayKlass_OOP_OOP_ITERATE_DEFN(          OopClosureType, nv_suffix)    \
+  TypeArrayKlass_OOP_OOP_ITERATE_DEFN_m(        OopClosureType, nv_suffix)    \
+  TypeArrayKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix)
+
+#endif // SHARE_VM_OOPS_TYPEARRAYKLASS_INLINE_HPP
--- a/hotspot/src/share/vm/precompiled/precompiled.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/precompiled/precompiled.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -94,7 +94,6 @@
 # include "gc_implementation/shared/spaceCounters.hpp"
 # include "gc_implementation/shared/spaceDecorator.hpp"
 # include "gc_interface/collectedHeap.hpp"
-# include "gc_interface/collectedHeap.inline.hpp"
 # include "gc_interface/gcCause.hpp"
 # include "interpreter/abstractInterpreter.hpp"
 # include "interpreter/bytecode.hpp"
@@ -114,15 +113,12 @@
 # include "memory/allocation.hpp"
 # include "memory/allocation.inline.hpp"
 # include "memory/barrierSet.hpp"
-# include "memory/barrierSet.inline.hpp"
 # include "memory/blockOffsetTable.hpp"
-# include "memory/blockOffsetTable.inline.hpp"
 # include "memory/cardTableModRefBS.hpp"
 # include "memory/collectorPolicy.hpp"
 # include "memory/defNewGeneration.hpp"
 # include "memory/gcLocker.hpp"
 # include "memory/genCollectedHeap.hpp"
-# include "memory/genOopClosures.hpp"
 # include "memory/genRemSet.hpp"
 # include "memory/generation.hpp"
 # include "memory/heap.hpp"
@@ -133,10 +129,8 @@
 # include "memory/referencePolicy.hpp"
 # include "memory/referenceProcessor.hpp"
 # include "memory/resourceArea.hpp"
-# include "memory/sharedHeap.hpp"
 # include "memory/space.hpp"
 # include "memory/threadLocalAllocBuffer.hpp"
-# include "memory/threadLocalAllocBuffer.inline.hpp"
 # include "memory/universe.hpp"
 # include "memory/universe.inline.hpp"
 # include "memory/watermark.hpp"
@@ -147,7 +141,6 @@
 # include "oops/instanceOop.hpp"
 # include "oops/instanceRefKlass.hpp"
 # include "oops/klass.hpp"
-# include "oops/klassPS.hpp"
 # include "oops/klassVtable.hpp"
 # include "oops/markOop.hpp"
 # include "oops/markOop.inline.hpp"
@@ -305,7 +298,6 @@
 # include "gc_implementation/concurrentMarkSweep/promotionInfo.hpp"
 # include "gc_implementation/g1/dirtyCardQueue.hpp"
 # include "gc_implementation/g1/g1BlockOffsetTable.hpp"
-# include "gc_implementation/g1/g1BlockOffsetTable.inline.hpp"
 # include "gc_implementation/g1/g1OopClosures.hpp"
 # include "gc_implementation/g1/g1_globals.hpp"
 # include "gc_implementation/g1/ptrQueue.hpp"
@@ -319,7 +311,6 @@
 # include "gc_implementation/parallelScavenge/psGCAdaptivePolicyCounters.hpp"
 # include "gc_implementation/parallelScavenge/psGenerationCounters.hpp"
 # include "gc_implementation/parallelScavenge/psOldGen.hpp"
-# include "gc_implementation/parallelScavenge/psParallelCompact.hpp"
 # include "gc_implementation/parallelScavenge/psVirtualspace.hpp"
 # include "gc_implementation/parallelScavenge/psYoungGen.hpp"
 # include "gc_implementation/shared/gcAdaptivePolicyCounters.hpp"
--- a/hotspot/src/share/vm/prims/jni.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/prims/jni.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -84,6 +84,9 @@
 
 static jint CurrentVersion = JNI_VERSION_1_8;
 
+#ifdef _WIN32
+extern LONG WINAPI topLevelExceptionFilter(_EXCEPTION_POINTERS* );
+#endif
 
 // The DT_RETURN_MARK macros create a scoped object to fire the dtrace
 // '-return' probe regardless of the return path is taken out of the function.
@@ -3924,7 +3927,7 @@
 DT_RETURN_MARK_DECL(CreateJavaVM, jint
                     , HOTSPOT_JNI_CREATEJAVAVM_RETURN(_ret_ref));
 
-_JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_CreateJavaVM(JavaVM **vm, void **penv, void *args) {
+static jint JNI_CreateJavaVM_inner(JavaVM **vm, void **penv, void *args) {
   HOTSPOT_JNI_CREATEJAVAVM_ENTRY((void **) vm, penv, args);
 
   jint result = JNI_ERR;
@@ -4001,18 +4004,14 @@
     }
 
 #ifndef PRODUCT
-  #ifndef CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED
-    #define CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED(f) f()
-  #endif
-
     // Check if we should compile all classes on bootclasspath
     if (CompileTheWorld) ClassLoader::compile_the_world();
     if (ReplayCompiles) ciReplay::replay(thread);
 
     // Some platforms (like Win*) need a wrapper around these test
     // functions in order to properly handle error conditions.
-    CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED(test_error_handler);
-    CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED(execute_internal_vm_tests);
+    test_error_handler();
+    execute_internal_vm_tests();
 #endif
 
     // Since this is not a JVM_ENTRY we have to set the thread state manually before leaving.
@@ -4045,8 +4044,23 @@
   }
 
   return result;
+
 }
 
+_JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_CreateJavaVM(JavaVM **vm, void **penv, void *args) {
+  jint result = 0;
+  // On Windows, let CreateJavaVM run with SEH protection
+#ifdef _WIN32
+  __try {
+#endif
+    result = JNI_CreateJavaVM_inner(vm, penv, args);
+#ifdef _WIN32
+  } __except(topLevelExceptionFilter((_EXCEPTION_POINTERS*)_exception_info())) {
+    // Nothing to do.
+  }
+#endif
+  return result;
+}
 
 _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_GetCreatedJavaVMs(JavaVM **vm_buf, jsize bufLen, jsize *numVMs) {
   // See bug 4367188, the wrapper can sometimes cause VM crashes
--- a/hotspot/src/share/vm/prims/whitebox.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/prims/whitebox.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -89,6 +89,10 @@
   return os::vm_page_size();
 WB_END
 
+WB_ENTRY(jlong, WB_GetVMLargePageSize(JNIEnv* env, jobject o))
+  return os::large_page_size();
+WB_END
+
 class WBIsKlassAliveClosure : public KlassClosure {
     Symbol* _name;
     bool _found;
@@ -1259,19 +1263,20 @@
 #define CC (char*)
 
 static JNINativeMethod methods[] = {
-  {CC"getObjectAddress",   CC"(Ljava/lang/Object;)J", (void*)&WB_GetObjectAddress  },
-  {CC"getObjectSize",      CC"(Ljava/lang/Object;)J", (void*)&WB_GetObjectSize     },
-  {CC"isObjectInOldGen",   CC"(Ljava/lang/Object;)Z", (void*)&WB_isObjectInOldGen  },
+  {CC"getObjectAddress0",   CC"(Ljava/lang/Object;)J", (void*)&WB_GetObjectAddress  },
+  {CC"getObjectSize0",      CC"(Ljava/lang/Object;)J", (void*)&WB_GetObjectSize     },
+  {CC"isObjectInOldGen0",   CC"(Ljava/lang/Object;)Z", (void*)&WB_isObjectInOldGen  },
   {CC"getHeapOopSize",     CC"()I",                   (void*)&WB_GetHeapOopSize    },
   {CC"getVMPageSize",      CC"()I",                   (void*)&WB_GetVMPageSize     },
+  {CC"getVMLargePageSize", CC"()J",                   (void*)&WB_GetVMLargePageSize},
   {CC"isClassAlive0",      CC"(Ljava/lang/String;)Z", (void*)&WB_IsClassAlive      },
-  {CC"parseCommandLine",
+  {CC"parseCommandLine0",
       CC"(Ljava/lang/String;C[Lsun/hotspot/parser/DiagnosticCommand;)[Ljava/lang/Object;",
       (void*) &WB_ParseCommandLine
   },
-  {CC"addToBootstrapClassLoaderSearch", CC"(Ljava/lang/String;)V",
+  {CC"addToBootstrapClassLoaderSearch0", CC"(Ljava/lang/String;)V",
                                                       (void*)&WB_AddToBootstrapClassLoaderSearch},
-  {CC"addToSystemClassLoaderSearch",    CC"(Ljava/lang/String;)V",
+  {CC"addToSystemClassLoaderSearch0",    CC"(Ljava/lang/String;)V",
                                                       (void*)&WB_AddToSystemClassLoaderSearch},
   {CC"getCompressedOopsMaxHeapSize", CC"()J",
       (void*)&WB_GetCompressedOopsMaxHeapSize},
@@ -1281,7 +1286,7 @@
   {CC"stressVirtualSpaceResize",CC"(JJJ)I",           (void*)&WB_StressVirtualSpaceResize},
 #if INCLUDE_ALL_GCS
   {CC"g1InConcurrentMark", CC"()Z",                   (void*)&WB_G1InConcurrentMark},
-  {CC"g1IsHumongous",      CC"(Ljava/lang/Object;)Z", (void*)&WB_G1IsHumongous     },
+  {CC"g1IsHumongous0",      CC"(Ljava/lang/Object;)Z", (void*)&WB_G1IsHumongous     },
   {CC"g1NumMaxRegions",    CC"()J",                   (void*)&WB_G1NumMaxRegions  },
   {CC"g1NumFreeRegions",   CC"()J",                   (void*)&WB_G1NumFreeRegions  },
   {CC"g1RegionSize",       CC"()I",                   (void*)&WB_G1RegionSize      },
@@ -1302,29 +1307,29 @@
 #endif // INCLUDE_NMT
   {CC"deoptimizeFrames",   CC"(Z)I",                  (void*)&WB_DeoptimizeFrames  },
   {CC"deoptimizeAll",      CC"()V",                   (void*)&WB_DeoptimizeAll     },
-  {CC"deoptimizeMethod",   CC"(Ljava/lang/reflect/Executable;Z)I",
+  {CC"deoptimizeMethod0",   CC"(Ljava/lang/reflect/Executable;Z)I",
                                                       (void*)&WB_DeoptimizeMethod  },
-  {CC"isMethodCompiled",   CC"(Ljava/lang/reflect/Executable;Z)Z",
+  {CC"isMethodCompiled0",   CC"(Ljava/lang/reflect/Executable;Z)Z",
                                                       (void*)&WB_IsMethodCompiled  },
-  {CC"isMethodCompilable", CC"(Ljava/lang/reflect/Executable;IZ)Z",
+  {CC"isMethodCompilable0", CC"(Ljava/lang/reflect/Executable;IZ)Z",
                                                       (void*)&WB_IsMethodCompilable},
-  {CC"isMethodQueuedForCompilation",
+  {CC"isMethodQueuedForCompilation0",
       CC"(Ljava/lang/reflect/Executable;)Z",          (void*)&WB_IsMethodQueuedForCompilation},
-  {CC"makeMethodNotCompilable",
+  {CC"makeMethodNotCompilable0",
       CC"(Ljava/lang/reflect/Executable;IZ)V",        (void*)&WB_MakeMethodNotCompilable},
-  {CC"testSetDontInlineMethod",
+  {CC"testSetDontInlineMethod0",
       CC"(Ljava/lang/reflect/Executable;Z)Z",         (void*)&WB_TestSetDontInlineMethod},
-  {CC"getMethodCompilationLevel",
+  {CC"getMethodCompilationLevel0",
       CC"(Ljava/lang/reflect/Executable;Z)I",         (void*)&WB_GetMethodCompilationLevel},
-  {CC"getMethodEntryBci",
+  {CC"getMethodEntryBci0",
       CC"(Ljava/lang/reflect/Executable;)I",          (void*)&WB_GetMethodEntryBci},
   {CC"getCompileQueueSize",
       CC"(I)I",                                       (void*)&WB_GetCompileQueueSize},
-  {CC"testSetForceInlineMethod",
+  {CC"testSetForceInlineMethod0",
       CC"(Ljava/lang/reflect/Executable;Z)Z",         (void*)&WB_TestSetForceInlineMethod},
-  {CC"enqueueMethodForCompilation",
+  {CC"enqueueMethodForCompilation0",
       CC"(Ljava/lang/reflect/Executable;II)Z",        (void*)&WB_EnqueueMethodForCompilation},
-  {CC"clearMethodState",
+  {CC"clearMethodState0",
       CC"(Ljava/lang/reflect/Executable;)V",          (void*)&WB_ClearMethodState},
   {CC"lockCompilation",    CC"()V",                   (void*)&WB_LockCompilation},
   {CC"unlockCompilation",  CC"()V",                   (void*)&WB_UnlockCompilation},
@@ -1363,7 +1368,7 @@
   {CC"incMetaspaceCapacityUntilGC", CC"(J)J",         (void*)&WB_IncMetaspaceCapacityUntilGC },
   {CC"metaspaceCapacityUntilGC", CC"()J",             (void*)&WB_MetaspaceCapacityUntilGC },
   {CC"getCPUFeatures",     CC"()Ljava/lang/String;",  (void*)&WB_GetCPUFeatures     },
-  {CC"getNMethod",         CC"(Ljava/lang/reflect/Executable;Z)[Ljava/lang/Object;",
+  {CC"getNMethod0",         CC"(Ljava/lang/reflect/Executable;Z)[Ljava/lang/Object;",
                                                       (void*)&WB_GetNMethod         },
   {CC"forceNMethodSweep",  CC"()V",                   (void*)&WB_ForceNMethodSweep  },
   {CC"allocateCodeBlob",   CC"(II)J",                 (void*)&WB_AllocateCodeBlob   },
@@ -1375,7 +1380,7 @@
   {CC"getThreadStackSize", CC"()J",                   (void*)&WB_GetThreadStackSize },
   {CC"getThreadRemainingStackSize", CC"()J",          (void*)&WB_GetThreadRemainingStackSize },
   {CC"assertMatchingSafepointCalls", CC"(ZZ)V",       (void*)&WB_AssertMatchingSafepointCalls },
-  {CC"isMonitorInflated",  CC"(Ljava/lang/Object;)Z", (void*)&WB_IsMonitorInflated  },
+  {CC"isMonitorInflated0",  CC"(Ljava/lang/Object;)Z", (void*)&WB_IsMonitorInflated  },
   {CC"forceSafepoint",     CC"()V",                   (void*)&WB_ForceSafepoint     },
   {CC"getMethodBooleanOption",
       CC"(Ljava/lang/reflect/Executable;Ljava/lang/String;)Ljava/lang/Boolean;",
--- a/hotspot/src/share/vm/runtime/arguments.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/runtime/arguments.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -242,6 +242,9 @@
  * and ignoring the value.  Once the JDK version reaches the 'accept_until'
  * limit, we flatly refuse to admit the existence of the flag.  This allows
  * a flag to die correctly over JDK releases using HSX.
+ * But now that HSX is no longer supported only options with a future
+ * accept_until value need to be listed, and the list can be pruned
+ * on each major release.
  */
 typedef struct {
   const char* name;
@@ -250,63 +253,8 @@
 } ObsoleteFlag;
 
 static ObsoleteFlag obsolete_jvm_flags[] = {
-  { "UseTrainGC",                    JDK_Version::jdk(5), JDK_Version::jdk(7) },
-  { "UseSpecialLargeObjectHandling", JDK_Version::jdk(5), JDK_Version::jdk(7) },
-  { "UseOversizedCarHandling",       JDK_Version::jdk(5), JDK_Version::jdk(7) },
-  { "TraceCarAllocation",            JDK_Version::jdk(5), JDK_Version::jdk(7) },
-  { "PrintTrainGCProcessingStats",   JDK_Version::jdk(5), JDK_Version::jdk(7) },
-  { "LogOfCarSpaceSize",             JDK_Version::jdk(5), JDK_Version::jdk(7) },
-  { "OversizedCarThreshold",         JDK_Version::jdk(5), JDK_Version::jdk(7) },
-  { "MinTickInterval",               JDK_Version::jdk(5), JDK_Version::jdk(7) },
-  { "DefaultTickInterval",           JDK_Version::jdk(5), JDK_Version::jdk(7) },
-  { "MaxTickInterval",               JDK_Version::jdk(5), JDK_Version::jdk(7) },
-  { "DelayTickAdjustment",           JDK_Version::jdk(5), JDK_Version::jdk(7) },
-  { "ProcessingToTenuringRatio",     JDK_Version::jdk(5), JDK_Version::jdk(7) },
-  { "MinTrainLength",                JDK_Version::jdk(5), JDK_Version::jdk(7) },
-  { "AppendRatio",         JDK_Version::jdk_update(6,10), JDK_Version::jdk(7) },
-  { "DefaultMaxRAM",       JDK_Version::jdk_update(6,18), JDK_Version::jdk(7) },
-  { "DefaultInitialRAMFraction",
-                           JDK_Version::jdk_update(6,18), JDK_Version::jdk(7) },
-  { "UseDepthFirstScavengeOrder",
-                           JDK_Version::jdk_update(6,22), JDK_Version::jdk(7) },
-  { "HandlePromotionFailure",
-                           JDK_Version::jdk_update(6,24), JDK_Version::jdk(8) },
-  { "MaxLiveObjectEvacuationRatio",
-                           JDK_Version::jdk_update(6,24), JDK_Version::jdk(8) },
-  { "ForceSharedSpaces",   JDK_Version::jdk_update(6,25), JDK_Version::jdk(8) },
-  { "UseParallelOldGCCompacting",
-                           JDK_Version::jdk_update(6,27), JDK_Version::jdk(8) },
-  { "UseParallelDensePrefixUpdate",
-                           JDK_Version::jdk_update(6,27), JDK_Version::jdk(8) },
-  { "UseParallelOldGCDensePrefix",
-                           JDK_Version::jdk_update(6,27), JDK_Version::jdk(8) },
-  { "AllowTransitionalJSR292",       JDK_Version::jdk(7), JDK_Version::jdk(8) },
-  { "UseCompressedStrings",          JDK_Version::jdk(7), JDK_Version::jdk(8) },
-  { "CMSPermGenPrecleaningEnabled", JDK_Version::jdk(8),  JDK_Version::jdk(9) },
-  { "CMSTriggerPermRatio", JDK_Version::jdk(8),  JDK_Version::jdk(9) },
-  { "CMSInitiatingPermOccupancyFraction", JDK_Version::jdk(8),  JDK_Version::jdk(9) },
-  { "AdaptivePermSizeWeight", JDK_Version::jdk(8),  JDK_Version::jdk(9) },
-  { "PermGenPadding", JDK_Version::jdk(8),  JDK_Version::jdk(9) },
-  { "PermMarkSweepDeadRatio", JDK_Version::jdk(8),  JDK_Version::jdk(9) },
-  { "PermSize", JDK_Version::jdk(8),  JDK_Version::jdk(9) },
-  { "MaxPermSize", JDK_Version::jdk(8),  JDK_Version::jdk(9) },
-  { "MinPermHeapExpansion", JDK_Version::jdk(8),  JDK_Version::jdk(9) },
-  { "MaxPermHeapExpansion", JDK_Version::jdk(8),  JDK_Version::jdk(9) },
-  { "CMSRevisitStackSize",           JDK_Version::jdk(8), JDK_Version::jdk(9) },
-  { "PrintRevisitStats",             JDK_Version::jdk(8), JDK_Version::jdk(9) },
-  { "UseVectoredExceptions",         JDK_Version::jdk(8), JDK_Version::jdk(9) },
-  { "UseSplitVerifier",              JDK_Version::jdk(8), JDK_Version::jdk(9) },
-  { "UseISM",                        JDK_Version::jdk(8), JDK_Version::jdk(9) },
-  { "UsePermISM",                    JDK_Version::jdk(8), JDK_Version::jdk(9) },
-  { "UseMPSS",                       JDK_Version::jdk(8), JDK_Version::jdk(9) },
-  { "UseStringCache",                JDK_Version::jdk(8), JDK_Version::jdk(9) },
   { "UseOldInlining",                JDK_Version::jdk(9), JDK_Version::jdk(10) },
   { "SafepointPollOffset",           JDK_Version::jdk(9), JDK_Version::jdk(10) },
-#ifdef PRODUCT
-  { "DesiredMethodLimit",
-                           JDK_Version::jdk_update(7, 2), JDK_Version::jdk(8) },
-#endif // PRODUCT
-  { "UseVMInterruptibleIO",          JDK_Version::jdk(8), JDK_Version::jdk(9) },
   { "UseBoundThreads",               JDK_Version::jdk(9), JDK_Version::jdk(10) },
   { "DefaultThreadPriority",         JDK_Version::jdk(9), JDK_Version::jdk(10) },
   { "NoYieldsInMicrolock",           JDK_Version::jdk(9), JDK_Version::jdk(10) },
@@ -1910,15 +1858,8 @@
   }
 }
 
-// This must be called after ergonomics because we want bytecode rewriting
-// if the server compiler is used, or if UseSharedSpaces is disabled.
+// This must be called after ergonomics.
 void Arguments::set_bytecode_flags() {
-  // Better not attempt to store into a read-only space.
-  if (UseSharedSpaces) {
-    FLAG_SET_DEFAULT(RewriteBytecodes, false);
-    FLAG_SET_DEFAULT(RewriteFrequentPairs, false);
-  }
-
   if (!RewriteBytecodes) {
     FLAG_SET_DEFAULT(RewriteFrequentPairs, false);
   }
@@ -3223,7 +3164,8 @@
       uintx max_tenuring_thresh = 0;
       if(!parse_uintx(tail, &max_tenuring_thresh, 0)) {
         jio_fprintf(defaultStream::error_stream(),
-                    "Invalid MaxTenuringThreshold: %s\n", option->optionString);
+          "Improperly specified VM option 'MaxTenuringThreshold=%s'\n", tail);
+        return JNI_EINVAL;
       }
       FLAG_SET_CMDLINE(uintx, MaxTenuringThreshold, max_tenuring_thresh);
 
@@ -3528,15 +3470,16 @@
   if (os::is_headless_jre()) {
     const char* headless = Arguments::get_property("java.awt.headless");
     if (headless == NULL) {
-      char envbuffer[128];
-      if (!os::getenv("JAVA_AWT_HEADLESS", envbuffer, sizeof(envbuffer))) {
+      const char *headless_env = ::getenv("JAVA_AWT_HEADLESS");
+      if (headless_env == NULL) {
         if (!add_property("java.awt.headless=true")) {
           return JNI_ENOMEM;
         }
       } else {
         char buffer[256];
-        strcpy(buffer, "java.awt.headless=");
-        strcat(buffer, envbuffer);
+        const char *key = "java.awt.headless=";
+        strcpy(buffer, key);
+        strncat(buffer, headless_env, 256 - strlen(key) - 1);
         if (!add_property(buffer)) {
           return JNI_ENOMEM;
         }
@@ -3567,75 +3510,95 @@
 }
 
 jint Arguments::parse_options_environment_variable(const char* name, SysClassPath* scp_p, bool* scp_assembly_required_p) {
-  const int N_MAX_OPTIONS = 64;
-  const int OPTION_BUFFER_SIZE = 1024;
-  char buffer[OPTION_BUFFER_SIZE];
-
-  // The variable will be ignored if it exceeds the length of the buffer.
+  char *buffer = ::getenv(name);
+
   // Don't check this variable if user has special privileges
   // (e.g. unix su command).
-  if (os::getenv(name, buffer, sizeof(buffer)) &&
-      !os::have_special_privileges()) {
-    JavaVMOption options[N_MAX_OPTIONS];      // Construct option array
-    jio_fprintf(defaultStream::error_stream(),
-                "Picked up %s: %s\n", name, buffer);
-    char* rd = buffer;                        // pointer to the input string (rd)
-    int i;
-    for (i = 0; i < N_MAX_OPTIONS;) {         // repeat for all options in the input string
-      while (isspace(*rd)) rd++;              // skip whitespace
-      if (*rd == 0) break;                    // we re done when the input string is read completely
-
-      // The output, option string, overwrites the input string.
-      // Because of quoting, the pointer to the option string (wrt) may lag the pointer to
-      // input string (rd).
-      char* wrt = rd;
-
-      options[i++].optionString = wrt;        // Fill in option
-      while (*rd != 0 && !isspace(*rd)) {     // unquoted strings terminate with a space or NULL
-        if (*rd == '\'' || *rd == '"') {      // handle a quoted string
-          int quote = *rd;                    // matching quote to look for
-          rd++;                               // don't copy open quote
-          while (*rd != quote) {              // include everything (even spaces) up until quote
-            if (*rd == 0) {                   // string termination means unmatched string
-              jio_fprintf(defaultStream::error_stream(),
-                          "Unmatched quote in %s\n", name);
-              return JNI_ERR;
-            }
-            *wrt++ = *rd++;                   // copy to option string
+  if (buffer == NULL || os::have_special_privileges()) {
+    return JNI_OK;
+  }
+
+  if ((buffer = os::strdup(buffer)) == NULL) {
+    return JNI_ENOMEM;
+  }
+
+  GrowableArray<JavaVMOption> *options = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<JavaVMOption>(2, true);    // Construct option array
+  jio_fprintf(defaultStream::error_stream(),
+              "Picked up %s: %s\n", name, buffer);
+  char* rd = buffer;                        // pointer to the input string (rd)
+  while (true) {                            // repeat for all options in the input string
+    while (isspace(*rd)) rd++;              // skip whitespace
+    if (*rd == 0) break;                    // we re done when the input string is read completely
+
+    // The output, option string, overwrites the input string.
+    // Because of quoting, the pointer to the option string (wrt) may lag the pointer to
+    // input string (rd).
+    char* wrt = rd;
+
+    JavaVMOption option;
+    option.optionString = wrt;
+    options->append(option);                // Fill in option
+    while (*rd != 0 && !isspace(*rd)) {     // unquoted strings terminate with a space or NULL
+      if (*rd == '\'' || *rd == '"') {      // handle a quoted string
+        int quote = *rd;                    // matching quote to look for
+        rd++;                               // don't copy open quote
+        while (*rd != quote) {              // include everything (even spaces) up until quote
+          if (*rd == 0) {                   // string termination means unmatched string
+            jio_fprintf(defaultStream::error_stream(),
+                        "Unmatched quote in %s\n", name);
+            delete options;
+            os::free(buffer);
+            return JNI_ERR;
           }
-          rd++;                               // don't copy close quote
-        } else {
-          *wrt++ = *rd++;                     // copy to option string
+          *wrt++ = *rd++;                   // copy to option string
         }
-      }
-      // Need to check if we're done before writing a NULL,
-      // because the write could be to the byte that rd is pointing to.
-      if (*rd++ == 0) {
-        *wrt = 0;
-        break;
-      }
-      *wrt = 0;                               // Zero terminate option
-    }
-    // Construct JavaVMInitArgs structure and parse as if it was part of the command line
-    JavaVMInitArgs vm_args;
-    vm_args.version = JNI_VERSION_1_2;
-    vm_args.options = options;
-    vm_args.nOptions = i;
-    vm_args.ignoreUnrecognized = IgnoreUnrecognizedVMOptions;
-
-    if (PrintVMOptions) {
-      const char* tail;
-      for (int i = 0; i < vm_args.nOptions; i++) {
-        const JavaVMOption *option = vm_args.options + i;
-        if (match_option(option, "-XX:", &tail)) {
-          logOption(tail);
-        }
+        rd++;                               // don't copy close quote
+      } else {
+        *wrt++ = *rd++;                     // copy to option string
       }
     }
-
-    return(parse_each_vm_init_arg(&vm_args, scp_p, scp_assembly_required_p, Flag::ENVIRON_VAR));
+    // Need to check if we're done before writing a NULL,
+    // because the write could be to the byte that rd is pointing to.
+    if (*rd++ == 0) {
+      *wrt = 0;
+      break;
+    }
+    *wrt = 0;                               // Zero terminate option
+  }
+  JavaVMOption* options_arr =
+      NEW_C_HEAP_ARRAY_RETURN_NULL(JavaVMOption, options->length(), mtInternal);
+  if (options_arr == NULL) {
+    delete options;
+    os::free(buffer);
+    return JNI_ENOMEM;
+  }
+  for (int i = 0; i < options->length(); i++) {
+    options_arr[i] = options->at(i);
   }
-  return JNI_OK;
+
+  // Construct JavaVMInitArgs structure and parse as if it was part of the command line
+  JavaVMInitArgs vm_args;
+  vm_args.version = JNI_VERSION_1_2;
+  vm_args.options = options_arr;
+  vm_args.nOptions = options->length();
+  vm_args.ignoreUnrecognized = IgnoreUnrecognizedVMOptions;
+
+  if (PrintVMOptions) {
+    const char* tail;
+    for (int i = 0; i < vm_args.nOptions; i++) {
+      const JavaVMOption *option = vm_args.options + i;
+      if (match_option(option, "-XX:", &tail)) {
+        logOption(tail);
+      }
+    }
+  }
+
+  jint result = parse_each_vm_init_arg(&vm_args, scp_p, scp_assembly_required_p,
+                                       Flag::ENVIRON_VAR);
+  FREE_C_HEAP_ARRAY(JavaVMOption, options_arr);
+  delete options;
+  os::free(buffer);
+  return result;
 }
 
 void Arguments::set_shared_spaces_flags() {
--- a/hotspot/src/share/vm/runtime/frame.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/runtime/frame.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -1104,9 +1104,9 @@
 // call f() on the interpreted Method*s in the stack.
 // Have to walk the entire code cache for the compiled frames Yuck.
 void frame::metadata_do(void f(Metadata*)) {
-  if (_cb != NULL && Interpreter::contains(pc())) {
+  if (is_interpreted_frame()) {
     Method* m = this->interpreter_frame_method();
-    assert(m != NULL, "huh?");
+    assert(m != NULL, "expecting a method in this frame");
     f(m);
   }
 }
--- a/hotspot/src/share/vm/runtime/globals.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/runtime/globals.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -1342,9 +1342,6 @@
   product(intx, TraceRedefineClasses, 0,                                    \
           "Trace level for JVMTI RedefineClasses")                          \
                                                                             \
-  develop(bool, StressMethodComparator, false,                              \
-          "Run the MethodComparator on all loaded methods")                 \
-                                                                            \
   /* change to false by default sometime after Mustang */                   \
   product(bool, VerifyMergedCPBytecodes, true,                              \
           "Verify bytecodes after RedefineClasses constant pool merging")   \
--- a/hotspot/src/share/vm/runtime/mutexLocker.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/runtime/mutexLocker.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -169,7 +169,7 @@
 #define def(var, type, pri, vm_block, safepoint_check_allowed ) {      \
   var = new type(Mutex::pri, #var, vm_block, safepoint_check_allowed); \
   assert(_num_mutex < MAX_NUM_MUTEX, "increase MAX_NUM_MUTEX");        \
-  _mutex_array[_num_mutex] = var;                                      \
+  _mutex_array[_num_mutex++] = var;                                      \
 }
 
 void mutex_init() {
--- a/hotspot/src/share/vm/runtime/os.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/runtime/os.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -813,16 +813,16 @@
   st->cr();
 }
 
-void os::print_environment_variables(outputStream* st, const char** env_list,
-                                     char* buffer, int len) {
+void os::print_environment_variables(outputStream* st, const char** env_list) {
   if (env_list) {
     st->print_cr("Environment Variables:");
 
     for (int i = 0; env_list[i] != NULL; i++) {
-      if (getenv(env_list[i], buffer, len)) {
+      char *envvar = ::getenv(env_list[i]);
+      if (envvar != NULL) {
         st->print("%s", env_list[i]);
         st->print("=");
-        st->print_cr("%s", buffer);
+        st->print_cr("%s", envvar);
       }
     }
   }
--- a/hotspot/src/share/vm/runtime/os.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/runtime/os.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -164,8 +164,7 @@
   // Override me as needed
   static int    file_name_strcmp(const char* s1, const char* s2);
 
-  // get/unset environment variable
-  static bool getenv(const char* name, char* buffer, int len);
+  // unset environment variable
   static bool unsetenv(const char* name);
 
   static bool have_special_privileges();
@@ -591,7 +590,7 @@
   static void pd_print_cpu_info(outputStream* st);
   static void print_memory_info(outputStream* st);
   static void print_dll_info(outputStream* st);
-  static void print_environment_variables(outputStream* st, const char** env_list, char* buffer, int len);
+  static void print_environment_variables(outputStream* st, const char** env_list);
   static void print_context(outputStream* st, void* context);
   static void print_register_info(outputStream* st, void* context);
   static void print_siginfo(outputStream* st, void* siginfo);
--- a/hotspot/src/share/vm/runtime/stubRoutines.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/runtime/stubRoutines.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, 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
@@ -213,31 +213,35 @@
 
 // simple test for SafeFetch32
 static void test_safefetch32() {
-  int dummy = 17;
-  int* const p_invalid = (int*) get_segfault_address();
-  int* const p_valid = &dummy;
-  int result_invalid = SafeFetch32(p_invalid, 0xABC);
-  assert(result_invalid == 0xABC, "SafeFetch32 error");
-  int result_valid = SafeFetch32(p_valid, 0xABC);
-  assert(result_valid == 17, "SafeFetch32 error");
+  if (CanUseSafeFetch32()) {
+    int dummy = 17;
+    int* const p_invalid = (int*) get_segfault_address();
+    int* const p_valid = &dummy;
+    int result_invalid = SafeFetch32(p_invalid, 0xABC);
+    assert(result_invalid == 0xABC, "SafeFetch32 error");
+    int result_valid = SafeFetch32(p_valid, 0xABC);
+    assert(result_valid == 17, "SafeFetch32 error");
+  }
 }
 
 // simple test for SafeFetchN
 static void test_safefetchN() {
+  if (CanUseSafeFetchN()) {
 #ifdef _LP64
-  const intptr_t v1 = UCONST64(0xABCD00000000ABCD);
-  const intptr_t v2 = UCONST64(0xDEFD00000000DEFD);
+    const intptr_t v1 = UCONST64(0xABCD00000000ABCD);
+    const intptr_t v2 = UCONST64(0xDEFD00000000DEFD);
 #else
-  const intptr_t v1 = 0xABCDABCD;
-  const intptr_t v2 = 0xDEFDDEFD;
+    const intptr_t v1 = 0xABCDABCD;
+    const intptr_t v2 = 0xDEFDDEFD;
 #endif
-  intptr_t dummy = v1;
-  intptr_t* const p_invalid = (intptr_t*) get_segfault_address();
-  intptr_t* const p_valid = &dummy;
-  intptr_t result_invalid = SafeFetchN(p_invalid, v2);
-  assert(result_invalid == v2, "SafeFetchN error");
-  intptr_t result_valid = SafeFetchN(p_valid, v2);
-  assert(result_valid == v1, "SafeFetchN error");
+    intptr_t dummy = v1;
+    intptr_t* const p_invalid = (intptr_t*) get_segfault_address();
+    intptr_t* const p_valid = &dummy;
+    intptr_t result_invalid = SafeFetchN(p_invalid, v2);
+    assert(result_invalid == v2, "SafeFetchN error");
+    intptr_t result_valid = SafeFetchN(p_valid, v2);
+    assert(result_valid == v1, "SafeFetchN error");
+  }
 }
 #endif
 
--- a/hotspot/src/share/vm/runtime/stubRoutines.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/runtime/stubRoutines.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -450,7 +450,11 @@
 
 
 // returns true if SafeFetch32 and SafeFetchN can be used safely (stubroutines are already generated)
-inline bool CanUseSafeFetch32() { return StubRoutines::SafeFetch32_stub() ? true : false; }
-inline bool CanUseSafeFetchN()  { return StubRoutines::SafeFetchN_stub() ? true : false; }
+inline bool CanUseSafeFetch32() {
+  return StubRoutines::SafeFetch32_stub() ? true : false;
+}
 
+inline bool CanUseSafeFetchN() {
+  return StubRoutines::SafeFetchN_stub() ? true : false;
+}
 #endif // SHARE_VM_RUNTIME_STUBROUTINES_HPP
--- a/hotspot/src/share/vm/runtime/thread.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/runtime/thread.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -272,6 +272,11 @@
 #endif // ASSERT
 }
 
+// Non-inlined version to be used where thread.inline.hpp shouldn't be included.
+Thread* Thread::current_noinline() {
+  return Thread::current();
+}
+
 void Thread::initialize_thread_local_storage() {
   // Note: Make sure this method only calls
   // non-blocking operations. Otherwise, it might not work
@@ -754,13 +759,9 @@
       return true;
     } else {
       guarantee(res == strong_roots_parity, "Or else what?");
-      assert(SharedHeap::heap()->workers()->active_workers() > 0,
-             "Should only fail when parallel.");
       return false;
     }
   }
-  assert(SharedHeap::heap()->workers()->active_workers() > 0,
-         "Should only fail when parallel.");
   return false;
 }
 
@@ -4056,7 +4057,7 @@
          "Not in range.");
 }
 
-#ifndef PRODUCT
+#ifdef ASSERT
 void Threads::assert_all_threads_claimed() {
   ALL_JAVA_THREADS(p) {
     const int thread_parity = p->oops_do_parity();
@@ -4064,22 +4065,9 @@
         err_msg("Thread " PTR_FORMAT " has incorrect parity %d != %d", p2i(p), thread_parity, _thread_claim_parity));
   }
 }
-#endif // PRODUCT
-
-void Threads::possibly_parallel_oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf) {
-  // Introduce a mechanism allowing parallel threads to claim threads as
-  // root groups.  Overhead should be small enough to use all the time,
-  // even in sequential code.
-  SharedHeap* sh = SharedHeap::heap();
-  // Cannot yet substitute active_workers for n_par_threads
-  // because of G1CollectedHeap::verify() use of
-  // SharedHeap::process_roots().  n_par_threads == 0 will
-  // turn off parallelism in process_roots while active_workers
-  // is being used for parallelism elsewhere.
-  bool is_par = sh->n_par_threads() > 0;
-  assert(!is_par ||
-         (SharedHeap::heap()->n_par_threads() ==
-         SharedHeap::heap()->workers()->active_workers()), "Mismatch");
+#endif // ASSERT
+
+void Threads::possibly_parallel_oops_do(bool is_par, OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf) {
   int cp = Threads::thread_claim_parity();
   ALL_JAVA_THREADS(p) {
     if (p->claim_oops_do(is_par, cp)) {
--- a/hotspot/src/share/vm/runtime/thread.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/runtime/thread.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -324,6 +324,8 @@
 
   // Returns the current thread
   static inline Thread* current();
+  // ... without having to include thread.inline.hpp.
+  static Thread* current_noinline();
 
   // Common thread operations
   static void set_priority(Thread* thread, ThreadPriority priority);
@@ -1886,15 +1888,28 @@
   // Does not include JNI_VERSION_1_1
   static jboolean is_supported_jni_version(jint version);
 
+  // The "thread claim parity" provides a way for threads to be claimed
+  // by parallel worker tasks.
+  //
+  // Each thread contains a a "parity" field. A task will claim the
+  // thread only if its parity field is the same as the global parity,
+  // which is updated by calling change_thread_claim_parity().
+  //
+  // For this to work change_thread_claim_parity() needs to be called
+  // exactly once in sequential code before starting parallel tasks
+  // that should claim threads.
+  //
+  // New threads get their parity set to 0 and change_thread_claim_parity()
+  // never set the global parity to 0.
   static int thread_claim_parity() { return _thread_claim_parity; }
   static void change_thread_claim_parity();
+  static void assert_all_threads_claimed() NOT_DEBUG_RETURN;
 
-  static void assert_all_threads_claimed() PRODUCT_RETURN;
   // Apply "f->do_oop" to all root oops in all threads.
   // This version may only be called by sequential code.
   static void oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf);
   // This version may be called by sequential or parallel code.
-  static void possibly_parallel_oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf);
+  static void possibly_parallel_oops_do(bool is_par, OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf);
   // This creates a list of GCTasks, one per thread.
   static void create_thread_roots_tasks(GCTaskQueue* q);
   // This creates a list of GCTasks, one per thread, for marking objects.
--- a/hotspot/src/share/vm/runtime/virtualspace.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/runtime/virtualspace.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -37,13 +37,22 @@
     _alignment(0), _special(false), _executable(false) {
 }
 
-ReservedSpace::ReservedSpace(size_t size) {
+ReservedSpace::ReservedSpace(size_t size, size_t preferred_page_size) {
+  bool has_preferred_page_size = preferred_page_size != 0;
   // Want to use large pages where possible and pad with small pages.
-  size_t page_size = os::page_size_for_region_unaligned(size, 1);
+  size_t page_size = has_preferred_page_size ? preferred_page_size : os::page_size_for_region_unaligned(size, 1);
   bool large_pages = page_size != (size_t)os::vm_page_size();
-  // Don't force the alignment to be large page aligned,
-  // since that will waste memory.
-  size_t alignment = os::vm_allocation_granularity();
+  size_t alignment;
+  if (large_pages && has_preferred_page_size) {
+    alignment = MAX2(page_size, (size_t)os::vm_allocation_granularity());
+    // ReservedSpace initialization requires size to be aligned to the given
+    // alignment. Align the size up.
+    size = align_size_up(size, alignment);
+  } else {
+    // Don't force the alignment to be large page aligned,
+    // since that will waste memory.
+    alignment = os::vm_allocation_granularity();
+  }
   initialize(size, alignment, large_pages, NULL, false);
 }
 
--- a/hotspot/src/share/vm/runtime/virtualspace.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/runtime/virtualspace.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -51,7 +51,11 @@
  public:
   // Constructor
   ReservedSpace();
-  ReservedSpace(size_t size);
+  // Initialize the reserved space with the given size. If preferred_page_size
+  // is set, use this as minimum page size/alignment. This may waste some space
+  // if the given size is not aligned to that value, as the reservation will be
+  // aligned up to the final alignment in this case.
+  ReservedSpace(size_t size, size_t preferred_page_size = 0);
   ReservedSpace(size_t size, size_t alignment, bool large,
                 char* requested_address = NULL);
   ReservedSpace(size_t size, size_t alignment, bool large, bool executable);
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -558,7 +558,6 @@
     static_field(GenCollectedHeap,             _gch,                                          GenCollectedHeap*)                     \
   nonstatic_field(GenCollectedHeap,            _young_gen,                                    Generation*)                           \
   nonstatic_field(GenCollectedHeap,            _old_gen,                                      Generation*)                           \
- nonstatic_field(GenCollectedHeap,             _n_gens,                                       int)                                   \
                                                                                                                                      \
   nonstatic_field(GenCollectorPolicy,          _young_gen_spec,                               GenerationSpec*)                       \
   nonstatic_field(GenCollectorPolicy,          _old_gen_spec,                                 GenerationSpec*)                       \
@@ -1501,8 +1500,7 @@
   /******************************************/                            \
                                                                           \
   declare_toplevel_type(CollectedHeap)                                    \
-           declare_type(SharedHeap,                   CollectedHeap)      \
-           declare_type(GenCollectedHeap,             SharedHeap)         \
+           declare_type(GenCollectedHeap,             CollectedHeap)      \
   declare_toplevel_type(Generation)                                       \
            declare_type(DefNewGeneration,             Generation)         \
            declare_type(CardGeneration,               Generation)         \
@@ -2265,8 +2263,6 @@
   declare_constant(CollectedHeap::ParallelScavengeHeap)                   \
   declare_constant(CollectedHeap::G1CollectedHeap)                        \
                                                                           \
-  declare_constant(GenCollectedHeap::max_gens)                            \
-                                                                          \
   /* constants from Generation::Name enum */                              \
                                                                           \
   declare_constant(Generation::DefNew)                                    \
--- a/hotspot/src/share/vm/services/diagnosticCommand.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -32,6 +32,7 @@
 #include "services/diagnosticArgument.hpp"
 #include "services/diagnosticCommand.hpp"
 #include "services/diagnosticFramework.hpp"
+#include "services/writeableFlags.hpp"
 #include "services/heapDumper.hpp"
 #include "services/management.hpp"
 #include "utilities/macros.hpp"
@@ -50,6 +51,7 @@
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CommandLineDCmd>(full_export, true, false));
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<PrintSystemPropertiesDCmd>(full_export, true, false));
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<PrintVMFlagsDCmd>(full_export, true, false));
+  DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<SetVMFlagDCmd>(full_export, true, false));
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VMDynamicLibrariesDCmd>(full_export, true, false));
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VMUptimeDCmd>(full_export, true, false));
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<SystemGCDCmd>(full_export, true, false));
@@ -62,6 +64,9 @@
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<SymboltableDCmd>(full_export, true, false));
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<StringtableDCmd>(full_export, true, false));
 #endif // INCLUDE_SERVICES
+#if INCLUDE_JVMTI
+  DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JVMTIDataDumpDCmd>(full_export, true, false));
+#endif // INCLUDE_JVMTI
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ThreadDumpDCmd>(full_export, true, false));
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<RotateGCLogDCmd>(full_export, true, false));
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassLoaderStatsDCmd>(full_export, true, false));
@@ -76,6 +81,7 @@
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JMXStartRemoteDCmd>(jmx_agent_export_flags, true,false));
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JMXStartLocalDCmd>(jmx_agent_export_flags, true,false));
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JMXStopRemoteDCmd>(jmx_agent_export_flags, true,false));
+  DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JMXStatusDCmd>(jmx_agent_export_flags, true,false));
 
 }
 
@@ -197,6 +203,46 @@
     }
 }
 
+SetVMFlagDCmd::SetVMFlagDCmd(outputStream* output, bool heap) :
+                                   DCmdWithParser(output, heap),
+  _flag("flag name", "The name of the flag we want to set",
+        "STRING", true),
+  _value("string value", "The value we want to set", "STRING", false) {
+  _dcmdparser.add_dcmd_argument(&_flag);
+  _dcmdparser.add_dcmd_argument(&_value);
+}
+
+void SetVMFlagDCmd::execute(DCmdSource source, TRAPS) {
+  const char* val = NULL;
+  if (_value.value() != NULL) {
+    val = _value.value();
+  }
+
+  FormatBuffer<80> err_msg("%s", "");
+  int ret = WriteableFlags::set_flag(_flag.value(), val, Flag::MANAGEMENT, err_msg);
+
+  if (ret != WriteableFlags::SUCCESS) {
+    output()->print_cr("%s", err_msg.buffer());
+  }
+}
+
+int SetVMFlagDCmd::num_arguments() {
+  ResourceMark rm;
+  SetVMFlagDCmd* dcmd = new SetVMFlagDCmd(NULL, false);
+  if (dcmd != NULL) {
+    DCmdMark mark(dcmd);
+    return dcmd->_dcmdparser.num_arguments();
+  } else {
+    return 0;
+  }
+}
+
+void JVMTIDataDumpDCmd::execute(DCmdSource source, TRAPS) {
+  if (JvmtiExport::should_post_data_dump()) {
+    JvmtiExport::post_data_dump();
+  }
+}
+
 void PrintSystemPropertiesDCmd::execute(DCmdSource source, TRAPS) {
   // load sun.misc.VMSupport
   Symbol* klass = vmSymbols::sun_misc_VMSupport();
@@ -663,6 +709,38 @@
     JavaCalls::call_static(&result, ik, vmSymbols::stopRemoteAgent_name(), vmSymbols::void_method_signature(), CHECK);
 }
 
+JMXStatusDCmd::JMXStatusDCmd(outputStream *output, bool heap_allocated) :
+  DCmd(output, heap_allocated) {
+  // do nothing
+}
+
+void JMXStatusDCmd::execute(DCmdSource source, TRAPS) {
+  ResourceMark rm(THREAD);
+  HandleMark hm(THREAD);
+
+  // Load and initialize the sun.management.Agent class
+  // invoke getManagementAgentStatus() method to generate the status info
+  // throw java.lang.NoSuchMethodError if method doesn't exist
+
+  Handle loader = Handle(THREAD, SystemDictionary::java_system_loader());
+  Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::sun_management_Agent(), loader, Handle(), true, CHECK);
+  instanceKlassHandle ik (THREAD, k);
+
+  JavaValue result(T_OBJECT);
+  JavaCalls::call_static(&result, ik, vmSymbols::getAgentStatus_name(), vmSymbols::void_string_signature(), CHECK);
+
+  jvalue* jv = (jvalue*) result.get_value_addr();
+  oop str = (oop) jv->l;
+  if (str != NULL) {
+      char* out = java_lang_String::as_utf8_string(str);
+      if (out) {
+          output()->print_cr("%s", out);
+          return;
+      }
+  }
+  output()->print_cr("Error obtaining management agent status");
+}
+
 VMDynamicLibrariesDCmd::VMDynamicLibrariesDCmd(outputStream *output, bool heap_allocated) :
   DCmd(output, heap_allocated) {
   // do nothing
--- a/hotspot/src/share/vm/services/diagnosticCommand.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/services/diagnosticCommand.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -131,6 +131,48 @@
   virtual void execute(DCmdSource source, TRAPS);
 };
 
+class SetVMFlagDCmd : public DCmdWithParser {
+protected:
+  DCmdArgument<char*> _flag;
+  DCmdArgument<char*> _value;
+
+public:
+  SetVMFlagDCmd(outputStream* output, bool heap);
+  static const char* name() { return "VM.set_flag"; }
+  static const char* description() {
+    return "Sets VM flag option using the provided value.";
+  }
+  static const char* impact() {
+    return "Low";
+  }
+  static const JavaPermission permission() {
+    JavaPermission p = {"java.lang.management.ManagementPermission",
+                        "control", NULL};
+    return p;
+  }
+  static int num_arguments();
+  virtual void execute(DCmdSource source, TRAPS);
+};
+
+class JVMTIDataDumpDCmd : public DCmd {
+public:
+  JVMTIDataDumpDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
+  static const char* name() { return "JVMTI.data_dump"; }
+  static const char* description() {
+    return "Signal the JVM to do a data-dump request for JVMTI.";
+  }
+  static const char* impact() {
+    return "High";
+  }
+  static const JavaPermission permission() {
+    JavaPermission p = {"java.lang.management.ManagementPermission",
+                        "monitor", NULL};
+    return p;
+  }
+  static int num_arguments() { return 0; }
+  virtual void execute(DCmdSource source, TRAPS);
+};
+
 class VMDynamicLibrariesDCmd : public DCmd {
 public:
   VMDynamicLibrariesDCmd(outputStream* output, bool heap);
@@ -410,6 +452,29 @@
   virtual void execute(DCmdSource source, TRAPS);
 };
 
+// Print the JMX system status
+class JMXStatusDCmd : public DCmd {
+public:
+  JMXStatusDCmd(outputStream *output, bool heap_allocated);
+
+  static const char *name() {
+    return "ManagementAgent.status";
+  }
+
+  static const char *description() {
+    return "Print the management agent status.";
+  }
+
+  static const JavaPermission permission() {
+    JavaPermission p = {"java.lang.management.ManagementPermission",
+                        "monitor", NULL};
+    return p;
+  }
+
+  virtual void execute(DCmdSource source, TRAPS);
+
+};
+
 class RotateGCLogDCmd : public DCmd {
 public:
   RotateGCLogDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
--- a/hotspot/src/share/vm/services/memTracker.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/services/memTracker.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -47,9 +47,9 @@
 NMT_TrackingLevel MemTracker::init_tracking_level() {
   NMT_TrackingLevel level = NMT_off;
   char buf[64];
-  char nmt_option[64];
   jio_snprintf(buf, sizeof(buf), "NMT_LEVEL_%d", os::current_process_id());
-  if (os::getenv(buf, nmt_option, sizeof(nmt_option))) {
+  const char *nmt_option = ::getenv(buf);
+  if (nmt_option != NULL) {
     if (strcmp(nmt_option, "summary") == 0) {
       level = NMT_summary;
     } else if (strcmp(nmt_option, "detail") == 0) {
@@ -311,4 +311,3 @@
   out->print_cr(" ");
   walker.report_statistics(out);
 }
-
--- a/hotspot/src/share/vm/services/memoryManager.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/services/memoryManager.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -53,20 +53,6 @@
   volatile instanceOop _memory_mgr_obj;
 
 public:
-  enum Name {
-    Abstract,
-    CodeCache,
-    Metaspace,
-    Copy,
-    MarkSweepCompact,
-    ParNew,
-    ConcurrentMarkSweep,
-    PSScavenge,
-    PSMarkSweep,
-    G1YoungGen,
-    G1OldGen
-  };
-
   MemoryManager();
 
   int num_memory_pools() const           { return _num_pools; }
@@ -80,7 +66,6 @@
   bool is_manager(instanceHandle mh)     { return mh() == _memory_mgr_obj; }
 
   virtual instanceOop get_memory_manager_instance(TRAPS);
-  virtual MemoryManager::Name kind()     { return MemoryManager::Abstract; }
   virtual bool is_gc_memory_manager()    { return false; }
   virtual const char* name() = 0;
 
@@ -98,7 +83,6 @@
   static GCMemoryManager* get_psMarkSweep_memory_manager();
   static GCMemoryManager* get_g1YoungGen_memory_manager();
   static GCMemoryManager* get_g1OldGen_memory_manager();
-
 };
 
 class CodeCacheMemoryManager : public MemoryManager {
@@ -106,16 +90,14 @@
 public:
   CodeCacheMemoryManager() : MemoryManager() {}
 
-  MemoryManager::Name kind() { return MemoryManager::CodeCache; }
-  const char* name()         { return "CodeCacheManager"; }
+  const char* name() { return "CodeCacheManager"; }
 };
 
 class MetaspaceMemoryManager : public MemoryManager {
 public:
   MetaspaceMemoryManager() : MemoryManager() {}
 
-  MemoryManager::Name kind() { return MemoryManager::Metaspace; }
-  const char *name()         { return "Metaspace Manager"; }
+  const char* name() { return "Metaspace Manager"; }
 };
 
 class GCStatInfo : public ResourceObj {
@@ -202,7 +184,6 @@
 
   void set_notification_enabled(bool enabled) { _notification_enabled = enabled; }
   bool is_notification_enabled() { return _notification_enabled; }
-  virtual MemoryManager::Name kind() = 0;
 };
 
 // These subclasses of GCMemoryManager are defined to include
@@ -213,8 +194,7 @@
 public:
   CopyMemoryManager() : GCMemoryManager() {}
 
-  MemoryManager::Name kind() { return MemoryManager::Copy; }
-  const char* name()         { return "Copy"; }
+  const char* name() { return "Copy"; }
 };
 
 class MSCMemoryManager : public GCMemoryManager {
@@ -222,9 +202,7 @@
 public:
   MSCMemoryManager() : GCMemoryManager() {}
 
-  MemoryManager::Name kind() { return MemoryManager::MarkSweepCompact; }
-  const char* name()         { return "MarkSweepCompact"; }
-
+  const char* name() { return "MarkSweepCompact"; }
 };
 
 class ParNewMemoryManager : public GCMemoryManager {
@@ -232,9 +210,7 @@
 public:
   ParNewMemoryManager() : GCMemoryManager() {}
 
-  MemoryManager::Name kind() { return MemoryManager::ParNew; }
-  const char* name()         { return "ParNew"; }
-
+  const char* name() { return "ParNew"; }
 };
 
 class CMSMemoryManager : public GCMemoryManager {
@@ -242,9 +218,7 @@
 public:
   CMSMemoryManager() : GCMemoryManager() {}
 
-  MemoryManager::Name kind() { return MemoryManager::ConcurrentMarkSweep; }
-  const char* name()         { return "ConcurrentMarkSweep";}
-
+  const char* name() { return "ConcurrentMarkSweep";}
 };
 
 class PSScavengeMemoryManager : public GCMemoryManager {
@@ -252,9 +226,7 @@
 public:
   PSScavengeMemoryManager() : GCMemoryManager() {}
 
-  MemoryManager::Name kind() { return MemoryManager::PSScavenge; }
-  const char* name()         { return "PS Scavenge"; }
-
+  const char* name() { return "PS Scavenge"; }
 };
 
 class PSMarkSweepMemoryManager : public GCMemoryManager {
@@ -262,8 +234,7 @@
 public:
   PSMarkSweepMemoryManager() : GCMemoryManager() {}
 
-  MemoryManager::Name kind() { return MemoryManager::PSMarkSweep; }
-  const char* name()         { return "PS MarkSweep"; }
+  const char* name() { return "PS MarkSweep"; }
 };
 
 class G1YoungGenMemoryManager : public GCMemoryManager {
@@ -271,8 +242,7 @@
 public:
   G1YoungGenMemoryManager() : GCMemoryManager() {}
 
-  MemoryManager::Name kind() { return MemoryManager::G1YoungGen; }
-  const char* name()         { return "G1 Young Generation"; }
+  const char* name() { return "G1 Young Generation"; }
 };
 
 class G1OldGenMemoryManager : public GCMemoryManager {
@@ -280,8 +250,7 @@
 public:
   G1OldGenMemoryManager() : GCMemoryManager() {}
 
-  MemoryManager::Name kind() { return MemoryManager::G1OldGen; }
-  const char* name()         { return "G1 Old Generation"; }
+  const char* name() { return "G1 Old Generation"; }
 };
 
 #endif // SHARE_VM_SERVICES_MEMORYMANAGER_HPP
--- a/hotspot/src/share/vm/services/memoryService.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/services/memoryService.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -126,9 +126,8 @@
   CollectorPolicy* policy = heap->collector_policy();
 
   assert(policy->is_generation_policy(), "Only support two generations");
-  guarantee(heap->n_gens() == 2, "Only support two-generation heap");
-
   GenCollectorPolicy* gen_policy = policy->as_generation_policy();
+  guarantee(gen_policy->number_of_generations() == 2, "Only support two-generation heap");
   if (gen_policy != NULL) {
     Generation::Name kind = gen_policy->young_gen_spec()->name();
     switch (kind) {
--- a/hotspot/src/share/vm/utilities/growableArray.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/utilities/growableArray.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -168,6 +168,8 @@
   GrowableArray(int initial_size, bool C_heap = false, MEMFLAGS F = mtInternal)
     : GenericGrowableArray(initial_size, 0, C_heap, F) {
     _data = (E*)raw_allocate(sizeof(E));
+// Needed for Visual Studio 2012 and older
+#pragma warning(suppress: 4345)
     for (int i = 0; i < _max; i++) ::new ((void*)&_data[i]) E();
   }
 
@@ -385,6 +387,8 @@
     E* newData = (E*)raw_allocate(sizeof(E));
     int i = 0;
     for (     ; i < _len; i++) ::new ((void*)&newData[i]) E(_data[i]);
+// Needed for Visual Studio 2012 and older
+#pragma warning(suppress: 4345)
     for (     ; i < _max; i++) ::new ((void*)&newData[i]) E();
     for (i = 0; i < old_max; i++) _data[i].~E();
     if (on_C_heap() && _data != NULL) {
--- a/hotspot/src/share/vm/utilities/stack.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/utilities/stack.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -96,11 +96,16 @@
 public:
   friend class StackIterator<E, F>;
 
+  // Number of elements that fit in 4K bytes minus the size of two pointers
+  // (link field and malloc header).
+  static const size_t _default_segment_size =  (4096 - 2 * sizeof(E*)) / sizeof(E);
+  static size_t default_segment_size() { return _default_segment_size; }
+
   // segment_size:    number of items per segment
   // max_cache_size:  maxmium number of *segments* to cache
   // max_size:        maximum number of items allowed, rounded to a multiple of
   //                  the segment size (0 == unlimited)
-  inline Stack(size_t segment_size = default_segment_size(),
+  inline Stack(size_t segment_size = _default_segment_size,
                size_t max_cache_size = 4, size_t max_size = 0);
   inline ~Stack() { clear(true); }
 
@@ -122,8 +127,6 @@
   // clear_cache is true, also release any cached segments.
   void clear(bool clear_cache = false);
 
-  static inline size_t default_segment_size();
-
 protected:
   // Each segment includes space for _seg_size elements followed by a link
   // (pointer) to the previous segment; the space is allocated as a single block
--- a/hotspot/src/share/vm/utilities/stack.inline.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/utilities/stack.inline.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -86,14 +86,6 @@
 }
 
 template <class E, MEMFLAGS F>
-size_t Stack<E, F>::default_segment_size()
-{
-  // Number of elements that fit in 4K bytes minus the size of two pointers
-  // (link field and malloc header).
-  return (4096 - 2 * sizeof(E*)) / sizeof(E);
-}
-
-template <class E, MEMFLAGS F>
 size_t Stack<E, F>::adjust_segment_size(size_t seg_size)
 {
   const size_t elem_sz = sizeof(E);
--- a/hotspot/src/share/vm/utilities/vmError.cpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/utilities/vmError.cpp	Thu Apr 16 14:05:48 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, 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
@@ -768,7 +768,7 @@
   STEP(220, "(printing environment variables)" )
 
      if (_verbose) {
-       os::print_environment_variables(st, env_list, buf, sizeof(buf));
+       os::print_environment_variables(st, env_list);
        st->cr();
      }
 
--- a/hotspot/src/share/vm/utilities/workgroup.hpp	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/src/share/vm/utilities/workgroup.hpp	Thu Apr 16 14:05:48 2015 -0700
@@ -340,18 +340,6 @@
   }
 };
 
-// Work gangs in garbage collectors: 2009-06-10
-//
-// SharedHeap - work gang for stop-the-world parallel collection.
-//   Used by
-//     ParNewGeneration
-//     CMSParRemarkTask
-//     CMSRefProcTaskExecutor
-//     G1CollectedHeap
-//     G1ParFinalCountTask
-// ConcurrentMark
-// CMSCollector
-
 // A class that acts as a synchronisation barrier. Workers enter
 // the barrier and must wait until all other workers have entered
 // before any of them may leave.
--- a/hotspot/test/TEST.groups	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/test/TEST.groups	Thu Apr 16 14:05:48 2015 -0700
@@ -394,6 +394,7 @@
 hotspot_gc = \
   sanity/ExecuteInternalVMTests.java \
   gc/ \
+  -gc/g1/TestGreyReclaimedHumongousObjects.java \
   -gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java
 
 hotspot_gc_closed = \
--- a/hotspot/test/compiler/startup/NumCompilerThreadsCheck.java	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/test/compiler/startup/NumCompilerThreadsCheck.java	Thu Apr 16 14:05:48 2015 -0700
@@ -40,20 +40,10 @@
     String expectedOutput = "CICompilerCount of -1 is invalid";
     out.shouldContain(expectedOutput);
 
-    if (isZeroVm()) {
+    if (Platform.isZero()) {
       String expectedLowWaterMarkText = "must be at least 0";
       out.shouldContain(expectedLowWaterMarkText);
     }
   }
 
-  private static boolean isZeroVm() {
-    String vmName = System.getProperty("java.vm.name");
-    if (vmName == null) {
-      throw new RuntimeException("No VM name");
-    }
-    if (vmName.toLowerCase().contains("zero")) {
-      return true;
-    }
-    return false;
-  }
 }
--- a/hotspot/test/gc/arguments/TestInitialTenuringThreshold.java	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/test/gc/arguments/TestInitialTenuringThreshold.java	Thu Apr 16 14:05:48 2015 -0700
@@ -70,6 +70,7 @@
     runWithThresholds(10, 0, true);
     runWithThresholds(9, 8, true);
     runWithThresholds(-1, 8, true);
+    runWithThresholds(0, -1, true);
     runWithThresholds(8, -1, true);
     runWithThresholds(16, 8, true);
     runWithThresholds(8, 17, true);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/arguments/TestVerifyBeforeAndAfterGCFlags.java	Thu Apr 16 14:05:48 2015 -0700
@@ -0,0 +1,119 @@
+/*
+* Copyright (c) 2015, 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
+* under the terms of the GNU General Public License version 2 only, as
+* published by the Free Software Foundation.
+*
+* This code is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+* version 2 for more details (a copy is included in the LICENSE file that
+* accompanied this code).
+*
+* You should have received a copy of the GNU General Public License version
+* 2 along with this work; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+*
+* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+* or visit www.oracle.com if you need additional information or have any
+* questions.
+*/
+
+/*
+ * @test TestVerifyBeforeAndAfterGCFlags
+ * @key gc
+ * @bug 8000831
+ * @summary Runs an simple application (GarbageProducer) with various
+         combinations of -XX:{+|-}Verify{After|Before}GC flags and checks that
+         output contain or doesn't contain expected patterns
+ * @modules java.management
+ * @library /testlibrary
+ * @run driver TestVerifyBeforeAndAfterGCFlags
+ */
+
+import java.util.ArrayList;
+import java.util.Collections;
+
+import com.oracle.java.testlibrary.Utils;
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.ProcessTools;
+
+public class TestVerifyBeforeAndAfterGCFlags {
+
+    // VerifyBeforeGC:[Verifying threads heap tenured eden syms strs zone dict metaspace chunks hand C-heap code cache ]
+    public static final String VERIFY_BEFORE_GC_PATTERN = "VerifyBeforeGC:\\[Verifying\\s+([^]\\s]+\\s+)+\\]";
+    // VerifyBeforeGC: VerifyBeforeGC: VerifyBeforeGC:
+    public static final String VERIFY_BEFORE_GC_CORRUPTED_PATTERN = "VerifyBeforeGC:(?!\\[Verifying[^]]+\\])";
+
+    // VerifyAfterGC:[Verifying threads heap tenured eden syms strs zone dict metaspace chunks hand C-heap code cache ]
+    public static final String VERIFY_AFTER_GC_PATTERN = "VerifyAfterGC:\\[Verifying\\s+([^]\\s]+\\s+)+\\]";
+    // VerifyAfterGC: VerifyAfterGC: VerifyAfterGC:
+    public static final String VERIFY_AFTER_GC_CORRUPTED_PATTERN = "VerifyAfterGC:(?!\\[Verifying[^]]+\\])";
+
+    public static void main(String args[]) throws Exception {
+        String[] filteredOpts = Utils.getFilteredTestJavaOpts(
+                                    new String[] { "-Xloggc:",
+                                                   "-XX:+UseGCLogFileRotation",
+                                                   "-XX:-DisplayVMOutput",
+                                                   "VerifyBeforeGC",
+                                                   "VerifyAfterGC" });
+        testVerifyFlags(false, false, filteredOpts);
+        testVerifyFlags(true,  true,  filteredOpts);
+        testVerifyFlags(true,  false, filteredOpts);
+        testVerifyFlags(false, true,  filteredOpts);
+    }
+
+    public static void testVerifyFlags(boolean verifyBeforeGC,
+                                       boolean verifyAfterGC,
+                                       String[] opts) throws Exception {
+        ArrayList<String> vmOpts = new ArrayList<>();
+        if (opts != null && (opts.length > 0)) {
+            Collections.addAll(vmOpts, opts);
+        }
+
+        Collections.addAll(vmOpts, new String[] {
+                                       "-Xmx5m",
+                                       "-Xms5m",
+                                       "-Xmn3m",
+                                       "-XX:+UnlockDiagnosticVMOptions",
+                                       (verifyBeforeGC ? "-XX:+VerifyBeforeGC"
+                                                       : "-XX:-VerifyBeforeGC"),
+                                       (verifyAfterGC ? "-XX:+VerifyAfterGC"
+                                                      : "-XX:-VerifyAfterGC"),
+                                       GarbageProducer.class.getName() });
+        ProcessBuilder procBuilder =
+            ProcessTools.createJavaProcessBuilder(vmOpts.toArray(
+                                                   new String[vmOpts.size()]));
+        OutputAnalyzer analyzer = new OutputAnalyzer(procBuilder.start());
+
+        analyzer.shouldHaveExitValue(0);
+        analyzer.shouldNotMatch(VERIFY_BEFORE_GC_CORRUPTED_PATTERN);
+        analyzer.shouldNotMatch(VERIFY_AFTER_GC_CORRUPTED_PATTERN);
+
+        if (verifyBeforeGC) {
+            analyzer.shouldMatch(VERIFY_BEFORE_GC_PATTERN);
+        } else {
+            analyzer.shouldNotMatch(VERIFY_BEFORE_GC_PATTERN);
+        }
+
+        if (verifyAfterGC) {
+            analyzer.shouldMatch(VERIFY_AFTER_GC_PATTERN);
+        } else {
+            analyzer.shouldNotMatch(VERIFY_AFTER_GC_PATTERN);
+        }
+    }
+
+    public static class GarbageProducer {
+        static long[][] garbage = new long[10][];
+
+        public static void main(String args[]) {
+            int j = 0;
+            for(int i = 0; i<1000; i++) {
+                garbage[j] = new long[10000];
+                j = (j+1)%garbage.length;
+            }
+        }
+    }
+}
--- a/hotspot/test/gc/g1/TestGCLogMessages.java	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/test/gc/g1/TestGCLogMessages.java	Thu Apr 16 14:05:48 2015 -0700
@@ -66,7 +66,6 @@
         new LogMessageWithLevel("SystemDictionary Roots", Level.FINEST),
         new LogMessageWithLevel("CLDG Roots", Level.FINEST),
         new LogMessageWithLevel("JVMTI Roots", Level.FINEST),
-        new LogMessageWithLevel("CodeCache Roots", Level.FINEST),
         new LogMessageWithLevel("SATB Filtering", Level.FINEST),
         new LogMessageWithLevel("CM RefProcessor Roots", Level.FINEST),
         new LogMessageWithLevel("Wait For Strong CLD", Level.FINEST),
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/g1/TestGreyReclaimedHumongousObjects.java	Thu Apr 16 14:05:48 2015 -0700
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test TestGreyReclaimedHumongousObjects.java
+ * @bug 8069367
+ * @requires vm.gc == "G1" | vm.gc == "null"
+ * @summary Test handling of marked but unscanned reclaimed humongous objects.
+ * @key gc
+ * @run main/othervm -XX:+UseG1GC -Xss32m -Xmx128m -XX:G1HeapRegionSize=1m
+ *      -XX:+UnlockExperimentalVMOptions
+ *          -XX:+G1EagerReclaimHumongousObjects
+ *          -XX:+G1EagerReclaimHumongousObjectsWithStaleRefs
+ *      TestGreyReclaimedHumongousObjects 1048576 90
+ */
+
+// This test spawns a bunch of threads, each of them rapidly
+// allocating large objects and storing them into a circular buffer
+// associated with the thread.  The circular buffer results in these
+// objects becoming dead in fairly short order.
+//
+// The situation we're trying to provoke is
+//
+// (1) A humongous object H is marked and added to the mark stack.
+//
+// (2) An evacuation pause determines H is no longer live, and
+// reclaims it.  This occurs before concurrent marking has gotten
+// around to processing the mark stack entry for H.
+//
+// (3) Concurrent marking processes the mark stack entry for H.  The
+// bug is that it would attempt to scan the now dead object.
+//
+// Unfortunately, this test is *very* sensitive to configuration.
+// Among the parameters that affect whether / how often we'll get into
+// the desired situation within a reasonable amount of time are:
+//
+// - THREAD_COUNT: The number of allocating threads.
+//
+// - OLD_COUNT: The number of objects each thread keeps.
+//
+// - MAX_MEMORY: The maximum heap size.
+//
+// - G1HeapRegionSize
+//
+// - The size of the objects being allocated.
+//
+// The parameter values specified here:
+//
+// - THREAD_COUNT = 12
+// - OLD_COUNT == 4
+// - MAX_MEMORY == 128m
+// - G1HeapRegionSize = 1m
+// - Object size = 1048576 (2 regions after header overhead and roundup)
+//
+// seems to work well at provoking the desired state fairly quickly.
+// Even relatively small perturbations may change that.  The key
+// factors seem to be keeping the heap mostly full of live objects but
+// having them become dead fairly quickly.
+
+import java.util.Date;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+import sun.management.ManagementFactoryHelper;
+import com.sun.management.HotSpotDiagnosticMXBean;
+import com.sun.management.VMOption;
+
+public class TestGreyReclaimedHumongousObjects {
+
+    static class NamedThreadFactory implements ThreadFactory {
+       private int threadNum = 0;
+
+       @Override
+       public Thread newThread(Runnable r) {
+         return new Thread(r, THREAD_NAME + (threadNum++));
+       }
+    }
+
+    static class Runner extends Thread {
+        private final Date startDate = new Date();
+        private final int obj_size;
+        private final Object[] old_garbage;
+        private int old_index = 0;
+
+        public Runner(int obj_size) {
+            this.obj_size = obj_size;
+            old_garbage = new Object[OLD_COUNT];
+        }
+
+        private void allocate_garbage() {
+            byte[] garbage = new byte[obj_size];
+            old_garbage[Math.abs(++old_index % OLD_COUNT)] = garbage;
+        }
+
+        @Override
+        public void run() {
+            try {
+                while (!isInterrupted()) {
+                    allocate_garbage();
+                    Thread.sleep(0); // Yield, to ensure interruptable.
+                }
+            } catch (InterruptedException e) {
+                System.out.println("Aborted after "
+                                   + (new Date().getTime() - startDate.getTime())
+                                   + " ms");
+                interrupt();
+            }
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        HotSpotDiagnosticMXBean diagnostic = ManagementFactoryHelper.getDiagnosticMXBean();
+
+        System.out.println("Max memory= " + MAX_MEMORY + " bytes");
+
+        int obj_size = 0;
+        long seconds_to_run = 0;
+        if (args.length != 2) {
+            throw new RuntimeException("Object size argument must be supplied");
+        } else {
+            obj_size = Integer.parseInt(args[0]);
+            seconds_to_run = Integer.parseInt(args[1]);
+        }
+        System.out.println("Objects size= " + obj_size + " bytes");
+        System.out.println("Seconds to run=" + seconds_to_run);
+
+        int region_size =
+            Integer.parseInt(diagnostic.getVMOption("G1HeapRegionSize").getValue());
+        if (obj_size < (region_size / 2)) {
+            throw new RuntimeException("Object size " + obj_size +
+                                       " is not humongous with region size " + region_size);
+        }
+
+        ExecutorService executor =
+            Executors.newFixedThreadPool(THREAD_COUNT, new NamedThreadFactory());
+        System.out.println("Starting " + THREAD_COUNT + " threads");
+
+        for (int i = 0; i < THREAD_COUNT; i++) {
+            executor.execute(new Runner(obj_size));
+        }
+
+        Thread.sleep(seconds_to_run * 1000);
+        executor.shutdownNow();
+
+        if (!executor.awaitTermination(10, TimeUnit.SECONDS)) {
+            System.err.println("Thread pool did not terminate after 10 seconds after shutdown");
+        }
+    }
+
+    private static final long MAX_MEMORY = Runtime.getRuntime().maxMemory();
+    private static final int OLD_COUNT = 4;
+    private static final int THREAD_COUNT = 12;
+    private static final String THREAD_NAME = "TestGreyRH-";
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/g1/TestLargePageUseForAuxMemory.java	Thu Apr 16 14:05:48 2015 -0700
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test TestLargePageUseForAuxMemory.java
+ * @bug 8058354
+ * @key gc
+ * @library /testlibrary /../../test/lib
+ * @requires (vm.gc=="G1" | vm.gc=="null")
+ * @build TestLargePageUseForAuxMemory
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @summary Test that auxiliary data structures are allocated using large pages if available.
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UseG1GC -XX:+WhiteBoxAPI -XX:+IgnoreUnrecognizedVMOptions -XX:+UseLargePages TestLargePageUseForAuxMemory
+ */
+
+import com.oracle.java.testlibrary.*;
+import sun.hotspot.WhiteBox;
+
+public class TestLargePageUseForAuxMemory {
+    static final int HEAP_REGION_SIZE = 4 * 1024 * 1024;
+    static long largePageSize;
+    static long smallPageSize;
+
+    static void checkSmallTables(OutputAnalyzer output, long expectedPageSize) throws Exception {
+        output.shouldContain("G1 'Block offset table': pg_sz=" + expectedPageSize);
+        output.shouldContain("G1 'Card counts table': pg_sz=" + expectedPageSize);
+    }
+
+    static void checkBitmaps(OutputAnalyzer output, long expectedPageSize) throws Exception {
+        output.shouldContain("G1 'Prev Bitmap': pg_sz=" + expectedPageSize);
+        output.shouldContain("G1 'Next Bitmap': pg_sz=" + expectedPageSize);
+    }
+
+    static void testVM(long heapsize, boolean cardsShouldUseLargePages, boolean bitmapShouldUseLargePages) throws Exception {
+        ProcessBuilder pb;
+        // Test with large page enabled.
+        pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
+                                                   "-XX:G1HeapRegionSize=" + HEAP_REGION_SIZE,
+                                                   "-Xms" + 10 * HEAP_REGION_SIZE,
+                                                   "-Xmx" + heapsize,
+                                                   "-XX:+TracePageSizes",
+                                                   "-XX:+UseLargePages",
+                                                   "-XX:+IgnoreUnrecognizedVMOptions",  // there is on ObjectAlignmentInBytes in 32 bit builds
+                                                   "-XX:ObjectAlignmentInBytes=8",
+                                                   "-version");
+
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        checkSmallTables(output, (cardsShouldUseLargePages ? largePageSize : smallPageSize));
+        checkBitmaps(output, (bitmapShouldUseLargePages ? largePageSize : smallPageSize));
+        output.shouldHaveExitValue(0);
+
+        // Test with large page disabled.
+        pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
+                                                   "-XX:G1HeapRegionSize=" + HEAP_REGION_SIZE,
+                                                   "-Xms" + 10 * HEAP_REGION_SIZE,
+                                                   "-Xmx" + heapsize,
+                                                   "-XX:+TracePageSizes",
+                                                   "-XX:-UseLargePages",
+                                                   "-XX:+IgnoreUnrecognizedVMOptions",  // there is on ObjectAlignmentInBytes in 32 bit builds
+                                                   "-XX:ObjectAlignmentInBytes=8",
+                                                   "-version");
+
+        output = new OutputAnalyzer(pb.start());
+        checkSmallTables(output, smallPageSize);
+        checkBitmaps(output, smallPageSize);
+        output.shouldHaveExitValue(0);
+    }
+
+    public static void main(String[] args) throws Exception {
+        if (!Platform.isDebugBuild()) {
+            System.out.println("Skip tests on non-debug builds because the required option TracePageSizes is a debug-only option.");
+            return;
+        }
+
+        WhiteBox wb = WhiteBox.getWhiteBox();
+        smallPageSize = wb.getVMPageSize();
+        largePageSize = wb.getVMLargePageSize();
+
+        if (largePageSize == 0) {
+            System.out.println("Skip tests because large page support does not seem to be available on this platform.");
+            return;
+        }
+
+        // To get large pages for the card table etc. we need at least a 1G heap (with 4k page size).
+        // 32 bit systems will have problems reserving such an amount of contiguous space, so skip the
+        // test there.
+        if (!Platform.is32bit()) {
+            // Size that a single card covers.
+            final int cardSize = 512;
+
+            final long heapSizeForCardTableUsingLargePages = largePageSize * cardSize;
+
+            testVM(heapSizeForCardTableUsingLargePages, true, true);
+            testVM(heapSizeForCardTableUsingLargePages + HEAP_REGION_SIZE, true, true);
+            testVM(heapSizeForCardTableUsingLargePages - HEAP_REGION_SIZE, false, true);
+        }
+
+        // Minimum heap requirement to get large pages for bitmaps is 128M heap. This seems okay to test
+        // everywhere.
+        final int bitmapTranslationFactor = 8 * 8; // ObjectAlignmentInBytes * BitsPerByte
+        final long heapSizeForBitmapUsingLargePages = largePageSize * bitmapTranslationFactor;
+
+        testVM(heapSizeForBitmapUsingLargePages, false, true);
+        testVM(heapSizeForBitmapUsingLargePages + HEAP_REGION_SIZE, false, true);
+        testVM(heapSizeForBitmapUsingLargePages - HEAP_REGION_SIZE, false, false);
+    }
+}
+
--- a/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrs.java	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrs.java	Thu Apr 16 14:05:48 2015 -0700
@@ -39,7 +39,7 @@
     if (Platform.is64bit()) {
       pb = ProcessTools.createJavaProcessBuilder(
         "-XX:+UseCompressedClassPointers", "-XX:+UseCompressedOops",
-        "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump");
+        "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./CDSCompressedKPtrs.jsa", "-Xshare:dump");
       OutputAnalyzer output = new OutputAnalyzer(pb.start());
       try {
         output.shouldContain("Loading classes to share");
@@ -47,7 +47,7 @@
 
         pb = ProcessTools.createJavaProcessBuilder(
           "-XX:+UseCompressedClassPointers", "-XX:+UseCompressedOops",
-          "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:on", "-version");
+          "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./CDSCompressedKPtrs.jsa", "-Xshare:on", "-version");
         output = new OutputAnalyzer(pb.start());
         output.shouldContain("sharing");
         output.shouldHaveExitValue(0);
--- a/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrsError.java	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrsError.java	Thu Apr 16 14:05:48 2015 -0700
@@ -36,10 +36,12 @@
 public class CDSCompressedKPtrsError {
   public static void main(String[] args) throws Exception {
     ProcessBuilder pb;
+    String filename = "./CDSCompressedKPtrsError.jsa";
+
     if (Platform.is64bit()) {
       pb = ProcessTools.createJavaProcessBuilder(
         "-XX:+UseCompressedOops", "-XX:+UseCompressedClassPointers", "-XX:+UnlockDiagnosticVMOptions",
-        "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump");
+        "-XX:SharedArchiveFile=" + filename, "-Xshare:dump");
       OutputAnalyzer output = new OutputAnalyzer(pb.start());
       try {
         output.shouldContain("Loading classes to share");
@@ -47,21 +49,21 @@
 
         pb = ProcessTools.createJavaProcessBuilder(
           "-XX:-UseCompressedClassPointers", "-XX:-UseCompressedOops",
-          "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:on", "-version");
+          "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=" + filename, "-Xshare:on", "-version");
         output = new OutputAnalyzer(pb.start());
         output.shouldContain("Unable to use shared archive");
         output.shouldHaveExitValue(0);
 
         pb = ProcessTools.createJavaProcessBuilder(
           "-XX:-UseCompressedClassPointers", "-XX:+UseCompressedOops",
-          "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:on", "-version");
+          "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=" + filename, "-Xshare:on", "-version");
         output = new OutputAnalyzer(pb.start());
         output.shouldContain("Unable to use shared archive");
         output.shouldHaveExitValue(0);
 
         pb = ProcessTools.createJavaProcessBuilder(
           "-XX:+UseCompressedClassPointers", "-XX:-UseCompressedOops",
-          "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:on", "-version");
+          "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=" + filename, "-Xshare:on", "-version");
         output = new OutputAnalyzer(pb.start());
         output.shouldContain("Unable to use shared archive");
         output.shouldHaveExitValue(0);
@@ -74,19 +76,19 @@
       // Test bad options with -Xshare:dump.
       pb = ProcessTools.createJavaProcessBuilder(
         "-XX:-UseCompressedOops", "-XX:+UseCompressedClassPointers", "-XX:+UnlockDiagnosticVMOptions",
-        "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump");
+        "-XX:SharedArchiveFile=./CDSCompressedKPtrsErrorBad1.jsa", "-Xshare:dump");
       output = new OutputAnalyzer(pb.start());
       output.shouldContain("Cannot dump shared archive");
 
       pb = ProcessTools.createJavaProcessBuilder(
         "-XX:+UseCompressedOops", "-XX:-UseCompressedClassPointers", "-XX:+UnlockDiagnosticVMOptions",
-        "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump");
+        "-XX:SharedArchiveFile=./CDSCompressedKPtrsErrorBad2.jsa", "-Xshare:dump");
       output = new OutputAnalyzer(pb.start());
       output.shouldContain("Cannot dump shared archive");
 
       pb = ProcessTools.createJavaProcessBuilder(
         "-XX:-UseCompressedOops", "-XX:-UseCompressedClassPointers", "-XX:+UnlockDiagnosticVMOptions",
-        "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump");
+        "-XX:SharedArchiveFile=./CDSCompressedKPtrsErrorBad3.jsa", "-Xshare:dump");
       output = new OutputAnalyzer(pb.start());
       output.shouldContain("Cannot dump shared archive");
 
--- a/hotspot/test/runtime/CDSCompressedKPtrs/XShareAuto.java	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/test/runtime/CDSCompressedKPtrs/XShareAuto.java	Thu Apr 16 14:05:48 2015 -0700
@@ -37,14 +37,14 @@
     public static void main(String[] args) throws Exception {
         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
             "-server", "-XX:+UnlockDiagnosticVMOptions",
-            "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump");
+            "-XX:SharedArchiveFile=./XShareAuto.jsa", "-Xshare:dump");
         OutputAnalyzer output = new OutputAnalyzer(pb.start());
         output.shouldContain("Loading classes to share");
         output.shouldHaveExitValue(0);
 
         pb = ProcessTools.createJavaProcessBuilder(
             "-server", "-XX:+UnlockDiagnosticVMOptions",
-            "-XX:SharedArchiveFile=./sample.jsa", "-version");
+            "-XX:SharedArchiveFile=./XShareAuto.jsa", "-version");
         output = new OutputAnalyzer(pb.start());
         // We asked for server but it could be aliased to something else
         if (output.getOutput().contains("Server VM")) {
@@ -59,7 +59,7 @@
 
         pb = ProcessTools.createJavaProcessBuilder(
             "-server", "-Xshare:auto", "-XX:+UnlockDiagnosticVMOptions",
-            "-XX:SharedArchiveFile=./sample.jsa", "-XX:+PrintSharedSpaces", "-version");
+            "-XX:SharedArchiveFile=./XShareAuto.jsa", "-XX:+PrintSharedSpaces", "-version");
         output = new OutputAnalyzer(pb.start());
         try {
             output.shouldContain("sharing");
--- a/hotspot/test/runtime/CompressedOops/CompressedClassPointers.java	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/test/runtime/CompressedOops/CompressedClassPointers.java	Thu Apr 16 14:05:48 2015 -0700
@@ -97,7 +97,7 @@
         // Test small heaps
         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
             "-XX:+UnlockDiagnosticVMOptions",
-            "-XX:SharedArchiveFile=./sample.jsa",
+            "-XX:SharedArchiveFile=./CompressedClassPointers.jsa",
             "-Xmx128m",
             "-XX:SharedBaseAddress=8g",
             "-XX:+PrintCompressedOopsMode",
@@ -110,7 +110,7 @@
 
           pb = ProcessTools.createJavaProcessBuilder(
             "-XX:+UnlockDiagnosticVMOptions",
-            "-XX:SharedArchiveFile=./sample.jsa",
+            "-XX:SharedArchiveFile=./CompressedClassPointers.jsa",
             "-Xmx128m",
             "-XX:SharedBaseAddress=8g",
             "-XX:+PrintCompressedOopsMode",
--- a/hotspot/test/runtime/ErrorHandling/SafeFetchInErrorHandlingTest.java	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/test/runtime/ErrorHandling/SafeFetchInErrorHandlingTest.java	Thu Apr 16 14:05:48 2015 -0700
@@ -1,3 +1,26 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileInputStream;
@@ -21,7 +44,7 @@
 
   public static void main(String[] args) throws Exception {
 
-    if (!Platform.isDebugBuild()) {
+    if (!Platform.isDebugBuild() || Platform.isZero()) {
       return;
     }
 
--- a/hotspot/test/runtime/NMT/NMTWithCDS.java	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/test/runtime/NMT/NMTWithCDS.java	Thu Apr 16 14:05:48 2015 -0700
@@ -37,14 +37,14 @@
   public static void main(String[] args) throws Exception {
     ProcessBuilder pb;
     pb = ProcessTools.createJavaProcessBuilder(
-        "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump");
+        "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./NMTWithCDS.jsa", "-Xshare:dump");
     OutputAnalyzer output = new OutputAnalyzer(pb.start());
     try {
       output.shouldContain("Loading classes to share");
       output.shouldHaveExitValue(0);
 
       pb = ProcessTools.createJavaProcessBuilder(
-        "-XX:+UnlockDiagnosticVMOptions", "-XX:NativeMemoryTracking=detail", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:on", "-version");
+        "-XX:+UnlockDiagnosticVMOptions", "-XX:NativeMemoryTracking=detail", "-XX:SharedArchiveFile=./NMTWithCDS.jsa", "-Xshare:on", "-version");
       output = new OutputAnalyzer(pb.start());
       output.shouldContain("sharing");
       output.shouldHaveExitValue(0);
--- a/hotspot/test/runtime/SharedArchiveFile/ArchiveDoesNotExist.java	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/test/runtime/SharedArchiveFile/ArchiveDoesNotExist.java	Thu Apr 16 14:05:48 2015 -0700
@@ -38,7 +38,7 @@
 
 public class ArchiveDoesNotExist {
     public static void main(String[] args) throws Exception {
-        String fileName = "test.jsa";
+        String fileName = "ArchiveDoesNotExist.jsa";
 
         File cdsFile = new File(fileName);
         if (cdsFile.exists())
--- a/hotspot/test/runtime/SharedArchiveFile/CdsDifferentObjectAlignment.java	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/test/runtime/SharedArchiveFile/CdsDifferentObjectAlignment.java	Thu Apr 16 14:05:48 2015 -0700
@@ -59,10 +59,11 @@
             createAlignment;
         String loadAlignmentArgument = "-XX:ObjectAlignmentInBytes=" +
             loadAlignment;
+        String filename = "./CdsDifferentObjectAlignment" + createAlignment + ".jsa";
 
         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
             "-XX:+UnlockDiagnosticVMOptions",
-            "-XX:SharedArchiveFile=./sample.jsa",
+            "-XX:SharedArchiveFile=" + filename,
             "-Xshare:dump",
             createAlignmentArgument);
 
@@ -72,7 +73,7 @@
 
         pb = ProcessTools.createJavaProcessBuilder(
             "-XX:+UnlockDiagnosticVMOptions",
-            "-XX:SharedArchiveFile=./sample.jsa",
+            "-XX:SharedArchiveFile=" + filename,
             "-Xshare:on",
             loadAlignmentArgument,
             "-version");
--- a/hotspot/test/runtime/SharedArchiveFile/CdsSameObjectAlignment.java	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/test/runtime/SharedArchiveFile/CdsSameObjectAlignment.java	Thu Apr 16 14:05:48 2015 -0700
@@ -55,10 +55,11 @@
         System.out.println("dumpAndLoadSharedArchive(): objectAlignmentInBytes = "
             + objectAlignmentInBytes);
 
+        String filename = "./CdsSameObjectAlignment" + objectAlignmentInBytes + ".jsa";
         // create shared archive
         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
             "-XX:+UnlockDiagnosticVMOptions",
-            "-XX:SharedArchiveFile=./sample.jsa",
+            "-XX:SharedArchiveFile=" + filename,
             "-Xshare:dump",
             objectAlignmentArg);
 
@@ -70,7 +71,7 @@
         // run using the shared archive
         pb = ProcessTools.createJavaProcessBuilder(
             "-XX:+UnlockDiagnosticVMOptions",
-            "-XX:SharedArchiveFile=./sample.jsa",
+            "-XX:SharedArchiveFile=" + filename,
             "-Xshare:on",
             objectAlignmentArg,
             "-version");
--- a/hotspot/test/runtime/SharedArchiveFile/DefaultUseWithClient.java	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/test/runtime/SharedArchiveFile/DefaultUseWithClient.java	Thu Apr 16 14:05:48 2015 -0700
@@ -36,7 +36,7 @@
 
 public class DefaultUseWithClient {
     public static void main(String[] args) throws Exception {
-        String fileName = "test.jsa";
+        String fileName = "DefaultUseWithClient.jsa";
 
         // On 32-bit windows CDS should be on by default in "-client" config
         // Skip this test on any other platform
--- a/hotspot/test/runtime/SharedArchiveFile/LimitSharedSizes.java	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/test/runtime/SharedArchiveFile/LimitSharedSizes.java	Thu Apr 16 14:05:48 2015 -0700
@@ -125,9 +125,11 @@
     };
 
     public static void main(String[] args) throws Exception {
-        String fileName = "test.jsa";
+        int counter = 0;
+        for (SharedSizeTestData td : testTable) {
+            String fileName = "LimitSharedSizes" + counter + ".jsa";
+            counter++;
 
-        for (SharedSizeTestData td : testTable) {
             String option = td.optionName + "=" + td.optionValue;
             System.out.println("testing option <" + option + ">");
 
--- a/hotspot/test/runtime/SharedArchiveFile/PrintSharedArchiveAndExit.java	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/test/runtime/SharedArchiveFile/PrintSharedArchiveAndExit.java	Thu Apr 16 14:05:48 2015 -0700
@@ -34,8 +34,10 @@
 
 public class PrintSharedArchiveAndExit {
   public static void main(String[] args) throws Exception {
+    String filename = "./PrintSharedArchiveAndExit.jsa";
+
     ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
-        "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump");
+        "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=" + filename, "-Xshare:dump");
     OutputAnalyzer output = new OutputAnalyzer(pb.start());
     try {
       output.shouldContain("Loading classes to share");
@@ -43,7 +45,7 @@
 
       // (1) With a valid archive
       pb = ProcessTools.createJavaProcessBuilder(
-          "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa",
+          "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=" + filename,
           "-XX:+PrintSharedArchiveAndExit", "-version");
       output = new OutputAnalyzer(pb.start());
       output.shouldContain("archive is valid");
@@ -51,7 +53,7 @@
       output.shouldHaveExitValue(0);               // Should report success in error code.
 
       pb = ProcessTools.createJavaProcessBuilder(
-          "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa",
+          "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=" + filename,
           "-XX:+PrintSharedArchiveAndExit");
       output = new OutputAnalyzer(pb.start());
       output.shouldContain("archive is valid");
@@ -61,7 +63,7 @@
       // (2) With an invalid archive (boot class path has been prepended)
       pb = ProcessTools.createJavaProcessBuilder(
           "-Xbootclasspath/p:foo.jar",
-          "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa",
+          "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=" + filename,
           "-XX:+PrintSharedArchiveAndExit", "-version");
       output = new OutputAnalyzer(pb.start());
       output.shouldContain("archive is invalid");
@@ -70,7 +72,7 @@
 
       pb = ProcessTools.createJavaProcessBuilder(
           "-Xbootclasspath/p:foo.jar",
-          "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa",
+          "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=" + filename,
           "-XX:+PrintSharedArchiveAndExit");
       output = new OutputAnalyzer(pb.start());
       output.shouldContain("archive is invalid");
--- a/hotspot/test/runtime/SharedArchiveFile/SharedArchiveFile.java	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/test/runtime/SharedArchiveFile/SharedArchiveFile.java	Thu Apr 16 14:05:48 2015 -0700
@@ -35,14 +35,14 @@
 public class SharedArchiveFile {
   public static void main(String[] args) throws Exception {
     ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
-        "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump");
+        "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./SharedArchiveFile.jsa", "-Xshare:dump");
     OutputAnalyzer output = new OutputAnalyzer(pb.start());
     try {
       output.shouldContain("Loading classes to share");
       output.shouldHaveExitValue(0);
 
       pb = ProcessTools.createJavaProcessBuilder(
-        "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:on", "-version");
+        "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./SharedArchiveFile.jsa", "-Xshare:on", "-version");
       output = new OutputAnalyzer(pb.start());
       output.shouldContain("sharing");
       output.shouldHaveExitValue(0);
--- a/hotspot/test/runtime/SharedArchiveFile/SharedBaseAddress.java	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/test/runtime/SharedArchiveFile/SharedBaseAddress.java	Thu Apr 16 14:05:48 2015 -0700
@@ -49,11 +49,12 @@
             return;
 
         for (String testEntry : testTable) {
+            String filename = "SharedBaseAddress" + testEntry + ".jsa";
             System.out.println("sharedBaseAddress = " + testEntry);
 
             ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
                "-XX:+UnlockDiagnosticVMOptions",
-               "-XX:SharedArchiveFile=test.jsa",
+               "-XX:SharedArchiveFile=" + filename,
                "-XX:SharedBaseAddress=" + testEntry,
                "-Xshare:dump");
 
@@ -64,7 +65,7 @@
             try {
                 pb = ProcessTools.createJavaProcessBuilder(
                     "-XX:+UnlockDiagnosticVMOptions",
-                    "-XX:SharedArchiveFile=test.jsa",
+                    "-XX:SharedArchiveFile=" + filename,
                     "-Xshare:on",
                     "-version");
                 output = new OutputAnalyzer(pb.start());
--- a/hotspot/test/runtime/SharedArchiveFile/SharedSymbolTableBucketSize.java	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/test/runtime/SharedArchiveFile/SharedSymbolTableBucketSize.java	Thu Apr 16 14:05:48 2015 -0700
@@ -38,7 +38,7 @@
         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
             "-Xshare:dump", "-XX:+PrintSharedSpaces",
             "-XX:+UnlockDiagnosticVMOptions",
-            "-XX:SharedArchiveFile=./sample.jsa",
+            "-XX:SharedArchiveFile=./SharedSymbolTableBucketSize.jsa",
             "-XX:SharedSymbolTableBucketSize=" + Integer.valueOf(bucket_size));
         OutputAnalyzer output = new OutputAnalyzer(pb.start());
         output.shouldContain("Loading classes to share");
@@ -60,7 +60,7 @@
           pb = ProcessTools.createJavaProcessBuilder(
                "-Xshare:dump", "-XX:+PrintSharedSpaces",
                "-XX:+UnlockDiagnosticVMOptions",
-               "-XX:SharedArchiveFile=./sample.jsa",
+               "-XX:SharedArchiveFile=./SharedSymbolTableBucketSize.jsa",
                input[i]);
           output = new OutputAnalyzer(pb.start());
           output.shouldContain("Improperly specified VM option");
--- a/hotspot/test/runtime/SharedArchiveFile/SpaceUtilizationCheck.java	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/test/runtime/SharedArchiveFile/SpaceUtilizationCheck.java	Thu Apr 16 14:05:48 2015 -0700
@@ -50,7 +50,7 @@
     public static void main(String[] args) throws Exception {
         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
            "-XX:+UnlockDiagnosticVMOptions",
-           "-XX:SharedArchiveFile=./test.jsa",
+           "-XX:SharedArchiveFile=./SpaceUtilizationCheck.jsa",
            "-Xshare:dump");
 
         OutputAnalyzer output = new OutputAnalyzer(pb.start());
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/handlerInTry/HandlerInTry.jasm	Thu Apr 16 14:05:48 2015 -0700
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * HandlerInTry contains a try block in a ctor whose handler is inside
+ * the same try block.  The try block starts at line 74 (try t2;), ends at
+ * line 106 (endtry t2;), but its handler starts at line 101 (catch t2 #0;).
+ */
+super public class HandlerInTry
+    version 51:0
+{
+
+public static final synthetic Field ___transactionFactory_2002349702336125:"Ljava/lang/Object;";
+
+public Method "<init>":"(Ljava/lang/Object;)V"
+    stack 5 locals 5
+{
+        invokestatic    Method ThreadLocalTransaction.getThreadLocalTransaction:"()Ljava/lang/Object;";
+        checkcast    class java/lang/Object;
+        astore_2;
+        aload_2;
+        invokestatic    Method TransactionLogicDonor.isActiveTransaction:"(Ljava/lang/Object;)Z";
+        ifeq    L21;
+        aload_0;
+        aload_1;
+        aload_2;
+        invokespecial    Method "<init>":"(Ljava/lang/Object;Ljava/lang/Object;)V";
+        return;
+    L21:    stack_frame_type append;
+        locals_map class java/lang/Object;
+        aload_2;
+        getstatic    Field ___transactionFactory_2002349702336125:"Ljava/lang/Object;";
+        invokestatic    Method TransactionLogicDonor.createTransaction:"(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;";
+        astore_2;
+        aload_2;
+        iconst_1;
+        pop;
+        aload_2;
+        invokestatic    Method ThreadLocalTransaction.setThreadLocalTransaction:"(Ljava/lang/Object;)V";
+        try t0, t1;
+        aload_0;
+        aload_1;
+        aload_2;
+        invokespecial    Method "<init>":"(Ljava/lang/Object;Ljava/lang/Object;)V";
+        aload_2;
+        pop;
+        aconst_null;
+        astore_2;
+        endtry t0, t1;
+        invokestatic    Method ThreadLocalTransaction.clearThreadLocalTransaction:"()V";
+        pop;
+        goto    L107;
+        catch t0 java/lang/Throwable;
+        try t2;
+        stack_frame_type full;
+        locals_map bogus, class java/lang/Object, class java/lang/Object;
+        stack_map class java/lang/Throwable;
+        astore_3;
+        aload_2;
+        pop;
+        aload_3;
+        instanceof    class ControlFlowError;
+        ifeq    L82;
+        new    class java/lang/NullPointerException;
+        dup;
+        invokespecial    Method java/lang/NullPointerException."<init>":"()V";
+        athrow;
+    L82:    stack_frame_type append;
+        locals_map class java/lang/Throwable;
+        aload_3;
+        instanceof    class java/lang/Error;
+        ifeq    L94;
+        aload_3;
+        checkcast    class java/lang/Error;
+        athrow;
+    L94:    stack_frame_type same;
+        aload_3;
+        checkcast    class java/lang/Exception;
+        athrow;
+        catch t1 #0;
+        catch t2 #0;
+        stack_frame_type full;
+        locals_map bogus, class java/lang/Object, class java/lang/Object;
+        stack_map class java/lang/Throwable;
+        astore    4;
+        endtry t2;
+        invokestatic    Method ThreadLocalTransaction.clearThreadLocalTransaction:"()V";
+        aload    4;
+        athrow;
+    L107:    stack_frame_type full;
+        locals_map class HandlerInTry, class java/lang/Object, null;
+        return;
+}
+
+} // end Class HandlerInTry
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/handlerInTry/IsolatedHandlerInTry.jasm	Thu Apr 16 14:05:48 2015 -0700
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * IsolatedHandlerInTry contains a try block in a ctor whose handler is inside
+ * the same try block but the handler can only be reached if an exception
+ * occurs.  The handler does a return.  So, a VerifyException should be thrown.
+ * The try block starts at line 77 (try t2;) and ends at line 113 (endtry t2;).
+ * Its handler starts at line 107 (catch t2 #0;).  The handler can only be reached
+ * by exception because of the athrow at line 106.
+ */
+super public class IsolatedHandlerInTry
+    version 51:0
+{
+
+public static final synthetic Field ___transactionFactory_2002349702336125:"Ljava/lang/Object;";
+
+public Method "<init>":"(Ljava/lang/Object;)V"
+    stack 5 locals 5
+{
+        invokestatic    Method ThreadLocalTransaction.getThreadLocalTransaction:"()Ljava/lang/Object;";
+        checkcast    class java/lang/Object;
+        astore_2;
+        aload_2;
+        invokestatic    Method TransactionLogicDonor.isActiveTransaction:"(Ljava/lang/Object;)Z";
+        ifeq    L21;
+        aload_0;
+        aload_1;
+        aload_2;
+        invokespecial    Method "<init>":"(Ljava/lang/Object;Ljava/lang/Object;)V";
+        return;
+    L21:    stack_frame_type append;
+        locals_map class java/lang/Object;
+        aload_2;
+        getstatic    Field ___transactionFactory_2002349702336125:"Ljava/lang/Object;";
+        invokestatic    Method TransactionLogicDonor.createTransaction:"(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;";
+        astore_2;
+        aload_2;
+        iconst_1;
+        pop;
+        aload_2;
+        invokestatic    Method ThreadLocalTransaction.setThreadLocalTransaction:"(Ljava/lang/Object;)V";
+        try t0, t1;
+        aload_0;
+        aload_1;
+        aload_2;
+        invokespecial    Method "<init>":"(Ljava/lang/Object;Ljava/lang/Object;)V";
+        aload_2;
+        pop;
+        aconst_null;
+        astore_2;
+        endtry t0, t1;
+        invokestatic    Method ThreadLocalTransaction.clearThreadLocalTransaction:"()V";
+        pop;
+        goto    L107;
+        catch t0 java/lang/Throwable;
+        try t2;
+        stack_frame_type full;
+        locals_map bogus, class java/lang/Object, class java/lang/Object;
+        stack_map class java/lang/Throwable;
+        astore_3;
+        aload_2;
+        pop;
+        aload_3;
+        instanceof    class ControlFlowError;
+        ifeq    L82;
+        new    class java/lang/NullPointerException;
+        dup;
+        invokespecial    Method java/lang/NullPointerException."<init>":"()V";
+        athrow;
+    L82:    stack_frame_type append;
+        locals_map class java/lang/Throwable;
+        aload_3;
+        instanceof    class java/lang/Error;
+        ifeq    L94;
+        aload_3;
+        checkcast    class java/lang/Error;
+        athrow;
+    L94:    stack_frame_type same;
+        aload_3;
+        checkcast    class java/lang/Exception;
+        catch t1 #0;
+        stack_frame_type full;
+        locals_map bogus, class java/lang/Object, class java/lang/Object;
+        stack_map class java/lang/Throwable;
+        athrow;
+        catch t2 #0;
+        stack_frame_type full;
+        locals_map bogus, class java/lang/Object, class java/lang/Object;
+        stack_map class java/lang/Throwable;
+        astore    4;
+        return;
+        endtry t2;
+        stack_frame_type full;
+        locals_map bogus, class java/lang/Object, class java/lang/Object, class java/lang/Object;
+        stack_map class java/lang/Throwable;
+        invokestatic    Method ThreadLocalTransaction.clearThreadLocalTransaction:"()V";
+        athrow;
+    L107:    stack_frame_type full;
+        locals_map class IsolatedHandlerInTry, class java/lang/Object, null;
+        return;
+}
+
+} // end Class IsolatedHandlerInTry
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/handlerInTry/LoadHandlerInTry.java	Thu Apr 16 14:05:48 2015 -0700
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8075118
+ * @summary Allow a ctor to call super() from a switch bytecode.
+ * @compile HandlerInTry.jasm
+ * @compile IsolatedHandlerInTry.jasm
+ * @run main/othervm -Xverify:all LoadHandlerInTry
+ */
+
+/*
+ * This test has two cases:
+ *
+ * 1. class HandlerInTry:  Class HandlerInTry contains a TRY block in a
+ *    constructor whose handler is inside the same TRY block.  The last
+ *    few bytecodes and exception table look like this:
+ *
+ *         ...
+ *      87: athrow
+ *      88: astore        4
+ *      90: invokestatic  #9
+ *      93: aload         4
+ *      95: athrow
+ *      96: return
+ *    Exception table:
+ *       from    to  target type
+ *          36    46    53   Class java/lang/Throwable
+ *          36    46    88   any
+ *          53    90    88   any
+ *
+ * Note that the target for the third handler in the Exception table is
+ * inside its TRY block.
+ * Without the fix for bug JDK-8075118, this test will time out.
+ *
+ *
+ * 2. class IsolatedHandlerInTry: Class IsolatedHandlerInTry also contains
+ *    a TRY block in a constructoer whose handler is inside its TRY block.
+ *    But the handler is only reachable if an exception is thrown.  The
+ *    handler's bytecodes will not get parsed as part of parsing the TRY
+ *    block.  They will only get parsed as a handler for the TRY block.
+ *    Since the isolated handler does a 'return', a VerifyError exception
+ *    should get thrown.
+ */
+
+public class LoadHandlerInTry {
+
+    public static void main(String[] args) throws Exception {
+        System.out.println("Regression test for bug 8075118");
+        try {
+            Class newClass = Class.forName("HandlerInTry");
+        } catch (Exception e) {
+            System.out.println("Failed: Exception was thrown: " + e.toString());
+            throw e;
+        }
+
+        try {
+            Class newClass = Class.forName("IsolatedHandlerInTry");
+            throw new RuntimeException(
+                 "Failed to throw VerifyError for IsolatedHandlerInTry");
+        } catch (java.lang.VerifyError e) {
+            System.out.println("Passed: VerifyError exception was thrown");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/stackMapCheck/BadMap.jasm	Thu Apr 16 14:05:48 2015 -0700
@@ -0,0 +1,152 @@
+ /*
+  * Copyright (c) 2015, 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
+  * under the terms of the GNU General Public License version 2 only, as
+  * published by the Free Software Foundation.
+  *
+  * This code is distributed in the hope that it will be useful, but WITHOUT
+  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+  * version 2 for more details (a copy is included in the LICENSE file that
+  * accompanied this code).
+  *
+  * You should have received a copy of the GNU General Public License version
+  * 2 along with this work; if not, write to the Free Software Foundation,
+  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+  *
+  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+  * or visit www.oracle.com if you need additional information or have any
+  * questions.
+  *
+  */
+
+/*
+ * This class should throw VerifyError because the StackMap for bytecode index
+ * 45 (astore_2, line 123) is incorrect. The stack maps for bytecode indexes 45
+ * and 49 (astore, line 133) do not match because 45 does not supply enough
+ * locals to satisfy 49.
+ *
+ * The astore_2 bytecode at bytecode index 45 changes the type state,
+ * preventing the stackmap mismatch.  But, if the incoming type state is used,
+ * as required by JVM Spec 8, then the verifier will detected the stackmap
+ * mismatch, and throw VerifyError.
+ */
+
+super public class BadMap
+    version 51:0
+{
+
+
+public Method "<init>":"()V"
+    stack 1 locals 1
+{
+        aload_0;
+        invokespecial    Method java/lang/Object."<init>":"()V";
+        return;
+}
+
+public static Method main:"([Ljava/lang/String;)V"
+    throws java/lang/Throwable
+    stack 0 locals 1
+{
+        return;
+}
+
+public static Method foo:"()V"
+    stack 3 locals 5
+{
+        iconst_0;
+        ifne    L5;
+        nop;
+        try t7;
+    L5:    stack_frame_type full;
+        aconst_null;
+        dup;
+        astore_0;
+        astore_1;
+        try t0;
+        aconst_null;
+        astore_0;
+        endtry t0;
+        goto    L19;
+        catch t0 java/io/IOException;
+        stack_frame_type full;
+        locals_map class java/lang/Object, null;
+        stack_map class java/io/IOException;
+        astore_2;
+        aconst_null;
+        dup;
+        astore_1;
+        astore_0;
+        try t1;
+    L19:    stack_frame_type full;
+        locals_map class java/lang/Object, class java/lang/Object;
+        aconst_null;
+        astore_2;
+        endtry t1;
+        aload_1;
+        ifnonnull    L37;
+        nop;
+        goto    L37;
+        catch t1 #0;
+        catch t2 #0;
+        try t2;
+        stack_frame_type full;
+        locals_map class java/lang/Object, class java/lang/Object;
+        stack_map class java/lang/Throwable;
+        astore_3;
+        endtry t2;
+        aload_1;
+        ifnonnull    L35;
+        nop;
+    L35:    stack_frame_type full;
+        locals_map class java/lang/Object, class java/lang/Object, bogus, class java/lang/Throwable;
+        aload_3;
+        athrow;
+        try t3, t4;
+    L37:    stack_frame_type full;
+        locals_map class java/lang/Object, class java/lang/Object, class java/lang/Object;
+        aload_1;
+        ifnonnull    L42;
+        nop;
+        endtry t3, t4;
+    L42:    stack_frame_type full;
+        locals_map class java/lang/Object, class java/lang/Object, class java/lang/Object;
+        goto    L54;
+        catch t3 java/lang/Exception;
+        try t5;
+        stack_frame_type full;
+        locals_map class java/lang/Object, class java/lang/Object;
+        stack_map class java/lang/Exception;
+        astore_2;   // astore_2, at bci 45, that changes the type state.
+        endtry t5;
+        goto    L54;
+        catch t4 #0;
+        catch t5 #0;
+        catch t6 #0;
+        try t6;
+        stack_frame_type full;
+        locals_map class java/lang/Object, class java/lang/Object, class java/lang/Object;
+        stack_map class java/lang/Throwable;
+        astore    4;
+        endtry t6;
+        aload    4;
+        athrow;
+    L54:    stack_frame_type full;
+        locals_map class java/lang/Object, class java/lang/Object, class java/lang/Object;
+        goto    L57;
+    L57:    stack_frame_type full;
+        locals_map class java/lang/Object, class java/lang/Object, class java/lang/Object;
+        nop;
+        endtry t7;
+        return;
+        catch t7 #0;
+        stack_frame_type full;
+        stack_map class java/lang/Throwable;
+        nop;
+        athrow;
+}
+
+} // end Class BadMap
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/stackMapCheck/BadMapDstore.jasm	Thu Apr 16 14:05:48 2015 -0700
@@ -0,0 +1,79 @@
+ /*
+  * Copyright (c) 2015, 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
+  * under the terms of the GNU General Public License version 2 only, as
+  * published by the Free Software Foundation.
+  *
+  * This code is distributed in the hope that it will be useful, but WITHOUT
+  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+  * version 2 for more details (a copy is included in the LICENSE file that
+  * accompanied this code).
+  *
+  * You should have received a copy of the GNU General Public License version
+  * 2 along with this work; if not, write to the Free Software Foundation,
+  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+  *
+  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+  * or visit www.oracle.com if you need additional information or have any
+  * questions.
+  *
+  */
+
+/*
+ * This class should throw VerifyError because the StackMap for bytecode index
+ * 9 (dstore_2, line 60) is incorrect. The stack maps for bytecode indexes 9
+ * and 18 (astore_2, line 70) do not match because 9 does not supply enough
+ * locals to satisfy 18.
+ *
+ * The dstore_2 bytecode at bytecode index 9 changes the type state,
+ * preventing the stackmap mismatch.  But, if the incoming type state is used,
+ * as required by JVM Spec 8, then the verifier will detected the stackmap
+ * mismatch, and throw VerifyError.
+ */
+
+super public class BadMapDstore
+    version 51:0
+{
+
+Field blah:I;
+
+public Method "<init>":"()V"
+    stack 1 locals 1
+{
+        aload_0;
+        invokespecial    Method java/lang/Object."<init>":"()V";
+        return;
+}
+
+public static Method main:"([Ljava/lang/String;)V"
+    stack 4 locals 4
+{
+        new    class BadMapDstore;
+        dup;
+        invokespecial    Method "<init>":"()V";
+        astore_1;
+        dconst_1;
+        try t0;
+        dstore_2;
+        aload_1;
+        iconst_5;
+        putfield    Field blah:"I";
+        endtry t0;
+        goto    L22;
+        catch t0 java/lang/Throwable;
+        stack_frame_type full;
+        locals_map class "[Ljava/lang/String;", class BadMapDstore, double;
+        stack_map class java/lang/Throwable;
+        astore_2;
+        aload_1;
+        dconst_0;
+        dstore_2;
+        pop;
+    L22:    stack_frame_type same;
+        return;
+}
+
+} // end Class BadMapDstore
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/stackMapCheck/BadMapIstore.jasm	Thu Apr 16 14:05:48 2015 -0700
@@ -0,0 +1,79 @@
+ /*
+  * Copyright (c) 2015, 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
+  * under the terms of the GNU General Public License version 2 only, as
+  * published by the Free Software Foundation.
+  *
+  * This code is distributed in the hope that it will be useful, but WITHOUT
+  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+  * version 2 for more details (a copy is included in the LICENSE file that
+  * accompanied this code).
+  *
+  * You should have received a copy of the GNU General Public License version
+  * 2 along with this work; if not, write to the Free Software Foundation,
+  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+  *
+  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+  * or visit www.oracle.com if you need additional information or have any
+  * questions.
+  *
+  */
+
+/*
+ * This class should throw VerifyError because the StackMap for bytecode index
+ * 9 (istore_2, line 60) is incorrect. The stack maps for bytecode indexes 9
+ * and 18 (astore_2, line 70) do not match because 9 does not supply enough
+ * locals to satisfy 18.
+ *
+ * The istore_2 bytecode at bytecode index 9 changes the type state,
+ * preventing the stackmap mismatch.  But, if the incoming type state is used,
+ * as required by JVM Spec 8, then the verifier will detected the stackmap
+ * mismatch, and throw VerifyError.
+ */
+
+super public class BadMapIstore
+    version 51:0
+{
+
+Field blah:I;
+
+public Method "<init>":"()V"
+    stack 1 locals 1
+{
+        aload_0;
+        invokespecial    Method java/lang/Object."<init>":"()V";
+        return;
+}
+
+public static Method main:"([Ljava/lang/String;)V"
+    stack 2 locals 3
+{
+        new    class BadMapIstore;
+        dup;
+        invokespecial    Method "<init>":"()V";
+        astore_1;
+        iconst_2;
+        try t0;
+        istore_2;
+        aload_1;
+        iconst_5;
+        putfield    Field blah:"I";
+        endtry t0;
+        goto    L22;
+        catch t0 java/lang/Throwable;
+        stack_frame_type full;
+        locals_map class "[Ljava/lang/String;", class BadMapIstore, int;
+        stack_map class java/lang/Throwable;
+        astore_2;
+        aload_1;
+        iconst_4;
+        istore_2;
+        pop;
+    L22:    stack_frame_type same;
+        return;
+}
+
+} // end Class BadMapIstore
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/stackMapCheck/StackMapCheck.java	Thu Apr 16 14:05:48 2015 -0700
@@ -0,0 +1,63 @@
+ /*
+  * Copyright (c) 2015, 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
+  * under the terms of the GNU General Public License version 2 only, as
+  * published by the Free Software Foundation.
+  *
+  * This code is distributed in the hope that it will be useful, but WITHOUT
+  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+  * version 2 for more details (a copy is included in the LICENSE file that
+  * accompanied this code).
+  *
+  * You should have received a copy of the GNU General Public License version
+  * 2 along with this work; if not, write to the Free Software Foundation,
+  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+  *
+  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+  * or visit www.oracle.com if you need additional information or have any
+  * questions.
+  *
+  */
+
+/*
+ * @test
+ * @bug 7127066
+ * @summary Class verifier accepts an invalid class file
+ * @compile BadMap.jasm
+ * @compile BadMapDstore.jasm
+ * @compile BadMapIstore.jasm
+ * @run main/othervm -Xverify:all StackMapCheck
+ */
+
+public class StackMapCheck {
+    public static void main(String args[]) throws Throwable {
+
+        System.out.println("Regression test for bug 7127066");
+        try {
+            Class newClass = Class.forName("BadMap");
+            throw new RuntimeException(
+                "StackMapCheck failed, BadMap did not throw VerifyError");
+        } catch (java.lang.VerifyError e) {
+            System.out.println("BadMap passed, VerifyError was thrown");
+        }
+
+        try {
+            Class newClass = Class.forName("BadMapDstore");
+            throw new RuntimeException(
+                "StackMapCheck failed, BadMapDstore did not throw VerifyError");
+        } catch (java.lang.VerifyError e) {
+            System.out.println("BadMapDstore passed, VerifyError was thrown");
+        }
+
+        try {
+            Class newClass = Class.forName("BadMapIstore");
+            throw new RuntimeException(
+                "StackMapCheck failed, BadMapIstore did not throw VerifyError");
+        } catch (java.lang.VerifyError e) {
+            System.out.println("BadMapIstore passed, VerifyError was thrown");
+        }
+    }
+}
--- a/hotspot/test/serviceability/attach/AttachWithStalePidFile.java	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/test/serviceability/attach/AttachWithStalePidFile.java	Thu Apr 16 14:05:48 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, 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
@@ -26,7 +26,6 @@
  * @bug 7162400
  * @key regression
  * @summary Regression test for attach issue where stale pid files in /tmp lead to connection issues
- * @ignore 8024055
  * @library /testlibrary
  * @build com.oracle.java.testlibrary.* AttachWithStalePidFileTarget
  * @run main AttachWithStalePidFile
@@ -79,9 +78,7 @@
       // wait for vm.paused file to be created and delete it once we find it.
       waitForAndResumeVM(pid);
 
-      // unfortunately there's no reliable way to know the VM is ready to receive the
-      // attach request so we have to do an arbitrary sleep.
-      Thread.sleep(5000);
+      waitForTargetReady(target);
 
       HotSpotVirtualMachine vm = (HotSpotVirtualMachine)VirtualMachine.attach(((Integer)pid).toString());
       BufferedReader remoteDataReader = new BufferedReader(new InputStreamReader(vm.remoteDataDump()));
@@ -101,6 +98,16 @@
     }
   }
 
+  private static void waitForTargetReady(Process target) throws IOException {
+    BufferedReader br = new BufferedReader(new InputStreamReader(target.getInputStream()));
+    String line = br.readLine();
+    // wait for the ready message having been printed or EOF (line == null)
+    while (line != null && !line.equals(AttachWithStalePidFileTarget.READY_MSG)) {
+        line = br.readLine();
+    }
+    // target VM ready
+  }
+
   private static Path createJavaPidFile(int pid) throws Exception {
     Path pidFile = Paths.get("/tmp/.java_pid" + pid);
     if(Files.exists(pidFile)) {
@@ -108,8 +115,10 @@
         Files.delete(pidFile);
       }
       catch(FileSystemException e) {
-        if(e.getReason().equals("Operation not permitted")) {
+        if(e.getReason().matches("Operation not permitted|Not owner")) {
           System.out.println("Unable to remove exisiting stale PID file" + pidFile);
+          System.out.println("===================================================");
+          e.printStackTrace(System.out);
           return null;
         }
         throw e;
--- a/hotspot/test/serviceability/attach/AttachWithStalePidFileTarget.java	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/test/serviceability/attach/AttachWithStalePidFileTarget.java	Thu Apr 16 14:05:48 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, 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
@@ -21,7 +21,10 @@
  * questions.
  */
 public class AttachWithStalePidFileTarget {
+  static final String READY_MSG = "*ready*";
   public static void main(String... args) throws Exception {
-    Thread.sleep(2*60*1000);
+      System.out.println(READY_MSG);
+      System.out.flush();
+      System.in.read();
   }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/jvmti/DataDumpDcmdTest.java	Thu Apr 16 14:05:48 2015 -0700
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.dcmd.CommandExecutor;
+import com.oracle.java.testlibrary.dcmd.JMXExecutor;
+import com.oracle.java.testlibrary.dcmd.PidJcmdExecutor;
+import org.testng.annotations.Test;
+
+/*
+ * @test
+ * @bug 8054890
+ * @summary Test of JVMTI.data_dump diagnostic command
+ * @library /testlibrary
+ * @build com.oracle.java.testlibrary.*
+ * @run testng DataDumpDcmdTest
+ */
+
+/**
+ * This test issues the "JVMTI.data_dump" command which will dump the related JVMTI
+ * data.
+ *
+ */
+public class DataDumpDcmdTest {
+    public void run(CommandExecutor executor) {
+        OutputAnalyzer output = executor.execute("JVMTI.data_dump");
+
+        output.stderrShouldBeEmpty();
+    }
+
+    @Test
+    public void jmx() throws Throwable {
+        run(new JMXExecutor());
+    }
+
+    @Test
+    public void cli() throws Throwable {
+        run(new PidJcmdExecutor());
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/vm/SetVMFlagTest.java	Thu Apr 16 14:05:48 2015 -0700
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.dcmd.CommandExecutor;
+import com.oracle.java.testlibrary.dcmd.JMXExecutor;
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+/*
+ * @test
+ * @bug 8054890
+ * @summary Test of VM.set_flag diagnostic command
+ * @library /testlibrary
+ * @build com.oracle.java.testlibrary.*
+ * @build com.oracle.java.testlibrary.dcmd.*
+ * @run testng SetVMFlagTest
+ */
+
+public class SetVMFlagTest {
+    private static final String MANAGEABLE_PATTERN = "\\s*bool\\s+(\\S+)\\s+[\\:]?=\\s+" +
+                                                     "(.*?)\\s+\\{manageable\\}";
+    private static final String IMMUTABLE_PATTERN = "\\s*uintx\\s+(\\S+)\\s+[\\:]?=\\s+" +
+                                                    "(.*?)\\s+\\{product\\}";
+
+    public void run(CommandExecutor executor) {
+        setMutableFlag(executor);
+        setMutableFlagWithInvalidValue(executor);
+        setImmutableFlag(executor);
+        setNonExistingFlag(executor);
+    }
+
+    @Test
+    public void jmx() {
+        run(new JMXExecutor());
+    }
+
+    private void setMutableFlag(CommandExecutor executor) {
+        OutputAnalyzer out = getAllFlags(executor);
+        String flagName = out.firstMatch(MANAGEABLE_PATTERN, 1);
+        String flagVal = out.firstMatch(MANAGEABLE_PATTERN, 2);
+
+        System.out.println("### Setting a mutable flag '" + flagName + "'");
+
+        if (flagVal == null) {
+            System.err.println(out.getOutput());
+            throw new Error("Can not find a boolean manageable flag");
+        }
+
+        Boolean blnVal = Boolean.parseBoolean(flagVal);
+
+        out = executor.execute("VM.set_flag " + flagName + " " + (blnVal ? 0 : 1));
+        out.stderrShouldBeEmpty();
+
+        out = getAllFlags(executor);
+
+        String newFlagVal = out.firstMatch(MANAGEABLE_PATTERN.replace("(\\S+)", flagName), 1);
+
+        assertNotEquals(newFlagVal, flagVal);
+    }
+
+    private void setMutableFlagWithInvalidValue(CommandExecutor executor) {
+        OutputAnalyzer out = getAllFlags(executor);
+        String flagName = out.firstMatch(MANAGEABLE_PATTERN, 1);
+        String flagVal = out.firstMatch(MANAGEABLE_PATTERN, 2);
+
+        System.out.println("### Setting a mutable flag '" + flagName + "' to an invalid value");
+
+        if (flagVal == null) {
+            System.err.println(out.getOutput());
+            throw new Error("Can not find a boolean manageable flag");
+        }
+
+        // a boolean flag accepts only 0/1 as its value
+        out = executor.execute("VM.set_flag " + flagName + " unexpected_value");
+        out.stderrShouldBeEmpty();
+        out.stdoutShouldContain("flag value must be a boolean (1 or 0)");
+
+        out = getAllFlags(executor);
+
+        String newFlagVal = out.firstMatch(MANAGEABLE_PATTERN.replace("(\\S+)", flagName), 1);
+
+        assertEquals(newFlagVal, flagVal);
+    }
+
+    private void setImmutableFlag(CommandExecutor executor) {
+        OutputAnalyzer out = getAllFlags(executor);
+        String flagName = out.firstMatch(IMMUTABLE_PATTERN, 1);
+        String flagVal = out.firstMatch(IMMUTABLE_PATTERN, 2);
+
+        System.out.println("### Setting an immutable flag '" + flagName + "'");
+
+        if (flagVal == null) {
+            System.err.println(out.getOutput());
+            throw new Error("Can not find an immutable uintx flag");
+        }
+
+        Long numVal = Long.parseLong(flagVal);
+
+        out = executor.execute("VM.set_flag " + flagName + " " + (numVal + 1));
+        out.stderrShouldBeEmpty();
+        out.stdoutShouldContain("only 'writeable' flags can be set");
+
+        out = getAllFlags(executor);
+
+        String newFlagVal = out.firstMatch(IMMUTABLE_PATTERN.replace("(\\S+)", flagName), 1);
+
+        assertEquals(newFlagVal, flagVal);
+    }
+
+    private void setNonExistingFlag(CommandExecutor executor) {
+        String unknownFlag = "ThisIsUnknownFlag";
+        System.out.println("### Setting a non-existing flag '" + unknownFlag + "'");
+        OutputAnalyzer out = executor.execute("VM.set_flag " + unknownFlag + " 1");
+        out.stderrShouldBeEmpty();
+        out.stdoutShouldContain("flag " + unknownFlag + " does not exist");
+    }
+
+    private OutputAnalyzer getAllFlags(CommandExecutor executor) {
+        return executor.execute("VM.flags -all", true);
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/hprof/cpu002.java	Thu Apr 16 14:05:48 2015 -0700
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8076421
+ * @summary Test of hprof option crashes Zero
+ * @compile cpu002.java
+ * @run main/othervm -Xrunhprof:cpu=times,file=cpu002.hprof.out cpu002
+ */
+
+import java.io.*;
+
+public class cpu002 {
+    public static final int PASSED = 0;
+    public static final int FAILED = 2;
+    public static final int JCK_STATUS_BASE = 95;
+
+    public static void main (String argv[]) {
+        System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+    }
+
+    public static int run(String argv[], PrintStream out) {
+        return PASSED;
+    }
+}
--- a/hotspot/test/serviceability/threads/TestFalseDeadLock.java	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/test/serviceability/threads/TestFalseDeadLock.java	Thu Apr 16 14:05:48 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, 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
@@ -28,7 +28,6 @@
 
 /*
  * @test
- * @ignore 8061157
  * @bug 8016304
  * @summary Make sure no deadlock is reported for this program which has no deadlocks.
  * @library /testlibrary
--- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java	Thu Apr 16 14:05:48 2015 -0700
@@ -48,6 +48,10 @@
         return vmName.endsWith(" Graal VM");
     }
 
+    public static boolean isZero() {
+        return vmName.endsWith(" Zero VM");
+    }
+
     public static boolean isMinimal() {
         return vmName.endsWith(" Minimal VM");
     }
--- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/dcmd/CommandExecutor.java	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/dcmd/CommandExecutor.java	Thu Apr 16 14:05:48 2015 -0700
@@ -40,16 +40,34 @@
      *          stderr, regardless of the specific executor used.
      */
     public final OutputAnalyzer execute(String cmd) throws CommandExecutorException {
-        System.out.printf("Running DCMD '%s' through '%s'%n", cmd, this.getClass().getSimpleName());
+        return execute(cmd, false);
+    }
+
+    /**
+     * Execute a diagnostic command
+     *
+     * @param cmd The diagnostic command to execute
+     * @param silent Do not print the command output
+     * @return an {@link jdk.testlibrary.OutputAnalyzer} encapsulating the output of the command
+     * @throws CommandExecutorException if there is an exception on the "calling side" while trying to execute the
+     *          Diagnostic Command. Exceptions thrown on the remote side are available as textual representations in
+     *          stderr, regardless of the specific executor used.
+     */
+    public final OutputAnalyzer execute(String cmd, boolean silent) throws CommandExecutorException {
+        if (!silent) {
+            System.out.printf("Running DCMD '%s' through '%s'%n", cmd, this.getClass().getSimpleName());
+        }
+
         OutputAnalyzer oa = executeImpl(cmd);
 
-        System.out.println("---------------- stdout ----------------");
-        System.out.println(oa.getStdout());
-        System.out.println("---------------- stderr ----------------");
-        System.out.println(oa.getStderr());
-        System.out.println("----------------------------------------");
-        System.out.println();
-
+        if (!silent) {
+            System.out.println("---------------- stdout ----------------");
+            System.out.println(oa.getStdout());
+            System.out.println("---------------- stderr ----------------");
+            System.out.println(oa.getStderr());
+            System.out.println("----------------------------------------");
+            System.out.println();
+        }
         return oa;
     }
 
--- a/hotspot/test/testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java	Wed Apr 15 11:01:56 2015 +0200
+++ b/hotspot/test/testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java	Thu Apr 16 14:05:48 2015 -0700
@@ -48,7 +48,7 @@
         ARCH("isARM", "isPPC", "isSparc", "isX86", "isX64"),
         BITNESS("is32bit", "is64bit"),
         OS("isAix", "isLinux", "isOSX", "isSolaris", "isWindows"),
-        VM_TYPE("isClient", "isServer", "isGraal", "isMinimal"),
+        VM_TYPE("isClient", "isServer", "isGraal", "isMinimal", "isZero"),
         IGNORED("isEmbedded", "isDebugBuild", "shouldSAAttach",
                 "canPtraceAttachLinux", "canAttachOSX", "isTieredSupported");