Merge jdk7-b29
authorduke
Wed, 05 Jul 2017 16:37:51 +0200
changeset 665 bfe4572fd301
parent 664 d980846edc0a (diff)
parent 573 f1b2334919a4 (current diff)
child 666 2ec3717dd4d1
child 667 75207090420d
child 669 aa5cabe2077d
child 672 9749234cee6d
child 682 3b56e15774b8
child 701 c86ebe5c13fd
child 717 66d97822d0bb
child 720 d128de813af0
child 723 2b7967865c46
child 726 b59b59d4278f
child 730 657ff1a9c0a0
child 746 b63a896706ee
Merge
--- a/.hgtags-top-repo	Wed Jul 05 16:37:21 2017 +0200
+++ b/.hgtags-top-repo	Wed Jul 05 16:37:51 2017 +0200
@@ -2,3 +2,4 @@
 cbc8ad9dd0e085a607427ea35411990982f19a36 jdk7-b25
 9410f77cc30c604d1caf7c9fe3a57fa19e1acbe8 jdk7-b26
 11b4dc9f2be3523ef989a0db8459eb56b3045c3a jdk7-b27
+56652b46f328937f6b9b5130f1e4cd80f48868ef jdk7-b28
--- a/corba/.hgtags	Wed Jul 05 16:37:21 2017 +0200
+++ b/corba/.hgtags	Wed Jul 05 16:37:51 2017 +0200
@@ -2,3 +2,4 @@
 5e61d5df62586474414d1058e9186441aa908f51 jdk7-b25
 0043eb3d4e628f049ff80a8c223b5657136085e7 jdk7-b26
 e84e9018bebbf3e5bafc5706e7882a15cb1c7d99 jdk7-b27
+27509b7d21ed783b3f6eb7b7612781c675a30c2f jdk7-b28
--- a/corba/make/common/shared/Compiler-sun.gmk	Wed Jul 05 16:37:21 2017 +0200
+++ b/corba/make/common/shared/Compiler-sun.gmk	Wed Jul 05 16:37:51 2017 +0200
@@ -31,6 +31,9 @@
 
 # Sun Studio Compiler settings specific to Solaris
 ifeq ($(PLATFORM), solaris)
+  # FIXUP: Change to SS12 when validated
+  #COMPILER_VERSION=SS12
+  #REQUIRED_CC_VER=5.9
   COMPILER_VERSION=SS11
   REQUIRED_CC_VER=5.8
   CC             = $(COMPILER_PATH)cc
@@ -51,8 +54,8 @@
 # Sun Studio Compiler settings specific to Linux
 ifeq ($(PLATFORM), linux)
   # This has not been tested
-  COMPILER_VERSION=SS11
-  REQUIRED_CC_VER=5.8
+  COMPILER_VERSION=SS12
+  REQUIRED_CC_VER=5.9
   CC             = $(COMPILER_PATH)cc
   CPP            = $(COMPILER_PATH)cc -E
   CXX            = $(COMPILER_PATH)CC
--- a/corba/make/jprt.config	Wed Jul 05 16:37:21 2017 +0200
+++ b/corba/make/jprt.config	Wed Jul 05 16:37:51 2017 +0200
@@ -123,9 +123,15 @@
 	solaris_arch=i386
     fi
 
-    # Get the SS11 compilers into path (make sure it matches ALT setting)
-    compiler_path=${jdk_devtools}/${solaris_arch}/SUNWspro/SS11/bin
-    compiler_name=SS11
+    # Get the compilers into path (make sure it matches ALT setting)
+    if [ "${JPRT_SOLARIS_COMPILER_NAME}" != "" ] ; then
+        compiler_name=${JPRT_SOLARIS_COMPILER_NAME}
+    else
+        # FIXUP: Change to SS12 when validated
+	#compiler_name=SS12
+        compiler_name=SS11
+    fi
+    compiler_path=${jdk_devtools}/${solaris_arch}/SUNWspro/${compiler_name}/bin
     ALT_COMPILER_PATH="${compiler_path}"
     export ALT_COMPILER_PATH
     dirMustExist "${compiler_path}" ALT_COMPILER_PATH
--- a/hotspot/.hgtags	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/.hgtags	Wed Jul 05 16:37:51 2017 +0200
@@ -2,3 +2,4 @@
 7836be3e92d0a4f9ee7566f602c91f5609534e66 jdk7-b25
 ad0b851458ff9d1d490ed2d79bb84f75a9fdb753 jdk7-b26
 e3d2692f8442e2d951166dc9bd9a330684754438 jdk7-b27
+c14dab40ed9bf45ad21150bd70c9c80cdf655415 jdk7-b28
--- a/hotspot/agent/make/Makefile	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/agent/make/Makefile	Wed Jul 05 16:37:51 2017 +0200
@@ -246,16 +246,16 @@
 all: filelist
 	@mkdir -p $(OUTPUT_DIR)
 	@echo "$(SA_BUILD_VERSION_PROP)" > $(SA_PROPERTIES)
-	@javac -source 1.4 -classpath $(CLASSPATH) -deprecation -sourcepath $(SRC_DIR) -g -d $(OUTPUT_DIR) @filelist
-	@rmic -classpath $(OUTPUT_DIR) -d $(OUTPUT_DIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer
+	@${JDK_HOME}/bin/javac -source 1.4 -classpath $(CLASSPATH) -deprecation -sourcepath $(SRC_DIR) -g -d $(OUTPUT_DIR) @filelist
+	@${JDK_HOME}/bin/rmic -classpath $(OUTPUT_DIR) -d $(OUTPUT_DIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer
 	rm -f $(OUTPUT_DIR)/sun/jvm/hotspot/utilities/soql/sa.js
 	cp $(SRC_DIR)/sun/jvm/hotspot/utilities/soql/sa.js $(OUTPUT_DIR)/sun/jvm/hotspot/utilities/soql
 
 allprof: filelist
 	@mkdir -p $(OUTPUT_DIR)
 	@echo "$(SA_BUILD_VERSION_PROP)" > $(SA_PROPERTIES)
-	@javac -source 1.4 -J-Xprof -classpath $(CLASSPATH) -deprecation -sourcepath $(SRC_DIR) -g -d $(OUTPUT_DIR) @filelist
-	@rmic -classpath $(OUTPUT_DIR) -d $(OUTPUT_DIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer
+	@${JDK_HOME}/bin/javac -source 1.4 -J-Xprof -classpath $(CLASSPATH) -deprecation -sourcepath $(SRC_DIR) -g -d $(OUTPUT_DIR) @filelist
+	@${JDK_HOME}/bin/rmic -classpath $(OUTPUT_DIR) -d $(OUTPUT_DIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer
 	rm -f $(OUTPUT_DIR)/sun/jvm/hotspot/utilities/soql/sa.js
 	cp $(SRC_DIR)/sun/jvm/hotspot/utilities/soql/sa.js $(OUTPUT_DIR)/sun/jvm/hotspot/utilities/soql
 
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/HSDB.java	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/HSDB.java	Wed Jul 05 16:37:51 2017 +0200
@@ -398,7 +398,7 @@
     frame.getContentPane().add(desktop);
     GraphicsUtilities.reshapeToAspectRatio(frame, 4.0f/3.0f, 0.75f, Toolkit.getDefaultToolkit().getScreenSize());
     GraphicsUtilities.centerInContainer(frame, Toolkit.getDefaultToolkit().getScreenSize());
-    frame.show();
+    frame.setVisible(true);
 
     Runtime.getRuntime().addShutdownHook(new java.lang.Thread() {
         public void run() {
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/SALauncherLoader.java	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/SALauncherLoader.java	Wed Jul 05 16:37:51 2017 +0200
@@ -148,7 +148,7 @@
         }
 
         try {
-            return file.toURL();
+            return file.toURI().toURL();
         } catch (MalformedURLException mue) {
             throw new InternalError(mue.getMessage());
         }
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/bugspot/Main.java	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/bugspot/Main.java	Wed Jul 05 16:37:51 2017 +0200
@@ -47,6 +47,6 @@
                                            4.0f/3.0f, 0.85f, Toolkit.getDefaultToolkit().getScreenSize());
     GraphicsUtilities.centerInContainer(frame,
                                         Toolkit.getDefaultToolkit().getScreenSize());
-    frame.show();
+    frame.setVisible(true);
   }
 }
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/jdi/SAJDIClassLoader.java	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/jdi/SAJDIClassLoader.java	Wed Jul 05 16:37:51 2017 +0200
@@ -78,7 +78,7 @@
         this(parent);
         this.classPathSet = true;
         try {
-            addURL(new File(classPath).toURL());
+            addURL(new File(classPath).toURI().toURL());
         } catch(MalformedURLException mue) {
             throw new RuntimeException(mue);
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/BinaryTreeDictionary.java	Wed Jul 05 16:37:51 2017 +0200
@@ -0,0 +1,59 @@
+/*
+ * @(#)BinaryTreeDictionary.java
+ * Copyright 2000-2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.memory;
+
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.runtime.*;
+
+public class BinaryTreeDictionary extends VMObject {
+   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("BinaryTreeDictionary");
+      totalSizeField = type.getCIntegerField("_totalSize");
+   }
+
+   // Fields
+   private static CIntegerField totalSizeField;
+
+   // Accessors
+   public long size() {
+      return totalSizeField.getValue(addr);
+   }
+
+   // Constructor
+   public BinaryTreeDictionary(Address addr) {
+      super(addr);
+   }
+}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/CompactibleFreeListSpace.java	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/CompactibleFreeListSpace.java	Wed Jul 05 16:37:51 2017 +0200
@@ -35,6 +35,20 @@
 public class CompactibleFreeListSpace extends CompactibleSpace {
    private static AddressField collectorField;
 
+   // for free size, three fields
+   //       FreeBlockDictionary* _dictionary;        // ptr to dictionary for large size blocks
+   //       FreeList _indexedFreeList[IndexSetSize]; // indexed array for small size blocks
+   //       LinearAllocBlock _smallLinearAllocBlock; // small linear alloc in TLAB
+   private static AddressField indexedFreeListField;
+   private static AddressField dictionaryField;
+   private static long         smallLinearAllocBlockFieldOffset;
+   private static long indexedFreeListSizeOf;
+
+   private int    heapWordSize;     // 4 for 32bit, 8 for 64 bits
+   private int    IndexSetStart;    // for small indexed list
+   private int    IndexSetSize;
+   private int    IndexSetStride;
+
    static {
       VM.registerVMInitializedObserver(new Observer() {
          public void update(Observable o, Object data) {
@@ -51,10 +65,26 @@
 
      Type type = db.lookupType("CompactibleFreeListSpace");
      collectorField = type.getAddressField("_collector");
+     collectorField       = type.getAddressField("_collector");
+     dictionaryField      = type.getAddressField("_dictionary");
+     indexedFreeListField = type.getAddressField("_indexedFreeList[0]");
+     smallLinearAllocBlockFieldOffset = type.getField("_smallLinearAllocBlock").getOffset();
    }
 
    public CompactibleFreeListSpace(Address addr) {
       super(addr);
+      if ( VM.getVM().isLP64() ) {
+         heapWordSize = 8;
+         IndexSetStart = 1;
+         IndexSetStride = 1;
+      }
+      else {
+         heapWordSize = 4;
+         IndexSetStart = 2;
+         IndexSetStride = 2;
+      }
+
+      IndexSetSize = 257;
    }
 
    // Accessing block offset table
@@ -62,9 +92,17 @@
     return (CMSCollector) VMObjectFactory.newObject(
                                  CMSCollector.class,
                                  collectorField.getValue(addr));
-  }
+   }
+
+   public long free0() {
+     return capacity() - used0();
+   }
 
    public long used() {
+     return capacity() - free();
+   }
+
+   public long used0() {
       List regions = getLiveRegions();
       long usedSize = 0L;
       for (Iterator itr = regions.iterator(); itr.hasNext();) {
@@ -75,11 +113,41 @@
    }
 
    public long free() {
-      return capacity() - used();
-   }
+      // small chunks
+      long size = 0;
+      Address cur = addr.addOffsetTo( indexedFreeListField.getOffset() );
+      cur = cur.addOffsetTo(IndexSetStart*FreeList.sizeOf());
+      for (int i=IndexSetStart; i<IndexSetSize; i += IndexSetStride) {
+         FreeList freeList = (FreeList) VMObjectFactory.newObject(FreeList.class, cur);
+         size += i*freeList.count();
+         cur= cur.addOffsetTo(IndexSetStride*FreeList.sizeOf());
+      }
+
+      // large block
+      BinaryTreeDictionary bfbd = (BinaryTreeDictionary) VMObjectFactory.newObject(BinaryTreeDictionary.class,
+                                                                                   dictionaryField.getValue(addr));
+      size += bfbd.size();
+
+
+      // linear block in TLAB
+      LinearAllocBlock lab = (LinearAllocBlock) VMObjectFactory.newObject(LinearAllocBlock.class,
+                                                                          addr.addOffsetTo(smallLinearAllocBlockFieldOffset));
+      size += lab.word_size();
+
+      return size*heapWordSize;
+  }
 
    public void printOn(PrintStream tty) {
       tty.print("free-list-space");
+      tty.print("[ " + bottom() + " , " + end() + " ) ");
+      long cap = capacity();
+      long used_size = used();
+      long free_size = free();
+      int  used_perc = (int)((double)used_size/cap*100);
+      tty.print("space capacity = " + cap + " used(" + used_perc + "%)= " + used_size + " ");
+      tty.print("free= " + free_size );
+      tty.print("\n");
+
    }
 
    public Address skipBlockSizeUsingPrintezisBits(Address pos) {
@@ -121,7 +189,7 @@
             cur = cur.addOffsetTo(adjustObjectSizeInBytes(size));
          }
 
-         if (FreeChunk.secondWordIndicatesFreeChunk(dbg.getAddressValue(klassOop))) {
+         if (FreeChunk.indicatesFreeChunk(cur)) {
             if (! cur.equals(regionStart)) {
                res.add(new MemRegion(regionStart, cur));
             }
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/DefNewGeneration.java	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/DefNewGeneration.java	Wed Jul 05 16:37:51 2017 +0200
@@ -96,9 +96,9 @@
   public void printOn(PrintStream tty) {
     tty.print("  eden");
     eden().printOn(tty);
-    tty.print("  from");
+    tty.print("\n  from");
     from().printOn(tty);
-    tty.print("  to  ");
+    tty.print("\n  to  ");
     to().printOn(tty);
   }
 }
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/FreeChunk.java	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/FreeChunk.java	Wed Jul 05 16:37:51 2017 +0200
@@ -28,6 +28,7 @@
 import sun.jvm.hotspot.debugger.*;
 import sun.jvm.hotspot.types.*;
 import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
 
 public class FreeChunk extends VMObject {
    static {
@@ -42,13 +43,13 @@
       Type type = db.lookupType("FreeChunk");
       nextField = type.getAddressField("_next");
       prevField = type.getAddressField("_prev");
-      sizeField = type.getCIntegerField("_size");
+      sizeField = type.getAddressField("_size");
    }
 
    // Fields
    private static AddressField nextField;
    private static AddressField prevField;
-   private static CIntegerField sizeField;
+   private static AddressField sizeField;
 
    // Accessors
    public FreeChunk next() {
@@ -61,20 +62,34 @@
    }
 
    public long size() {
-      return sizeField.getValue(addr);
+      if (VM.getVM().isCompressedOopsEnabled()) {
+        Mark mark = new Mark(sizeField.getValue(addr));
+        return mark.getSize();
+      } else {
+        Address size = sizeField.getValue(addr);
+        Debugger dbg = VM.getVM().getDebugger();
+        return dbg.getAddressValue(size);
+      }
    }
 
    public FreeChunk(Address addr) {
       super(addr);
    }
 
-   public static boolean secondWordIndicatesFreeChunk(long word) {
-      return (word & 0x1L) == 0x1L;
+   public static boolean indicatesFreeChunk(Address cur) {
+      FreeChunk f = new FreeChunk(cur);
+      return f.isFree();
    }
 
    public boolean isFree() {
-      Debugger dbg = VM.getVM().getDebugger();
-      Address prev = prevField.getValue(addr);
-      return secondWordIndicatesFreeChunk(dbg.getAddressValue(prev));
+      if (VM.getVM().isCompressedOopsEnabled()) {
+        Mark mark = new Mark(sizeField.getValue(addr));
+        return mark.isCmsFreeChunk();
+      } else {
+        Address prev = prevField.getValue(addr);
+        Debugger dbg = VM.getVM().getDebugger();
+        long word = dbg.getAddressValue(prev);
+        return (word & 0x1L) == 0x1L;
+      }
    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/FreeList.java	Wed Jul 05 16:37:51 2017 +0200
@@ -0,0 +1,72 @@
+/*
+ * @(#)FreeList.java
+ *
+ * Copyright 2000-2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.memory;
+
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.runtime.*;
+
+public class FreeList extends VMObject {
+   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("FreeList");
+      sizeField = type.getCIntegerField("_size");
+      countField = type.getCIntegerField("_count");
+      headerSize = type.getSize();
+   }
+
+   // Fields
+   private static CIntegerField sizeField;
+   private static CIntegerField countField;
+   private static long          headerSize;
+
+   //Constructor
+   public FreeList(Address address) {
+     super(address);
+   }
+
+   // Accessors
+   public long size() {
+      return sizeField.getValue(addr);
+   }
+
+   public long count() {
+      return  countField.getValue(addr);
+   }
+
+   public static long sizeOf() {
+     return headerSize;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/LinearAllocBlock.java	Wed Jul 05 16:37:51 2017 +0200
@@ -0,0 +1,59 @@
+/*
+ * @(#)BinaryTreeDictionary.java
+ * Copyright 2000-2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.memory;
+
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.runtime.*;
+
+public class LinearAllocBlock extends VMObject {
+   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("LinearAllocBlock");
+      word_sizeField= type.getCIntegerField("_word_size");
+   }
+
+   // Fields
+   private static CIntegerField word_sizeField;
+
+   // Accessors
+   public long word_size() {
+      return word_sizeField.getValue(addr);
+   }
+
+   // Constructor
+   public LinearAllocBlock(Address addr) {
+      super(addr);
+   }
+}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Mark.java	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Mark.java	Wed Jul 05 16:37:51 2017 +0200
@@ -79,6 +79,11 @@
     noHashInPlace       = db.lookupLongConstant("markOopDesc::no_hash_in_place").longValue();
     noLockInPlace       = db.lookupLongConstant("markOopDesc::no_lock_in_place").longValue();
     maxAge              = db.lookupLongConstant("markOopDesc::max_age").longValue();
+
+    /* Constants in markOop used by CMS. */
+    cmsShift            = db.lookupLongConstant("markOopDesc::cms_shift").longValue();
+    cmsMask             = db.lookupLongConstant("markOopDesc::cms_mask").longValue();
+    sizeShift           = db.lookupLongConstant("markOopDesc::size_shift").longValue();
   }
 
   // Field accessors
@@ -120,6 +125,11 @@
 
   private static long maxAge;
 
+  /* Constants in markOop used by CMS. */
+  private static long cmsShift;
+  private static long cmsMask;
+  private static long sizeShift;
+
   public Mark(Address addr) {
     super(addr);
   }
@@ -290,4 +300,11 @@
   //
   //  // Recover address of oop from encoded form used in mark
   //  inline void* decode_pointer() { return clear_lock_bits(); }
+
+  // Copy markOop methods for CMS here.
+  public boolean isCmsFreeChunk() {
+    return isUnlocked() &&
+           (Bits.maskBitsLong(value() >> cmsShift, cmsMask) & 0x1L) == 0x1L;
+  }
+  public long getSize() { return (long)(value() >> sizeShift); }
 }
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/OopUtilities.java	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/OopUtilities.java	Wed Jul 05 16:37:51 2017 +0200
@@ -274,10 +274,10 @@
        // hc_klass is a HotSpot magic field and hence we can't
        // find it from InstanceKlass for java.lang.Class.
        TypeDataBase db = VM.getVM().getTypeDataBase();
-       int hcKlassOffset = (int) Oop.getHeaderSize();
+       int hcKlassOffset = (int) Instance.getHeaderSize();
        try {
           hcKlassOffset += (db.lookupIntConstant("java_lang_Class::hc_klass_offset").intValue() *
-                           db.getAddressSize());
+                           VM.getVM().getHeapOopSize());
        } catch (RuntimeException re) {
           // ignore, currently java_lang_Class::hc_klass_offset is zero
        }
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/AnnotatedMemoryPanel.java	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/AnnotatedMemoryPanel.java	Wed Jul 05 16:37:51 2017 +0200
@@ -648,6 +648,6 @@
           System.exit(0);
         }
       });
-    frame.show();
+    frame.setVisible(true);
   }
 }
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/CommandProcessorPanel.java	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/CommandProcessorPanel.java	Wed Jul 05 16:37:51 2017 +0200
@@ -220,7 +220,7 @@
                 }
             });
         frame.setSize(500, 500);
-        frame.show();
+        frame.setVisible(true);
         panel.requestFocus();
     }
 }
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/DebuggerConsolePanel.java	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/DebuggerConsolePanel.java	Wed Jul 05 16:37:51 2017 +0200
@@ -226,7 +226,7 @@
         }
       });
     frame.setSize(500, 500);
-    frame.show();
+    frame.setVisible(true);
     panel.requestFocus();
   }
 }
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/HighPrecisionJScrollBar.java	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/HighPrecisionJScrollBar.java	Wed Jul 05 16:37:51 2017 +0200
@@ -424,7 +424,7 @@
         }
       });
     frame.getContentPane().add(hpsb);
-    frame.show();
+    frame.setVisible(true);
   }
 
 }
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/JFrameWrapper.java	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/JFrameWrapper.java	Wed Jul 05 16:37:51 2017 +0200
@@ -43,7 +43,7 @@
   public void       setVisible(boolean visible) { frame.setVisible(visible);     }
   public void       setSize(int x, int y)       { frame.setSize(x, y);           }
   public void       pack()                      { frame.pack();                  }
-  public void       show()                      { frame.show();                  }
+  public void       show()                      { frame.setVisible(true);        }
   public void       dispose()                   { frame.dispose();               }
   public void       setBackground(Color color)  { frame.setBackground(color);    }
   public void       setResizable(boolean resizable) { frame.setResizable(resizable); }
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/treetable/JTreeTable.java	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/treetable/JTreeTable.java	Wed Jul 05 16:37:51 2017 +0200
@@ -477,9 +477,9 @@
     static class TreeTableTextField extends JTextField {
         public int offset;
 
-        public void reshape(int x, int y, int w, int h) {
+        public void setBounds(int x, int y, int w, int h) {
             int newX = Math.max(x, offset);
-            super.reshape(newX, y, w - (newX - x), h);
+            super.setBounds(newX, y, w - (newX - x), h);
         }
     }
 
--- a/hotspot/make/hotspot_version	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/make/hotspot_version	Wed Jul 05 16:37:51 2017 +0200
@@ -35,7 +35,7 @@
 
 HS_MAJOR_VER=13
 HS_MINOR_VER=0
-HS_BUILD_NUMBER=01
+HS_BUILD_NUMBER=02
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=7
--- a/hotspot/make/jprt.config	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/make/jprt.config	Wed Jul 05 16:37:51 2017 +0200
@@ -68,8 +68,23 @@
 	solaris_arch=i386
     fi
 
-    # Get the SS11 compilers into path (make sure it matches ALT setting)
-    compiler_path=${slashjava}/devtools/${solaris_arch}/SUNWspro/SS11/bin
+    if [ "${JPRT_SOLARIS_COMPILER_NAME}" != "" ] ; then
+        compiler_name=${JPRT_SOLARIS_COMPILER_NAME}
+    else
+        if [ "${JPRT_JOB_PRODUCT_RELEASE}" = "jdk6"      -o \
+             "${JPRT_JOB_PRODUCT_RELEASE}" = "jdk6u10"   -o \
+             "${JPRT_JOB_PRODUCT_RELEASE}" = "jdk6perf" ] ; then
+            # All jdk6 builds use SS11
+            compiler_name=SS11
+        else
+            # FIXUP: Change to SS12 once it has been validated.
+	    #compiler_name=SS12
+            compiler_name=SS11
+        fi
+    fi
+    
+    # Get into path (make sure it matches ALT setting)
+    compiler_path=${slashjava}/devtools/${solaris_arch}/SUNWspro/${compiler_name}/bin
     dirMustExist "${compiler_path}" COMPILER_PATH
     path4sdk=${compiler_path}
 
--- a/hotspot/make/jprt.properties	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/make/jprt.properties	Wed Jul 05 16:37:51 2017 +0200
@@ -24,209 +24,274 @@
 
 # Properties for jprt
 
-JPRT.tools.default.release=jdk1.7.0
+# All build result bundles are full jdks, so the 64bit testing does not 
+#    need the 32bit sibling bundle installed.
+#    Note: If the hotspot/make/Makefile changed to only bundle the 64bit files
+#          when bundling 64bit, and stripped out the 64bit files from any 32bit
+#          bundles, then this setting would be need to be "true".
+
+jprt.need.sibling.build=false
+
+# At submit time, the release supplied will be in jprt.submit.release
+#    and will be one of the official release names defined in jprt.
+#    jprt supports property value expansion using ${property.name} syntax.
 
-# Build result bundles are not partial builds| but include everything
-JPRT.need.sibling.build=false
+# This tells jprt what default release we want to build
+
+jprt.tools.default.release=${jprt.submit.release}
+
+# Define the Solaris platforms we want for the various releases
+
+jprt.my.solaris.sparc.jdk7=solaris_sparc_5.10
+jprt.my.solaris.sparc.jdk6=solaris_sparc_5.8
+jprt.my.solaris.sparc.jdk6perf=solaris_sparc_5.8
+jprt.my.solaris.sparc.jdk6u10=solaris_sparc_5.8
+jprt.my.solaris.sparc=${jprt.my.solaris.sparc.${jprt.tools.default.release}}
 
-# Directories needed to build
-JPRT.bundle.src.dirs=make src agent
-JPRT.bundle.exclude.src.dirs=build
+jprt.my.solaris.sparcv9.jdk7=solaris_sparcv9_5.10
+jprt.my.solaris.sparcv9.jdk6=solaris_sparcv9_5.8
+jprt.my.solaris.sparcv9.jdk6perf=solaris_sparcv9_5.8
+jprt.my.solaris.sparcv9.jdk6u10=solaris_sparcv9_5.8
+jprt.my.solaris.sparcv9=${jprt.my.solaris.sparcv9.${jprt.tools.default.release}}
+
+jprt.my.solaris.i586.jdk7=solaris_i586_5.10
+jprt.my.solaris.i586.jdk6=solaris_i586_5.8
+jprt.my.solaris.i586.jdk6perf=solaris_i586_5.8
+jprt.my.solaris.i586.jdk6u10=solaris_i586_5.8
+jprt.my.solaris.i586=${jprt.my.solaris.i586.${jprt.tools.default.release}}
 
+jprt.my.solaris.x64.jdk7=solaris_x64_5.10
+jprt.my.solaris.x64.jdk6=solaris_x64_5.10
+jprt.my.solaris.x64.jdk6perf=solaris_x64_5.10
+jprt.my.solaris.x64.jdk6u10=solaris_x64_5.10
+jprt.my.solaris.x64=${jprt.my.solaris.x64.${jprt.tools.default.release}}
+
+jprt.my.linux.i586=linux_i586
+jprt.my.linux.x64=linux_x64
+jprt.my.windows.i586=windows_i586
+jprt.my.windows.x64=windows_x64
+
+# Standard list of jprt build targets for this source tree
+
+jprt.build.targets= \
+    ${jprt.my.solaris.sparc}-{product|fastdebug|debug}, \
+    ${jprt.my.solaris.sparcv9}-{product|fastdebug|debug}, \
+    ${jprt.my.solaris.i586}-{product|fastdebug|debug}, \
+    ${jprt.my.solaris.x64}-{product|fastdebug|debug}, \
+    ${jprt.my.linux.i586}-{product|fastdebug|debug}, \
+    ${jprt.my.linux.x64}-{product|fastdebug}, \
+    ${jprt.my.windows.i586}-{product|fastdebug|debug}, \
+    ${jprt.my.windows.x64}-{product|fastdebug|debug}
 
-# Standard list of JPRT build targets for this workspace
-JPRT.build.targets= \
-    solaris_sparc_5.10-{product|fastdebug|debug}, \
-    solaris_sparcv9_5.10-{product|fastdebug|debug}, \
-    solaris_i586_5.10-{product|fastdebug|debug}, \
-    solaris_x64_5.10-{product|fastdebug|debug}, \
-    linux_i586-{product|fastdebug|debug}, \
-    linux_x64-{product|fastdebug}, \
-    windows_i586-{product|fastdebug|debug}, \
-    windows_x64-{product|fastdebug|debug}
+# Subset lists of test targets for this source tree
+
+jprt.my.solaris.sparc.test.targets= \
+    ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-jvm98, \
+    ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-scimark, \
+    ${jprt.my.solaris.sparc}-product-{c1|c2}-runThese, \
+    ${jprt.my.solaris.sparc}-product-{c1|c2}-runThese_Xcomp, \
+    ${jprt.my.solaris.sparc}-product-{c1|c2}-runThese_Xcomp_2, \
+    ${jprt.my.solaris.sparc}-product-{c1|c2}-runThese_Xcomp_3, \
+    ${jprt.my.solaris.sparc}-fastdebug-c1-runThese_Xshare, \
+    ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_default, \
+    ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_SerialGC, \
+    ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_ParallelGC, \
+    ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_ParNewGC, \
+    ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_CMS, \
+    ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_default_2, \
+    ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_SerialGC_2, \
+    ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_ParallelGC_2, \
+    ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_ParNewGC_2, \
+    ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_CMS_2, \
+    ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCOld_default, \
+    ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCOld_SerialGC, \
+    ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCOld_ParallelGC, \
+    ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCOld_ParNewGC, \
+    ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCOld_CMS, \
+    ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-jbb_default, \
+    ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-jbb_SerialGC, \
+    ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-jbb_ParallelGC, \
+    ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-jbb_CMS, \
+    ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-scimark_2, \
+    ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-scimark_3
+
+jprt.my.solaris.sparcv9.test.targets= \
+    ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jvm98, \
+    ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-scimark, \
+    ${jprt.my.solaris.sparcv9}-product-c2-runThese, \
+    ${jprt.my.solaris.sparcv9}-product-c2-runThese_Xcomp, \
+    ${jprt.my.solaris.sparcv9}-product-c2-runThese_Xcomp_2, \
+    ${jprt.my.solaris.sparcv9}-product-c2-runThese_Xcomp_3, \
+    ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_default, \
+    ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_SerialGC, \
+    ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_ParallelGC, \
+    ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_ParNewGC, \
+    ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_CMS, \
+    ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_default_2, \
+    ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_SerialGC_2, \
+    ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_ParallelGC_2, \
+    ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_ParNewGC_2, \
+    ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_CMS_2, \
+    ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCOld_default, \
+    ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCOld_SerialGC, \
+    ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCOld_ParallelGC, \
+    ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCOld_ParNewGC, \
+    ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCOld_CMS, \
+    ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jbb_default, \
+    ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jbb_SerialGC, \
+    ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jbb_ParallelGC, \
+    ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jbb_CMS, \
+    ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-scimark_2, \
+    ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-scimark_3
 
-# Standard list of JPRT test targets for this workspace
-JPRT.test.targets = \
-    solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-jvm98, \
-    solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-scimark, \
-    solaris_sparcv9_5.10-{product|fastdebug}-c2-jvm98, \
-    solaris_sparcv9_5.10-{product|fastdebug}-c2-scimark, \
-    solaris_i586_5.10-{product|fastdebug}-{c1|c2}-jvm98, \
-    solaris_i586_5.10-{product|fastdebug}-{c1|c2}-scimark, \
-    solaris_x64_5.10-{product|fastdebug}-c2-jvm98, \
-    solaris_x64_5.10-{product|fastdebug}-c2-scimark, \
-    linux_i586-{product|fastdebug}-{c1|c2}-jvm98, \
-    linux_i586-{product|fastdebug}-{c1|c2}-scimark, \
-    linux_x64-{product|fastdebug}-c2-jvm98, \
-    linux_x64-{product|fastdebug}-c2-scimark, \
-    windows_i586-{product|fastdebug}-{c1|c2}-jvm98, \
-    windows_i586-{product|fastdebug}-{c1|c2}-scimark, \
-    windows_x64-{product|fastdebug}-c2-jvm98, \
-    windows_x64-{product|fastdebug}-c2-scimark, \
-    solaris_sparc_5.10-product-{c1|c2}-runThese, \
-    solaris_sparc_5.10-product-{c1|c2}-runThese_Xcomp, \
-    solaris_sparc_5.10-product-{c1|c2}-runThese_Xcomp_2, \
-    solaris_sparc_5.10-product-{c1|c2}-runThese_Xcomp_3, \
-    solaris_sparc_5.10-fastdebug-c1-runThese_Xshare, \
-    solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-GCBasher_default, \
-    solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-GCBasher_SerialGC, \
-    solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-GCBasher_ParallelGC, \
-    solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-GCBasher_ParNewGC, \
-    solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-GCBasher_CMS, \
-    solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-GCBasher_default_2, \
-    solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-GCBasher_SerialGC_2, \
-    solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-GCBasher_ParallelGC_2, \
-    solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-GCBasher_ParNewGC_2, \
-    solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-GCBasher_CMS_2, \
-    solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-GCOld_default, \
-    solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-GCOld_SerialGC, \
-    solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-GCOld_ParallelGC, \
-    solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-GCOld_ParNewGC, \
-    solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-GCOld_CMS, \
-    solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-jbb_default, \
-    solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-jbb_SerialGC, \
-    solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-jbb_ParallelGC, \
-    solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-jbb_CMS, \
-    solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-scimark_2, \
-    solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-scimark_3, \
-    solaris_sparcv9_5.10-product-c2-runThese, \
-    solaris_sparcv9_5.10-product-c2-runThese_Xcomp, \
-    solaris_sparcv9_5.10-product-c2-runThese_Xcomp_2, \
-    solaris_sparcv9_5.10-product-c2-runThese_Xcomp_3, \
-    solaris_sparcv9_5.10-{product|fastdebug}-c2-GCBasher_default, \
-    solaris_sparcv9_5.10-{product|fastdebug}-c2-GCBasher_SerialGC, \
-    solaris_sparcv9_5.10-{product|fastdebug}-c2-GCBasher_ParallelGC, \
-    solaris_sparcv9_5.10-{product|fastdebug}-c2-GCBasher_ParNewGC, \
-    solaris_sparcv9_5.10-{product|fastdebug}-c2-GCBasher_CMS, \
-    solaris_sparcv9_5.10-{product|fastdebug}-c2-GCBasher_default_2, \
-    solaris_sparcv9_5.10-{product|fastdebug}-c2-GCBasher_SerialGC_2, \
-    solaris_sparcv9_5.10-{product|fastdebug}-c2-GCBasher_ParallelGC_2, \
-    solaris_sparcv9_5.10-{product|fastdebug}-c2-GCBasher_ParNewGC_2, \
-    solaris_sparcv9_5.10-{product|fastdebug}-c2-GCBasher_CMS_2, \
-    solaris_sparcv9_5.10-{product|fastdebug}-c2-GCOld_default, \
-    solaris_sparcv9_5.10-{product|fastdebug}-c2-GCOld_SerialGC, \
-    solaris_sparcv9_5.10-{product|fastdebug}-c2-GCOld_ParallelGC, \
-    solaris_sparcv9_5.10-{product|fastdebug}-c2-GCOld_ParNewGC, \
-    solaris_sparcv9_5.10-{product|fastdebug}-c2-GCOld_CMS, \
-    solaris_sparcv9_5.10-{product|fastdebug}-c2-jbb_default, \
-    solaris_sparcv9_5.10-{product|fastdebug}-c2-jbb_SerialGC, \
-    solaris_sparcv9_5.10-{product|fastdebug}-c2-jbb_ParallelGC, \
-    solaris_sparcv9_5.10-{product|fastdebug}-c2-jbb_CMS, \
-    solaris_sparcv9_5.10-{product|fastdebug}-c2-scimark_2, \
-    solaris_sparcv9_5.10-{product|fastdebug}-c2-scimark_3, \
-    solaris_x64-product-c2-runThese, \
-    solaris_x64-product-c2-runThese_Xcomp, \
-    solaris_x64-{product|fastdebug}-c2-GCBasher_default, \
-    solaris_x64-{product|fastdebug}-c2-GCBasher_SerialGC, \
-    solaris_x64-{product|fastdebug}-c2-GCBasher_ParallelGC, \
-    solaris_x64-{product|fastdebug}-c2-GCBasher_ParNewGC, \
-    solaris_x64-{product|fastdebug}-c2-GCBasher_CMS, \
-    solaris_x64-{product|fastdebug}-c2-GCBasher_default_2, \
-    solaris_x64-{product|fastdebug}-c2-GCBasher_SerialGC_2, \
-    solaris_x64-{product|fastdebug}-c2-GCBasher_ParallelGC_2, \
-    solaris_x64-{product|fastdebug}-c2-GCBasher_ParNewGC_2, \
-    solaris_x64-{product|fastdebug}-c2-GCBasher_CMS_2, \
-    solaris_x64-{product|fastdebug}-c2-GCOld_default, \
-    solaris_x64-{product|fastdebug}-c2-GCOld_SerialGC, \
-    solaris_x64-{product|fastdebug}-c2-GCOld_ParallelGC, \
-    solaris_x64-{product|fastdebug}-c2-GCOld_ParNewGC, \
-    solaris_x64-{product|fastdebug}-c2-GCOld_CMS, \
-    solaris_x64-{product|fastdebug}-c2-jbb_default, \
-    solaris_x64-{product|fastdebug}-c2-jbb_SerialGC, \
-    solaris_x64-{product|fastdebug}-c2-jbb_ParallelGC, \
-    solaris_x64-{product|fastdebug}-c2-jbb_CMS, \
-    solaris_i586_5.10-product-{c1|c2}-runThese_Xcomp, \
-    solaris_i586_5.10-product-c2-runThese_Xcomp_2, \
-    solaris_i586_5.10-fastdebug-c1-runThese_Xcomp_2, \
-    solaris_i586_5.10-fastdebug-c1-runThese_Xshare, \
-    solaris_i586_5.10-product-c1-GCBasher_default, \
-    solaris_i586_5.10-product-c1-GCBasher_SerialGC, \
-    solaris_i586_5.10-product-c1-GCBasher_ParallelGC, \
-    solaris_i586_5.10-product-c1-GCBasher_ParNewGC, \
-    solaris_i586_5.10-product-c1-GCBasher_CMS, \
-    solaris_i586_5.10-fastdebug-c2-GCBasher_default, \
-    solaris_i586_5.10-fastdebug-c2-GCBasher_SerialGC, \
-    solaris_i586_5.10-fastdebug-c2-GCBasher_ParallelGC, \
-    solaris_i586_5.10-fastdebug-c2-GCBasher_ParNewGC, \
-    solaris_i586_5.10-fastdebug-c2-GCBasher_CMS, \
-    solaris_i586_5.10-product-c1-GCOld_default, \
-    solaris_i586_5.10-product-c1-GCOld_SerialGC, \
-    solaris_i586_5.10-product-c1-GCOld_ParallelGC, \
-    solaris_i586_5.10-product-c1-GCOld_ParNewGC, \
-    solaris_i586_5.10-product-c1-GCOld_CMS, \
-    solaris_i586_5.10-fastdebug-c2-jbb_default, \
-    solaris_i586_5.10-fastdebug-c2-jbb_ParallelGC, \
-    solaris_i586_5.10-fastdebug-c2-jbb_CMS, \
-    solaris_i586_5.10-{product|fastdebug}-{c1|c2}-scimark_2, \
-    solaris_i586_5.10-{product|fastdebug}-{c1|c2}-scimark_3, \
-    linux_i586-product-c1-runThese_Xcomp, \
-    linux_i586-product-c1-runThese_Xcomp_2, \
-    linux_i586-product-c1-runThese_Xcomp_3, \
-    linux_i586-fastdebug-c1-runThese_Xshare, \
-    linux_i586-fastdebug-c2-runThese_Xcomp, \
-    linux_i586-fastdebug-c2-runThese_Xcomp_2, \
-    linux_i586-{product|fastdebug}-{c1|c2}-GCBasher_default, \
-    linux_i586-{product|fastdebug}-{c1|c2}-GCBasher_SerialGC, \
-    linux_i586-{product|fastdebug}-{c1|c2}-GCBasher_ParallelGC, \
-    linux_i586-{product|fastdebug}-{c1|c2}-GCBasher_ParNewGC, \
-    linux_i586-{product|fastdebug}-{c1|c2}-GCBasher_CMS, \
-    linux_i586-product-{c1|c2}-GCOld_default, \
-    linux_i586-product-{c1|c2}-GCOld_SerialGC, \
-    linux_i586-product-{c1|c2}-GCOld_ParallelGC, \
-    linux_i586-product-{c1|c2}-GCOld_ParNewGC, \
-    linux_i586-product-{c1|c2}-GCOld_CMS, \
-    linux_i586-{product|fastdebug}-c1-jbb_default, \
-    linux_i586-{product|fastdebug}-c1-jbb_ParallelGC, \
-    linux_i586-{product|fastdebug}-c1-jbb_CMS, \
-    linux_i586-{product|fastdebug}-c2-scimark_2, \
-    linux_i586-{product|fastdebug}-c2-scimark_3, \
-    linux_x64-{product|fastdebug}-c2-GCBasher_default, \
-    linux_x64-{product|fastdebug}-c2-GCBasher_SerialGC, \
-    linux_x64-{product|fastdebug}-c2-GCBasher_ParallelGC, \
-    linux_x64-{product|fastdebug}-c2-GCBasher_ParNewGC, \
-    linux_x64-{product|fastdebug}-c2-GCBasher_CMS, \
-    linux_x64-{product|fastdebug}-c2-GCOld_default, \
-    linux_x64-{product|fastdebug}-c2-GCOld_SerialGC, \
-    linux_x64-{product|fastdebug}-c2-GCOld_ParallelGC, \
-    linux_x64-{product|fastdebug}-c2-GCOld_ParNewGC, \
-    linux_x64-{product|fastdebug}-c2-GCOld_CMS, \
-    linux_x64-{product|fastdebug}-c2-jbb_default, \
-    linux_x64-{product|fastdebug}-c2-jbb_ParallelGC, \
-    linux_x64-{product|fastdebug}-c2-scimark_2, \
-    linux_x64-{product|fastdebug}-c2-scimark_3, \
-    windows_i586-product-{c1|c2}-runThese, \
-    windows_i586-product-{c1|c2}-runThese_Xcomp, \
-    windows_i586-fastdebug-c1-runThese_Xshare, \
-    windows_i586-{product|fastdebug}-{c1|c2}-GCBasher_default, \
-    windows_i586-{product|fastdebug}-{c1|c2}-GCBasher_SerialGC, \
-    windows_i586-{product|fastdebug}-{c1|c2}-GCBasher_ParallelGC, \
-    windows_i586-{product|fastdebug}-{c1|c2}-GCBasher_ParNewGC, \
-    windows_i586-{product|fastdebug}-{c1|c2}-GCBasher_CMS, \
-    windows_i586-product-{c1|c2}-GCOld_default, \
-    windows_i586-product-{c1|c2}-GCOld_SerialGC, \
-    windows_i586-product-{c1|c2}-GCOld_ParallelGC, \
-    windows_i586-product-{c1|c2}-GCOld_ParNewGC, \
-    windows_i586-product-{c1|c2}-GCOld_CMS, \
-    windows_i586-{product|fastdebug}-{c1|c2}-jbb_default, \
-    windows_i586-product-{c1|c2}-jbb_ParallelGC, \
-    windows_i586-product-{c1|c2}-jbb_CMS, \
-    windows_i586-product-{c1|c2}-scimark_2, \
-    windows_i586-product-{c1|c2}-scimark_3, \
-    windows_x64-product-c2-runThese, \
-    windows_x64-product-c2-runThese_Xcomp, \
-    windows_x64-{product|fastdebug}-c2-GCBasher_default, \
-    windows_x64-{product|fastdebug}-c2-GCBasher_SerialGC, \
-    windows_x64-{product|fastdebug}-c2-GCBasher_ParallelGC, \
-    windows_x64-{product|fastdebug}-c2-GCBasher_ParNewGC, \
-    windows_x64-{product|fastdebug}-c2-GCBasher_CMS, \
-    windows_x64-{product|fastdebug}-c2-GCOld_default, \
-    windows_x64-{product|fastdebug}-c2-GCOld_SerialGC, \
-    windows_x64-{product|fastdebug}-c2-GCOld_ParallelGC, \
-    windows_x64-{product|fastdebug}-c2-GCOld_ParNewGC, \
-    windows_x64-{product|fastdebug}-c2-GCOld_CMS, \
-    windows_x64-{product|fastdebug}-c2-jbb_default, \
-    windows_x64-product-c2-jbb_CMS, \
-    windows_x64-product-c2-jbb_ParallelGC, \
-    windows_x64-{product|fastdebug}-c2-scimark_2, \
-    windows_x64-{product|fastdebug}-c2-scimark_3
+jprt.my.solaris.x64.test.targets= \
+    ${jprt.my.solaris.x64}-{product|fastdebug}-c2-jvm98, \
+    ${jprt.my.solaris.x64}-{product|fastdebug}-c2-scimark, \
+    ${jprt.my.solaris.x64}-product-c2-runThese, \
+    ${jprt.my.solaris.x64}-product-c2-runThese_Xcomp, \
+    ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_default, \
+    ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_SerialGC, \
+    ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_ParallelGC, \
+    ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_ParNewGC, \
+    ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_CMS, \
+    ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_default_2, \
+    ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_SerialGC_2, \
+    ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_ParallelGC_2, \
+    ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_ParNewGC_2, \
+    ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_CMS_2, \
+    ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_default, \
+    ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_SerialGC, \
+    ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_ParallelGC, \
+    ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_ParNewGC, \
+    ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_CMS, \
+    ${jprt.my.solaris.x64}-{product|fastdebug}-c2-jbb_default, \
+    ${jprt.my.solaris.x64}-{product|fastdebug}-c2-jbb_SerialGC, \
+    ${jprt.my.solaris.x64}-{product|fastdebug}-c2-jbb_ParallelGC, \
+    ${jprt.my.solaris.x64}-{product|fastdebug}-c2-jbb_CMS
+
+jprt.my.solaris.i586.test.targets= \
+    ${jprt.my.solaris.i586}-{product|fastdebug}-{c1|c2}-jvm98, \
+    ${jprt.my.solaris.i586}-{product|fastdebug}-{c1|c2}-scimark, \
+    ${jprt.my.solaris.i586}-product-{c1|c2}-runThese_Xcomp, \
+    ${jprt.my.solaris.i586}-product-c2-runThese_Xcomp_2, \
+    ${jprt.my.solaris.i586}-fastdebug-c1-runThese_Xcomp_2, \
+    ${jprt.my.solaris.i586}-fastdebug-c1-runThese_Xshare, \
+    ${jprt.my.solaris.i586}-product-c1-GCBasher_default, \
+    ${jprt.my.solaris.i586}-product-c1-GCBasher_SerialGC, \
+    ${jprt.my.solaris.i586}-product-c1-GCBasher_ParallelGC, \
+    ${jprt.my.solaris.i586}-product-c1-GCBasher_ParNewGC, \
+    ${jprt.my.solaris.i586}-product-c1-GCBasher_CMS, \
+    ${jprt.my.solaris.i586}-fastdebug-c2-GCBasher_default, \
+    ${jprt.my.solaris.i586}-fastdebug-c2-GCBasher_SerialGC, \
+    ${jprt.my.solaris.i586}-fastdebug-c2-GCBasher_ParallelGC, \
+    ${jprt.my.solaris.i586}-fastdebug-c2-GCBasher_ParNewGC, \
+    ${jprt.my.solaris.i586}-fastdebug-c2-GCBasher_CMS, \
+    ${jprt.my.solaris.i586}-product-c1-GCOld_default, \
+    ${jprt.my.solaris.i586}-product-c1-GCOld_SerialGC, \
+    ${jprt.my.solaris.i586}-product-c1-GCOld_ParallelGC, \
+    ${jprt.my.solaris.i586}-product-c1-GCOld_ParNewGC, \
+    ${jprt.my.solaris.i586}-product-c1-GCOld_CMS, \
+    ${jprt.my.solaris.i586}-fastdebug-c2-jbb_default, \
+    ${jprt.my.solaris.i586}-fastdebug-c2-jbb_ParallelGC, \
+    ${jprt.my.solaris.i586}-fastdebug-c2-jbb_CMS, \
+    ${jprt.my.solaris.i586}-{product|fastdebug}-{c1|c2}-scimark_2, \
+    ${jprt.my.solaris.i586}-{product|fastdebug}-{c1|c2}-scimark_3
 
+jprt.my.linux.i586.test.targets = \
+    ${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-jvm98, \
+    ${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-scimark, \
+    ${jprt.my.linux.i586}-product-c1-runThese_Xcomp, \
+    ${jprt.my.linux.i586}-product-c1-runThese_Xcomp_2, \
+    ${jprt.my.linux.i586}-product-c1-runThese_Xcomp_3, \
+    ${jprt.my.linux.i586}-fastdebug-c1-runThese_Xshare, \
+    ${jprt.my.linux.i586}-fastdebug-c2-runThese_Xcomp, \
+    ${jprt.my.linux.i586}-fastdebug-c2-runThese_Xcomp_2, \
+    ${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-GCBasher_default, \
+    ${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-GCBasher_SerialGC, \
+    ${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-GCBasher_ParallelGC, \
+    ${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-GCBasher_ParNewGC, \
+    ${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-GCBasher_CMS, \
+    ${jprt.my.linux.i586}-product-{c1|c2}-GCOld_default, \
+    ${jprt.my.linux.i586}-product-{c1|c2}-GCOld_SerialGC, \
+    ${jprt.my.linux.i586}-product-{c1|c2}-GCOld_ParallelGC, \
+    ${jprt.my.linux.i586}-product-{c1|c2}-GCOld_ParNewGC, \
+    ${jprt.my.linux.i586}-product-{c1|c2}-GCOld_CMS, \
+    ${jprt.my.linux.i586}-{product|fastdebug}-c1-jbb_default, \
+    ${jprt.my.linux.i586}-{product|fastdebug}-c1-jbb_ParallelGC, \
+    ${jprt.my.linux.i586}-{product|fastdebug}-c1-jbb_CMS, \
+    ${jprt.my.linux.i586}-{product|fastdebug}-c2-scimark_2, \
+    ${jprt.my.linux.i586}-{product|fastdebug}-c2-scimark_3
+
+jprt.my.linux.x64.test.targets = \
+    ${jprt.my.linux.x64}-{product|fastdebug}-c2-jvm98, \
+    ${jprt.my.linux.x64}-{product|fastdebug}-c2-scimark, \
+    ${jprt.my.linux.x64}-{product|fastdebug}-c2-GCBasher_default, \
+    ${jprt.my.linux.x64}-{product|fastdebug}-c2-GCBasher_SerialGC, \
+    ${jprt.my.linux.x64}-{product|fastdebug}-c2-GCBasher_ParallelGC, \
+    ${jprt.my.linux.x64}-{product|fastdebug}-c2-GCBasher_ParNewGC, \
+    ${jprt.my.linux.x64}-{product|fastdebug}-c2-GCBasher_CMS, \
+    ${jprt.my.linux.x64}-{product|fastdebug}-c2-GCOld_default, \
+    ${jprt.my.linux.x64}-{product|fastdebug}-c2-GCOld_SerialGC, \
+    ${jprt.my.linux.x64}-{product|fastdebug}-c2-GCOld_ParallelGC, \
+    ${jprt.my.linux.x64}-{product|fastdebug}-c2-GCOld_ParNewGC, \
+    ${jprt.my.linux.x64}-{product|fastdebug}-c2-GCOld_CMS, \
+    ${jprt.my.linux.x64}-{product|fastdebug}-c2-jbb_default, \
+    ${jprt.my.linux.x64}-{product|fastdebug}-c2-jbb_ParallelGC, \
+    ${jprt.my.linux.x64}-{product|fastdebug}-c2-scimark_2, \
+    ${jprt.my.linux.x64}-{product|fastdebug}-c2-scimark_3
+
+jprt.my.windows.i586.test.targets = \
+    ${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-jvm98, \
+    ${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-scimark, \
+    ${jprt.my.windows.i586}-product-{c1|c2}-runThese, \
+    ${jprt.my.windows.i586}-product-{c1|c2}-runThese_Xcomp, \
+    ${jprt.my.windows.i586}-fastdebug-c1-runThese_Xshare, \
+    ${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-GCBasher_default, \
+    ${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-GCBasher_SerialGC, \
+    ${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-GCBasher_ParallelGC, \
+    ${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-GCBasher_ParNewGC, \
+    ${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-GCBasher_CMS, \
+    ${jprt.my.windows.i586}-product-{c1|c2}-GCOld_default, \
+    ${jprt.my.windows.i586}-product-{c1|c2}-GCOld_SerialGC, \
+    ${jprt.my.windows.i586}-product-{c1|c2}-GCOld_ParallelGC, \
+    ${jprt.my.windows.i586}-product-{c1|c2}-GCOld_ParNewGC, \
+    ${jprt.my.windows.i586}-product-{c1|c2}-GCOld_CMS, \
+    ${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-jbb_default, \
+    ${jprt.my.windows.i586}-product-{c1|c2}-jbb_ParallelGC, \
+    ${jprt.my.windows.i586}-product-{c1|c2}-jbb_CMS, \
+    ${jprt.my.windows.i586}-product-{c1|c2}-scimark_2, \
+    ${jprt.my.windows.i586}-product-{c1|c2}-scimark_3
+
+jprt.my.windows.x64.test.targets = \
+    ${jprt.my.windows.x64}-{product|fastdebug}-c2-jvm98, \
+    ${jprt.my.windows.x64}-{product|fastdebug}-c2-scimark, \
+    ${jprt.my.windows.x64}-product-c2-runThese, \
+    ${jprt.my.windows.x64}-product-c2-runThese_Xcomp, \
+    ${jprt.my.windows.x64}-{product|fastdebug}-c2-GCBasher_default, \
+    ${jprt.my.windows.x64}-{product|fastdebug}-c2-GCBasher_SerialGC, \
+    ${jprt.my.windows.x64}-{product|fastdebug}-c2-GCBasher_ParallelGC, \
+    ${jprt.my.windows.x64}-{product|fastdebug}-c2-GCBasher_ParNewGC, \
+    ${jprt.my.windows.x64}-{product|fastdebug}-c2-GCBasher_CMS, \
+    ${jprt.my.windows.x64}-{product|fastdebug}-c2-GCOld_default, \
+    ${jprt.my.windows.x64}-{product|fastdebug}-c2-GCOld_SerialGC, \
+    ${jprt.my.windows.x64}-{product|fastdebug}-c2-GCOld_ParallelGC, \
+    ${jprt.my.windows.x64}-{product|fastdebug}-c2-GCOld_ParNewGC, \
+    ${jprt.my.windows.x64}-{product|fastdebug}-c2-GCOld_CMS, \
+    ${jprt.my.windows.x64}-{product|fastdebug}-c2-jbb_default, \
+    ${jprt.my.windows.x64}-product-c2-jbb_CMS, \
+    ${jprt.my.windows.x64}-product-c2-jbb_ParallelGC, \
+    ${jprt.my.windows.x64}-{product|fastdebug}-c2-scimark_2, \
+    ${jprt.my.windows.x64}-{product|fastdebug}-c2-scimark_3
+
+# The complete list of test targets for jprt
+
+jprt.test.targets = \
+  ${jprt.my.solaris.sparc.test.targets}, \
+  ${jprt.my.solaris.sparcv9.test.targets}, \
+  ${jprt.my.solaris.i586.test.targets}, \
+  ${jprt.my.solaris.x64.test.targets}, \
+  ${jprt.my.linux.i586.test.targets}, \
+  ${jprt.my.linux.x64.test.targets}, \
+  ${jprt.my.windows.i586.test.targets}, \
+  ${jprt.my.windows.x64.test.targets}
+
--- a/hotspot/make/solaris/makefiles/amd64.make	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/make/solaris/makefiles/amd64.make	Wed Jul 05 16:37:51 2017 +0200
@@ -45,10 +45,6 @@
 OPT_CFLAGS/generateOptoStub.o = -xO2
 OPT_CFLAGS/thread.o = -xO2
 
-# Work around for 6624782
-OPT_CFLAGS/instanceKlass.o = -Qoption ube -no_a2lf
-OPT_CFLAGS/objArrayKlass.o = -Qoption ube -no_a2lf
-
 else
 
 ifeq ("${Platform_compiler}", "gcc")
--- a/hotspot/make/solaris/makefiles/debug.make	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/make/solaris/makefiles/debug.make	Wed Jul 05 16:37:51 2017 +0200
@@ -29,7 +29,8 @@
 DEBUG_CFLAGS/BYFILE = $(DEBUG_CFLAGS/$@)$(DEBUG_CFLAGS/DEFAULT$(DEBUG_CFLAGS/$@))
 
 ifeq ("${Platform_compiler}", "sparcWorks")
-ifeq ($(shell expr $(COMPILER_REV) \>= 5.8), 1)
+
+ifeq ($(COMPILER_REV),5.8)
   # SS11 SEGV when compiling with -g and -xarch=v8, using different backend
   DEBUG_CFLAGS/compileBroker.o = $(DEBUG_CFLAGS) -xO0
   DEBUG_CFLAGS/jvmtiTagMap.o   = $(DEBUG_CFLAGS) -xO0
--- a/hotspot/make/solaris/makefiles/dtrace.make	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/make/solaris/makefiles/dtrace.make	Wed Jul 05 16:37:51 2017 +0200
@@ -92,12 +92,12 @@
 $(XLIBJVM_DB): $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS).h $(LIBJVM_DB_MAPFILE)
 	@echo Making $@
 	$(QUIETLY) mkdir -p 64/ ; \
-	$(CC) $(SYMFLAG) -xarch=$(XARCH) -D$(TYPE) -I. -I$(GENERATED) \
+	$(CC) $(SYMFLAG) $(ARCHFLAG/$(XARCH)) -D$(TYPE) -I. -I$(GENERATED) \
 		$(SHARED_FLAG) $(LFLAGS_JVM_DB) -o $@ $(DTRACE_SRCDIR)/$(JVM_DB).c -lc
 $(XLIBJVM_DTRACE): $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE)
 	@echo Making $@
 	$(QUIETLY) mkdir -p 64/ ; \
-	$(CC) $(SYMFLAG) -xarch=$(XARCH) -D$(TYPE) -I. \
+	$(CC) $(SYMFLAG) $(ARCHFLAG/$(XARCH)) -D$(TYPE) -I. \
 		$(SHARED_FLAG) $(LFLAGS_JVM_DTRACE) -o $@ $(DTRACE_SRCDIR)/$(JVM_DTRACE).c -lc -lthread -ldoor
 endif # ifneq ("${ISA}","${BUILDARCH}")
 
--- a/hotspot/make/solaris/makefiles/fastdebug.make	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/make/solaris/makefiles/fastdebug.make	Wed Jul 05 16:37:51 2017 +0200
@@ -25,7 +25,7 @@
 # Sets make macros for making debug version of VM
 
 # Compiler specific DEBUG_CFLAGS are passed in from gcc.make, sparcWorks.make
-# They may also specify FASTDEBUG_CFLAGS, but it defaults to DEBUG_FLAGS.
+# They may also specify FASTDEBUG_CFLAGS, but it defaults to DEBUG_CFLAGS.
 
 FASTDEBUG_CFLAGS$(FASTDEBUG_CFLAGS) = $(DEBUG_CFLAGS)
 
@@ -35,15 +35,26 @@
 
 ifeq ("${Platform_compiler}", "sparcWorks")
 OPT_CFLAGS/SLOWER = -xO2
-ifeq ($(shell expr $(COMPILER_REV) \>= 5.5), 1)
-# CC 5.5 has bug 4908364 with -xO4 
+
+# Problem with SS12 compiler, dtrace doesn't like the .o files  (bug 6693876)
+ifeq ($(COMPILER_REV), 5.9)
+  # Not clear this workaround could be skipped in some cases.
+  OPT_CFLAGS/vmGCOperations.o = $(OPT_CFLAGS/SLOWER)
+  OPT_CFLAGS/java.o = $(OPT_CFLAGS/SLOWER)
+  OPT_CFLAGS/jni.o = $(OPT_CFLAGS/SLOWER)
+endif
+
+ifeq ($(COMPILER_REV), 5.5)
+# CC 5.5 has bug 4908364 with -xO4  (Fixed in 5.6)
 OPT_CFLAGS/library_call.o = $(OPT_CFLAGS/SLOWER)
-else # COMPILER_REV >= 5.5
+endif # COMPILER_REV == 5.5
+
+ifeq ($(shell expr $(COMPILER_REV) \<= 5.4), 1)
 # Compilation of *_<arch>.cpp can take an hour or more at O3.  Use O2
 # See comments at top of sparc.make.
 OPT_CFLAGS/ad_$(Platform_arch).o = $(OPT_CFLAGS/SLOWER)
 OPT_CFLAGS/dfa_$(Platform_arch).o = $(OPT_CFLAGS/SLOWER)
-endif # COMPILER_REV >= 5.5
+endif # COMPILER_REV <= 5.4
 
 ifeq (${COMPILER_REV}, 5.0)
 # Avoid a compiler bug caused by using -xO<level> -g<level>
--- a/hotspot/make/solaris/makefiles/jvmg.make	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/make/solaris/makefiles/jvmg.make	Wed Jul 05 16:37:51 2017 +0200
@@ -29,7 +29,8 @@
 DEBUG_CFLAGS/BYFILE = $(DEBUG_CFLAGS/$@)$(DEBUG_CFLAGS/DEFAULT$(DEBUG_CFLAGS/$@))
 
 ifeq ("${Platform_compiler}", "sparcWorks")
-ifeq ($(shell expr $(COMPILER_REV) \>= 5.8), 1)
+
+ifeq ($(COMPILER_REV),5.8))
   # SS11 SEGV when compiling with -g and -xarch=v8, using different backend
   DEBUG_CFLAGS/compileBroker.o = $(DEBUG_CFLAGS) -xO0
   DEBUG_CFLAGS/jvmtiTagMap.o   = $(DEBUG_CFLAGS) -xO0
--- a/hotspot/make/solaris/makefiles/optimized.make	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/make/solaris/makefiles/optimized.make	Wed Jul 05 16:37:51 2017 +0200
@@ -30,12 +30,21 @@
 OPT_CFLAGS/BYFILE = $(OPT_CFLAGS/$@)$(OPT_CFLAGS/DEFAULT$(OPT_CFLAGS/$@))
 
 # (OPT_CFLAGS/SLOWER is also available, to alter compilation of buggy files)
+ifeq ("${Platform_compiler}", "sparcWorks")
 
-# Workaround SS11 bug 6345274 (all platforms)
-ifeq ("${Platform_compiler}", "sparcWorks")
-ifeq ($(shell expr $(COMPILER_REV) \>= 5.8), 1)
+# Problem with SS12 compiler, dtrace doesn't like the .o files  (bug 6693876)
+ifeq ($(COMPILER_REV),5.9)
+  # Not clear this workaround could be skipped in some cases.
+  OPT_CFLAGS/vmGCOperations.o = $(OPT_CFLAGS/SLOWER) -g
+  OPT_CFLAGS/java.o = $(OPT_CFLAGS/SLOWER) -g
+  OPT_CFLAGS/jni.o = $(OPT_CFLAGS/SLOWER) -g
+endif
+
+# Workaround SS11 bug 6345274 (all platforms) (Fixed in SS11 patch and SS12)
+ifeq ($(COMPILER_REV),5.8))
 OPT_CFLAGS/ciTypeFlow.o = $(OPT_CFLAGS/O2)
-endif # COMPILER_REV >= 5.8
+endif # COMPILER_REV == 5.8
+
 endif # Platform_compiler == sparcWorks
 
 # If you set HOTSPARC_GENERIC=yes, you disable all OPT_CFLAGS settings
--- a/hotspot/make/solaris/makefiles/product.make	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/make/solaris/makefiles/product.make	Wed Jul 05 16:37:51 2017 +0200
@@ -38,12 +38,21 @@
 endif
 
 # (OPT_CFLAGS/SLOWER is also available, to alter compilation of buggy files)
+ifeq ("${Platform_compiler}", "sparcWorks")
 
-# Workaround SS11 bug 6345274 (all platforms)
-ifeq ("${Platform_compiler}", "sparcWorks")
-ifeq ($(shell expr $(COMPILER_REV) \>= 5.8), 1)
+# Problem with SS12 compiler, dtrace doesn't like the .o files  (bug 6693876)
+ifeq ($(COMPILER_REV),5.9)
+  # Not clear this workaround could be skipped in some cases.
+  OPT_CFLAGS/vmGCOperations.o = $(OPT_CFLAGS/SLOWER) -g
+  OPT_CFLAGS/java.o = $(OPT_CFLAGS/SLOWER) -g
+  OPT_CFLAGS/jni.o = $(OPT_CFLAGS/SLOWER) -g
+endif
+
+# Workaround SS11 bug 6345274 (all platforms) (Fixed in SS11 patch and SS12)
+ifeq ($(COMPILER_REV),5.8)
 OPT_CFLAGS/ciTypeFlow.o = $(OPT_CFLAGS/O2)
-endif # COMPILER_REV >= 5.8
+endif # COMPILER_REV == 5.8
+
 endif # Platform_compiler == sparcWorks
 
 # If you set HOTSPARC_GENERIC=yes, you disable all OPT_CFLAGS settings
--- a/hotspot/make/solaris/makefiles/sparc.make	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/make/solaris/makefiles/sparc.make	Wed Jul 05 16:37:51 2017 +0200
@@ -23,7 +23,7 @@
 #
 
 Obj_Files += solaris_sparc.o
-ASFLAGS += $(ARCHFLAG)
+ASFLAGS += $(AS_ARCHFLAG)
 
 ifeq ("${Platform_compiler}", "sparcWorks")
 ifeq ($(shell expr $(COMPILER_REV) \< 5.5), 1)
--- a/hotspot/make/solaris/makefiles/sparcWorks.make	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/make/solaris/makefiles/sparcWorks.make	Wed Jul 05 16:37:51 2017 +0200
@@ -28,6 +28,8 @@
 CC	= cc
 CPP	= CC
 
+# Note that this 'as' is an older version of the Sun Studio 'fbe', and will
+#   use the older style options. The 'fbe' options will match 'cc' and 'CC'.
 AS	= /usr/ccs/bin/as
 
 NM	= /usr/ccs/bin/nm
@@ -43,25 +45,33 @@
 C_COMPILER_REV := \
 $(shell $(CC) -V 2>&1 | grep -i "cc:" |  sed -e 's/^.*\([1-9]\.[0-9][0-9]*\).*/\1/')
 
-VALIDATED_COMPILER_REV   := 5.8
-VALIDATED_C_COMPILER_REV := 5.8
+# Pick which compiler is validated
+ifeq ($(JDK_MINOR_VERSION),6)
+  # Validated compiler for JDK6 is SS11 (5.8)
+  VALIDATED_COMPILER_REV   := 5.8
+  VALIDATED_C_COMPILER_REV := 5.8
+else
+  # FIXUP: Change to SS12 (5.9) once it has been validated.
+  # Validated compiler for JDK7 is SS12 (5.9)
+  #VALIDATED_COMPILER_REV   := 5.9
+  #VALIDATED_C_COMPILER_REV := 5.9
+  VALIDATED_COMPILER_REV   := 5.8
+  VALIDATED_C_COMPILER_REV := 5.8
+endif
 
+# Warning messages about not using the above validated version
 ENFORCE_COMPILER_REV${ENFORCE_COMPILER_REV} := ${VALIDATED_COMPILER_REV}
 ifneq (${COMPILER_REV},${ENFORCE_COMPILER_REV})
-dummy_target_to_enforce_compiler_rev:
-	@echo "Wrong ${CPP} version:  ${COMPILER_REV}. " \
-	"Use version ${ENFORCE_COMPILER_REV}, or set" \
-	"ENFORCE_COMPILER_REV=${COMPILER_REV}."
-	@exit 1
+dummy_target_to_enforce_compiler_rev:=\
+$(info WARNING: You are using CC version ${COMPILER_REV} \
+and should be using version ${ENFORCE_COMPILER_REV})
 endif
 
 ENFORCE_C_COMPILER_REV${ENFORCE_C_COMPILER_REV} := ${VALIDATED_C_COMPILER_REV}
 ifneq (${C_COMPILER_REV},${ENFORCE_C_COMPILER_REV})
-dummy_target_to_enforce_c_compiler_rev:
-	@echo "Wrong ${CC} version:  ${C_COMPILER_REV}. " \
-	"Use version ${ENFORCE_C_COMPILER_REV}, or set" \
-	"ENFORCE_C_COMPILER_REV=${C_COMPILER_REV}."
-	@exit 1
+dummy_target_to_enforce_c_compiler_rev:=\
+$(info WARNING: You are using cc version ${C_COMPILER_REV} \
+and should be using version ${ENFORCE_C_COMPILER_REV})
 endif
 
 # Fail the build if __fabsf is used.  __fabsf exists only in Solaris 8 2/04
@@ -90,20 +100,44 @@
 $(shell uname -r | awk -F. '{ if ($$2 >= 7) print "-DSOLARIS_7_OR_LATER"; }')
 CFLAGS += ${SOLARIS_7_OR_LATER}
 
-ARCHFLAG         = $(ARCHFLAG/$(BUILDARCH))
-# set ARCHFLAG/BUILDARCH which will ultimately be ARCHFLAG
+# New architecture options started in SS12 (5.9), we need both styles to build.
+#   The older arch options for SS11 (5.8) or older and also for /usr/ccs/bin/as.
+#   Note: SS12 default for 32bit sparc is now the same as v8plus, so the
+#         settings below have changed all SS12 32bit sparc builds to be v8plus.
+#         The older SS11 (5.8) settings have remained as they always have been.
 ifeq ($(TYPE),COMPILER2)
-ARCHFLAG/sparc   = -xarch=v8plus
+  ARCHFLAG_OLD/sparc   = -xarch=v8plus
 else
-ifeq ($(TYPE),TIERED)
-ARCHFLAG/sparc   = -xarch=v8plus
-else
-ARCHFLAG/sparc   = -xarch=v8
+  ifeq ($(TYPE),TIERED)
+    ARCHFLAG_OLD/sparc = -xarch=v8plus
+  else
+    ARCHFLAG_OLD/sparc = -xarch=v8
+  endif
 endif
+ARCHFLAG_NEW/sparc   = -m32 -xarch=sparc
+ARCHFLAG_OLD/sparcv9 = -xarch=v9
+ARCHFLAG_NEW/sparcv9 = -m64 -xarch=sparc
+ARCHFLAG_OLD/i486    =
+ARCHFLAG_NEW/i486    = -m32
+ARCHFLAG_OLD/amd64   = -xarch=amd64
+ARCHFLAG_NEW/amd64   = -m64
+
+# Select the ARCHFLAGs and other SS12 (5.9) options
+ifeq ($(shell expr $(COMPILER_REV) \>= 5.9), 1)
+  ARCHFLAG/sparc   = $(ARCHFLAG_NEW/sparc)
+  ARCHFLAG/sparcv9 = $(ARCHFLAG_NEW/sparcv9)
+  ARCHFLAG/i486    = $(ARCHFLAG_NEW/i486)
+  ARCHFLAG/amd64   = $(ARCHFLAG_NEW/amd64)
+else
+  ARCHFLAG/sparc   = $(ARCHFLAG_OLD/sparc)
+  ARCHFLAG/sparcv9 = $(ARCHFLAG_OLD/sparcv9)
+  ARCHFLAG/i486    = $(ARCHFLAG_OLD/i486)
+  ARCHFLAG/amd64   = $(ARCHFLAG_OLD/amd64)
 endif
-ARCHFLAG/sparcv9 = -xarch=v9
-ARCHFLAG/i486  =
-ARCHFLAG/amd64  = -xarch=amd64
+
+# ARCHFLAGS for the current build arch
+ARCHFLAG    = $(ARCHFLAG/$(BUILDARCH))
+AS_ARCHFLAG = $(ARCHFLAG_OLD/$(BUILDARCH))
 
 # Optional sub-directory in /usr/lib where BUILDARCH libraries are kept.
 ISA_DIR=$(ISA_DIR/$(BUILDARCH))
@@ -166,13 +200,13 @@
 
 ifeq ("${Platform_arch_model}", "x86_64")
 
-ASFLAGS += -xarch=amd64
-CFLAGS  += -xarch=amd64
+ASFLAGS += $(AS_ARCHFLAG)
+CFLAGS  += $(ARCHFLAG/amd64)
 # this one seemed useless
-LFLAGS_VM  += -xarch=amd64
+LFLAGS_VM  += $(ARCHFLAG/amd64)
 # this one worked
-LFLAGS  += -xarch=amd64
-AOUT_FLAGS += -xarch=amd64
+LFLAGS  += $(ARCHFLAG/amd64)
+AOUT_FLAGS += $(ARCHFLAG/amd64)
 
 # -xO3 is faster than -xO4 on specjbb with SS10 compiler
 OPT_CFLAGS=-xO4 $(EXTRA_OPT_CFLAGS)
@@ -224,7 +258,7 @@
 
 LFLAGS += -mt
 
-endif	# COMPILER_REV >= VALIDATED_COMPILER_REV
+endif	# COMPILER_REV >= 5.5
 
 ######################################
 # End 5.5 Forte compiler options     #
@@ -293,7 +327,7 @@
 LFLAGS += -library=Crun
 LIBS   += -library=Crun -lCrun
 
-endif	# COMPILER_REV >= VALIDATED_COMPILER_REV
+endif	# COMPILER_REV == 5.2
 
 ##################################
 # End 5.2 Forte compiler options #
@@ -320,6 +354,7 @@
 
 # Had to hoist this higher apparently because of other changes. Must
 # come before -xarch specification.
+#  NOTE: native says optimize for the machine doing the compile, bad news.
 CFLAGS += -xtarget=native
 
 CFLAGS     += $(ARCHFLAG)
@@ -359,7 +394,7 @@
 endif  # 32bit x86
 
 # The following options run into misaligned ldd problem (raj)
-#OPT_CFLAGS = -fast -O4 -xarch=v8 -xchip=ultra
+#OPT_CFLAGS = -fast -O4 $(ARCHFLAG/sparc) -xchip=ultra
 
 # no more exceptions
 CFLAGS/NOEX=-noex
@@ -427,6 +462,15 @@
 FASTDEBUG_CFLAGS = -g0
 # The -g0 setting allows the C++ frontend to inline, which is a big win.
 
+# Special global options for SS12
+ifeq ($(COMPILER_REV),5.9)
+  # There appears to be multiple issues with the new Dwarf2 debug format, so
+  #   we tell the compiler to use the older 'stabs' debug format all the time.
+  #   Note that this needs to be used in optimized compiles too to be 100%.
+  #   This is a workaround for SS12 (5.9) bug 6694600
+  CFLAGS += -xdebugformat=stabs
+endif
+
 # Enable the following CFLAGS additions if you need to compare the
 # built ELF objects.
 #
--- a/hotspot/make/solaris/makefiles/sparcv9.make	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/make/solaris/makefiles/sparcv9.make	Wed Jul 05 16:37:51 2017 +0200
@@ -23,7 +23,7 @@
 #
 
 Obj_Files += solaris_sparc.o
-ASFLAGS += $(ARCHFLAG)
+ASFLAGS += $(AS_ARCHFLAG)
 
 ifeq ("${Platform_compiler}", "sparcWorks")
 ifeq ($(shell expr $(COMPILER_REV) \< 5.5), 1)
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -1523,6 +1523,21 @@
   return Address(d, address(obj), oop_Relocation::spec(oop_index));
 }
 
+void  MacroAssembler::set_narrow_oop(jobject obj, Register d) {
+  assert(oop_recorder() != NULL, "this assembler needs an OopRecorder");
+  int oop_index = oop_recorder()->find_index(obj);
+  RelocationHolder rspec = oop_Relocation::spec(oop_index);
+
+  assert_not_delayed();
+  // Relocation with special format (see relocInfo_sparc.hpp).
+  relocate(rspec, 1);
+  // Assembler::sethi(0x3fffff, d);
+  emit_long( op(branch_op) | rd(d) | op2(sethi_op2) | hi22(0x3fffff) );
+  // Don't add relocation for 'add'. Do patching during 'sethi' processing.
+  add(d, 0x3ff, d);
+
+}
+
 
 void MacroAssembler::align(int modulus) {
   while (offset() % modulus != 0) nop();
@@ -3406,13 +3421,15 @@
   set((intptr_t)markOopDesc::prototype()->copy_set_hash(0x2), t2);
   st_ptr(t2, top, oopDesc::mark_offset_in_bytes()); // set up the mark word
   // set klass to intArrayKlass
-  set((intptr_t)Universe::intArrayKlassObj_addr(), t2);
-  ld_ptr(t2, 0, t2);
-  store_klass(t2, top);
   sub(t1, typeArrayOopDesc::header_size(T_INT), t1);
   add(t1, ThreadLocalAllocBuffer::alignment_reserve(), t1);
   sll_ptr(t1, log2_intptr(HeapWordSize/sizeof(jint)), t1);
   st(t1, top, arrayOopDesc::length_offset_in_bytes());
+  set((intptr_t)Universe::intArrayKlassObj_addr(), t2);
+  ld_ptr(t2, 0, t2);
+  // store klass last.  concurrent gcs assumes klass length is valid if
+  // klass field is not null.
+  store_klass(t2, top);
   verify_oop(top);
 
   // refill the tlab with an eden allocation
@@ -3537,28 +3554,32 @@
   }
 }
 
-void MacroAssembler::load_klass(Register s, Register d) {
+void MacroAssembler::load_klass(Register src_oop, Register klass) {
   // The number of bytes in this code is used by
   // MachCallDynamicJavaNode::ret_addr_offset()
   // if this changes, change that.
   if (UseCompressedOops) {
-    lduw(s, oopDesc::klass_offset_in_bytes(), d);
-    decode_heap_oop_not_null(d);
+    lduw(src_oop, oopDesc::klass_offset_in_bytes(), klass);
+    decode_heap_oop_not_null(klass);
   } else {
-    ld_ptr(s, oopDesc::klass_offset_in_bytes(), d);
+    ld_ptr(src_oop, oopDesc::klass_offset_in_bytes(), klass);
   }
 }
 
-// ??? figure out src vs. dst!
-void MacroAssembler::store_klass(Register d, Register s1) {
+void MacroAssembler::store_klass(Register klass, Register dst_oop) {
   if (UseCompressedOops) {
-    assert(s1 != d, "not enough registers");
-    encode_heap_oop_not_null(d);
-    // Zero out entire klass field first.
-    st_ptr(G0, s1, oopDesc::klass_offset_in_bytes());
-    st(d, s1, oopDesc::klass_offset_in_bytes());
+    assert(dst_oop != klass, "not enough registers");
+    encode_heap_oop_not_null(klass);
+    st(klass, dst_oop, oopDesc::klass_offset_in_bytes());
   } else {
-    st_ptr(d, s1, oopDesc::klass_offset_in_bytes());
+    st_ptr(klass, dst_oop, oopDesc::klass_offset_in_bytes());
+  }
+}
+
+void MacroAssembler::store_klass_gap(Register s, Register d) {
+  if (UseCompressedOops) {
+    assert(s != d, "not enough registers");
+    st(s, d, oopDesc::klass_gap_offset_in_bytes());
   }
 }
 
@@ -3622,6 +3643,7 @@
 
 void MacroAssembler::encode_heap_oop(Register src, Register dst) {
   assert (UseCompressedOops, "must be compressed");
+  verify_oop(src);
   Label done;
   if (src == dst) {
     // optimize for frequent case src == dst
@@ -3643,12 +3665,14 @@
 
 void MacroAssembler::encode_heap_oop_not_null(Register r) {
   assert (UseCompressedOops, "must be compressed");
+  verify_oop(r);
   sub(r, G6_heapbase, r);
   srlx(r, LogMinObjAlignmentInBytes, r);
 }
 
 void MacroAssembler::encode_heap_oop_not_null(Register src, Register dst) {
   assert (UseCompressedOops, "must be compressed");
+  verify_oop(src);
   sub(src, G6_heapbase, dst);
   srlx(dst, LogMinObjAlignmentInBytes, dst);
 }
@@ -3661,11 +3685,13 @@
   bpr(rc_nz, true, Assembler::pt, dst, done);
   delayed() -> add(dst, G6_heapbase, dst); // annuled if not taken
   bind(done);
+  verify_oop(dst);
 }
 
 void  MacroAssembler::decode_heap_oop_not_null(Register r) {
   // Do not add assert code to this unless you change vtableStubs_sparc.cpp
   // pd_code_size_limit.
+  // Also do not verify_oop as this is called by verify_oop.
   assert (UseCompressedOops, "must be compressed");
   sllx(r, LogMinObjAlignmentInBytes, r);
   add(r, G6_heapbase, r);
@@ -3674,6 +3700,7 @@
 void  MacroAssembler::decode_heap_oop_not_null(Register src, Register dst) {
   // Do not add assert code to this unless you change vtableStubs_sparc.cpp
   // pd_code_size_limit.
+  // Also do not verify_oop as this is called by verify_oop.
   assert (UseCompressedOops, "must be compressed");
   sllx(src, LogMinObjAlignmentInBytes, dst);
   add(dst, G6_heapbase, dst);
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp	Wed Jul 05 16:37:51 2017 +0200
@@ -1977,8 +1977,9 @@
   inline void movbool( bool boolconst, Register d) { mov( (int) boolconst, d); }
 
   // klass oop manipulations if compressed
-  void load_klass(Register  src_oop, Register dst);
-  void store_klass(Register dst_oop, Register s1);
+  void load_klass(Register src_oop, Register klass);
+  void store_klass(Register klass, Register dst_oop);
+  void store_klass_gap(Register s, Register dst_oop);
 
    // oop manipulations
   void load_heap_oop(const Address& s, Register d, int offset = 0);
@@ -2103,6 +2104,8 @@
   inline void set_oop_constant( jobject obj, Register d ); // uses constant_oop_address
   inline void set_oop         ( Address obj_addr );        // same as load_address
 
+  void set_narrow_oop( jobject obj, Register d );
+
   // nop padding
   void align(int modulus);
 
--- a/hotspot/src/cpu/sparc/vm/relocInfo_sparc.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/relocInfo_sparc.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -87,6 +87,17 @@
 #ifdef _LP64
     jint inst2;
     guarantee(Assembler::inv_op2(inst)==Assembler::sethi_op2, "must be sethi");
+    if (format() != 0) {
+      assert(type() == relocInfo::oop_type, "only narrow oops case");
+      jint np = oopDesc::encode_heap_oop((oop)x);
+      inst &= ~Assembler::hi22(-1);
+      inst |=  Assembler::hi22((intptr_t)np);
+      ip->set_long_at(0, inst);
+      inst2 = ip->long_at( NativeInstruction::nop_instruction_size );
+      guarantee(Assembler::inv_op(inst2)==Assembler::arith_op, "arith op");
+      ip->set_long_at(NativeInstruction::nop_instruction_size, ip->set_data32_simm13( inst2, (intptr_t)np));
+      break;
+    }
     ip->set_data64_sethi( ip->addr_at(0), (intptr_t)x );
 #ifdef COMPILER2
     // [RGV] Someone must have missed putting in a reloc entry for the
--- a/hotspot/src/cpu/sparc/vm/relocInfo_sparc.hpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/relocInfo_sparc.hpp	Wed Jul 05 16:37:51 2017 +0200
@@ -31,7 +31,12 @@
 
     // There is no need for format bits; the instructions are
     // sufficiently self-identifying.
+#ifndef _LP64
     format_width       =  0
+#else
+    // Except narrow oops in 64-bits VM.
+    format_width       =  1
+#endif
   };
 
 
--- a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -2556,7 +2556,6 @@
   int total_strings = 0;
   int first_arg_to_pass = 0;
   int total_c_args = 0;
-  int box_offset = java_lang_boxing_object::value_offset_in_bytes();
 
   // Skip the receiver as dtrace doesn't want to see it
   if( !method->is_static() ) {
@@ -2721,7 +2720,8 @@
 #endif /* ASSERT */
 
   VMRegPair zero;
-  zero.set2(G0->as_VMReg());
+  const Register g0 = G0; // without this we get a compiler warning (why??)
+  zero.set2(g0->as_VMReg());
 
   int c_arg, j_arg;
 
@@ -2778,7 +2778,9 @@
             __ br_null(in_reg, true, Assembler::pn, skipUnbox);
             __ delayed()->mov(G0, tmp);
 
-            switch (out_sig_bt[c_arg]) {
+            BasicType bt = out_sig_bt[c_arg];
+            int box_offset = java_lang_boxing_object::value_offset_in_bytes(bt);
+            switch (bt) {
                 case T_BYTE:
                   __ ldub(in_reg, box_offset, tmp); break;
                 case T_SHORT:
--- a/hotspot/src/cpu/sparc/vm/sparc.ad	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/sparc.ad	Wed Jul 05 16:37:51 2017 +0200
@@ -5471,7 +5471,6 @@
 // Load Klass Pointer
 instruct loadKlass(iRegP dst, memory mem) %{
   match(Set dst (LoadKlass mem));
-  predicate(!n->in(MemNode::Address)->bottom_type()->is_narrow());
   ins_cost(MEMORY_REF_COST);
   size(4);
 
@@ -5486,11 +5485,11 @@
   ins_pipe(iload_mem);
 %}
 
-// Load Klass Pointer
-instruct loadKlassComp(iRegP dst, memory mem) %{
-  match(Set dst (LoadKlass mem));
-  predicate(n->in(MemNode::Address)->bottom_type()->is_narrow());
+// Load narrow Klass Pointer
+instruct loadNKlass(iRegN dst, memory mem) %{
+  match(Set dst (LoadNKlass mem));
   ins_cost(MEMORY_REF_COST);
+  size(4);
 
   format %{ "LDUW   $mem,$dst\t! compressed klass ptr" %}
 
@@ -5503,9 +5502,6 @@
      } else {
        __ lduw(base, $mem$$disp, dst);
      }
-     // klass oop never null but this is generated for nonheader klass loads
-     // too which can be null.
-     __ decode_heap_oop(dst);
   %}
   ins_pipe(iload_mem);
 %}
@@ -5609,22 +5605,24 @@
   ins_pipe(loadConP_poll);
 %}
 
+instruct loadConN0(iRegN dst, immN0 src) %{
+  match(Set dst src);
+
+  size(4);
+  format %{ "CLR    $dst\t! compressed NULL ptr" %}
+  ins_encode( SetNull( dst ) );
+  ins_pipe(ialu_imm);
+%}
+
 instruct loadConN(iRegN dst, immN src) %{
   match(Set dst src);
-  ins_cost(DEFAULT_COST * 2);
-  format %{ "SET    $src,$dst\t!ptr" %}
+  ins_cost(DEFAULT_COST * 3/2);
+  format %{ "SET    $src,$dst\t! compressed ptr" %}
   ins_encode %{
-    address con = (address)$src$$constant;
     Register dst = $dst$$Register;
-    if (con == NULL) {
-      __ mov(G0, dst);
-    } else {
-      __ set_oop((jobject)$src$$constant, dst);
-      __ encode_heap_oop(dst);
-    }
-  %}
-  ins_pipe(loadConP);
-
+    __ set_narrow_oop((jobject)$src$$constant, dst);
+  %}
+  ins_pipe(ialu_hi_lo_reg);
 %}
 
 instruct loadConL(iRegL dst, immL src, o7RegL tmp) %{
@@ -5977,7 +5975,8 @@
 %}
 
 instruct decodeHeapOop(iRegP dst, iRegN src) %{
-  predicate(n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull);
+  predicate(n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull &&
+            n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant);
   match(Set dst (DecodeN src));
   format %{ "decode_heap_oop $src, $dst" %}
   ins_encode %{
@@ -5987,7 +5986,8 @@
 %}
 
 instruct decodeHeapOop_not_null(iRegP dst, iRegN src) %{
-  predicate(n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull);
+  predicate(n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull ||
+            n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant);
   match(Set dst (DecodeN src));
   format %{ "decode_heap_oop_not_null $src, $dst" %}
   ins_encode %{
@@ -6258,6 +6258,34 @@
   ins_pipe(ialu_imm);
 %}
 
+// Conditional move for RegN. Only cmov(reg,reg).
+instruct cmovNP_reg(cmpOpP cmp, flagsRegP pcc, iRegN dst, iRegN src) %{
+  match(Set dst (CMoveN (Binary cmp pcc) (Binary dst src)));
+  ins_cost(150);
+  format %{ "MOV$cmp $pcc,$src,$dst" %}
+  ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::ptr_cc)) );
+  ins_pipe(ialu_reg);
+%}
+
+// This instruction also works with CmpN so we don't need cmovNN_reg.
+instruct cmovNI_reg(cmpOp cmp, flagsReg icc, iRegN dst, iRegN src) %{
+  match(Set dst (CMoveN (Binary cmp icc) (Binary dst src)));
+  ins_cost(150);
+  size(4);
+  format %{ "MOV$cmp  $icc,$src,$dst" %}
+  ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::icc)) );
+  ins_pipe(ialu_reg);
+%}
+
+instruct cmovNF_reg(cmpOpF cmp, flagsRegF fcc, iRegN dst, iRegN src) %{
+  match(Set dst (CMoveN (Binary cmp fcc) (Binary dst src)));
+  ins_cost(150);
+  size(4);
+  format %{ "MOV$cmp $fcc,$src,$dst" %}
+  ins_encode( enc_cmov_reg_f(cmp,dst,src, fcc) );
+  ins_pipe(ialu_reg);
+%}
+
 // Conditional move
 instruct cmovPP_reg(cmpOpP cmp, flagsRegP pcc, iRegP dst, iRegP src) %{
   match(Set dst (CMoveP (Binary cmp pcc) (Binary dst src)));
@@ -6275,6 +6303,7 @@
   ins_pipe(ialu_imm);
 %}
 
+// This instruction also works with CmpN so we don't need cmovPN_reg.
 instruct cmovPI_reg(cmpOp cmp, flagsReg icc, iRegP dst, iRegP src) %{
   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
   ins_cost(150);
@@ -6650,10 +6679,9 @@
   ins_pipe( long_memory_op );
 %}
 
-instruct compareAndSwapN_bool_comp(iRegP mem_ptr, iRegN oldval, iRegN newval, iRegI res, o7RegI tmp, flagsReg ccr ) %{
+instruct compareAndSwapN_bool(iRegP mem_ptr, iRegN oldval, iRegN newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{
   match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval)));
-  effect( USE mem_ptr, KILL ccr, KILL tmp);
-
+  effect( USE mem_ptr, KILL ccr, KILL tmp1);
   format %{
             "MOV    $newval,O7\n\t"
             "CASA   [$mem_ptr],$oldval,O7\t! If $oldval==[$mem_ptr] Then store O7 into [$mem_ptr], set O7=[$mem_ptr] in any case\n\t"
@@ -6661,18 +6689,8 @@
             "MOV    1,$res\n\t"
             "MOVne  icc,R_G0,$res"
   %}
-  ins_encode %{
-    Register Rmem = reg_to_register_object($mem_ptr$$reg);
-    Register Rold = reg_to_register_object($oldval$$reg);
-    Register Rnew = reg_to_register_object($newval$$reg);
-    Register Rres = reg_to_register_object($res$$reg);
-
-    __ cas(Rmem, Rold, Rnew);
-    __ cmp( Rold, Rnew );
-    __ mov(1, Rres);
-    __ movcc( Assembler::notEqual, false, Assembler::icc, G0, Rres );
-  %}
-
+  ins_encode( enc_casi(mem_ptr, oldval, newval),
+              enc_iflags_ne_to_boolean(res) );
   ins_pipe( long_memory_op );
 %}
 
@@ -8265,6 +8283,27 @@
   ins_pipe(ialu_cconly_reg_imm);
 %}
 
+// Compare Narrow oops
+instruct compN_iRegN(flagsReg icc, iRegN op1, iRegN op2 ) %{
+  match(Set icc (CmpN op1 op2));
+
+  size(4);
+  format %{ "CMP    $op1,$op2\t! compressed ptr" %}
+  opcode(Assembler::subcc_op3, Assembler::arith_op);
+  ins_encode( form3_rs1_rs2_rd( op1, op2, R_G0 ) );
+  ins_pipe(ialu_cconly_reg_reg);
+%}
+
+instruct compN_iRegN_immN0(flagsReg icc, iRegN op1, immN0 op2 ) %{
+  match(Set icc (CmpN op1 op2));
+
+  size(4);
+  format %{ "CMP    $op1,$op2\t! compressed ptr" %}
+  opcode(Assembler::subcc_op3, Assembler::arith_op);
+  ins_encode( form3_rs1_simm13_rd( op1, op2, R_G0 ) );
+  ins_pipe(ialu_cconly_reg_imm);
+%}
+
 //----------Max and Min--------------------------------------------------------
 // Min Instructions
 // Conditional move for min
@@ -8595,6 +8634,14 @@
   ins_pipe(ialu_imm);
 %}
 
+instruct cmovNL_reg(cmpOp cmp, flagsRegL xcc, iRegN dst, iRegN src) %{
+  match(Set dst (CMoveN (Binary cmp xcc) (Binary dst src)));
+  ins_cost(150);
+  format %{ "MOV$cmp  $xcc,$src,$dst" %}
+  ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::xcc)) );
+  ins_pipe(ialu_reg);
+%}
+
 instruct cmovPL_reg(cmpOp cmp, flagsRegL xcc, iRegP dst, iRegP src) %{
   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
   ins_cost(150);
@@ -8826,16 +8873,6 @@
 %}
 
 
-instruct compP_iRegN_immN0(flagsRegP pcc, iRegN op1, immN0 op2 ) %{
-  match(Set pcc (CmpN op1 op2));
-
-  size(4);
-  format %{ "CMP    $op1,$op2\t! ptr" %}
-  opcode(Assembler::subcc_op3, Assembler::arith_op);
-  ins_encode( form3_rs1_simm13_rd( op1, op2, R_G0 ) );
-  ins_pipe(ialu_cconly_reg_imm);
-%}
-
 // ============================================================================
 // inlined locking and unlocking
 
--- a/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -3222,7 +3222,8 @@
     __ set((intptr_t)markOopDesc::prototype(), G4_scratch);
   }
   __ st_ptr(G4_scratch, RallocatedObject, oopDesc::mark_offset_in_bytes());       // mark
-  __ store_klass(RinstanceKlass, RallocatedObject); // klass
+  __ store_klass_gap(G0, RallocatedObject);         // klass gap if compressed
+  __ store_klass(RinstanceKlass, RallocatedObject); // klass (last for cms)
 
   {
     SkipIfEqual skip_if(
--- a/hotspot/src/cpu/x86/vm/assembler_x86_32.hpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/assembler_x86_32.hpp	Wed Jul 05 16:37:51 2017 +0200
@@ -1054,7 +1054,7 @@
   // range (0 <= offset <= page_size).
 
   void null_check(Register reg, int offset = -1);
-  static bool needs_explicit_null_check(int offset);
+  static bool needs_explicit_null_check(intptr_t offset);
 
   // Required platform-specific helpers for Label::patch_instructions.
   // They _shadow_ the declarations in AbstractAssembler, which are undefined.
--- a/hotspot/src/cpu/x86/vm/assembler_x86_64.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/assembler_x86_64.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -683,7 +683,8 @@
 
   case REP8(0xB8): // movl/q r, #32/#64(oop?)
     if (which == end_pc_operand)  return ip + (is_64bit ? 8 : 4);
-    assert((which == call32_operand || which == imm64_operand) && is_64bit, "");
+    assert((which == call32_operand || which == imm64_operand) && is_64bit ||
+           which == narrow_oop_operand && !is_64bit, "");
     return ip;
 
   case 0x69: // imul r, a, #32
@@ -909,7 +910,8 @@
   } else if (r->is_call() || format == call32_operand) {
     opnd = locate_operand(inst, call32_operand);
   } else if (r->is_data()) {
-    assert(format == imm64_operand || format == disp32_operand, "format ok");
+    assert(format == imm64_operand || format == disp32_operand ||
+           format == narrow_oop_operand, "format ok");
     opnd = locate_operand(inst, (WhichOperand) format);
   } else {
     assert(format == 0, "cannot specify a format");
@@ -4933,6 +4935,8 @@
   movq(Address(top, arrayOopDesc::length_offset_in_bytes()), t1);
   // set klass to intArrayKlass
   movptr(t1, ExternalAddress((address) Universe::intArrayKlassObj_addr()));
+  // store klass last.  concurrent gcs assumes klass length is valid if
+  // klass field is not null.
   store_klass(top, t1);
 
   // refill the tlab with an eden allocation
@@ -5003,8 +5007,7 @@
   jcc(Assembler::notEqual, cas_label);
   // The bias pattern is present in the object's header. Need to check
   // whether the bias owner and the epoch are both still current.
-  load_klass(tmp_reg, obj_reg);
-  movq(tmp_reg, Address(tmp_reg, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()));
+  load_prototype_header(tmp_reg, obj_reg);
   orq(tmp_reg, r15_thread);
   xorq(tmp_reg, swap_reg);
   andq(tmp_reg, ~((int) markOopDesc::age_mask_in_place));
@@ -5078,8 +5081,7 @@
   //
   // FIXME: due to a lack of registers we currently blow away the age
   // bits in this situation. Should attempt to preserve them.
-  load_klass(tmp_reg, obj_reg);
-  movq(tmp_reg, Address(tmp_reg, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()));
+  load_prototype_header(tmp_reg, obj_reg);
   orq(tmp_reg, r15_thread);
   if (os::is_MP()) {
     lock();
@@ -5109,8 +5111,7 @@
   //
   // FIXME: due to a lack of registers we currently blow away the age
   // bits in this situation. Should attempt to preserve them.
-  load_klass(tmp_reg, obj_reg);
-  movq(tmp_reg, Address(tmp_reg, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()));
+  load_prototype_header(tmp_reg, obj_reg);
   if (os::is_MP()) {
     lock();
   }
@@ -5154,17 +5155,32 @@
   }
 }
 
+void MacroAssembler::load_prototype_header(Register dst, Register src) {
+  if (UseCompressedOops) {
+    movl(dst, Address(src, oopDesc::klass_offset_in_bytes()));
+    movq(dst, Address(r12_heapbase, dst, Address::times_8, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()));
+  } else {
+    movq(dst, Address(src, oopDesc::klass_offset_in_bytes()));
+    movq(dst, Address(dst, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()));
+  }
+}
+
 void MacroAssembler::store_klass(Register dst, Register src) {
   if (UseCompressedOops) {
     encode_heap_oop_not_null(src);
-    // zero the entire klass field first as the gap needs to be zeroed too.
-    movptr(Address(dst, oopDesc::klass_offset_in_bytes()), NULL_WORD);
     movl(Address(dst, oopDesc::klass_offset_in_bytes()), src);
   } else {
     movq(Address(dst, oopDesc::klass_offset_in_bytes()), src);
   }
 }
 
+void MacroAssembler::store_klass_gap(Register dst, Register src) {
+  if (UseCompressedOops) {
+    // Store to klass gap in destination
+    movl(Address(dst, oopDesc::klass_gap_offset_in_bytes()), src);
+  }
+}
+
 void MacroAssembler::load_heap_oop(Register dst, Address src) {
   if (UseCompressedOops) {
     movl(dst, src);
@@ -5188,13 +5204,15 @@
 void MacroAssembler::encode_heap_oop(Register r) {
   assert (UseCompressedOops, "should be compressed");
 #ifdef ASSERT
-  Label ok;
-  pushq(rscratch1); // cmpptr trashes rscratch1
-  cmpptr(r12_heapbase, ExternalAddress((address)Universe::heap_base_addr()));
-  jcc(Assembler::equal, ok);
-  stop("MacroAssembler::encode_heap_oop: heap base corrupted?");
-  bind(ok);
-  popq(rscratch1);
+  if (CheckCompressedOops) {
+    Label ok;
+    pushq(rscratch1); // cmpptr trashes rscratch1
+    cmpptr(r12_heapbase, ExternalAddress((address)Universe::heap_base_addr()));
+    jcc(Assembler::equal, ok);
+    stop("MacroAssembler::encode_heap_oop: heap base corrupted?");
+    bind(ok);
+    popq(rscratch1);
+  }
 #endif
   verify_oop(r, "broken oop in encode_heap_oop");
   testq(r, r);
@@ -5206,11 +5224,13 @@
 void MacroAssembler::encode_heap_oop_not_null(Register r) {
   assert (UseCompressedOops, "should be compressed");
 #ifdef ASSERT
-  Label ok;
-  testq(r, r);
-  jcc(Assembler::notEqual, ok);
-  stop("null oop passed to encode_heap_oop_not_null");
-  bind(ok);
+  if (CheckCompressedOops) {
+    Label ok;
+    testq(r, r);
+    jcc(Assembler::notEqual, ok);
+    stop("null oop passed to encode_heap_oop_not_null");
+    bind(ok);
+  }
 #endif
   verify_oop(r, "broken oop in encode_heap_oop_not_null");
   subq(r, r12_heapbase);
@@ -5220,11 +5240,13 @@
 void MacroAssembler::encode_heap_oop_not_null(Register dst, Register src) {
   assert (UseCompressedOops, "should be compressed");
 #ifdef ASSERT
-  Label ok;
-  testq(src, src);
-  jcc(Assembler::notEqual, ok);
-  stop("null oop passed to encode_heap_oop_not_null2");
-  bind(ok);
+  if (CheckCompressedOops) {
+    Label ok;
+    testq(src, src);
+    jcc(Assembler::notEqual, ok);
+    stop("null oop passed to encode_heap_oop_not_null2");
+    bind(ok);
+  }
 #endif
   verify_oop(src, "broken oop in encode_heap_oop_not_null2");
   if (dst != src) {
@@ -5237,14 +5259,16 @@
 void  MacroAssembler::decode_heap_oop(Register r) {
   assert (UseCompressedOops, "should be compressed");
 #ifdef ASSERT
-  Label ok;
-  pushq(rscratch1);
-  cmpptr(r12_heapbase,
-         ExternalAddress((address)Universe::heap_base_addr()));
-  jcc(Assembler::equal, ok);
-  stop("MacroAssembler::decode_heap_oop: heap base corrupted?");
-  bind(ok);
-  popq(rscratch1);
+  if (CheckCompressedOops) {
+    Label ok;
+    pushq(rscratch1);
+    cmpptr(r12_heapbase,
+           ExternalAddress((address)Universe::heap_base_addr()));
+    jcc(Assembler::equal, ok);
+    stop("MacroAssembler::decode_heap_oop: heap base corrupted?");
+    bind(ok);
+    popq(rscratch1);
+  }
 #endif
 
   Label done;
@@ -5265,6 +5289,7 @@
   assert (UseCompressedOops, "should only be used for compressed headers");
   // Cannot assert, unverified entry point counts instructions (see .ad file)
   // vtableStubs also counts instructions in pd_code_size_limit.
+  // Also do not verify_oop as this is called by verify_oop.
   assert(Address::times_8 == LogMinObjAlignmentInBytes, "decode alg wrong");
   leaq(r, Address(r12_heapbase, r, Address::times_8, 0));
 }
@@ -5273,10 +5298,24 @@
   assert (UseCompressedOops, "should only be used for compressed headers");
   // Cannot assert, unverified entry point counts instructions (see .ad file)
   // vtableStubs also counts instructions in pd_code_size_limit.
+  // Also do not verify_oop as this is called by verify_oop.
   assert(Address::times_8 == LogMinObjAlignmentInBytes, "decode alg wrong");
   leaq(dst, Address(r12_heapbase, src, Address::times_8, 0));
 }
 
+void  MacroAssembler::set_narrow_oop(Register dst, jobject obj) {
+  assert(oop_recorder() != NULL, "this assembler needs an OopRecorder");
+  int oop_index = oop_recorder()->find_index(obj);
+  RelocationHolder rspec = oop_Relocation::spec(oop_index);
+
+  // movl dst,obj
+  InstructionMark im(this);
+  int encode = prefix_and_encode(dst->encoding());
+  emit_byte(0xB8 | encode);
+  emit_data(oop_index, rspec, narrow_oop_operand);
+}
+
+
 Assembler::Condition MacroAssembler::negate_condition(Assembler::Condition cond) {
   switch (cond) {
     // Note some conditions are synonyms for others
--- a/hotspot/src/cpu/x86/vm/assembler_x86_64.hpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/assembler_x86_64.hpp	Wed Jul 05 16:37:51 2017 +0200
@@ -490,7 +490,12 @@
     imm64_operand  = 0,          // embedded 64-bit immediate operand
     disp32_operand = 1,          // embedded 32-bit displacement
     call32_operand = 2,          // embedded 32-bit self-relative displacement
+#ifndef AMD64
     _WhichOperand_limit = 3
+#else
+     narrow_oop_operand = 3,     // embedded 32-bit immediate narrow oop
+    _WhichOperand_limit = 4
+#endif
   };
 
   public:
@@ -1023,7 +1028,7 @@
   // is needed if the offset is within a certain range (0 <= offset <=
   // page_size).
   void null_check(Register reg, int offset = -1);
-  static bool needs_explicit_null_check(int offset);
+  static bool needs_explicit_null_check(intptr_t offset);
 
   // Required platform-specific helpers for Label::patch_instructions.
   // They _shadow_ the declarations in AbstractAssembler, which are undefined.
@@ -1104,6 +1109,9 @@
   // oop manipulations
   void load_klass(Register dst, Register src);
   void store_klass(Register dst, Register src);
+  void store_klass_gap(Register dst, Register src);
+
+  void load_prototype_header(Register dst, Register src);
 
   void load_heap_oop(Register dst, Address src);
   void store_heap_oop(Address dst, Register src);
@@ -1114,6 +1122,8 @@
   void encode_heap_oop_not_null(Register dst, Register src);
   void decode_heap_oop_not_null(Register dst, Register src);
 
+  void set_narrow_oop(Register dst, jobject obj);
+
   // Stack frame creation/removal
   void enter();
   void leave();
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -233,7 +233,7 @@
   assert(Rsub_klass != rcx, "rcx holds 2ndary super array length");
   assert(Rsub_klass != rdi, "rdi holds 2ndary super array scan ptr");
 
-  Label not_subtype, loop;
+  Label not_subtype, not_subtype_pop, loop;
 
   // Profile the not-null value's klass.
   profile_typecheck(rcx, Rsub_klass, rdi); // blows rcx, rdi
@@ -272,12 +272,13 @@
   // and we store values in objArrays always encoded, thus we need to encode value
   // before repne
   if (UseCompressedOops) {
+    pushq(rax);
     encode_heap_oop(rax);
     repne_scanl();
     // Not equal?
-    jcc(Assembler::notEqual, not_subtype);
-    // decode heap oop here for movq
-    decode_heap_oop(rax);
+    jcc(Assembler::notEqual, not_subtype_pop);
+    // restore heap oop here for movq
+    popq(rax);
   } else {
     repne_scanq();
     jcc(Assembler::notEqual, not_subtype);
@@ -287,9 +288,10 @@
                Klass::secondary_super_cache_offset_in_bytes()), rax);
   jmp(ok_is_subtype);
 
+  bind(not_subtype_pop);
+  // restore heap oop here for miss
+  if (UseCompressedOops) popq(rax);
   bind(not_subtype);
-  // decode heap oop here for miss
-  if (UseCompressedOops) decode_heap_oop(rax);
   profile_typecheck_failed(rcx); // blows rcx
 }
 
--- a/hotspot/src/cpu/x86/vm/relocInfo_x86.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/relocInfo_x86.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -30,11 +30,15 @@
 #ifdef AMD64
   x += o;
   typedef Assembler::WhichOperand WhichOperand;
-  WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm64, call32
+  WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm64, call32, narrow oop
   assert(which == Assembler::disp32_operand ||
+         which == Assembler::narrow_oop_operand ||
          which == Assembler::imm64_operand, "format unpacks ok");
   if (which == Assembler::imm64_operand) {
     *pd_address_in_code() = x;
+  } else if (which == Assembler::narrow_oop_operand) {
+    address disp = Assembler::locate_operand(addr(), which);
+    *(int32_t*) disp = oopDesc::encode_heap_oop((oop)x);
   } else {
     // Note:  Use runtime_call_type relocations for call32_operand.
     address ip = addr();
--- a/hotspot/src/cpu/x86/vm/relocInfo_x86.hpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/relocInfo_x86.hpp	Wed Jul 05 16:37:51 2017 +0200
@@ -29,5 +29,10 @@
     offset_unit        =  1,
 
     // Encodes Assembler::disp32_operand vs. Assembler::imm32_operand.
+#ifndef AMD64
     format_width       =  1
+#else
+    // vs Assembler::narrow_oop_operand.
+    format_width       =  2
+#endif
   };
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -1920,7 +1920,6 @@
   int total_strings = 0;
   int first_arg_to_pass = 0;
   int total_c_args = 0;
-  int box_offset = java_lang_boxing_object::value_offset_in_bytes();
 
   if( !method->is_static() ) {  // Pass in receiver first
     in_sig_bt[i++] = T_OBJECT;
@@ -2131,7 +2130,10 @@
           assert(dst.first()->is_stack() &&
                  (!dst.second()->is_valid() || dst.second()->is_stack()),
                  "value(s) must go into stack slots");
-          if ( out_sig_bt[c_arg] == T_LONG ) {
+
+          BasicType bt = out_sig_bt[c_arg];
+          int box_offset = java_lang_boxing_object::value_offset_in_bytes(bt);
+          if ( bt == T_LONG ) {
             __ movl(rbx, Address(in_reg,
                                  box_offset + VMRegImpl::stack_slot_size));
             __ movl(Address(rsp, reg2offset_out(dst.second())), rbx);
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -1950,7 +1950,6 @@
   int total_strings = 0;
   int first_arg_to_pass = 0;
   int total_c_args = 0;
-  int box_offset = java_lang_boxing_object::value_offset_in_bytes();
 
   // Skip the receiver as dtrace doesn't want to see it
   if( !method->is_static() ) {
@@ -2197,8 +2196,10 @@
               __ testq(in_reg, in_reg);
               __ jcc(Assembler::zero, skipUnbox);
 
+              BasicType bt = out_sig_bt[c_arg];
+              int box_offset = java_lang_boxing_object::value_offset_in_bytes(bt);
               Address src1(in_reg, box_offset);
-              if ( out_sig_bt[c_arg] == T_LONG ) {
+              if ( bt == T_LONG ) {
                 __ movq(in_reg,  src1);
                 __ movq(stack_dst, in_reg);
                 assert(out_sig_bt[c_arg+1] == T_VOID, "must be");
@@ -2460,8 +2461,10 @@
           Label skip;
           __ testq(r, r);
           __ jcc(Assembler::equal, skip);
+          BasicType bt = out_sig_bt[c_arg];
+          int box_offset = java_lang_boxing_object::value_offset_in_bytes(bt);
           Address src1(r, box_offset);
-          if ( out_sig_bt[c_arg] == T_LONG ) {
+          if ( bt == T_LONG ) {
             __ movq(r, src1);
           } else {
             __ movl(r, src1);
--- a/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -3163,7 +3163,9 @@
       __ movptr(Address(rax, oopDesc::mark_offset_in_bytes()),
                (intptr_t) markOopDesc::prototype()); // header (address 0x1)
     }
-    __ store_klass(rax, rsi);  // klass
+    __ xorl(rcx, rcx); // use zero reg to clear memory (shorter code)
+    __ store_klass_gap(rax, rcx);  // zero klass gap for compressed oops
+    __ store_klass(rax, rsi);      // store klass last
     __ jmp(done);
   }
 
--- a/hotspot/src/cpu/x86/vm/x86_32.ad	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/x86_32.ad	Wed Jul 05 16:37:51 2017 +0200
@@ -3806,6 +3806,78 @@
     masm.bind(DONE_LABEL);
   %}
 
+  enc_class enc_Array_Equals(eDIRegP ary1, eSIRegP ary2, eAXRegI tmp1, eBXRegI tmp2, eCXRegI result) %{
+    Label TRUE_LABEL, FALSE_LABEL, DONE_LABEL, COMPARE_LOOP_HDR, COMPARE_LOOP;
+    MacroAssembler masm(&cbuf);
+
+    Register ary1Reg   = as_Register($ary1$$reg);
+    Register ary2Reg   = as_Register($ary2$$reg);
+    Register tmp1Reg   = as_Register($tmp1$$reg);
+    Register tmp2Reg   = as_Register($tmp2$$reg);
+    Register resultReg = as_Register($result$$reg);
+
+    int length_offset  = arrayOopDesc::length_offset_in_bytes();
+    int base_offset    = arrayOopDesc::base_offset_in_bytes(T_CHAR);
+
+    // Check the input args
+    masm.cmpl(ary1Reg, ary2Reg);
+    masm.jcc(Assembler::equal, TRUE_LABEL);
+    masm.testl(ary1Reg, ary1Reg);
+    masm.jcc(Assembler::zero, FALSE_LABEL);
+    masm.testl(ary2Reg, ary2Reg);
+    masm.jcc(Assembler::zero, FALSE_LABEL);
+
+    // Check the lengths
+    masm.movl(tmp2Reg, Address(ary1Reg, length_offset));
+    masm.movl(resultReg, Address(ary2Reg, length_offset));
+    masm.cmpl(tmp2Reg, resultReg);
+    masm.jcc(Assembler::notEqual, FALSE_LABEL);
+    masm.testl(resultReg, resultReg);
+    masm.jcc(Assembler::zero, TRUE_LABEL);
+
+    // Get the number of 4 byte vectors to compare
+    masm.shrl(resultReg, 1);
+
+    // Check for odd-length arrays
+    masm.andl(tmp2Reg, 1);
+    masm.testl(tmp2Reg, tmp2Reg);
+    masm.jcc(Assembler::zero, COMPARE_LOOP_HDR);
+
+    // Compare 2-byte "tail" at end of arrays
+    masm.load_unsigned_word(tmp1Reg, Address(ary1Reg, resultReg, Address::times_4, base_offset));
+    masm.load_unsigned_word(tmp2Reg, Address(ary2Reg, resultReg, Address::times_4, base_offset));
+    masm.cmpl(tmp1Reg, tmp2Reg);
+    masm.jcc(Assembler::notEqual, FALSE_LABEL);
+    masm.testl(resultReg, resultReg);
+    masm.jcc(Assembler::zero, TRUE_LABEL);
+
+    // Setup compare loop
+    masm.bind(COMPARE_LOOP_HDR);
+    // Shift tmp1Reg and tmp2Reg to the last 4-byte boundary of the arrays
+    masm.leal(tmp1Reg, Address(ary1Reg, resultReg, Address::times_4, base_offset));
+    masm.leal(tmp2Reg, Address(ary2Reg, resultReg, Address::times_4, base_offset));
+    masm.negl(resultReg);
+
+    // 4-byte-wide compare loop
+    masm.bind(COMPARE_LOOP);
+    masm.movl(ary1Reg, Address(tmp1Reg, resultReg, Address::times_4, 0));
+    masm.movl(ary2Reg, Address(tmp2Reg, resultReg, Address::times_4, 0));
+    masm.cmpl(ary1Reg, ary2Reg);
+    masm.jcc(Assembler::notEqual, FALSE_LABEL);
+    masm.increment(resultReg);
+    masm.jcc(Assembler::notZero, COMPARE_LOOP);
+
+    masm.bind(TRUE_LABEL);
+    masm.movl(resultReg, 1);   // return true
+    masm.jmp(DONE_LABEL);
+
+    masm.bind(FALSE_LABEL);
+    masm.xorl(resultReg, resultReg); // return false
+
+    // That's it
+    masm.bind(DONE_LABEL);
+  %}
+
   enc_class enc_pop_rdx() %{
     emit_opcode(cbuf,0x5A);
   %}
@@ -11565,6 +11637,17 @@
   ins_pipe( pipe_slow );
 %}
 
+// fast array equals
+instruct array_equals(eDIRegP ary1, eSIRegP ary2, eAXRegI tmp1, eBXRegI tmp2, eCXRegI result, eFlagsReg cr) %{
+  match(Set result (AryEq ary1 ary2));
+  effect(USE_KILL ary1, USE_KILL ary2, KILL tmp1, KILL tmp2, KILL cr);
+  //ins_cost(300);
+
+  format %{ "Array Equals $ary1,$ary2 -> $result    // KILL EAX, EBX" %}
+  ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, result) );
+  ins_pipe( pipe_slow );
+%}
+
 //----------Control Flow Instructions------------------------------------------
 // Signed compare Instructions
 instruct compI_eReg(eFlagsReg cr, eRegI op1, eRegI op2) %{
--- a/hotspot/src/cpu/x86/vm/x86_64.ad	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/x86_64.ad	Wed Jul 05 16:37:51 2017 +0200
@@ -3808,6 +3808,78 @@
     masm.bind(DONE_LABEL);
   %}
 
+  enc_class enc_Array_Equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI tmp1, rbx_RegI tmp2, rcx_RegI result) %{
+    Label TRUE_LABEL, FALSE_LABEL, DONE_LABEL, COMPARE_LOOP_HDR, COMPARE_LOOP;
+    MacroAssembler masm(&cbuf);
+
+    Register ary1Reg   = as_Register($ary1$$reg);
+    Register ary2Reg   = as_Register($ary2$$reg);
+    Register tmp1Reg   = as_Register($tmp1$$reg);
+    Register tmp2Reg   = as_Register($tmp2$$reg);
+    Register resultReg = as_Register($result$$reg);
+
+    int length_offset  = arrayOopDesc::length_offset_in_bytes();
+    int base_offset    = arrayOopDesc::base_offset_in_bytes(T_CHAR);
+
+    // Check the input args
+    masm.cmpq(ary1Reg, ary2Reg);                        
+    masm.jcc(Assembler::equal, TRUE_LABEL);
+    masm.testq(ary1Reg, ary1Reg);                       
+    masm.jcc(Assembler::zero, FALSE_LABEL);
+    masm.testq(ary2Reg, ary2Reg);                       
+    masm.jcc(Assembler::zero, FALSE_LABEL);
+
+    // Check the lengths
+    masm.movl(tmp2Reg, Address(ary1Reg, length_offset));
+    masm.movl(resultReg, Address(ary2Reg, length_offset));
+    masm.cmpl(tmp2Reg, resultReg);
+    masm.jcc(Assembler::notEqual, FALSE_LABEL);
+    masm.testl(resultReg, resultReg);
+    masm.jcc(Assembler::zero, TRUE_LABEL);
+
+    // Get the number of 4 byte vectors to compare
+    masm.shrl(resultReg, 1);
+
+    // Check for odd-length arrays
+    masm.andl(tmp2Reg, 1);
+    masm.testl(tmp2Reg, tmp2Reg);
+    masm.jcc(Assembler::zero, COMPARE_LOOP_HDR);
+
+    // Compare 2-byte "tail" at end of arrays
+    masm.load_unsigned_word(tmp1Reg, Address(ary1Reg, resultReg, Address::times_4, base_offset));
+    masm.load_unsigned_word(tmp2Reg, Address(ary2Reg, resultReg, Address::times_4, base_offset));
+    masm.cmpl(tmp1Reg, tmp2Reg);
+    masm.jcc(Assembler::notEqual, FALSE_LABEL);
+    masm.testl(resultReg, resultReg);
+    masm.jcc(Assembler::zero, TRUE_LABEL);
+
+    // Setup compare loop
+    masm.bind(COMPARE_LOOP_HDR);
+    // Shift tmp1Reg and tmp2Reg to the last 4-byte boundary of the arrays
+    masm.leaq(tmp1Reg, Address(ary1Reg, resultReg, Address::times_4, base_offset));
+    masm.leaq(tmp2Reg, Address(ary2Reg, resultReg, Address::times_4, base_offset));
+    masm.negq(resultReg);
+
+    // 4-byte-wide compare loop
+    masm.bind(COMPARE_LOOP);
+    masm.movl(ary1Reg, Address(tmp1Reg, resultReg, Address::times_4, 0));
+    masm.movl(ary2Reg, Address(tmp2Reg, resultReg, Address::times_4, 0));
+    masm.cmpl(ary1Reg, ary2Reg);
+    masm.jcc(Assembler::notEqual, FALSE_LABEL);
+    masm.incrementq(resultReg);
+    masm.jcc(Assembler::notZero, COMPARE_LOOP);
+
+    masm.bind(TRUE_LABEL);
+    masm.movl(resultReg, 1);   // return true
+    masm.jmp(DONE_LABEL);
+
+    masm.bind(FALSE_LABEL);
+    masm.xorl(resultReg, resultReg); // return false
+
+    // That's it
+    masm.bind(DONE_LABEL);
+  %}
+
   enc_class enc_rethrow()
   %{
     cbuf.set_inst_mark();
@@ -5202,15 +5274,15 @@
   %}
 %}
 
-// Indirect Memory Times Scale Plus Index Register Plus Offset Operand
-operand indIndexScaleOffsetComp(rRegN src, immL32 off, r12RegL base) %{
+// Indirect Narrow Oop Plus Offset Operand
+operand indNarrowOopOffset(rRegN src, immL32 off) %{
   constraint(ALLOC_IN_RC(ptr_reg));
-  match(AddP (DecodeN src base) off);
+  match(AddP (DecodeN src) off);
 
   op_cost(10);
-  format %{"[$base + $src << 3 + $off] (compressed)" %}
+  format %{"[R12 + $src << 3 + $off] (compressed oop addressing)" %}
   interface(MEMORY_INTER) %{
-    base($base);
+    base(0xc); // R12
     index($src);
     scale(0x3);
     disp($off);
@@ -5365,7 +5437,7 @@
 
 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex,
                indIndexScale, indIndexScaleOffset, indPosIndexScaleOffset,
-               indIndexScaleOffsetComp);
+               indNarrowOopOffset);
 
 //----------PIPELINE-----------------------------------------------------------
 // Rules which define the behavior of the target architectures pipeline.
@@ -6044,10 +6116,9 @@
 %}
 
 // Load Compressed Pointer
-instruct loadN(rRegN dst, memory mem, rFlagsReg cr)
+instruct loadN(rRegN dst, memory mem)
 %{
    match(Set dst (LoadN mem));
-   effect(KILL cr);
 
    ins_cost(125); // XXX
    format %{ "movl    $dst, $mem\t# compressed ptr" %}
@@ -6064,7 +6135,6 @@
 instruct loadKlass(rRegP dst, memory mem)
 %{
   match(Set dst (LoadKlass mem));
-  predicate(!n->in(MemNode::Address)->bottom_type()->is_narrow());
 
   ins_cost(125); // XXX
   format %{ "movq    $dst, $mem\t# class" %}
@@ -6073,22 +6143,17 @@
   ins_pipe(ialu_reg_mem); // XXX
 %}
 
-// Load Klass Pointer
-instruct loadKlassComp(rRegP dst, memory mem)
-%{
-  match(Set dst (LoadKlass mem));
-  predicate(n->in(MemNode::Address)->bottom_type()->is_narrow());
+// Load narrow Klass Pointer
+instruct loadNKlass(rRegN dst, memory mem)
+%{
+  match(Set dst (LoadNKlass mem));
 
   ins_cost(125); // XXX
-  format %{ "movl    $dst, $mem\t# compressed class\n\t"
-            "decode_heap_oop $dst,$dst" %}
+  format %{ "movl    $dst, $mem\t# compressed klass ptr" %}
   ins_encode %{
     Address addr = build_address($mem$$base, $mem$$index, $mem$$scale, $mem$$disp);
     Register dst = as_Register($dst$$reg);
     __ movl(dst, addr);
-    // klass is never null in the header but this is generated for all
-    // klass loads not just the _klass field in the header.
-    __ decode_heap_oop(dst);
   %}
   ins_pipe(ialu_reg_mem); // XXX
 %}
@@ -6362,16 +6427,14 @@
   match(Set dst src);
 
   ins_cost(125);
-  format %{ "movq    $dst, $src\t# compressed ptr\n\t"
-            "encode_heap_oop_not_null $dst,$dst" %}
+  format %{ "movl    $dst, $src\t# compressed ptr" %}
   ins_encode %{
     address con = (address)$src$$constant;
     Register dst = $dst$$Register;
     if (con == NULL) {
       ShouldNotReachHere();
     } else {
-      __ movoop(dst, (jobject)$src$$constant);
-      __ encode_heap_oop_not_null(dst);
+      __ set_narrow_oop(dst, (jobject)$src$$constant);
     }
   %}
   ins_pipe(ialu_reg_fat); // XXX
@@ -6633,13 +6696,12 @@
 %}
 
 // Store Compressed Pointer
-instruct storeN(memory mem, rRegN src, rFlagsReg cr)
+instruct storeN(memory mem, rRegN src)
 %{
   match(Set mem (StoreN mem src));
-  effect(KILL cr);
 
   ins_cost(125); // XXX
-  format %{ "movl    $mem, $src\t# ptr" %}
+  format %{ "movl    $mem, $src\t# compressed ptr" %}
   ins_encode %{
     Address addr = build_address($mem$$base, $mem$$index, $mem$$scale, $mem$$disp);
     Register src = as_Register($src$$reg);
@@ -7027,7 +7089,8 @@
 %}
 
 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{
-  predicate(n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull);
+  predicate(n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull &&
+            n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant);
   match(Set dst (DecodeN src));
   effect(KILL cr);
   format %{ "decode_heap_oop $dst,$src" %}
@@ -7043,7 +7106,8 @@
 %}
 
 instruct decodeHeapOop_not_null(rRegP dst, rRegN src) %{
-  predicate(n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull);
+  predicate(n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull ||
+            n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant);
   match(Set dst (DecodeN src));
   format %{ "decode_heap_oop_not_null $dst,$src" %}
   ins_encode %{
@@ -7143,6 +7207,30 @@
 %}
 
 // Conditional move
+instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop)
+%{
+  match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
+
+  ins_cost(200); // XXX
+  format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %}
+  opcode(0x0F, 0x40);
+  ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src));
+  ins_pipe(pipe_cmov_reg);
+%}
+
+// Conditional move
+instruct cmovN_regU(rRegN dst, rRegN src, rFlagsRegU cr, cmpOpU cop)
+%{
+  match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
+
+  ins_cost(200); // XXX
+  format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %}
+  opcode(0x0F, 0x40);
+  ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src));
+  ins_pipe(pipe_cmov_reg);
+%}
+
+// Conditional move
 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop)
 %{
   match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
@@ -10862,6 +10950,18 @@
   ins_pipe( pipe_slow );
 %}
 
+// fast array equals
+instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI tmp1, 
+                      rbx_RegI tmp2, rcx_RegI result, rFlagsReg cr) %{
+  match(Set result (AryEq ary1 ary2));
+  effect(USE_KILL ary1, USE_KILL ary2, KILL tmp1, KILL tmp2, KILL cr);
+  //ins_cost(300);
+
+  format %{ "Array Equals $ary1,$ary2 -> $result    // KILL RAX, RBX" %}
+  ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, result) );
+  ins_pipe( pipe_slow );
+%}
+
 //----------Control Flow Instructions------------------------------------------
 // Signed compare Instructions
 
@@ -11055,14 +11155,50 @@
   ins_pipe(ialu_cr_reg_imm);
 %}
 
+
+instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2)
+%{
+  match(Set cr (CmpN op1 op2));
+
+  format %{ "cmpl    $op1, $op2\t# compressed ptr" %}
+  ins_encode %{ __ cmpl(as_Register($op1$$reg), as_Register($op2$$reg)); %}
+  ins_pipe(ialu_cr_reg_reg);
+%}
+
+instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem)
+%{
+  match(Set cr (CmpN src (LoadN mem)));
+
+  ins_cost(500); // XXX
+  format %{ "cmpl    $src, mem\t# compressed ptr" %}
+  ins_encode %{
+    Address adr = build_address($mem$$base, $mem$$index, $mem$$scale, $mem$$disp);
+    __ cmpl(as_Register($src$$reg), adr);
+  %}
+  ins_pipe(ialu_cr_reg_mem);
+%}
+
 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{
   match(Set cr (CmpN src zero));
 
-  format %{ "testl   $src, $src" %}
+  format %{ "testl   $src, $src\t# compressed ptr" %}
   ins_encode %{ __ testl($src$$Register, $src$$Register); %}
   ins_pipe(ialu_cr_reg_imm);
 %}
 
+instruct testN_reg_mem(rFlagsReg cr, memory mem, immN0 zero)
+%{
+  match(Set cr (CmpN (LoadN mem) zero));
+
+  ins_cost(500); // XXX
+  format %{ "testl   $mem, 0xffffffff\t# compressed ptr" %}
+  ins_encode %{
+    Address addr = build_address($mem$$base, $mem$$index, $mem$$scale, $mem$$disp);
+    __ cmpl(addr, (int)0xFFFFFFFF);
+  %}
+  ins_pipe(ialu_cr_reg_mem);
+%}
+
 // Yanked all unsigned pointer compare operations.
 // Pointer compares are done with CmpP which is already unsigned.
 
--- a/hotspot/src/os_cpu/linux_x86/vm/assembler_linux_x86_32.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/os_cpu/linux_x86/vm/assembler_linux_x86_32.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -40,7 +40,7 @@
   movptr(thread, tls);
 }
 
-bool MacroAssembler::needs_explicit_null_check(int offset) {
+bool MacroAssembler::needs_explicit_null_check(intptr_t offset) {
   // Linux kernel guarantees that the first page is always unmapped. Don't
   // assume anything more than that.
   bool offset_in_first_page =   0 <= offset  &&  offset < os::vm_page_size();
--- a/hotspot/src/os_cpu/linux_x86/vm/assembler_linux_x86_64.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/os_cpu/linux_x86/vm/assembler_linux_x86_64.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -66,8 +66,21 @@
    }
 }
 
-// NOTE: since the linux kernel resides at the low end of
-// user address space, no null pointer check is needed.
-bool MacroAssembler::needs_explicit_null_check(int offset) {
-  return offset < 0 || offset >= 0x100000;
+bool MacroAssembler::needs_explicit_null_check(intptr_t offset) {
+  // Exception handler checks the nmethod's implicit null checks table
+  // only when this method returns false.
+  if (UseCompressedOops) {
+    // The first page after heap_base is unmapped and
+    // the 'offset' is equal to [heap_base + offset] for
+    // narrow oop implicit null checks.
+    uintptr_t heap_base = (uintptr_t)Universe::heap_base();
+    if ((uintptr_t)offset >= heap_base) {
+      // Normalize offset for the next check.
+      offset = (intptr_t)(pointer_delta((void*)offset, (void*)heap_base, 1));
+    }
+  }
+  // Linux kernel guarantees that the first page is always unmapped. Don't
+  // assume anything more than that.
+  bool offset_in_first_page =   0 <= offset  &&  offset < os::vm_page_size();
+  return !offset_in_first_page;
 }
--- a/hotspot/src/os_cpu/solaris_x86/vm/assembler_solaris_x86_32.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/os_cpu/solaris_x86/vm/assembler_solaris_x86_32.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -80,7 +80,7 @@
   popl(thread);
 }
 
-bool MacroAssembler::needs_explicit_null_check(int offset) {
+bool MacroAssembler::needs_explicit_null_check(intptr_t offset) {
   // Identical to Sparc/Solaris code
   bool offset_in_first_page =   0 <= offset  &&  offset < os::vm_page_size();
   return !offset_in_first_page;
--- a/hotspot/src/os_cpu/solaris_x86/vm/assembler_solaris_x86_64.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/os_cpu/solaris_x86/vm/assembler_solaris_x86_64.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -86,8 +86,21 @@
   }
 }
 
-bool MacroAssembler::needs_explicit_null_check(int offset) {
+bool MacroAssembler::needs_explicit_null_check(intptr_t offset) {
   // Identical to Sparc/Solaris code
+
+  // Exception handler checks the nmethod's implicit null checks table
+  // only when this method returns false.
+  if (UseCompressedOops) {
+    // The first page after heap_base is unmapped and
+    // the 'offset' is equal to [heap_base + offset] for
+    // narrow oop implicit null checks.
+    uintptr_t heap_base = (uintptr_t)Universe::heap_base();
+    if ((uintptr_t)offset >= heap_base) {
+      // Normalize offset for the next check.
+      offset = (intptr_t)(pointer_delta((void*)offset, (void*)heap_base, 1));
+    }
+  }
   bool offset_in_first_page = 0 <= offset && offset < os::vm_page_size();
   return !offset_in_first_page;
 }
--- a/hotspot/src/os_cpu/windows_x86/vm/assembler_windows_x86_32.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/os_cpu/windows_x86/vm/assembler_windows_x86_32.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -59,6 +59,6 @@
   movl(thread, Address(thread, ThreadLocalStorage::get_thread_ptr_offset()));
 }
 
-bool MacroAssembler::needs_explicit_null_check(int offset) {
+bool MacroAssembler::needs_explicit_null_check(intptr_t offset) {
   return offset < 0 || (int)os::vm_page_size() <= offset;
 }
--- a/hotspot/src/os_cpu/windows_x86/vm/assembler_windows_x86_64.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/os_cpu/windows_x86/vm/assembler_windows_x86_64.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -66,6 +66,18 @@
    }
 }
 
-bool MacroAssembler::needs_explicit_null_check(int offset) {
-  return offset < 0 || (int)os::vm_page_size() <= offset;
+bool MacroAssembler::needs_explicit_null_check(intptr_t offset) {
+  // Exception handler checks the nmethod's implicit null checks table
+  // only when this method returns false.
+  if (UseCompressedOops) {
+    // The first page after heap_base is unmapped and
+    // the 'offset' is equal to [heap_base + offset] for
+    // narrow oop implicit null checks.
+    uintptr_t heap_base = (uintptr_t)Universe::heap_base();
+    if ((uintptr_t)offset >= heap_base) {
+      // Normalize offset for the next check.
+      offset = (intptr_t)(pointer_delta((void*)offset, (void*)heap_base, 1));
+    }
+  }
+  return offset < 0 || os::vm_page_size() <= offset;
 }
--- a/hotspot/src/share/vm/adlc/forms.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/adlc/forms.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -252,6 +252,7 @@
   if( strcmp(opType,"LoadF")==0 )  return Form::idealF;
   if( strcmp(opType,"LoadI")==0 )  return Form::idealI;
   if( strcmp(opType,"LoadKlass")==0 )  return Form::idealP;
+  if( strcmp(opType,"LoadNKlass")==0 ) return Form::idealN;
   if( strcmp(opType,"LoadL")==0 )  return Form::idealL;
   if( strcmp(opType,"LoadL_unaligned")==0 )  return Form::idealL;
   if( strcmp(opType,"LoadPLocked")==0 )  return Form::idealP;
--- a/hotspot/src/share/vm/adlc/formssel.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/adlc/formssel.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -3313,7 +3313,7 @@
     "Store8B","Store4B","Store8C","Store4C","Store2C",
     "Load4I" ,"Load2I" ,"Load2L" ,"Load2D" ,"Load4F" ,"Load2F" ,"Load16B" ,
     "Load8B" ,"Load4B" ,"Load8C" ,"Load4C" ,"Load2C" ,"Load8S", "Load4S","Load2S",
-    "LoadRange", "LoadKlass", "LoadL_unaligned", "LoadD_unaligned",
+    "LoadRange", "LoadKlass", "LoadNKlass", "LoadL_unaligned", "LoadD_unaligned",
     "LoadPLocked", "LoadLLocked",
     "StorePConditional", "StoreLConditional",
     "CompareAndSwapI", "CompareAndSwapL", "CompareAndSwapP", "CompareAndSwapN",
--- a/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -218,6 +218,13 @@
   ciInstanceKlass* callee_holder = ciEnv::get_instance_klass_for_declared_method_holder(holder);
   ciInstanceKlass* actual_recv = callee_holder;
 
+  // some methods are obviously bindable without any type checks so
+  // convert them directly to an invokespecial.
+  if (target->is_loaded() && !target->is_abstract() &&
+      target->can_be_statically_bound() && code == Bytecodes::_invokevirtual) {
+    code = Bytecodes::_invokespecial;
+  }
+
   // compute size of arguments
   int arg_size = target->arg_size();
   if (!target->is_loaded() && code == Bytecodes::_invokestatic) {
--- a/hotspot/src/share/vm/ci/ciInstanceKlass.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/ci/ciInstanceKlass.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -392,12 +392,12 @@
   assert(!is_java_lang_Object(), "bootstrap OK");
 
   // Size in bytes of my fields, including inherited fields.
-  int fsize = nonstatic_field_size() * wordSize;
+  int fsize = nonstatic_field_size() * heapOopSize;
 
   ciInstanceKlass* super = this->super();
   GrowableArray<ciField*>* super_fields = NULL;
   if (super != NULL && super->has_nonstatic_fields()) {
-    int super_fsize  = super->nonstatic_field_size() * wordSize;
+    int super_fsize  = super->nonstatic_field_size() * heapOopSize;
     int super_flen   = super->nof_nonstatic_fields();
     super_fields = super->_nonstatic_fields;
     assert(super_flen == 0 || super_fields != NULL, "first get nof_fields");
@@ -438,7 +438,7 @@
     // This is a minor inefficiency classFileParser.cpp.
     last_offset = offset + size;
   }
-  assert(last_offset <= (int)sizeof(oopDesc) + fsize, "no overflow");
+  assert(last_offset <= (int)instanceOopDesc::base_offset_in_bytes() + fsize, "no overflow");
 #endif
 
   _nonstatic_fields = fields;
--- a/hotspot/src/share/vm/ci/ciMethod.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/ci/ciMethod.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -878,7 +878,7 @@
         (TieredCompilation && code->compiler() != NULL && code->compiler()->is_c1())) {
       return 0;
     }
-    return code->code_size();
+    return code->code_end() - code->verified_entry_point();
   )
 }
 
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -44,6 +44,7 @@
 
 // Used for backward compatibility reasons:
 // - to check for javac bug fixes that happened after 1.5
+// - also used as the max version when running in jdk6
 #define JAVA_6_VERSION                    50
 
 
@@ -2664,8 +2665,8 @@
                                   fac.static_byte_count ), wordSize );
     static_field_size           = (next_static_type_offset -
                                   next_static_oop_offset) / wordSize;
-    first_nonstatic_field_offset = (instanceOopDesc::header_size() +
-                                    nonstatic_field_size) * wordSize;
+    first_nonstatic_field_offset = instanceOopDesc::base_offset_in_bytes() +
+                                   nonstatic_field_size * heapOopSize;
     next_nonstatic_field_offset = first_nonstatic_field_offset;
 
     // Add fake fields for java.lang.Class instances (also see below)
@@ -2734,9 +2735,9 @@
       next_nonstatic_byte_offset  = next_nonstatic_short_offset +
                                     (nonstatic_short_count * BytesPerShort);
       next_nonstatic_type_offset  = align_size_up((next_nonstatic_byte_offset +
-                                    nonstatic_byte_count ), wordSize );
+                                    nonstatic_byte_count ), heapOopSize );
       orig_nonstatic_field_size   = nonstatic_field_size +
-        ((next_nonstatic_type_offset - first_nonstatic_field_offset)/wordSize);
+      ((next_nonstatic_type_offset - first_nonstatic_field_offset)/heapOopSize);
     }
 #endif
     bool compact_fields   = CompactFields;
@@ -2791,18 +2792,8 @@
     int nonstatic_short_space_offset;
     int nonstatic_byte_space_offset;
 
-    bool compact_into_header = (UseCompressedOops &&
-                                allocation_style == 1 && compact_fields &&
-                                !super_has_nonstatic_fields);
-
-    if( compact_into_header || nonstatic_double_count > 0 ) {
-      int offset;
-      // Pack something in with the header if no super klass has done so.
-      if (compact_into_header) {
-        offset = oopDesc::klass_gap_offset_in_bytes();
-      } else {
-        offset = next_nonstatic_double_offset;
-      }
+    if( nonstatic_double_count > 0 ) {
+      int offset = next_nonstatic_double_offset;
       next_nonstatic_double_offset = align_size_up(offset, BytesPerLong);
       if( compact_fields && offset != next_nonstatic_double_offset ) {
         // Allocate available fields into the gap before double field.
@@ -2830,8 +2821,7 @@
         }
         // Allocate oop field in the gap if there are no other fields for that.
         nonstatic_oop_space_offset = offset;
-        if(!compact_into_header && length >= heapOopSize &&
-            nonstatic_oop_count > 0 &&
+        if( length >= heapOopSize && nonstatic_oop_count > 0 &&
             allocation_style != 0 ) { // when oop fields not first
           nonstatic_oop_count      -= 1;
           nonstatic_oop_space_count = 1; // Only one will fit
@@ -2854,14 +2844,13 @@
     } else { // allocation_style == 1
       next_nonstatic_oop_offset = next_nonstatic_byte_offset + nonstatic_byte_count;
       if( nonstatic_oop_count > 0 ) {
-        notaligned_offset = next_nonstatic_oop_offset;
         next_nonstatic_oop_offset = align_size_up(next_nonstatic_oop_offset, heapOopSize);
       }
       notaligned_offset = next_nonstatic_oop_offset + (nonstatic_oop_count * heapOopSize);
     }
-    next_nonstatic_type_offset = align_size_up(notaligned_offset, wordSize );
+    next_nonstatic_type_offset = align_size_up(notaligned_offset, heapOopSize );
     nonstatic_field_size = nonstatic_field_size + ((next_nonstatic_type_offset
-                                      - first_nonstatic_field_offset)/wordSize);
+                                   - first_nonstatic_field_offset)/heapOopSize);
 
     // Iterate over fields again and compute correct offsets.
     // The field allocation type was temporarily stored in the offset slot.
@@ -2962,9 +2951,10 @@
     // Size of instances
     int instance_size;
 
+    next_nonstatic_type_offset = align_size_up(notaligned_offset, wordSize );
     instance_size = align_object_size(next_nonstatic_type_offset / wordSize);
 
-    assert(instance_size == align_object_size(instanceOopDesc::header_size() + nonstatic_field_size), "consistent layout helper value");
+    assert(instance_size == align_object_size(align_size_up((instanceOopDesc::base_offset_in_bytes() + nonstatic_field_size*heapOopSize), wordSize) / wordSize), "consistent layout helper value");
 
     // Size of non-static oop map blocks (in words) allocated at end of klass
     int nonstatic_oop_map_size = compute_oop_map_size(super_klass, nonstatic_oop_map_count, first_nonstatic_oop_offset);
@@ -3122,13 +3112,15 @@
 #ifndef PRODUCT
     if( PrintCompactFieldsSavings ) {
       if( nonstatic_field_size < orig_nonstatic_field_size ) {
-        tty->print("[Saved %d of %3d words in %s]\n",
-                 orig_nonstatic_field_size - nonstatic_field_size,
-                 orig_nonstatic_field_size, this_klass->external_name());
+        tty->print("[Saved %d of %d bytes in %s]\n",
+                 (orig_nonstatic_field_size - nonstatic_field_size)*heapOopSize,
+                 orig_nonstatic_field_size*heapOopSize,
+                 this_klass->external_name());
       } else if( nonstatic_field_size > orig_nonstatic_field_size ) {
-        tty->print("[Wasted %d over %3d words in %s]\n",
-                 nonstatic_field_size - orig_nonstatic_field_size,
-                 orig_nonstatic_field_size, this_klass->external_name());
+        tty->print("[Wasted %d over %d bytes in %s]\n",
+                 (nonstatic_field_size - orig_nonstatic_field_size)*heapOopSize,
+                 orig_nonstatic_field_size*heapOopSize,
+                 this_klass->external_name());
       }
     }
 #endif
@@ -3516,9 +3508,11 @@
 }
 
 bool ClassFileParser::is_supported_version(u2 major, u2 minor) {
+  u2 max_version = JDK_Version::is_gte_jdk17x_version() ?
+    JAVA_MAX_SUPPORTED_VERSION : JAVA_6_VERSION;
   return (major >= JAVA_MIN_SUPPORTED_VERSION) &&
-         (major <= JAVA_MAX_SUPPORTED_VERSION) &&
-         ((major != JAVA_MAX_SUPPORTED_VERSION) ||
+         (major <= max_version) &&
+         ((major != max_version) ||
           (minor <= JAVA_MAX_SUPPORTED_MINOR_VERSION));
 }
 
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -1872,7 +1872,7 @@
       box->float_field_put(value_offset, value->f);
       break;
     case T_DOUBLE:
-      box->double_field_put(value_offset, value->d);
+      box->double_field_put(long_value_offset, value->d);
       break;
     case T_BYTE:
       box->byte_field_put(value_offset, value->b);
@@ -1884,7 +1884,7 @@
       box->int_field_put(value_offset, value->i);
       break;
     case T_LONG:
-      box->long_field_put(value_offset, value->j);
+      box->long_field_put(long_value_offset, value->j);
       break;
     default:
       return NULL;
@@ -1915,7 +1915,7 @@
     value->f = box->float_field(value_offset);
     break;
   case T_DOUBLE:
-    value->d = box->double_field(value_offset);
+    value->d = box->double_field(long_value_offset);
     break;
   case T_BYTE:
     value->b = box->byte_field(value_offset);
@@ -1927,7 +1927,7 @@
     value->i = box->int_field(value_offset);
     break;
   case T_LONG:
-    value->j = box->long_field(value_offset);
+    value->j = box->long_field(long_value_offset);
     break;
   default:
     return T_ILLEGAL;
@@ -1949,7 +1949,7 @@
     box->float_field_put(value_offset, value->f);
     break;
   case T_DOUBLE:
-    box->double_field_put(value_offset, value->d);
+    box->double_field_put(long_value_offset, value->d);
     break;
   case T_BYTE:
     box->byte_field_put(value_offset, value->b);
@@ -1961,7 +1961,7 @@
     box->int_field_put(value_offset, value->i);
     break;
   case T_LONG:
-    box->long_field_put(value_offset, value->j);
+    box->long_field_put(long_value_offset, value->j);
     break;
   default:
     return T_ILLEGAL;
@@ -2163,6 +2163,7 @@
 int java_lang_reflect_Field::signature_offset;
 int java_lang_reflect_Field::annotations_offset;
 int java_lang_boxing_object::value_offset;
+int java_lang_boxing_object::long_value_offset;
 int java_lang_ref_Reference::referent_offset;
 int java_lang_ref_Reference::queue_offset;
 int java_lang_ref_Reference::next_offset;
@@ -2282,10 +2283,7 @@
 // are not available to determine the offset_of_static_fields.
 void JavaClasses::compute_hard_coded_offsets() {
   const int x = heapOopSize;
-  // Objects don't get allocated in the gap in the header with compressed oops
-  // for these special classes because hard coded offsets can't be conditional
-  // so base_offset_in_bytes() is wrong here, allocate after the header.
-  const int header = sizeof(instanceOopDesc);
+  const int header = instanceOopDesc::base_offset_in_bytes();
 
   // Do the String Class
   java_lang_String::value_offset  = java_lang_String::hc_value_offset  * x + header;
@@ -2308,7 +2306,8 @@
   java_lang_Throwable::stackTrace_offset = java_lang_Throwable::hc_stackTrace_offset * x + header;
 
   // java_lang_boxing_object
-  java_lang_boxing_object::value_offset = java_lang_boxing_object::hc_value_offset * x + header;
+  java_lang_boxing_object::value_offset = java_lang_boxing_object::hc_value_offset + header;
+  java_lang_boxing_object::long_value_offset = align_size_up((java_lang_boxing_object::hc_value_offset + header), BytesPerLong);
 
   // java_lang_ref_Reference:
   java_lang_ref_Reference::referent_offset = java_lang_ref_Reference::hc_referent_offset * x + header;
@@ -2322,7 +2321,7 @@
   java_lang_ref_Reference::number_of_fake_oop_fields = 1;
 
   // java_lang_ref_SoftReference Class
-  java_lang_ref_SoftReference::timestamp_offset = java_lang_ref_SoftReference::hc_timestamp_offset * x + header;
+  java_lang_ref_SoftReference::timestamp_offset = align_size_up((java_lang_ref_SoftReference::hc_timestamp_offset * x + header), BytesPerLong);
   // Don't multiply static fields because they are always in wordSize units
   java_lang_ref_SoftReference::static_clock_offset = java_lang_ref_SoftReference::hc_static_clock_offset * x;
 
@@ -2469,6 +2468,9 @@
 #define CHECK_OFFSET(klass_name, cpp_klass_name, field_name, field_sig) \
   valid &= check_offset(klass_name, cpp_klass_name :: field_name ## _offset, #field_name, field_sig)
 
+#define CHECK_LONG_OFFSET(klass_name, cpp_klass_name, field_name, field_sig) \
+  valid &= check_offset(klass_name, cpp_klass_name :: long_ ## field_name ## _offset, #field_name, field_sig)
+
 #define CHECK_STATIC_OFFSET(klass_name, cpp_klass_name, field_name, field_sig) \
   valid &= check_static_offset(klass_name, cpp_klass_name :: static_ ## field_name ## _offset, #field_name, field_sig)
 
@@ -2501,11 +2503,11 @@
   CHECK_OFFSET("java/lang/Boolean",   java_lang_boxing_object, value, "Z");
   CHECK_OFFSET("java/lang/Character", java_lang_boxing_object, value, "C");
   CHECK_OFFSET("java/lang/Float",     java_lang_boxing_object, value, "F");
-  CHECK_OFFSET("java/lang/Double",    java_lang_boxing_object, value, "D");
+  CHECK_LONG_OFFSET("java/lang/Double", java_lang_boxing_object, value, "D");
   CHECK_OFFSET("java/lang/Byte",      java_lang_boxing_object, value, "B");
   CHECK_OFFSET("java/lang/Short",     java_lang_boxing_object, value, "S");
   CHECK_OFFSET("java/lang/Integer",   java_lang_boxing_object, value, "I");
-  CHECK_OFFSET("java/lang/Long",      java_lang_boxing_object, value, "J");
+  CHECK_LONG_OFFSET("java/lang/Long", java_lang_boxing_object, value, "J");
 
   // java.lang.ClassLoader
 
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/classfile/javaClasses.hpp	Wed Jul 05 16:37:51 2017 +0200
@@ -653,6 +653,7 @@
    hc_value_offset = 0
   };
   static int value_offset;
+  static int long_value_offset;
 
   static oop initialize_and_allocate(BasicType type, TRAPS);
  public:
@@ -665,7 +666,10 @@
   static bool is_instance(oop box)                 { return basic_type(box) != T_ILLEGAL; }
   static bool is_instance(oop box, BasicType type) { return basic_type(box) == type; }
 
-  static int value_offset_in_bytes() { return value_offset; }
+  static int value_offset_in_bytes(BasicType type) {
+    return ( type == T_LONG || type == T_DOUBLE ) ? long_value_offset :
+                                                    value_offset;
+  }
 
   // Debugging
   friend class JavaClasses;
@@ -747,7 +751,7 @@
  public:
   enum {
    // The timestamp is a long field and may need to be adjusted for alignment.
-   hc_timestamp_offset    = align_object_offset_(hc_discovered_offset + 1)
+   hc_timestamp_offset  = hc_discovered_offset + 1
   };
   enum {
    hc_static_clock_offset = 0
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp	Wed Jul 05 16:37:51 2017 +0200
@@ -283,6 +283,7 @@
   template(cache_field_name,                          "cache")                                    \
   template(value_name,                                "value")                                    \
   template(frontCacheEnabled_name,                    "frontCacheEnabled")                        \
+  template(stringCacheEnabled_name,                   "stringCacheEnabled")                       \
                                                                                                   \
   /* non-intrinsic name/signature pairs: */                                                       \
   template(register_method_name,                      "register")                                 \
@@ -564,6 +565,10 @@
    do_name(     copyOfRange_name,                                "copyOfRange")                                         \
    do_signature(copyOfRange_signature,        "([Ljava/lang/Object;IILjava/lang/Class;)[Ljava/lang/Object;")            \
                                                                                                                         \
+  do_intrinsic(_equalsC,                  java_util_Arrays,       equals_name,    equalsC_signature,             F_S)   \
+   do_name(     equals_name,                                     "equals")                                              \
+   do_signature(equalsC_signature,                               "([C[C)Z")                                             \
+                                                                                                                        \
   do_intrinsic(_invoke,                   java_lang_reflect_Method, invoke_name, object_array_object_object_signature, F_R) \
   /*   (symbols invoke_name and invoke_signature defined above) */                                                      \
                                                                                                                         \
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.hpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.hpp	Wed Jul 05 16:37:51 2017 +0200
@@ -130,6 +130,7 @@
 const size_t MIN_TREE_CHUNK_SIZE  = sizeof(TreeChunk)/HeapWordSize;
 
 class BinaryTreeDictionary: public FreeBlockDictionary {
+  friend class VMStructs;
   bool       _splay;
   size_t     _totalSize;
   size_t     _totalFreeBlocks;
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -805,28 +805,30 @@
   // This must be volatile, or else there is a danger that the compiler
   // will compile the code below into a sometimes-infinite loop, by keeping
   // the value read the first time in a register.
-  oop o = (oop)p;
-  volatile oop* second_word_addr = o->klass_addr();
   while (true) {
-    klassOop k = (klassOop)(*second_word_addr);
     // We must do this until we get a consistent view of the object.
-    if (FreeChunk::secondWordIndicatesFreeChunk((intptr_t)k)) {
-      FreeChunk* fc = (FreeChunk*)p;
-      volatile size_t* sz_addr = (volatile size_t*)(fc->size_addr());
-      size_t res = (*sz_addr);
-      klassOop k2 = (klassOop)(*second_word_addr);  // Read to confirm.
-      if (k == k2) {
+    if (FreeChunk::indicatesFreeChunk(p)) {
+      volatile FreeChunk* fc = (volatile FreeChunk*)p;
+      size_t res = fc->size();
+      // If the object is still a free chunk, return the size, else it
+      // has been allocated so try again.
+      if (FreeChunk::indicatesFreeChunk(p)) {
         assert(res != 0, "Block size should not be 0");
         return res;
       }
-    } else if (k != NULL) {
-      assert(k->is_oop(true /* ignore mark word */), "Should really be klass oop.");
-      assert(o->is_parsable(), "Should be parsable");
-      assert(o->is_oop(true /* ignore mark word */), "Should be an oop.");
-      size_t res = o->size_given_klass(k->klass_part());
-      res = adjustObjectSize(res);
-      assert(res != 0, "Block size should not be 0");
-      return res;
+    } else {
+      // must read from what 'p' points to in each loop.
+      klassOop k = ((volatile oopDesc*)p)->klass_or_null();
+      if (k != NULL) {
+        assert(k->is_oop(true /* ignore mark word */), "Should really be klass oop.");
+        oop o = (oop)p;
+        assert(o->is_parsable(), "Should be parsable");
+        assert(o->is_oop(true /* ignore mark word */), "Should be an oop.");
+        size_t res = o->size_given_klass(k->klass_part());
+        res = adjustObjectSize(res);
+        assert(res != 0, "Block size should not be 0");
+        return res;
+      }
     }
   }
 }
@@ -845,31 +847,31 @@
   // This must be volatile, or else there is a danger that the compiler
   // will compile the code below into a sometimes-infinite loop, by keeping
   // the value read the first time in a register.
-  oop o = (oop)p;
-  volatile oop* second_word_addr = o->klass_addr();
   DEBUG_ONLY(uint loops = 0;)
   while (true) {
-    klassOop k = (klassOop)(*second_word_addr);
     // We must do this until we get a consistent view of the object.
-    if (FreeChunk::secondWordIndicatesFreeChunk((intptr_t)k)) {
-      FreeChunk* fc = (FreeChunk*)p;
-      volatile size_t* sz_addr = (volatile size_t*)(fc->size_addr());
-      size_t res = (*sz_addr);
-      klassOop k2 = (klassOop)(*second_word_addr);  // Read to confirm.
-      if (k == k2) {
+    if (FreeChunk::indicatesFreeChunk(p)) {
+      volatile FreeChunk* fc = (volatile FreeChunk*)p;
+      size_t res = fc->size();
+      if (FreeChunk::indicatesFreeChunk(p)) {
         assert(res != 0, "Block size should not be 0");
         assert(loops == 0, "Should be 0");
         return res;
       }
-    } else if (k != NULL && o->is_parsable()) {
-      assert(k->is_oop(), "Should really be klass oop.");
-      assert(o->is_oop(), "Should be an oop");
-      size_t res = o->size_given_klass(k->klass_part());
-      res = adjustObjectSize(res);
-      assert(res != 0, "Block size should not be 0");
-      return res;
     } else {
-      return c->block_size_if_printezis_bits(p);
+      // must read from what 'p' points to in each loop.
+      klassOop k = ((volatile oopDesc*)p)->klass_or_null();
+      if (k != NULL && ((oopDesc*)p)->is_parsable()) {
+        assert(k->is_oop(), "Should really be klass oop.");
+        oop o = (oop)p;
+        assert(o->is_oop(), "Should be an oop");
+        size_t res = o->size_given_klass(k->klass_part());
+        res = adjustObjectSize(res);
+        assert(res != 0, "Block size should not be 0");
+        return res;
+      } else {
+        return c->block_size_if_printezis_bits(p);
+      }
     }
     assert(loops == 0, "Can loop at most once");
     DEBUG_ONLY(loops++;)
@@ -907,9 +909,8 @@
   // and those objects (if garbage) may have been modified to hold
   // live range information.
   // assert(ParallelGCThreads > 0 || _bt.block_start(p) == p, "Should be a block boundary");
-  klassOop k = oop(p)->klass();
-  intptr_t ki = (intptr_t)k;
-  if (FreeChunk::secondWordIndicatesFreeChunk(ki)) return false;
+  if (FreeChunk::indicatesFreeChunk(p)) return false;
+  klassOop k = oop(p)->klass_or_null();
   if (k != NULL) {
     // Ignore mark word because it may have been used to
     // chain together promoted objects (the last one
@@ -1027,7 +1028,7 @@
     FreeChunk* fc = (FreeChunk*)res;
     fc->markNotFree();
     assert(!fc->isFree(), "shouldn't be marked free");
-    assert(oop(fc)->klass() == NULL, "should look uninitialized");
+    assert(oop(fc)->klass_or_null() == NULL, "should look uninitialized");
     // Verify that the block offset table shows this to
     // be a single block, but not one which is unallocated.
     _bt.verify_single_block(res, size);
@@ -2593,7 +2594,7 @@
   }
   res->markNotFree();
   assert(!res->isFree(), "shouldn't be marked free");
-  assert(oop(res)->klass() == NULL, "should look uninitialized");
+  assert(oop(res)->klass_or_null() == NULL, "should look uninitialized");
   // mangle a just allocated object with a distinct pattern.
   debug_only(res->mangleAllocated(word_sz));
   return (HeapWord*)res;
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -190,7 +190,8 @@
   // depends on this property.
   debug_only(
     FreeChunk* junk = NULL;
-    assert(junk->prev_addr() == (void*)(oop(junk)->klass_addr()),
+    assert(UseCompressedOops ||
+           junk->prev_addr() == (void*)(oop(junk)->klass_addr()),
            "Offset of FreeChunk::_prev within FreeChunk must match"
            "  that of OopDesc::_klass within OopDesc");
   )
@@ -1039,7 +1040,7 @@
                                       // mark end of object
   }
   // check that oop looks uninitialized
-  assert(oop(start)->klass() == NULL, "_klass should be NULL");
+  assert(oop(start)->klass_or_null() == NULL, "_klass should be NULL");
 }
 
 void CMSCollector::promoted(bool par, HeapWord* start,
@@ -1309,17 +1310,25 @@
      }
   }
   oop obj = oop(obj_ptr);
-  assert(obj->klass() == NULL, "Object should be uninitialized here.");
+  assert(obj->klass_or_null() == NULL, "Object should be uninitialized here.");
   // Otherwise, copy the object.  Here we must be careful to insert the
   // klass pointer last, since this marks the block as an allocated object.
+  // Except with compressed oops it's the mark word.
   HeapWord* old_ptr = (HeapWord*)old;
   if (word_sz > (size_t)oopDesc::header_size()) {
     Copy::aligned_disjoint_words(old_ptr + oopDesc::header_size(),
                                  obj_ptr + oopDesc::header_size(),
                                  word_sz - oopDesc::header_size());
   }
+
+  if (UseCompressedOops) {
+    // Copy gap missed by (aligned) header size calculation above
+    obj->set_klass_gap(old->klass_gap());
+  }
+
   // Restore the mark word copied above.
   obj->set_mark(m);
+
   // Now we can track the promoted object, if necessary.  We take care
   // To delay the transition from uninitialized to full object
   // (i.e., insertion of klass pointer) until after, so that it
@@ -1327,7 +1336,8 @@
   if (promoInfo->tracking()) {
     promoInfo->track((PromotedObject*)obj, old->klass());
   }
-  // Finally, install the klass pointer.
+
+  // Finally, install the klass pointer (this should be volatile).
   obj->set_klass(old->klass());
 
   assert(old->is_oop(), "Will dereference klass ptr below");
@@ -6165,7 +6175,7 @@
 HeapWord* CMSCollector::next_card_start_after_block(HeapWord* addr) const {
   size_t sz = 0;
   oop p = (oop)addr;
-  if (p->klass() != NULL && p->is_parsable()) {
+  if (p->klass_or_null() != NULL && p->is_parsable()) {
     sz = CompactibleFreeListSpace::adjustObjectSize(p->size());
   } else {
     sz = block_size_using_printezis_bits(addr);
@@ -6602,7 +6612,7 @@
   }
   if (_bitMap->isMarked(addr)) {
     // it's marked; is it potentially uninitialized?
-    if (p->klass() != NULL) {
+    if (p->klass_or_null() != NULL) {
       if (CMSPermGenPrecleaningEnabled && !p->is_parsable()) {
         // Signal precleaning to redirty the card since
         // the klass pointer is already installed.
@@ -6615,11 +6625,8 @@
         if (p->is_objArray()) {
           // objArrays are precisely marked; restrict scanning
           // to dirty cards only.
-          size = p->oop_iterate(_scanningClosure, mr);
-          assert(size == CompactibleFreeListSpace::adjustObjectSize(size),
-                 "adjustObjectSize should be the identity for array sizes, "
-                 "which are necessarily larger than minimum object size of "
-                 "two heap words");
+          size = CompactibleFreeListSpace::adjustObjectSize(
+                   p->oop_iterate(_scanningClosure, mr));
         } else {
           // A non-array may have been imprecisely marked; we need
           // to scan object in its entirety.
@@ -6653,7 +6660,7 @@
     }
   } else {
     // Either a not yet marked object or an uninitialized object
-    if (p->klass() == NULL || !p->is_parsable()) {
+    if (p->klass_or_null() == NULL || !p->is_parsable()) {
       // An uninitialized object, skip to the next card, since
       // we may not be able to read its P-bits yet.
       assert(size == 0, "Initial value");
@@ -6710,7 +6717,7 @@
   HeapWord* addr = (HeapWord*)p;
   DEBUG_ONLY(_collector->verify_work_stacks_empty();)
   assert(!_span.contains(addr), "we are scanning the survivor spaces");
-  assert(p->klass() != NULL, "object should be initializd");
+  assert(p->klass_or_null() != NULL, "object should be initializd");
   assert(p->is_parsable(), "must be parsable.");
   // an initialized object; ignore mark word in verification below
   // since we are running concurrent with mutators
@@ -6868,7 +6875,7 @@
     assert(_skipBits == 0, "tautology");
     _skipBits = 2;  // skip next two marked bits ("Printezis-marks")
     oop p = oop(addr);
-    if (p->klass() == NULL || !p->is_parsable()) {
+    if (p->klass_or_null() == NULL || !p->is_parsable()) {
       DEBUG_ONLY(if (!_verifying) {)
         // We re-dirty the cards on which this object lies and increase
         // the _threshold so that we'll come back to scan this object
@@ -6890,7 +6897,7 @@
           if (_threshold < end_card_addr) {
             _threshold = end_card_addr;
           }
-          if (p->klass() != NULL) {
+          if (p->klass_or_null() != NULL) {
             // Redirty the range of cards...
             _mut->mark_range(redirty_range);
           } // ...else the setting of klass will dirty the card anyway.
@@ -7048,7 +7055,7 @@
     assert(_skip_bits == 0, "tautology");
     _skip_bits = 2;  // skip next two marked bits ("Printezis-marks")
     oop p = oop(addr);
-    if (p->klass() == NULL || !p->is_parsable()) {
+    if (p->klass_or_null() == NULL || !p->is_parsable()) {
       // in the case of Clean-on-Enter optimization, redirty card
       // and avoid clearing card by increasing  the threshold.
       return;
@@ -8023,7 +8030,7 @@
            "alignment problem");
 
     #ifdef DEBUG
-      if (oop(addr)->klass() != NULL &&
+      if (oop(addr)->klass_or_null() != NULL &&
           (   !_collector->should_unload_classes()
            || oop(addr)->is_parsable())) {
         // Ignore mark word because we are running concurrent with mutators
@@ -8036,7 +8043,7 @@
 
   } else {
     // This should be an initialized object that's alive.
-    assert(oop(addr)->klass() != NULL &&
+    assert(oop(addr)->klass_or_null() != NULL &&
            (!_collector->should_unload_classes()
             || oop(addr)->is_parsable()),
            "Should be an initialized object");
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.hpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.hpp	Wed Jul 05 16:37:51 2017 +0200
@@ -22,88 +22,6 @@
  *
  */
 
-//
-// Free block maintenance for Concurrent Mark Sweep Generation
-//
-// The main data structure for free blocks are
-// . an indexed array of small free blocks, and
-// . a dictionary of large free blocks
-//
-
-// No virtuals in FreeChunk (don't want any vtables).
-
-// A FreeChunk is merely a chunk that can be in a doubly linked list
-// and has a size field. NOTE: FreeChunks are distinguished from allocated
-// objects in two ways (by the sweeper). The second word (prev) has the
-// LSB set to indicate a free chunk; allocated objects' klass() pointers
-// don't have their LSB set. The corresponding bit in the CMSBitMap is
-// set when the chunk is allocated. There are also blocks that "look free"
-// but are not part of the free list and should not be coalesced into larger
-// free blocks. These free blocks have their two LSB's set.
-
-class FreeChunk VALUE_OBJ_CLASS_SPEC {
-  friend class VMStructs;
-  FreeChunk* _next;
-  FreeChunk* _prev;
-  size_t     _size;
-
- public:
-  NOT_PRODUCT(static const size_t header_size();)
-  // Returns "true" if the "wrd", which is required to be the second word
-  // of a block, indicates that the block represents a free chunk.
-  static bool secondWordIndicatesFreeChunk(intptr_t wrd) {
-    return (wrd & 0x1) == 0x1;
-  }
-  bool isFree()       const {
-    return secondWordIndicatesFreeChunk((intptr_t)_prev);
-  }
-  bool cantCoalesce() const { return (((intptr_t)_prev) & 0x3) == 0x3; }
-  FreeChunk* next()   const { return _next; }
-  FreeChunk* prev()   const { return (FreeChunk*)(((intptr_t)_prev) & ~(0x3)); }
-  debug_only(void* prev_addr() const { return (void*)&_prev; })
-
-  void linkAfter(FreeChunk* ptr) {
-    linkNext(ptr);
-    if (ptr != NULL) ptr->linkPrev(this);
-  }
-  void linkAfterNonNull(FreeChunk* ptr) {
-    assert(ptr != NULL, "precondition violation");
-    linkNext(ptr);
-    ptr->linkPrev(this);
-  }
-  void linkNext(FreeChunk* ptr) { _next = ptr; }
-  void linkPrev(FreeChunk* ptr) { _prev = (FreeChunk*)((intptr_t)ptr | 0x1); }
-  void clearPrev()              { _prev = NULL; }
-  void clearNext()              { _next = NULL; }
-  void dontCoalesce()      {
-    // the block should be free
-    assert(isFree(), "Should look like a free block");
-    _prev = (FreeChunk*)(((intptr_t)_prev) | 0x2);
-  }
-  void markFree()    { _prev = (FreeChunk*)((intptr_t)_prev | 0x1);    }
-  void markNotFree() { _prev = NULL; }
-
-  size_t size()           const { return _size; }
-  void setSize(size_t size)     { _size = size; }
-
-  // For volatile reads:
-  size_t* size_addr()           { return &_size; }
-
-  // Return the address past the end of this chunk
-  HeapWord* end() const { return ((HeapWord*) this) + _size; }
-
-  // debugging
-  void verify()             const PRODUCT_RETURN;
-  void verifyList()         const PRODUCT_RETURN;
-  void mangleAllocated(size_t size) PRODUCT_RETURN;
-  void mangleFreed(size_t size)     PRODUCT_RETURN;
-};
-
-// Alignment helpers etc.
-#define numQuanta(x,y) ((x+y-1)/y)
-enum AlignmentConstants {
-  MinChunkSize = numQuanta(sizeof(FreeChunk), MinObjAlignmentInBytes) * MinObjAlignment
-};
 
 // A FreeBlockDictionary is an abstract superclass that will allow
 // a number of alternative implementations in the future.
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -47,15 +47,15 @@
   Copy::fill_to_words(addr + hdr, size - hdr, baadbabeHeapWord);
 }
 
-void FreeChunk::mangleFreed(size_t size) {
+void FreeChunk::mangleFreed(size_t sz) {
   assert(baadbabeHeapWord != deadbeefHeapWord, "Need distinct patterns");
   // mangle all but the header of a just-freed block of storage
   // just prior to passing it to the storage dictionary
-  assert(size >= MinChunkSize, "smallest size of object");
-  assert(size == _size, "just checking");
+  assert(sz >= MinChunkSize, "smallest size of object");
+  assert(sz == size(), "just checking");
   HeapWord* addr = (HeapWord*)this;
   size_t hdr = header_size();
-  Copy::fill_to_words(addr + hdr, size - hdr, deadbeefHeapWord);
+  Copy::fill_to_words(addr + hdr, sz - hdr, deadbeefHeapWord);
 }
 
 void FreeChunk::verifyList() const {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.hpp	Wed Jul 05 16:37:51 2017 +0200
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2001-2005 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+//
+// Free block maintenance for Concurrent Mark Sweep Generation
+//
+// The main data structure for free blocks are
+// . an indexed array of small free blocks, and
+// . a dictionary of large free blocks
+//
+
+// No virtuals in FreeChunk (don't want any vtables).
+
+// A FreeChunk is merely a chunk that can be in a doubly linked list
+// and has a size field. NOTE: FreeChunks are distinguished from allocated
+// objects in two ways (by the sweeper), depending on whether the VM is 32 or
+// 64 bits.
+// In 32 bits or 64 bits without CompressedOops, the second word (prev) has the
+// LSB set to indicate a free chunk; allocated objects' klass() pointers
+// don't have their LSB set. The corresponding bit in the CMSBitMap is
+// set when the chunk is allocated. There are also blocks that "look free"
+// but are not part of the free list and should not be coalesced into larger
+// free blocks. These free blocks have their two LSB's set.
+
+class FreeChunk VALUE_OBJ_CLASS_SPEC {
+  friend class VMStructs;
+  // For 64 bit compressed oops, the markOop encodes both the size and the
+  // indication that this is a FreeChunk and not an object.
+  volatile size_t   _size;
+  FreeChunk* _prev;
+  FreeChunk* _next;
+
+  markOop mark()     const volatile { return (markOop)_size; }
+  void set_mark(markOop m)          { _size = (size_t)m; }
+
+ public:
+  NOT_PRODUCT(static const size_t header_size();)
+
+  // Returns "true" if the address indicates that the block represents
+  // a free chunk.
+  static bool indicatesFreeChunk(const HeapWord* addr) {
+    // Force volatile read from addr because value might change between
+    // calls.  We really want the read of _mark and _prev from this pointer
+    // to be volatile but making the fields volatile causes all sorts of
+    // compilation errors.
+    return ((volatile FreeChunk*)addr)->isFree();
+  }
+
+  bool isFree() const volatile {
+    LP64_ONLY(if (UseCompressedOops) return mark()->is_cms_free_chunk(); else)
+    return (((intptr_t)_prev) & 0x1) == 0x1;
+  }
+  bool cantCoalesce() const {
+    assert(isFree(), "can't get coalesce bit on not free");
+    return (((intptr_t)_prev) & 0x2) == 0x2;
+  }
+  void dontCoalesce() {
+    // the block should be free
+    assert(isFree(), "Should look like a free block");
+    _prev = (FreeChunk*)(((intptr_t)_prev) | 0x2);
+  }
+  FreeChunk* prev() const {
+    return (FreeChunk*)(((intptr_t)_prev) & ~(0x3));
+  }
+
+  debug_only(void* prev_addr() const { return (void*)&_prev; })
+
+  size_t size() const volatile {
+    LP64_ONLY(if (UseCompressedOops) return mark()->get_size(); else )
+    return _size;
+  }
+  void setSize(size_t sz) {
+    LP64_ONLY(if (UseCompressedOops) set_mark(markOopDesc::set_size_and_free(sz)); else )
+    _size = sz;
+  }
+
+  FreeChunk* next()   const { return _next; }
+
+  void linkAfter(FreeChunk* ptr) {
+    linkNext(ptr);
+    if (ptr != NULL) ptr->linkPrev(this);
+  }
+  void linkAfterNonNull(FreeChunk* ptr) {
+    assert(ptr != NULL, "precondition violation");
+    linkNext(ptr);
+    ptr->linkPrev(this);
+  }
+  void linkNext(FreeChunk* ptr) { _next = ptr; }
+  void linkPrev(FreeChunk* ptr) {
+     LP64_ONLY(if (UseCompressedOops) _prev = ptr; else)
+     _prev = (FreeChunk*)((intptr_t)ptr | 0x1);
+  }
+  void clearPrev()              { _prev = NULL; }
+  void clearNext()              { _next = NULL; }
+  void markNotFree() {
+   LP64_ONLY(if (UseCompressedOops) set_mark(markOopDesc::prototype());)
+   // Also set _prev to null
+   _prev = NULL;
+  }
+
+  // Return the address past the end of this chunk
+  HeapWord* end() const { return ((HeapWord*) this) + size(); }
+
+  // debugging
+  void verify()             const PRODUCT_RETURN;
+  void verifyList()         const PRODUCT_RETURN;
+  void mangleAllocated(size_t size) PRODUCT_RETURN;
+  void mangleFreed(size_t size)     PRODUCT_RETURN;
+};
+
+// Alignment helpers etc.
+#define numQuanta(x,y) ((x+y-1)/y)
+enum AlignmentConstants {
+  MinChunkSize = numQuanta(sizeof(FreeChunk), MinObjAlignmentInBytes) * MinObjAlignment
+};
+
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.hpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.hpp	Wed Jul 05 16:37:51 2017 +0200
@@ -38,6 +38,7 @@
 
 class FreeList VALUE_OBJ_CLASS_SPEC {
   friend class CompactibleFreeListSpace;
+  friend class VMStructs;
   friend class printTreeCensusClosure;
   FreeChunk*    _head;          // List of free chunks
   FreeChunk*    _tail;          // Tail of list of free chunks
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp	Wed Jul 05 16:37:51 2017 +0200
@@ -23,6 +23,7 @@
  */
 
 #define VM_STRUCTS_CMS(nonstatic_field, \
+                   volatile_nonstatic_field, \
                    static_field) \
   nonstatic_field(CompactibleFreeListSpace,    _collector,                                    CMSCollector*)                         \
   nonstatic_field(CompactibleFreeListSpace,    _bt,                                           BlockOffsetArrayNonContigSpace)        \
@@ -36,9 +37,17 @@
   nonstatic_field(CMSCollector,                _markBitMap,                                   CMSBitMap)                             \
   nonstatic_field(ConcurrentMarkSweepGeneration, _cmsSpace,                                   CompactibleFreeListSpace*)             \
      static_field(ConcurrentMarkSweepThread,   _collector,                                    CMSCollector*)                         \
+  volatile_nonstatic_field(FreeChunk,          _size,                                         size_t)                                \
   nonstatic_field(FreeChunk,                   _next,                                         FreeChunk*)                            \
   nonstatic_field(FreeChunk,                   _prev,                                         FreeChunk*)                            \
-  nonstatic_field(FreeChunk,                   _size,                                         size_t)
+  nonstatic_field(LinearAllocBlock,            _word_size,                                    size_t)                                \
+  nonstatic_field(FreeList,                    _size,                                         size_t)                                \
+  nonstatic_field(FreeList,                    _count,                                        ssize_t)                               \
+  nonstatic_field(BinaryTreeDictionary,        _totalSize,                                    size_t)                                \
+  nonstatic_field(CompactibleFreeListSpace,    _dictionary,                                   FreeBlockDictionary*)                  \
+  nonstatic_field(CompactibleFreeListSpace,    _indexedFreeList[0],                           FreeList)                              \
+  nonstatic_field(CompactibleFreeListSpace,    _smallLinearAllocBlock,                        LinearAllocBlock)
+
 
 #define VM_TYPES_CMS(declare_type,                                        \
                      declare_toplevel_type)                               \
@@ -57,7 +66,14 @@
   declare_toplevel_type(SurrogateLockerThread*)                           \
   declare_toplevel_type(CompactibleFreeListSpace*)                        \
   declare_toplevel_type(CMSCollector*)                                    \
-  declare_toplevel_type(FreeChunk*)
+  declare_toplevel_type(FreeChunk*)                                       \
+  declare_toplevel_type(BinaryTreeDictionary*)                            \
+  declare_toplevel_type(FreeBlockDictionary*)                             \
+  declare_toplevel_type(FreeList*)                                        \
+  declare_toplevel_type(FreeList)                                         \
+  declare_toplevel_type(LinearAllocBlock)                                 \
+  declare_toplevel_type(FreeBlockDictionary)                              \
+            declare_type(BinaryTreeDictionary,        FreeBlockDictionary)
 
 #define VM_INT_CONSTANTS_CMS(declare_constant)                            \
   declare_constant(Generation::ConcurrentMarkSweep)                       \
--- a/hotspot/src/share/vm/gc_implementation/includeDB_gc_concurrentMarkSweep	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/includeDB_gc_concurrentMarkSweep	Wed Jul 05 16:37:51 2017 +0200
@@ -206,6 +206,7 @@
 
 freeBlockDictionary.hpp                 allocation.hpp
 freeBlockDictionary.hpp                 debug.hpp
+freeBlockDictionary.hpp                 freeChunk.hpp
 freeBlockDictionary.hpp                 globalDefinitions.hpp
 freeBlockDictionary.hpp                 memRegion.hpp
 freeBlockDictionary.hpp                 mutex.hpp
@@ -214,6 +215,14 @@
 freeChunk.cpp                           copy.hpp
 freeChunk.cpp                           freeBlockDictionary.hpp
 
+freeChunk.hpp                           allocation.hpp
+freeChunk.hpp                           debug.hpp
+freeChunk.hpp                           globalDefinitions.hpp
+freeChunk.hpp                           markOop.hpp
+freeChunk.hpp                           memRegion.hpp
+freeChunk.hpp                           mutex.hpp
+freeChunk.hpp                           ostream.hpp
+
 freeList.cpp                            freeBlockDictionary.hpp
 freeList.cpp                            freeList.hpp
 freeList.cpp                            globals.hpp
--- a/hotspot/src/share/vm/gc_implementation/includeDB_gc_shared	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/includeDB_gc_shared	Wed Jul 05 16:37:51 2017 +0200
@@ -54,6 +54,7 @@
 markSweep.inline.hpp                    psParallelCompact.hpp
 
 mutableNUMASpace.cpp                    mutableNUMASpace.hpp
+mutableNUMASpace.cpp                    oop.inline.hpp
 mutableNUMASpace.cpp                    sharedHeap.hpp
 mutableNUMASpace.cpp                    thread_<os_family>.inline.hpp
 
--- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -1169,18 +1169,18 @@
   // Trim off a prefix of at most objsFromOverflow items
   int i = 1;
   oop cur = prefix;
-  while (i < objsFromOverflow && cur->klass() != NULL) {
+  while (i < objsFromOverflow && cur->klass_or_null() != NULL) {
     i++; cur = oop(cur->klass());
   }
 
   // Reattach remaining (suffix) to overflow list
-  if (cur->klass() != NULL) {
+  if (cur->klass_or_null() != NULL) {
     oop suffix = oop(cur->klass());
     cur->set_klass_to_list_ptr(NULL);
 
     // Find last item of suffix list
     oop last = suffix;
-    while (last->klass() != NULL) {
+    while (last->klass_or_null() != NULL) {
       last = oop(last->klass());
     }
     // Atomically prepend suffix to current overflow list
--- a/hotspot/src/share/vm/gc_implementation/shared/immutableSpace.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/shared/immutableSpace.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -66,7 +66,7 @@
 
 #endif
 
-void ImmutableSpace::verify(bool allow_dirty) const {
+void ImmutableSpace::verify(bool allow_dirty) {
   HeapWord* p = bottom();
   HeapWord* t = end();
   HeapWord* prev_p = NULL;
--- a/hotspot/src/share/vm/gc_implementation/shared/immutableSpace.hpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/shared/immutableSpace.hpp	Wed Jul 05 16:37:51 2017 +0200
@@ -59,5 +59,5 @@
   // Debugging
   virtual void print() const            PRODUCT_RETURN;
   virtual void print_short() const      PRODUCT_RETURN;
-  virtual void verify(bool allow_dirty) const;
+  virtual void verify(bool allow_dirty);
 };
--- a/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -599,12 +599,28 @@
 // Mark the the holes in chunks below the top() as invalid.
 void MutableNUMASpace::set_top(HeapWord* value) {
   bool found_top = false;
-  for (int i = 0; i < lgrp_spaces()->length(); i++) {
+  for (int i = 0; i < lgrp_spaces()->length();) {
     LGRPSpace *ls = lgrp_spaces()->at(i);
     MutableSpace *s = ls->space();
     HeapWord *top = MAX2((HeapWord*)round_down((intptr_t)s->top(), page_size()), s->bottom());
 
     if (s->contains(value)) {
+      // Check if setting the chunk's top to a given value would create a hole less than
+      // a minimal object; assuming that's not the last chunk in which case we don't care.
+      if (i < lgrp_spaces()->length() - 1) {
+        size_t remainder = pointer_delta(s->end(), value);
+        const size_t minimal_object_size = oopDesc::header_size();
+        if (remainder < minimal_object_size && remainder > 0) {
+          // Add a filler object of a minimal size, it will cross the chunk boundary.
+          SharedHeap::fill_region_with_object(MemRegion(value, minimal_object_size));
+          value += minimal_object_size;
+          assert(!s->contains(value), "Should be in the next chunk");
+          // Restart the loop from the same chunk, since the value has moved
+          // to the next one.
+          continue;
+        }
+      }
+
       if (!os::numa_has_static_binding() && top < value && top < s->end()) {
         ls->add_invalid_region(MemRegion(top, value));
       }
@@ -620,6 +636,7 @@
           s->set_top(s->end());
         }
     }
+    i++;
   }
   MutableSpace::set_top(value);
 }
@@ -700,12 +717,14 @@
   MutableSpace *s = lgrp_spaces()->at(i)->space();
   HeapWord *p = s->cas_allocate(size);
   if (p != NULL) {
-    size_t remainder = pointer_delta(s->end(), p);
+    size_t remainder = pointer_delta(s->end(), p + size);
     if (remainder < (size_t)oopDesc::header_size() && remainder > 0) {
       if (s->cas_deallocate(p, size)) {
         // We were the last to allocate and created a fragment less than
         // a minimal object.
         p = NULL;
+      } else {
+        guarantee(false, "Deallocation should always succeed");
       }
     }
   }
@@ -761,10 +780,12 @@
   }
 }
 
-void MutableNUMASpace::verify(bool allow_dirty) const {
- for (int i = 0; i < lgrp_spaces()->length(); i++) {
-    lgrp_spaces()->at(i)->space()->verify(allow_dirty);
-  }
+void MutableNUMASpace::verify(bool allow_dirty) {
+  // This can be called after setting an arbitary value to the space's top,
+  // so an object can cross the chunk boundary. We ensure the parsablity
+  // of the space and just walk the objects in linear fashion.
+  ensure_parsability();
+  MutableSpace::verify(allow_dirty);
 }
 
 // Scan pages and gather stats about page placement and size.
--- a/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp	Wed Jul 05 16:37:51 2017 +0200
@@ -192,7 +192,7 @@
   // Debugging
   virtual void print_on(outputStream* st) const;
   virtual void print_short_on(outputStream* st) const;
-  virtual void verify(bool allow_dirty) const;
+  virtual void verify(bool allow_dirty);
 
   virtual void set_top(HeapWord* value);
 };
--- a/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -118,7 +118,7 @@
                  bottom(), top(), end());
 }
 
-void MutableSpace::verify(bool allow_dirty) const {
+void MutableSpace::verify(bool allow_dirty) {
   HeapWord* p = bottom();
   HeapWord* t = top();
   HeapWord* prev_p = NULL;
--- a/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.hpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.hpp	Wed Jul 05 16:37:51 2017 +0200
@@ -98,5 +98,5 @@
   virtual void print_on(outputStream* st) const;
   virtual void print_short() const;
   virtual void print_short_on(outputStream* st) const;
-  virtual void verify(bool allow_dirty) const;
+  virtual void verify(bool allow_dirty);
 };
--- a/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp	Wed Jul 05 16:37:51 2017 +0200
@@ -90,11 +90,12 @@
                                                 HeapWord* obj,
                                                 size_t size,
                                                 int length) {
+  // Set array length before setting the _klass field
+  // in post_allocation_setup_common() because the klass field
+  // indicates that the object is parsable by concurrent GC.
   assert(length >= 0, "length should be non-negative");
+  ((arrayOop)obj)->set_length(length);
   post_allocation_setup_common(klass, obj, size);
-  // Must set length after installing klass as set_klass zeros the length
-  // field in UseCompressedOops
-  ((arrayOop)obj)->set_length(length);
   assert(((oop)obj)->blueprint()->oop_is_array(), "must be an array");
   // notify jvmti and dtrace (must be after length is set for dtrace)
   post_allocation_notify(klass, (oop)obj);
@@ -224,6 +225,7 @@
   assert(obj != NULL, "cannot initialize NULL object");
   const size_t hs = oopDesc::header_size();
   assert(size >= hs, "unexpected object size");
+  ((oop)obj)->set_klass_gap(0);
   Copy::fill_to_aligned_words(obj + hs, size - hs);
 }
 
--- a/hotspot/src/share/vm/includeDB_core	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/includeDB_core	Wed Jul 05 16:37:51 2017 +0200
@@ -3492,6 +3492,7 @@
 relocInfo_<arch>.cpp                    assembler.inline.hpp
 relocInfo_<arch>.cpp                    assembler_<arch_model>.inline.hpp
 relocInfo_<arch>.cpp                    nativeInst_<arch>.hpp
+relocInfo_<arch>.cpp                    oop.inline.hpp
 relocInfo_<arch>.cpp                    relocInfo.hpp
 relocInfo_<arch>.cpp                    safepoint.hpp
 
--- a/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -1931,6 +1931,7 @@
               } else {
                 result->set_mark(markOopDesc::prototype());
               }
+              result->set_klass_gap(0);
               result->set_klass(k_entry);
               SET_STACK_OBJECT(result, 0);
               UPDATE_PC_AND_TOS_AND_CONTINUE(3, 1);
--- a/hotspot/src/share/vm/interpreter/bytecodeInterpreterWithChecks.xml	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/interpreter/bytecodeInterpreterWithChecks.xml	Wed Jul 05 16:37:51 2017 +0200
@@ -1,7 +1,25 @@
 <?xml version="1.0"?> 
 <!-- 
-     Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
-     SUN PROPRIETARY/CONFIDENTIAL.  Use is subject to license terms.
+     Copyright 1997-2000 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+     CA 95054 USA or visit www.sun.com if you need additional information or
+     have any questions.
 -->
 <!DOCTYPE processcode [
   <!ELEMENT processcode ANY>
--- a/hotspot/src/share/vm/interpreter/bytecodeInterpreterWithChecks.xsl	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/interpreter/bytecodeInterpreterWithChecks.xsl	Wed Jul 05 16:37:51 2017 +0200
@@ -1,10 +1,29 @@
 <?xml version="1.0"?> 
 <!-- 
-     Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
-     SUN PROPRIETARY/CONFIDENTIAL.  Use is subject to license terms.
+     Copyright 1997-2000 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+     CA 95054 USA or visit www.sun.com if you need additional information or
+     have any questions.
 -->
 
 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+<xsl:output method="text" indent="no" omit-xml-declaration="yes"/>
 
 <xsl:template match="processcode">
 <xsl:text>
@@ -15,7 +34,6 @@
 
 </xsl:text>
 
-<xsl:output method="text" indent="no" omit-xml-declaration="yes"/>
 </xsl:template>
 
 </xsl:stylesheet>
--- a/hotspot/src/share/vm/memory/space.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/memory/space.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -815,6 +815,7 @@
            "size for smallest fake object doesn't match");
     instanceOop obj = (instanceOop) allocate(size);
     obj->set_mark(markOopDesc::prototype());
+    obj->set_klass_gap(0);
     obj->set_klass(SystemDictionary::object_klass());
   }
 }
--- a/hotspot/src/share/vm/oops/arrayOop.hpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/oops/arrayOop.hpp	Wed Jul 05 16:37:51 2017 +0200
@@ -41,11 +41,10 @@
   // Header size computation.
   // The header is considered the oop part of this type plus the length.
   // Returns the aligned header_size_in_bytes.  This is not equivalent to
-  // sizeof(arrayOopDesc) which should not appear in the code, except here.
+  // sizeof(arrayOopDesc) which should not appear in the code.
   static int header_size_in_bytes() {
-    size_t hs = UseCompressedOops ?
-            sizeof(arrayOopDesc) :
-            align_size_up(sizeof(arrayOopDesc) + sizeof(int), HeapWordSize);
+    size_t hs = align_size_up(length_offset_in_bytes() + sizeof(int),
+                              HeapWordSize);
 #ifdef ASSERT
     // make sure it isn't called before UseCompressedOops is initialized.
     static size_t arrayoopdesc_hs = 0;
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp	Wed Jul 05 16:37:51 2017 +0200
@@ -180,9 +180,8 @@
   // End of the oop block.
   //
 
-  // number of words used by non-static fields in this klass (including
-  // inherited fields but after header_size()).  If fields are compressed into
-  // header, this can be zero so it's not the same as number of static fields.
+  // Number of heapOopSize words used by non-static fields in this klass
+  // (including inherited fields but after header_size()).
   int             _nonstatic_field_size;
   int             _static_field_size;    // number words used by static fields (oop and non-oop) in this klass
   int             _static_oop_field_size;// number of static oop fields in this klass
--- a/hotspot/src/share/vm/oops/instanceKlassKlass.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/oops/instanceKlassKlass.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -581,7 +581,7 @@
   OopMapBlock* map     = ik->start_of_nonstatic_oop_maps();
   OopMapBlock* end_map = map + ik->nonstatic_oop_map_size();
   while (map < end_map) {
-    st->print("%d-%d ", map->offset(), map->offset() + oopSize*(map->length() - 1));
+    st->print("%d-%d ", map->offset(), map->offset() + heapOopSize*(map->length() - 1));
     map++;
   }
   st->cr();
--- a/hotspot/src/share/vm/oops/instanceOop.hpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/oops/instanceOop.hpp	Wed Jul 05 16:37:51 2017 +0200
@@ -39,14 +39,7 @@
 
   static bool contains_field_offset(int offset, int nonstatic_field_size) {
     int base_in_bytes = base_offset_in_bytes();
-    if (UseCompressedOops) {
-      return (offset >= base_in_bytes &&
-              // field can be embedded in header, or is after header.
-              (offset < (int)sizeof(instanceOopDesc) ||
-              (offset-(int)sizeof(instanceOopDesc))/wordSize < nonstatic_field_size));
-    } else {
-      return (offset >= base_in_bytes &&
-              (offset-base_in_bytes)/wordSize < nonstatic_field_size);
-    }
+    return (offset >= base_in_bytes &&
+            (offset-base_in_bytes) < nonstatic_field_size * heapOopSize);
   }
 };
--- a/hotspot/src/share/vm/oops/markOop.hpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/oops/markOop.hpp	Wed Jul 05 16:37:51 2017 +0200
@@ -29,8 +29,10 @@
 //
 // Bit-format of an object header (most significant first):
 //
-//
-//  unused:0/25 hash:25/31 age:4 biased_lock:1 lock:2 = 32/64 bits
+//  32 bits: unused:0  hash:25 age:4 biased_lock:1 lock:2
+//  64 bits: unused:24 hash:31 cms:2 age:4 biased_lock:1 lock:2
+//           unused:20 size:35 cms:2 age:4 biased_lock:1 lock:2 (if cms
+//                                                               free chunk)
 //
 //  - hash contains the identity hash value: largest value is
 //    31 bits, see os::random().  Also, 64-bit vm's require
@@ -91,6 +93,7 @@
          biased_lock_bits         = 1,
          max_hash_bits            = BitsPerWord - age_bits - lock_bits - biased_lock_bits,
          hash_bits                = max_hash_bits > 31 ? 31 : max_hash_bits,
+         cms_bits                 = LP64_ONLY(1) NOT_LP64(0),
          epoch_bits               = 2
   };
 
@@ -106,7 +109,8 @@
   enum { lock_shift               = 0,
          biased_lock_shift        = lock_bits,
          age_shift                = lock_bits + biased_lock_bits,
-         hash_shift               = lock_bits + biased_lock_bits + age_bits,
+         cms_shift                = age_shift + age_bits,
+         hash_shift               = cms_shift + cms_bits,
          epoch_shift              = hash_shift
   };
 
@@ -118,7 +122,9 @@
          age_mask                 = right_n_bits(age_bits),
          age_mask_in_place        = age_mask << age_shift,
          epoch_mask               = right_n_bits(epoch_bits),
-         epoch_mask_in_place      = epoch_mask << epoch_shift
+         epoch_mask_in_place      = epoch_mask << epoch_shift,
+         cms_mask                 = right_n_bits(cms_bits),
+         cms_mask_in_place        = cms_mask << cms_shift
 #ifndef _WIN64
          ,hash_mask               = right_n_bits(hash_bits),
          hash_mask_in_place       = (address_word)hash_mask << hash_shift
@@ -360,4 +366,40 @@
 
   // see the definition in markOop.cpp for the gory details
   bool should_not_be_cached() const;
+
+  // These markOops indicate cms free chunk blocks and not objects.
+  // In 64 bit, the markOop is set to distinguish them from oops.
+  // These are defined in 32 bit mode for vmStructs.
+  const static uintptr_t cms_free_chunk_pattern  = 0x1;
+
+  // Constants for the size field.
+  enum { size_shift                = cms_shift + cms_bits,
+         size_bits                 = 35    // need for compressed oops 32G
+       };
+  // These values are too big for Win64
+  const static uintptr_t size_mask = LP64_ONLY(right_n_bits(size_bits))
+                                     NOT_LP64(0);
+  const static uintptr_t size_mask_in_place =
+                                     (address_word)size_mask << size_shift;
+
+#ifdef _LP64
+  static markOop cms_free_prototype() {
+    return markOop(((intptr_t)prototype() & ~cms_mask_in_place) |
+                   ((cms_free_chunk_pattern & cms_mask) << cms_shift));
+  }
+  uintptr_t cms_encoding() const {
+    return mask_bits(value() >> cms_shift, cms_mask);
+  }
+  bool is_cms_free_chunk() const {
+    return is_neutral() &&
+           (cms_encoding() & cms_free_chunk_pattern) == cms_free_chunk_pattern;
+  }
+
+  size_t get_size() const       { return (size_t)(value() >> size_shift); }
+  static markOop set_size_and_free(size_t size) {
+    assert((size & ~size_mask) == 0, "shouldn't overflow size field");
+    return markOop(((intptr_t)cms_free_prototype() & ~size_mask_in_place) |
+                   (((intptr_t)size & size_mask) << size_shift));
+  }
+#endif // _LP64
 };
--- a/hotspot/src/share/vm/oops/methodDataOop.hpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/oops/methodDataOop.hpp	Wed Jul 05 16:37:51 2017 +0200
@@ -158,7 +158,6 @@
     assert(ProfileTraps, "used only under +ProfileTraps");
     uint old_flags = (_header._struct._flags & flag_mask);
     _header._struct._flags = (new_state << trap_shift) | old_flags;
-    assert(trap_state() == new_state, "sanity");
   }
 
   u1 flags() {
--- a/hotspot/src/share/vm/oops/oop.hpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/oops/oop.hpp	Wed Jul 05 16:37:51 2017 +0200
@@ -77,10 +77,15 @@
   void init_mark();
 
   klassOop klass() const;
+  klassOop klass_or_null() const volatile;
   oop* klass_addr();
   narrowOop* compressed_klass_addr();
 
   void set_klass(klassOop k);
+
+  // For klass field compression
+  int klass_gap() const;
+  void set_klass_gap(int z);
   // For when the klass pointer is being used as a linked list "next" field.
   void set_klass_to_list_ptr(oop k);
 
--- a/hotspot/src/share/vm/oops/oop.inline.hpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/oops/oop.inline.hpp	Wed Jul 05 16:37:51 2017 +0200
@@ -36,7 +36,15 @@
 inline klassOop oopDesc::klass() const {
   if (UseCompressedOops) {
     return (klassOop)decode_heap_oop_not_null(_metadata._compressed_klass);
-      // can be NULL in CMS, but isn't supported on CMS yet.
+  } else {
+    return _metadata._klass;
+  }
+}
+
+inline klassOop oopDesc::klass_or_null() const volatile {
+  // can be NULL in CMS
+  if (UseCompressedOops) {
+    return (klassOop)decode_heap_oop(_metadata._compressed_klass);
   } else {
     return _metadata._klass;
   }
@@ -64,15 +72,22 @@
   assert(Universe::is_bootstrapping() || k != NULL, "must be a real klassOop");
   assert(Universe::is_bootstrapping() || k->is_klass(), "not a klassOop");
   if (UseCompressedOops) {
-    // zero the gap when the klass is set, by zeroing the pointer sized
-    // part of the union.
-    _metadata._klass = NULL;
     oop_store_without_check(compressed_klass_addr(), (oop)k);
   } else {
     oop_store_without_check(klass_addr(), (oop) k);
   }
 }
 
+inline int oopDesc::klass_gap() const {
+  return *(int*)(((intptr_t)this) + klass_gap_offset_in_bytes());
+}
+
+inline void oopDesc::set_klass_gap(int v) {
+  if (UseCompressedOops) {
+    *(int*)(((intptr_t)this) + klass_gap_offset_in_bytes()) = v;
+  }
+}
+
 inline void oopDesc::set_klass_to_list_ptr(oop k) {
   // This is only to be used during GC, for from-space objects, so no
   // barrier is needed.
@@ -505,7 +520,7 @@
   // try to find metaclass cycle safely without seg faulting on bad input
   // we should reach klassKlassObj by following klass link at most 3 times
   for (int i = 0; i < 3; i++) {
-    obj = obj->klass();
+    obj = obj->klass_or_null();
     // klass should be aligned and in permspace
     if (!check_obj_alignment(obj)) return false;
     if (!Universe::heap()->is_in_permanent(obj)) return false;
--- a/hotspot/src/share/vm/opto/c2_globals.hpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/opto/c2_globals.hpp	Wed Jul 05 16:37:51 2017 +0200
@@ -390,5 +390,8 @@
                                                                             \
   product(intx, MaxLabelRootDepth, 1100,                                    \
           "Maximum times call Label_Root to prevent stack overflow")        \
+                                                                            \
+  diagnostic(intx, DominatorSearchLimit, 1000,                              \
+          "Iterations limit in Node::dominates")                            \
 
 C2_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_NOTPRODUCT_FLAG)
--- a/hotspot/src/share/vm/opto/callnode.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/opto/callnode.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -637,7 +637,7 @@
   }
   Compile *C = phase->C;
   int offset = adrInst_t->offset();
-  assert(offset >= 0, "should be valid offset");
+  assert(adrInst_t->klass_is_exact() && offset >= 0, "should be valid offset");
   ciKlass* adr_k = adrInst_t->klass();
   assert(adr_k->is_loaded() &&
          adr_k->is_java_klass() &&
@@ -674,12 +674,11 @@
       ciKlass* at_k = at_ptr->klass();
       if ((adrInst_t->base() == at_ptr->base()) &&
           at_k->is_loaded() &&
-          at_k->is_java_klass() &&
-          !at_k->is_interface()) {
+          at_k->is_java_klass()) {
         // If we have found an argument matching addr_t, check if the field
         // at the specified offset is modified.
-        int at_idx = C->get_alias_index(at_ptr->add_offset(offset)->isa_oopptr());
-        if (base_idx == at_idx &&
+        if ((at_k->is_interface() || adr_k == at_k ||
+             adr_k->is_subclass_of(at_k) && !at_ptr->klass_is_exact()) &&
             (bcea == NULL ||
              bcea->is_arg_modified(i - TypeFunc::Parms, offset, size))) {
           return true;
--- a/hotspot/src/share/vm/opto/callnode.hpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/opto/callnode.hpp	Wed Jul 05 16:37:51 2017 +0200
@@ -388,9 +388,6 @@
   void               set_next_exception(SafePointNode* n);
   bool                   has_exceptions() const { return next_exception() != NULL; }
 
-  // Does this node have a use of n other than in debug information?
-  virtual bool           has_non_debug_use(Node *n)  {return false; }
-
   // Standard Node stuff
   virtual int            Opcode() const;
   virtual bool           pinned() const { return true; }
@@ -497,7 +494,7 @@
   // Returns true if the call may modify n
   virtual bool        may_modify(const TypePtr *addr_t, PhaseTransform *phase);
   // Does this node have a use of n other than in debug information?
-  virtual bool        has_non_debug_use(Node *n);
+  bool                has_non_debug_use(Node *n);
   // Returns the unique CheckCastPP of a call
   // or result projection is there are several CheckCastPP
   // or returns NULL if there is no one.
--- a/hotspot/src/share/vm/opto/cfgnode.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/opto/cfgnode.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -707,8 +707,14 @@
 //------------------------split_out_instance-----------------------------------
 // Split out an instance type from a bottom phi.
 PhiNode* PhiNode::split_out_instance(const TypePtr* at, PhaseIterGVN *igvn) const {
-  assert(type() == Type::MEMORY && (adr_type() == TypePtr::BOTTOM ||
-         adr_type() == TypeRawPtr::BOTTOM) , "bottom or raw memory required");
+  const TypeOopPtr *t_oop = at->isa_oopptr();
+  assert(t_oop != NULL && t_oop->is_instance(), "expecting instance oopptr");
+  const TypePtr *t = adr_type();
+  assert(type() == Type::MEMORY &&
+         (t == TypePtr::BOTTOM || t == TypeRawPtr::BOTTOM ||
+          t->isa_oopptr() && !t->is_oopptr()->is_instance() &&
+          t->is_oopptr()->cast_to_instance(t_oop->instance_id()) == t_oop),
+         "bottom or raw memory required");
 
   // Check if an appropriate node already exists.
   Node *region = in(0);
@@ -1342,7 +1348,7 @@
     Node *n = phi->in(i);
     if( !n ) return NULL;
     if( phase->type(n) == Type::TOP ) return NULL;
-    if( n->Opcode() == Op_ConP )
+    if( n->Opcode() == Op_ConP || n->Opcode() == Op_ConN )
       break;
   }
   if( i >= phi->req() )         // Only split for constants
@@ -1615,64 +1621,6 @@
     if (opt != NULL)  return opt;
   }
 
-  if (in(1) != NULL && in(1)->Opcode() == Op_AddP && can_reshape) {
-    // Try to undo Phi of AddP:
-    //   (Phi (AddP base base y) (AddP base2 base2 y))
-    // becomes:
-    //   newbase := (Phi base base2)
-    //   (AddP newbase newbase y)
-    //
-    // This occurs as a result of unsuccessful split_thru_phi and
-    // interferes with taking advantage of addressing modes.  See the
-    // clone_shift_expressions code in matcher.cpp
-    Node* addp = in(1);
-    const Type* type = addp->in(AddPNode::Base)->bottom_type();
-    Node* y = addp->in(AddPNode::Offset);
-    if (y != NULL && addp->in(AddPNode::Base) == addp->in(AddPNode::Address)) {
-      // make sure that all the inputs are similar to the first one,
-      // i.e. AddP with base == address and same offset as first AddP
-      bool doit = true;
-      for (uint i = 2; i < req(); i++) {
-        if (in(i) == NULL ||
-            in(i)->Opcode() != Op_AddP ||
-            in(i)->in(AddPNode::Base) != in(i)->in(AddPNode::Address) ||
-            in(i)->in(AddPNode::Offset) != y) {
-          doit = false;
-          break;
-        }
-        // Accumulate type for resulting Phi
-        type = type->meet(in(i)->in(AddPNode::Base)->bottom_type());
-      }
-      Node* base = NULL;
-      if (doit) {
-        // Check for neighboring AddP nodes in a tree.
-        // If they have a base, use that it.
-        for (DUIterator_Fast kmax, k = this->fast_outs(kmax); k < kmax; k++) {
-          Node* u = this->fast_out(k);
-          if (u->is_AddP()) {
-            Node* base2 = u->in(AddPNode::Base);
-            if (base2 != NULL && !base2->is_top()) {
-              if (base == NULL)
-                base = base2;
-              else if (base != base2)
-                { doit = false; break; }
-            }
-          }
-        }
-      }
-      if (doit) {
-        if (base == NULL) {
-          base = new (phase->C, in(0)->req()) PhiNode(in(0), type, NULL);
-          for (uint i = 1; i < req(); i++) {
-            base->init_req(i, in(i)->in(AddPNode::Base));
-          }
-          phase->is_IterGVN()->register_new_node_with_optimizer(base);
-        }
-        return new (phase->C, 4) AddPNode(base, base, y);
-      }
-    }
-  }
-
   // Split phis through memory merges, so that the memory merges will go away.
   // Piggy-back this transformation on the search for a unique input....
   // It will be as if the merged memory is the unique value of the phi.
--- a/hotspot/src/share/vm/opto/chaitin.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/opto/chaitin.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -1385,7 +1385,7 @@
             cisc->ins_req(1,src);         // Requires a memory edge
           }
           b->_nodes.map(j,cisc);          // Insert into basic block
-          n->replace_by(cisc); // Correct graph
+          n->subsume_by(cisc); // Correct graph
           //
           ++_used_cisc_instructions;
 #ifndef PRODUCT
--- a/hotspot/src/share/vm/opto/classes.hpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/opto/classes.hpp	Wed Jul 05 16:37:51 2017 +0200
@@ -37,6 +37,7 @@
 macro(AllocateArray)
 macro(AndI)
 macro(AndL)
+macro(AryEq)
 macro(AtanD)
 macro(Binary)
 macro(Bool)
@@ -64,6 +65,7 @@
 macro(CMoveI)
 macro(CMoveL)
 macro(CMoveP)
+macro(CMoveN)
 macro(CmpN)
 macro(CmpD)
 macro(CmpD3)
@@ -133,6 +135,7 @@
 macro(LoadF)
 macro(LoadI)
 macro(LoadKlass)
+macro(LoadNKlass)
 macro(LoadL)
 macro(LoadL_unaligned)
 macro(LoadPLocked)
--- a/hotspot/src/share/vm/opto/compile.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/opto/compile.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -368,7 +368,12 @@
   BufferBlob* blob = BufferBlob::create("Compile::scratch_buffer", size);
   // Record the buffer blob for next time.
   set_scratch_buffer_blob(blob);
-  guarantee(scratch_buffer_blob() != NULL, "Need BufferBlob for code generation");
+  // Have we run out of code space?
+  if (scratch_buffer_blob() == NULL) {
+    // Let CompilerBroker disable further compilations.
+    record_failure("Not enough space for scratch buffer in CodeCache");
+    return;
+  }
 
   // Initialize the relocation buffers
   relocInfo* locs_buf = (relocInfo*) blob->instructions_end() - MAX_locs_size;
@@ -1065,6 +1070,8 @@
       // No constant oop pointers (such as Strings); they alias with
       // unknown strings.
       tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,offset);
+    } else if( to->is_instance_field() ) {
+      tj = to; // Keep NotNull and klass_is_exact for instance type
     } else if( ptr == TypePtr::NotNull || to->klass_is_exact() ) {
       // During the 2nd round of IterGVN, NotNull castings are removed.
       // Make sure the Bottom and NotNull variants alias the same.
@@ -1084,7 +1091,7 @@
     } else {
       ciInstanceKlass *canonical_holder = k->get_canonical_holder(offset);
       if (!k->equals(canonical_holder) || tj->offset() != offset) {
-        tj = to = TypeInstPtr::make(TypePtr::BotPTR, canonical_holder, false, NULL, offset, to->instance_id());
+        tj = to = TypeInstPtr::make(to->ptr(), canonical_holder, false, NULL, offset, to->instance_id());
       }
     }
   }
@@ -1835,6 +1842,7 @@
 // Implement items 1-5 from final_graph_reshaping below.
 static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &fpu ) {
 
+  if ( n->outcnt() == 0 ) return; // dead node
   uint nop = n->Opcode();
 
   // Check for 2-input instruction with "last use" on right input.
@@ -1901,7 +1909,7 @@
     break;
   case Op_Opaque1:              // Remove Opaque Nodes before matching
   case Op_Opaque2:              // Remove Opaque Nodes before matching
-    n->replace_by(n->in(1));
+    n->subsume_by(n->in(1));
     break;
   case Op_CallStaticJava:
   case Op_CallJava:
@@ -1961,6 +1969,7 @@
   case Op_LoadC:
   case Op_LoadI:
   case Op_LoadKlass:
+  case Op_LoadNKlass:
   case Op_LoadL:
   case Op_LoadL_unaligned:
   case Op_LoadPLocked:
@@ -1983,14 +1992,94 @@
   }
 
   case Op_AddP: {               // Assert sane base pointers
-    const Node *addp = n->in(AddPNode::Address);
+    Node *addp = n->in(AddPNode::Address);
     assert( !addp->is_AddP() ||
             addp->in(AddPNode::Base)->is_top() || // Top OK for allocation
             addp->in(AddPNode::Base) == n->in(AddPNode::Base),
             "Base pointers must match" );
+#ifdef _LP64
+    if (UseCompressedOops &&
+        addp->Opcode() == Op_ConP &&
+        addp == n->in(AddPNode::Base) &&
+        n->in(AddPNode::Offset)->is_Con()) {
+      // Use addressing with narrow klass to load with offset on x86.
+      // On sparc loading 32-bits constant and decoding it have less
+      // instructions (4) then load 64-bits constant (7).
+      // Do this transformation here since IGVN will convert ConN back to ConP.
+      const Type* t = addp->bottom_type();
+      if (t->isa_oopptr()) {
+        Node* nn = NULL;
+
+        // Look for existing ConN node of the same exact type.
+        Compile* C = Compile::current();
+        Node* r  = C->root();
+        uint cnt = r->outcnt();
+        for (uint i = 0; i < cnt; i++) {
+          Node* m = r->raw_out(i);
+          if (m!= NULL && m->Opcode() == Op_ConN &&
+              m->bottom_type()->is_narrowoop()->make_oopptr() == t) {
+            nn = m;
+            break;
+          }
+        }
+        if (nn != NULL) {
+          // Decode a narrow oop to match address
+          // [R12 + narrow_oop_reg<<3 + offset]
+          nn = new (C,  2) DecodeNNode(nn, t);
+          n->set_req(AddPNode::Base, nn);
+          n->set_req(AddPNode::Address, nn);
+          if (addp->outcnt() == 0) {
+            addp->disconnect_inputs(NULL);
+          }
+        }
+      }
+    }
+#endif
     break;
   }
 
+#ifdef _LP64
+  case Op_CmpP:
+    // Do this transformation here to preserve CmpPNode::sub() and
+    // other TypePtr related Ideal optimizations (for example, ptr nullness).
+    if( n->in(1)->is_DecodeN() ) {
+      Compile* C = Compile::current();
+      Node* in2 = NULL;
+      if( n->in(2)->is_DecodeN() ) {
+        in2 = n->in(2)->in(1);
+      } else if ( n->in(2)->Opcode() == Op_ConP ) {
+        const Type* t = n->in(2)->bottom_type();
+        if (t == TypePtr::NULL_PTR) {
+          Node *in1 = n->in(1);
+          if (Matcher::clone_shift_expressions) {
+            // x86, ARM and friends can handle 2 adds in addressing mode.
+            // Decode a narrow oop and do implicit NULL check in address
+            // [R12 + narrow_oop_reg<<3 + offset]
+            in2 = ConNode::make(C, TypeNarrowOop::NULL_PTR);
+          } else {
+            // Don't replace CmpP(o ,null) if 'o' is used in AddP
+            // to generate implicit NULL check on Sparc where
+            // narrow oops can't be used in address.
+            uint i = 0;
+            for (; i < in1->outcnt(); i++) {
+              if (in1->raw_out(i)->is_AddP())
+                break;
+            }
+            if (i >= in1->outcnt()) {
+              in2 = ConNode::make(C, TypeNarrowOop::NULL_PTR);
+            }
+          }
+        } else if (t->isa_oopptr()) {
+          in2 = ConNode::make(C, t->is_oopptr()->make_narrowoop());
+        }
+      }
+      if( in2 != NULL ) {
+        Node* cmpN = new (C, 3) CmpNNode(n->in(1)->in(1), in2);
+        n->subsume_by( cmpN );
+      }
+    }
+#endif
+
   case Op_ModI:
     if (UseDivMod) {
       // Check if a%b and a/b both exist
@@ -2000,13 +2089,13 @@
         Compile* C = Compile::current();
         if (Matcher::has_match_rule(Op_DivModI)) {
           DivModINode* divmod = DivModINode::make(C, n);
-          d->replace_by(divmod->div_proj());
-          n->replace_by(divmod->mod_proj());
+          d->subsume_by(divmod->div_proj());
+          n->subsume_by(divmod->mod_proj());
         } else {
           // replace a%b with a-((a/b)*b)
           Node* mult = new (C, 3) MulINode(d, d->in(2));
           Node* sub  = new (C, 3) SubINode(d->in(1), mult);
-          n->replace_by( sub );
+          n->subsume_by( sub );
         }
       }
     }
@@ -2021,13 +2110,13 @@
         Compile* C = Compile::current();
         if (Matcher::has_match_rule(Op_DivModL)) {
           DivModLNode* divmod = DivModLNode::make(C, n);
-          d->replace_by(divmod->div_proj());
-          n->replace_by(divmod->mod_proj());
+          d->subsume_by(divmod->div_proj());
+          n->subsume_by(divmod->mod_proj());
         } else {
           // replace a%b with a-((a/b)*b)
           Node* mult = new (C, 3) MulLNode(d, d->in(2));
           Node* sub  = new (C, 3) SubLNode(d->in(1), mult);
-          n->replace_by( sub );
+          n->subsume_by( sub );
         }
       }
     }
@@ -2073,7 +2162,7 @@
       // Replace many operand PackNodes with a binary tree for matching
       PackNode* p = (PackNode*) n;
       Node* btp = p->binaryTreePack(Compile::current(), 1, n->req());
-      n->replace_by(btp);
+      n->subsume_by(btp);
     }
     break;
   default:
--- a/hotspot/src/share/vm/opto/connode.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/opto/connode.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -35,16 +35,16 @@
 
 //------------------------------make-------------------------------------------
 ConNode *ConNode::make( Compile* C, const Type *t ) {
-  if (t->isa_narrowoop()) return new (C, 1) ConNNode( t->is_narrowoop() );
   switch( t->basic_type() ) {
   case T_INT:       return new (C, 1) ConINode( t->is_int() );
-  case T_ARRAY:     return new (C, 1) ConPNode( t->is_aryptr() );
   case T_LONG:      return new (C, 1) ConLNode( t->is_long() );
   case T_FLOAT:     return new (C, 1) ConFNode( t->is_float_constant() );
   case T_DOUBLE:    return new (C, 1) ConDNode( t->is_double_constant() );
   case T_VOID:      return new (C, 1) ConNode ( Type::TOP );
   case T_OBJECT:    return new (C, 1) ConPNode( t->is_oopptr() );
+  case T_ARRAY:     return new (C, 1) ConPNode( t->is_aryptr() );
   case T_ADDRESS:   return new (C, 1) ConPNode( t->is_ptr() );
+  case T_NARROWOOP: return new (C, 1) ConNNode( t->is_narrowoop() );
     // Expected cases:  TypePtr::NULL_PTR, any is_rawptr()
     // Also seen: AnyPtr(TopPTR *+top); from command line:
     //   r -XX:+PrintOpto -XX:CIStart=285 -XX:+CompileTheWorld -XX:CompileTheWorldStartAt=660
@@ -185,6 +185,7 @@
   case T_LONG:    return new (C, 4) CMoveLNode( bol, left, right, t->is_long() );
   case T_OBJECT:  return new (C, 4) CMovePNode( c, bol, left, right, t->is_oopptr() );
   case T_ADDRESS: return new (C, 4) CMovePNode( c, bol, left, right, t->is_ptr() );
+  case T_NARROWOOP: return new (C, 4) CMoveNNode( c, bol, left, right, t );
   default:
     ShouldNotReachHere();
     return NULL;
@@ -556,7 +557,7 @@
   const Type *t = phase->type( in(1) );
   if( t == Type::TOP ) return in(1);
 
-  if (in(1)->Opcode() == Op_EncodeP) {
+  if (in(1)->is_EncodeP()) {
     // (DecodeN (EncodeP p)) -> p
     return in(1)->in(1);
   }
@@ -570,16 +571,19 @@
   return bottom_type();
 }
 
-Node* DecodeNNode::decode(PhaseGVN* phase, Node* value) {
-  if (value->Opcode() == Op_EncodeP) {
+Node* DecodeNNode::decode(PhaseTransform* phase, Node* value) {
+  if (value->is_EncodeP()) {
     // (DecodeN (EncodeP p)) -> p
     return value->in(1);
   }
   const Type* newtype = value->bottom_type();
   if (newtype == TypeNarrowOop::NULL_PTR) {
     return phase->transform(new (phase->C, 1) ConPNode(TypePtr::NULL_PTR));
+  } else if (newtype->isa_narrowoop()) {
+    return phase->transform(new (phase->C, 2) DecodeNNode(value, newtype->is_narrowoop()->make_oopptr()));
   } else {
-    return phase->transform(new (phase->C, 2) DecodeNNode(value, newtype->is_narrowoop()->make_oopptr()));
+    ShouldNotReachHere();
+    return NULL; // to make C++ compiler happy.
   }
 }
 
@@ -587,7 +591,7 @@
   const Type *t = phase->type( in(1) );
   if( t == Type::TOP ) return in(1);
 
-  if (in(1)->Opcode() == Op_DecodeN) {
+  if (in(1)->is_DecodeN()) {
     // (EncodeP (DecodeN p)) -> p
     return in(1)->in(1);
   }
@@ -601,8 +605,8 @@
   return bottom_type();
 }
 
-Node* EncodePNode::encode(PhaseGVN* phase, Node* value) {
-  if (value->Opcode() == Op_DecodeN) {
+Node* EncodePNode::encode(PhaseTransform* phase, Node* value) {
+  if (value->is_DecodeN()) {
     // (EncodeP (DecodeN p)) -> p
     return value->in(1);
   }
@@ -617,6 +621,9 @@
   }
 }
 
+Node *EncodePNode::Ideal_DU_postCCP( PhaseCCP *ccp ) {
+  return MemNode::Ideal_common_DU_postCCP(ccp, this, in(1));
+}
 
 //=============================================================================
 //------------------------------Identity---------------------------------------
--- a/hotspot/src/share/vm/opto/connode.hpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/opto/connode.hpp	Wed Jul 05 16:37:51 2017 +0200
@@ -70,11 +70,6 @@
     else
       return new (C, 1) ConPNode( TypeRawPtr::make(con) );
   }
-
-  static ConPNode* make( Compile *C, ciObject* con ) {
-    return new (C, 1) ConPNode( TypeOopPtr::make_from_constant(con) );
-  }
-
 };
 
 
@@ -84,11 +79,6 @@
 public:
   ConNNode( const TypeNarrowOop *t ) : ConNode(t) {}
   virtual int Opcode() const;
-
-  static ConNNode* make( Compile *C, ciObject* con ) {
-    return new (C, 1) ConNNode( TypeNarrowOop::make_from_constant(con) );
-  }
-
 };
 
 
@@ -210,7 +200,14 @@
   virtual int Opcode() const;
 };
 
-//------------------------------ConstraintCastNode-------------------------------------
+//------------------------------CMoveNNode-------------------------------------
+class CMoveNNode : public CMoveNode {
+public:
+  CMoveNNode( Node *c, Node *bol, Node *left, Node *right, const Type* t ) : CMoveNode(bol,left,right,t) { init_req(Control,c); }
+  virtual int Opcode() const;
+};
+
+//------------------------------ConstraintCastNode-----------------------------
 // cast to a different range
 class ConstraintCastNode: public TypeNode {
 public:
@@ -274,6 +271,7 @@
  public:
   EncodePNode(Node* value, const Type* type):
     TypeNode(type, 2) {
+    init_class_id(Class_EncodeP);
     init_req(0, NULL);
     init_req(1, value);
   }
@@ -282,7 +280,8 @@
   virtual const Type *Value( PhaseTransform *phase ) const;
   virtual uint  ideal_reg() const { return Op_RegN; }
 
-  static Node* encode(PhaseGVN* phase, Node* value);
+  static Node* encode(PhaseTransform* phase, Node* value);
+  virtual Node *Ideal_DU_postCCP( PhaseCCP *ccp );
 };
 
 //------------------------------DecodeN--------------------------------
@@ -293,6 +292,7 @@
  public:
   DecodeNNode(Node* value, const Type* type):
     TypeNode(type, 2) {
+    init_class_id(Class_DecodeN);
     init_req(0, NULL);
     init_req(1, value);
   }
@@ -301,7 +301,7 @@
   virtual const Type *Value( PhaseTransform *phase ) const;
   virtual uint  ideal_reg() const { return Op_RegP; }
 
-  static Node* decode(PhaseGVN* phase, Node* value);
+  static Node* decode(PhaseTransform* phase, Node* value);
 };
 
 //------------------------------Conv2BNode-------------------------------------
--- a/hotspot/src/share/vm/opto/doCall.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/opto/doCall.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -580,7 +580,7 @@
   Node* ex_klass_node = NULL;
   if (has_ex_handler() && !ex_type->klass_is_exact()) {
     Node* p = basic_plus_adr( ex_node, ex_node, oopDesc::klass_offset_in_bytes());
-    ex_klass_node = _gvn.transform(new (C, 3) LoadKlassNode(NULL, immutable_memory(), p, TypeInstPtr::KLASS, TypeKlassPtr::OBJECT));
+    ex_klass_node = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p, TypeInstPtr::KLASS, TypeKlassPtr::OBJECT) );
 
     // Compute the exception klass a little more cleverly.
     // Obvious solution is to simple do a LoadKlass from the 'ex_node'.
@@ -592,7 +592,7 @@
       ex_klass_node = new (C, ex_node->req()) PhiNode( ex_node->in(0), TypeKlassPtr::OBJECT );
       for( uint i = 1; i < ex_node->req(); i++ ) {
         Node* p = basic_plus_adr( ex_node->in(i), ex_node->in(i), oopDesc::klass_offset_in_bytes() );
-        Node* k = _gvn.transform(new (C, 3) LoadKlassNode(0, immutable_memory(), p, TypeInstPtr::KLASS, TypeKlassPtr::OBJECT));
+        Node* k = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p, TypeInstPtr::KLASS, TypeKlassPtr::OBJECT) );
         ex_klass_node->init_req( i, k );
       }
       _gvn.set_type(ex_klass_node, TypeKlassPtr::OBJECT);
--- a/hotspot/src/share/vm/opto/escape.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/opto/escape.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -417,11 +417,18 @@
   //       | |
   //       AddP  ( base == address )
   //
+  // case #8. narrow Klass's field reference.
+  //      LoadNKlass
+  //       |
+  //      DecodeN
+  //       | |
+  //       AddP  ( base == address )
+  //
   Node *base = addp->in(AddPNode::Base)->uncast();
   if (base->is_top()) { // The AddP case #3 and #6.
     base = addp->in(AddPNode::Address)->uncast();
     assert(base->Opcode() == Op_ConP || base->Opcode() == Op_ThreadLocal ||
-           base->Opcode() == Op_CastX2P ||
+           base->Opcode() == Op_CastX2P || base->is_DecodeN() ||
            (base->is_Mem() && base->bottom_type() == TypeRawPtr::NOTNULL) ||
            (base->is_Proj() && base->in(0)->is_Allocate()), "sanity");
   }
@@ -888,6 +895,23 @@
       record_for_optimizer(n);
       if (alloc->is_Allocate() && ptn->_scalar_replaceable &&
           (t->isa_instptr() || t->isa_aryptr())) {
+
+        // First, put on the worklist all Field edges from Connection Graph
+        // which is more accurate then putting immediate users from Ideal Graph.
+        for (uint e = 0; e < ptn->edge_count(); e++) {
+          Node *use = _nodes->adr_at(ptn->edge_target(e))->_node;
+          assert(ptn->edge_type(e) == PointsToNode::FieldEdge && use->is_AddP(),
+                 "only AddP nodes are Field edges in CG");
+          if (use->outcnt() > 0) { // Don't process dead nodes
+            Node* addp2 = find_second_addp(use, use->in(AddPNode::Base));
+            if (addp2 != NULL) {
+              assert(alloc->is_AllocateArray(),"array allocation was expected");
+              alloc_worklist.append_if_missing(addp2);
+            }
+            alloc_worklist.append_if_missing(use);
+          }
+        }
+
         // An allocation may have an Initialize which has raw stores. Scan
         // the users of the raw allocation result and push AddP users
         // on alloc_worklist.
@@ -919,6 +943,8 @@
       tinst = igvn->type(base)->isa_oopptr();
     } else if (n->is_Phi() ||
                n->is_CheckCastPP() ||
+               n->is_EncodeP() ||
+               n->is_DecodeN() ||
                (n->is_ConstraintCast() && n->Opcode() == Op_CastPP)) {
       if (visited.test_set(n->_idx)) {
         assert(n->is_Phi(), "loops only through Phi's");
@@ -935,13 +961,25 @@
         tinst = igvn->type(val)->isa_oopptr();
         assert(tinst != NULL && tinst->is_instance() &&
                tinst->instance_id() == elem , "instance type expected.");
-        const TypeOopPtr *tn_t = igvn->type(tn)->isa_oopptr();
+
+        const TypeOopPtr *tn_t = NULL;
+        const Type *tn_type = igvn->type(tn);
+        if (tn_type->isa_narrowoop()) {
+          tn_t = tn_type->is_narrowoop()->make_oopptr()->isa_oopptr();
+        } else {
+          tn_t = tn_type->isa_oopptr();
+        }
 
         if (tn_t != NULL &&
  tinst->cast_to_instance(TypeOopPtr::UNKNOWN_INSTANCE)->higher_equal(tn_t)) {
+          if (tn_type->isa_narrowoop()) {
+            tn_type = tinst->make_narrowoop();
+          } else {
+            tn_type = tinst;
+          }
           igvn->hash_delete(tn);
-          igvn->set_type(tn, tinst);
-          tn->set_type(tinst);
+          igvn->set_type(tn, tn_type);
+          tn->set_type(tn_type);
           igvn->hash_insert(tn);
           record_for_optimizer(n);
         }
@@ -978,6 +1016,8 @@
         alloc_worklist.append_if_missing(use);
       } else if (use->is_Phi() ||
                  use->is_CheckCastPP() ||
+                 use->is_EncodeP() ||
+                 use->is_DecodeN() ||
                  (use->is_ConstraintCast() && use->Opcode() == Op_CastPP)) {
         alloc_worklist.append_if_missing(use);
       }
@@ -1199,7 +1239,7 @@
 
 void ConnectionGraph::compute_escape() {
 
-  // 1. Populate Connection Graph with Ideal nodes.
+  // 1. Populate Connection Graph (CG) with Ideal nodes.
 
   Unique_Node_List worklist_init;
   worklist_init.map(_compile->unique(), NULL);  // preallocate space
@@ -1281,11 +1321,13 @@
       remove_deferred(ni, &deferred_edges, &visited);
       if (n->is_AddP()) {
         // If this AddP computes an address which may point to more that one
-        // object, nothing the address points to can be scalar replaceable.
+        // object or more then one field (array's element), nothing the address
+        // points to can be scalar replaceable.
         Node *base = get_addp_base(n);
         ptset.Clear();
         PointsTo(ptset, base, igvn);
-        if (ptset.Size() > 1) {
+        if (ptset.Size() > 1 ||
+            (ptset.Size() != 0 && ptn->offset() == Type::OffsetBot)) {
           for( VectorSetI j(&ptset); j.test(); ++j ) {
             uint pt = j.elem;
             ptnode_adr(pt)->_scalar_replaceable = false;
@@ -1538,6 +1580,7 @@
       if (k->Opcode() == Op_LoadKlass) {
         kt = k->as_Load()->type()->isa_klassptr();
       } else {
+        // Also works for DecodeN(LoadNKlass).
         kt = k->as_Type()->type()->isa_klassptr();
       }
       assert(kt != NULL, "TypeKlassPtr  required.");
@@ -1776,6 +1819,7 @@
       break;
     }
     case Op_LoadKlass:
+    case Op_LoadNKlass:
     {
       add_node(n, PointsToNode::JavaObject, PointsToNode::GlobalEscape, true);
       break;
@@ -1979,12 +2023,18 @@
       assert(false, "Op_ConP");
       break;
     }
+    case Op_ConN:
+    {
+      assert(false, "Op_ConN");
+      break;
+    }
     case Op_CreateEx:
     {
       assert(false, "Op_CreateEx");
       break;
     }
     case Op_LoadKlass:
+    case Op_LoadNKlass:
     {
       assert(false, "Op_LoadKlass");
       break;
--- a/hotspot/src/share/vm/opto/graphKit.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/opto/graphKit.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -532,7 +532,7 @@
         C->log()->elem("hot_throw preallocated='1' reason='%s'",
                        Deoptimization::trap_reason_name(reason));
       const TypeInstPtr* ex_con  = TypeInstPtr::make(ex_obj);
-      Node*              ex_node = _gvn.transform(new (C, 1) ConPNode(ex_con));
+      Node*              ex_node = _gvn.transform( ConNode::make(C, ex_con) );
 
       // Clear the detail message of the preallocated exception object.
       // Weblogic sometimes mutates the detail message of exceptions
@@ -1043,7 +1043,7 @@
   Node* akls = AllocateNode::Ideal_klass(obj, &_gvn);
   if (akls != NULL)  return akls;
   Node* k_adr = basic_plus_adr(obj, oopDesc::klass_offset_in_bytes());
-  return _gvn.transform( new (C, 3) LoadKlassNode(0, immutable_memory(), k_adr, TypeInstPtr::KLASS) );
+  return _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), k_adr, TypeInstPtr::KLASS) );
 }
 
 //-------------------------load_array_length-----------------------------------
@@ -2210,7 +2210,7 @@
   // cache which is mutable so can't use immutable memory.  Other
   // types load from the super-class display table which is immutable.
   Node *kmem = might_be_cache ? memory(p2) : immutable_memory();
-  Node *nkls = _gvn.transform( new (C, 3) LoadKlassNode( NULL, kmem, p2, _gvn.type(p2)->is_ptr(), TypeKlassPtr::OBJECT_OR_NULL ) );
+  Node *nkls = _gvn.transform( LoadKlassNode::make( _gvn, kmem, p2, _gvn.type(p2)->is_ptr(), TypeKlassPtr::OBJECT_OR_NULL ) );
 
   // Compile speed common case: ARE a subtype and we canNOT fail
   if( superklass == nkls )
@@ -2801,7 +2801,6 @@
     // initialization, and source them from the new InitializeNode.
     // This will allow us to observe initializations when they occur,
     // and link them properly (as a group) to the InitializeNode.
-    Node* klass_node = alloc->in(AllocateNode::KlassNode);
     assert(init->in(InitializeNode::Memory) == malloc, "");
     MergeMemNode* minit_in = MergeMemNode::make(C, malloc);
     init->set_req(InitializeNode::Memory, minit_in);
--- a/hotspot/src/share/vm/opto/lcm.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/opto/lcm.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -113,6 +113,7 @@
     case Op_LoadN:
     case Op_LoadS:
     case Op_LoadKlass:
+    case Op_LoadNKlass:
     case Op_LoadRange:
     case Op_LoadD_unaligned:
     case Op_LoadL_unaligned:
@@ -133,6 +134,7 @@
       if( mach->in(2) != val ) continue;
       break;                    // Found a memory op?
     case Op_StrComp:
+    case Op_AryEq:
       // Not a legit memory op for implicit null check regardless of
       // embedded loads
       continue;
--- a/hotspot/src/share/vm/opto/library_call.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/opto/library_call.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -163,6 +163,7 @@
   bool inline_native_newArray();
   bool inline_native_getLength();
   bool inline_array_copyOf(bool is_copyOfRange);
+  bool inline_array_equals();
   bool inline_native_clone(bool is_virtual);
   bool inline_native_Reflection_getCallerClass();
   bool inline_native_AtomicLong_get();
@@ -259,6 +260,7 @@
     switch (id) {
     case vmIntrinsics::_indexOf:
     case vmIntrinsics::_compareTo:
+    case vmIntrinsics::_equalsC:
       break;  // InlineNatives does not control String.compareTo
     default:
       return NULL;
@@ -272,6 +274,9 @@
   case vmIntrinsics::_indexOf:
     if (!SpecialStringIndexOf)  return NULL;
     break;
+  case vmIntrinsics::_equalsC:
+    if (!SpecialArraysEquals)  return NULL;
+    break;
   case vmIntrinsics::_arraycopy:
     if (!InlineArrayCopy)  return NULL;
     break;
@@ -586,6 +591,8 @@
     return inline_array_copyOf(false);
   case vmIntrinsics::_copyOfRange:
     return inline_array_copyOf(true);
+  case vmIntrinsics::_equalsC:
+    return inline_array_equals();
   case vmIntrinsics::_clone:
     return inline_native_clone(intrinsic()->is_virtual());
 
@@ -813,6 +820,24 @@
   return true;
 }
 
+//------------------------------inline_array_equals----------------------------
+bool LibraryCallKit::inline_array_equals() {
+
+  if (!Matcher::has_match_rule(Op_AryEq)) return false;
+
+  _sp += 2;
+  Node *argument2 = pop();
+  Node *argument1 = pop();
+
+  Node* equals =
+    _gvn.transform(new (C, 3) AryEqNode(control(),
+                                        argument1,
+                                        argument2)
+                   );
+  push(equals);
+  return true;
+}
+
 // Java version of String.indexOf(constant string)
 // class StringDecl {
 //   StringDecl(char[] ca) {
@@ -896,7 +921,7 @@
   Node* sourcea       = basic_plus_adr(string_object, string_object, value_offset);
   Node* source        = make_load(no_ctrl, sourcea, source_type, T_OBJECT, string_type->add_offset(value_offset));
 
-  Node* target = _gvn.transform(ConPNode::make(C, target_array));
+  Node* target = _gvn.transform( makecon(TypeOopPtr::make_from_constant(target_array)) );
   jint target_length = target_array->length();
   const TypeAry* target_array_type = TypeAry::make(TypeInt::CHAR, TypeInt::make(0, target_length, Type::WidenMin));
   const TypeAryPtr* target_type = TypeAryPtr::make(TypePtr::BotPTR, target_array_type, target_array->klass(), true, Type::OffsetBot);
@@ -2168,7 +2193,7 @@
     // (They don't if CAS fails, but it isn't worth checking.)
     pre_barrier(control(), base, adr, alias_idx, newval, value_type, T_OBJECT);
 #ifdef _LP64
-    if (adr->bottom_type()->is_narrow()) {
+    if (adr->bottom_type()->is_ptr_to_narrowoop()) {
       cas = _gvn.transform(new (C, 5) CompareAndSwapNNode(control(), mem, adr,
                                                            EncodePNode::encode(&_gvn, newval),
                                                            EncodePNode::encode(&_gvn, oldval)));
@@ -2454,7 +2479,7 @@
   if (region == NULL)  never_see_null = true;
   Node* p = basic_plus_adr(mirror, offset);
   const TypeKlassPtr*  kls_type = TypeKlassPtr::OBJECT_OR_NULL;
-  Node* kls = _gvn.transform(new (C, 3) LoadKlassNode(0, immutable_memory(), p, TypeRawPtr::BOTTOM, kls_type));
+  Node* kls = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p, TypeRawPtr::BOTTOM, kls_type) );
   _sp += nargs; // any deopt will start just before call to enclosing method
   Node* null_ctl = top();
   kls = null_check_oop(kls, &null_ctl, never_see_null);
@@ -2634,7 +2659,7 @@
       phi->add_req(makecon(TypeInstPtr::make(env()->Object_klass()->java_mirror())));
     // If we fall through, it's a plain class.  Get its _super.
     p = basic_plus_adr(kls, Klass::super_offset_in_bytes() + sizeof(oopDesc));
-    kls = _gvn.transform(new (C, 3) LoadKlassNode(0, immutable_memory(), p, TypeRawPtr::BOTTOM, TypeKlassPtr::OBJECT_OR_NULL));
+    kls = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p, TypeRawPtr::BOTTOM, TypeKlassPtr::OBJECT_OR_NULL) );
     null_ctl = top();
     kls = null_check_oop(kls, &null_ctl);
     if (null_ctl != top()) {
@@ -2720,7 +2745,7 @@
     args[which_arg] = _gvn.transform(arg);
 
     Node* p = basic_plus_adr(arg, class_klass_offset);
-    Node* kls = new (C, 3) LoadKlassNode(0, immutable_memory(), p, adr_type, kls_type);
+    Node* kls = LoadKlassNode::make(_gvn, immutable_memory(), p, adr_type, kls_type);
     klasses[which_arg] = _gvn.transform(kls);
   }
 
@@ -2838,6 +2863,8 @@
   _sp += nargs;  // set original stack for use by uncommon_trap
   mirror = do_null_check(mirror, T_OBJECT);
   _sp -= nargs;
+  // If mirror or obj is dead, only null-path is taken.
+  if (stopped())  return true;
 
   enum { _normal_path = 1, _slow_path = 2, PATH_LIMIT };
   RegionNode* result_reg = new(C, PATH_LIMIT) RegionNode(PATH_LIMIT);
@@ -3827,24 +3854,22 @@
   if (!stopped()) {
     // Copy the fastest available way.
     // (No need for PreserveJVMState, since we're using it all up now.)
+    // TODO: generate fields/elements copies for small objects instead.
     Node* src  = obj;
     Node* dest = raw_obj;
-    Node* end  = dest;
     Node* size = _gvn.transform(alloc_siz);
 
     // Exclude the header.
     int base_off = instanceOopDesc::base_offset_in_bytes();
     if (UseCompressedOops) {
-      // copy the header gap though.
-      Node* sptr = basic_plus_adr(src,  base_off);
-      Node* dptr = basic_plus_adr(dest, base_off);
-      Node* sval = make_load(control(), sptr, TypeInt::INT, T_INT, raw_adr_type);
-      store_to_memory(control(), dptr, sval, T_INT, raw_adr_type);
-      base_off += sizeof(int);
+      assert(base_off % BytesPerLong != 0, "base with compressed oops");
+      // With compressed oops base_offset_in_bytes is 12 which creates
+      // the gap since countx is rounded by 8 bytes below.
+      // Copy klass and the gap.
+      base_off = instanceOopDesc::klass_offset_in_bytes();
     }
     src  = basic_plus_adr(src,  base_off);
     dest = basic_plus_adr(dest, base_off);
-    end  = basic_plus_adr(end,  size);
 
     // Compute the length also, if needed:
     Node* countx = size;
@@ -4388,7 +4413,7 @@
       // (At this point we can assume disjoint_bases, since types differ.)
       int ek_offset = objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc);
       Node* p1 = basic_plus_adr(dest_klass, ek_offset);
-      Node* n1 = new (C, 3) LoadKlassNode(0, immutable_memory(), p1, TypeRawPtr::BOTTOM);
+      Node* n1 = LoadKlassNode::make(_gvn, immutable_memory(), p1, TypeRawPtr::BOTTOM);
       Node* dest_elem_klass = _gvn.transform(n1);
       Node* cv = generate_checkcast_arraycopy(adr_type,
                                               dest_elem_klass,
--- a/hotspot/src/share/vm/opto/loopnode.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/opto/loopnode.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -2632,6 +2632,7 @@
     case Op_LoadD_unaligned:
     case Op_LoadL_unaligned:
     case Op_StrComp:            // Does a bunch of load-like effects
+    case Op_AryEq:
       pinned = false;
     }
     if( pinned ) {
--- a/hotspot/src/share/vm/opto/loopopts.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/opto/loopopts.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -464,6 +464,7 @@
     case T_FLOAT:
     case T_DOUBLE:
     case T_ADDRESS:             // (RawPtr)
+    case T_NARROWOOP:
       cost++;
       break;
     case T_OBJECT: {            // Base oops are OK, but not derived oops
--- a/hotspot/src/share/vm/opto/macro.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/opto/macro.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -458,7 +458,7 @@
         }
       } else if (use->is_SafePoint()) {
         SafePointNode* sfpt = use->as_SafePoint();
-        if (sfpt->has_non_debug_use(res)) {
+        if (sfpt->is_Call() && sfpt->as_Call()->has_non_debug_use(res)) {
           // Object is passed as argument.
           DEBUG_ONLY(disq_node = use;)
           NOT_PRODUCT(fail_eliminate = "Object is passed as argument";)
@@ -1282,12 +1282,6 @@
   }
   rawmem = make_store(control, rawmem, object, oopDesc::mark_offset_in_bytes(), mark_node, T_ADDRESS);
 
-  if (UseCompressedOops) {
-    Node *zeronode = makecon(TypeInt::ZERO);
-    // store uncompressed 0 into klass ptr to zero out gap.  The gap is
-    // used for primitive fields and has to be zeroed.
-    rawmem = make_store(control, rawmem, object, oopDesc::klass_gap_offset_in_bytes(), zeronode, T_INT);
-  }
   rawmem = make_store(control, rawmem, object, oopDesc::klass_offset_in_bytes(), klass_node, T_OBJECT);
   int header_size = alloc->minimum_header_size();  // conservatively small
 
--- a/hotspot/src/share/vm/opto/matcher.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/opto/matcher.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -52,7 +52,7 @@
 #ifdef ASSERT
   _old2new_map(C->comp_arena()),
 #endif
-  _shared_constants(C->comp_arena()),
+  _shared_nodes(C->comp_arena()),
   _reduceOp(reduceOp), _leftOp(leftOp), _rightOp(rightOp),
   _swallowed(swallowed),
   _begin_inst_chain_rule(_BEGIN_INST_CHAIN_RULE),
@@ -744,6 +744,7 @@
   if (nidx == Compile::AliasIdxBot && midx == Compile::AliasIdxTop) {
     switch (n->Opcode()) {
     case Op_StrComp:
+    case Op_AryEq:
     case Op_MemBarVolatile:
     case Op_MemBarCPUOrder: // %%% these ideals should have narrower adr_type?
       nidx = Compile::AliasIdxTop;
@@ -880,7 +881,7 @@
         Node *m = n->in(i);          // Get input
         int op = m->Opcode();
         assert((op == Op_BoxLock) == jvms->is_monitor_use(i), "boxes only at monitor sites");
-        if( op == Op_ConI || op == Op_ConP ||
+        if( op == Op_ConI || op == Op_ConP || op == Op_ConN ||
             op == Op_ConF || op == Op_ConD || op == Op_ConL
             // || op == Op_BoxLock  // %%%% enable this and remove (+++) in chaitin.cpp
             ) {
@@ -1191,7 +1192,7 @@
   uint cnt = n->req();
   uint start = 1;
   if( mem != (Node*)1 ) start = MemNode::Memory+1;
-  if( n->Opcode() == Op_AddP ) {
+  if( n->is_AddP() ) {
     assert( mem == (Node*)1, "" );
     start = AddPNode::Base+1;
   }
@@ -1219,7 +1220,7 @@
   if( t->singleton() ) {
     // Never force constants into registers.  Allow them to match as
     // constants or registers.  Copies of the same value will share
-    // the same register.  See find_shared_constant.
+    // the same register.  See find_shared_node.
     return false;
   } else {                      // Not a constant
     // Stop recursion if they have different Controls.
@@ -1243,12 +1244,10 @@
       if( j == max_scan )       // No post-domination before scan end?
         return true;            // Then break the match tree up
     }
-
-    if (m->Opcode() == Op_DecodeN && m->outcnt() == 2) {
+    if (m->is_DecodeN() && Matcher::clone_shift_expressions) {
       // These are commonly used in address expressions and can
-      // efficiently fold into them in some cases but because they are
-      // consumed by AddP they commonly have two users.
-      if (m->raw_out(0) == m->raw_out(1) && m->raw_out(0)->Opcode() == Op_AddP) return false;
+      // efficiently fold into them on X64 in some cases.
+      return false;
     }
   }
 
@@ -1368,13 +1367,16 @@
 // which reduces the number of copies of a constant in the final
 // program.  The register allocator is free to split uses later to
 // split live ranges.
-MachNode* Matcher::find_shared_constant(Node* leaf, uint rule) {
-  if (!leaf->is_Con()) return NULL;
+MachNode* Matcher::find_shared_node(Node* leaf, uint rule) {
+  if (!leaf->is_Con() && !leaf->is_DecodeN()) return NULL;
 
   // See if this Con has already been reduced using this rule.
-  if (_shared_constants.Size() <= leaf->_idx) return NULL;
-  MachNode* last = (MachNode*)_shared_constants.at(leaf->_idx);
+  if (_shared_nodes.Size() <= leaf->_idx) return NULL;
+  MachNode* last = (MachNode*)_shared_nodes.at(leaf->_idx);
   if (last != NULL && rule == last->rule()) {
+    // Don't expect control change for DecodeN
+    if (leaf->is_DecodeN())
+      return last;
     // Get the new space root.
     Node* xroot = new_node(C->root());
     if (xroot == NULL) {
@@ -1420,9 +1422,9 @@
 MachNode *Matcher::ReduceInst( State *s, int rule, Node *&mem ) {
   assert( rule >= NUM_OPERANDS, "called with operand rule" );
 
-  MachNode* shared_con = find_shared_constant(s->_leaf, rule);
-  if (shared_con != NULL) {
-    return shared_con;
+  MachNode* shared_node = find_shared_node(s->_leaf, rule);
+  if (shared_node != NULL) {
+    return shared_node;
   }
 
   // Build the object to represent this state & prepare for recursive calls
@@ -1447,7 +1449,7 @@
     mach->ins_req(MemNode::Memory,mem);
 
   // If the _leaf is an AddP, insert the base edge
-  if( leaf->Opcode() == Op_AddP )
+  if( leaf->is_AddP() )
     mach->ins_req(AddPNode::Base,leaf->in(AddPNode::Base));
 
   uint num_proj = _proj_list.size();
@@ -1475,9 +1477,9 @@
     guarantee(_proj_list.size() == num_proj, "no allocation during spill generation");
   }
 
-  if (leaf->is_Con()) {
+  if (leaf->is_Con() || leaf->is_DecodeN()) {
     // Record the con for sharing
-    _shared_constants.map(leaf->_idx, ex);
+    _shared_nodes.map(leaf->_idx, ex);
   }
 
   return ex;
@@ -1716,6 +1718,7 @@
         mstack.push(n->in(0), Pre_Visit);     // Visit Control input
         continue;                             // while (mstack.is_nonempty())
       case Op_StrComp:
+      case Op_AryEq:
         set_shared(n); // Force result into register (it will be anyways)
         break;
       case Op_ConP: {  // Convert pointers above the centerline to NUL
@@ -1726,6 +1729,14 @@
         }
         break;
       }
+      case Op_ConN: {  // Convert narrow pointers above the centerline to NUL
+        TypeNode *tn = n->as_Type(); // Constants derive from type nodes
+        const TypePtr* tp = tn->type()->is_narrowoop()->make_oopptr();
+        if (tp->_ptr == TypePtr::AnyNull) {
+          tn->set_type(TypeNarrowOop::NULL_PTR);
+        }
+        break;
+      }
       case Op_Binary:         // These are introduced in the Post_Visit state.
         ShouldNotReachHere();
         break;
@@ -1760,6 +1771,7 @@
       case Op_LoadF:
       case Op_LoadI:
       case Op_LoadKlass:
+      case Op_LoadNKlass:
       case Op_LoadL:
       case Op_LoadS:
       case Op_LoadP:
@@ -1817,7 +1829,7 @@
             Node *adr = m->in(AddPNode::Address);
 
             // Intel, ARM and friends can handle 2 adds in addressing mode
-            if( clone_shift_expressions && adr->Opcode() == Op_AddP &&
+            if( clone_shift_expressions && adr->is_AddP() &&
                 // AtomicAdd is not an addressing expression.
                 // Cheap to find it by looking for screwy base.
                 !adr->in(AddPNode::Base)->is_top() ) {
@@ -1891,6 +1903,7 @@
       case Op_CMoveF:
       case Op_CMoveI:
       case Op_CMoveL:
+      case Op_CMoveN:
       case Op_CMoveP: {
         // Restructure into a binary tree for Matching.  It's possible that
         // we could move this code up next to the graph reshaping for IfNodes
--- a/hotspot/src/share/vm/opto/matcher.hpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/opto/matcher.hpp	Wed Jul 05 16:37:51 2017 +0200
@@ -48,7 +48,7 @@
   void ReduceOper( State *s, int newrule, Node *&mem, MachNode *mach );
 
   // If this node already matched using "rule", return the MachNode for it.
-  MachNode* find_shared_constant(Node* con, uint rule);
+  MachNode* find_shared_node(Node* n, uint rule);
 
   // Convert a dense opcode number to an expanded rule number
   const int *_reduceOp;
@@ -81,7 +81,7 @@
 
   Node_List &_proj_list;        // For Machine nodes killing many values
 
-  Node_Array _shared_constants;
+  Node_Array _shared_nodes;
 
   debug_only(Node_Array _old2new_map;)   // Map roots of ideal-trees to machine-roots
 
--- a/hotspot/src/share/vm/opto/memnode.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/opto/memnode.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -133,7 +133,9 @@
     PhiNode *mphi = result->as_Phi();
     assert(mphi->bottom_type() == Type::MEMORY, "memory phi required");
     const TypePtr *t = mphi->adr_type();
-    if (t == TypePtr::BOTTOM || t == TypeRawPtr::BOTTOM) {
+    if (t == TypePtr::BOTTOM || t == TypeRawPtr::BOTTOM ||
+        t->isa_oopptr() && !t->is_oopptr()->is_instance() &&
+        t->is_oopptr()->cast_to_instance(t_oop->instance_id()) == t_oop) {
       // clone the Phi with our address type
       result = mphi->split_out_instance(t_adr, igvn);
     } else {
@@ -154,7 +156,7 @@
                        phase->C->must_alias(adr_check, alias_idx );
     // Sometimes dead array references collapse to a[-1], a[-2], or a[-3]
     if( !consistent && adr_check != NULL && !adr_check->empty() &&
-           tp->isa_aryptr() &&    tp->offset() == Type::OffsetBot &&
+               tp->isa_aryptr() &&        tp->offset() == Type::OffsetBot &&
         adr_check->isa_aryptr() && adr_check->offset() != Type::OffsetBot &&
         ( adr_check->offset() == arrayOopDesc::length_offset_in_bytes() ||
           adr_check->offset() == oopDesc::klass_offset_in_bytes() ||
@@ -251,21 +253,31 @@
   if (dom == NULL || dom->is_top() || sub == NULL || sub->is_top())
     return false; // Conservative answer for dead code
 
-  // Check 'dom'.
+  // Check 'dom'. Skip Proj and CatchProj nodes.
   dom = dom->find_exact_control(dom);
   if (dom == NULL || dom->is_top())
     return false; // Conservative answer for dead code
 
-  if (dom->is_Start() || dom->is_Root() || dom == sub)
+  if (dom == sub) {
+    // For the case when, for example, 'sub' is Initialize and the original
+    // 'dom' is Proj node of the 'sub'.
+    return false;
+  }
+
+  if (dom->is_Con() || dom->is_Start() || dom->is_Root() || dom == sub)
     return true;
 
   // 'dom' dominates 'sub' if its control edge and control edges
   // of all its inputs dominate or equal to sub's control edge.
 
   // Currently 'sub' is either Allocate, Initialize or Start nodes.
-  assert(sub->is_Allocate() || sub->is_Initialize() || sub->is_Start(), "expecting only these nodes");
+  // Or Region for the check in LoadNode::Ideal();
+  // 'sub' should have sub->in(0) != NULL.
+  assert(sub->is_Allocate() || sub->is_Initialize() || sub->is_Start() ||
+         sub->is_Region(), "expecting only these nodes");
 
   // Get control edge of 'sub'.
+  Node* orig_sub = sub;
   sub = sub->find_exact_control(sub->in(0));
   if (sub == NULL || sub->is_top())
     return false; // Conservative answer for dead code
@@ -291,14 +303,16 @@
 
     for (uint next = 0; next < dom_list.size(); next++) {
       Node* n = dom_list.at(next);
+      if (n == orig_sub)
+        return false; // One of dom's inputs dominated by sub.
       if (!n->is_CFG() && n->pinned()) {
         // Check only own control edge for pinned non-control nodes.
         n = n->find_exact_control(n->in(0));
         if (n == NULL || n->is_top())
           return false; // Conservative answer for dead code
         assert(n->is_CFG(), "expecting control");
-      }
-      if (n->is_Start() || n->is_Root()) {
+        dom_list.push(n);
+      } else if (n->is_Con() || n->is_Start() || n->is_Root()) {
         only_dominating_controls = true;
       } else if (n->is_CFG()) {
         if (n->dominates(sub, nlist))
@@ -308,12 +322,11 @@
       } else {
         // First, own control edge.
         Node* m = n->find_exact_control(n->in(0));
-        if (m == NULL)
-          continue;
-        if (m->is_top())
-          return false; // Conservative answer for dead code
-        dom_list.push(m);
-
+        if (m != NULL) {
+          if (m->is_top())
+            return false; // Conservative answer for dead code
+          dom_list.push(m);
+        }
         // Now, the rest of edges.
         uint cnt = n->req();
         for (uint i = 1; i < cnt; i++) {
@@ -577,6 +590,9 @@
 // Find any cast-away of null-ness and keep its control.  Null cast-aways are
 // going away in this pass and we need to make this memory op depend on the
 // gating null check.
+Node *MemNode::Ideal_DU_postCCP( PhaseCCP *ccp ) {
+  return Ideal_common_DU_postCCP(ccp, this, in(MemNode::Address));
+}
 
 // I tried to leave the CastPP's in.  This makes the graph more accurate in
 // some sense; we get to keep around the knowledge that an oop is not-null
@@ -586,15 +602,14 @@
 // some of the more trivial cases in the optimizer.  Removing more useless
 // Phi's started allowing Loads to illegally float above null checks.  I gave
 // up on this approach.  CNC 10/20/2000
-Node *MemNode::Ideal_DU_postCCP( PhaseCCP *ccp ) {
-  Node *ctr = in(MemNode::Control);
-  Node *mem = in(MemNode::Memory);
-  Node *adr = in(MemNode::Address);
+// This static method may be called not from MemNode (EncodePNode calls it).
+// Only the control edge of the node 'n' might be updated.
+Node *MemNode::Ideal_common_DU_postCCP( PhaseCCP *ccp, Node* n, Node* adr ) {
   Node *skipped_cast = NULL;
   // Need a null check?  Regular static accesses do not because they are
   // from constant addresses.  Array ops are gated by the range check (which
   // always includes a NULL check).  Just check field ops.
-  if( !ctr ) {
+  if( n->in(MemNode::Control) == NULL ) {
     // Scan upwards for the highest location we can place this memory op.
     while( true ) {
       switch( adr->Opcode() ) {
@@ -619,10 +634,10 @@
         }
         // CastPP is going away in this pass!  We need this memory op to be
         // control-dependent on the test that is guarding the CastPP.
-        ccp->hash_delete(this);
-        set_req(MemNode::Control, adr->in(0));
-        ccp->hash_insert(this);
-        return this;
+        ccp->hash_delete(n);
+        n->set_req(MemNode::Control, adr->in(0));
+        ccp->hash_insert(n);
+        return n;
 
       case Op_Phi:
         // Attempt to float above a Phi to some dominating point.
@@ -653,10 +668,10 @@
           adr = adr->in(1);
           continue;
         }
-        ccp->hash_delete(this);
-        set_req(MemNode::Control, adr->in(0));
-        ccp->hash_insert(this);
-        return this;
+        ccp->hash_delete(n);
+        n->set_req(MemNode::Control, adr->in(0));
+        ccp->hash_insert(n);
+        return n;
 
         // List of "safe" opcodes; those that implicitly block the memory
         // op below any null check.
@@ -665,10 +680,13 @@
       case Op_LoadP:            // Loading from within a klass
       case Op_LoadN:            // Loading from within a klass
       case Op_LoadKlass:        // Loading from within a klass
+      case Op_LoadNKlass:       // Loading from within a klass
       case Op_ConP:             // Loading from a klass
+      case Op_ConN:             // Loading from a klass
       case Op_CreateEx:         // Sucking up the guts of an exception oop
       case Op_Con:              // Reading from TLS
       case Op_CMoveP:           // CMoveP is pinned
+      case Op_CMoveN:           // CMoveN is pinned
         break;                  // No progress
 
       case Op_Proj:             // Direct call to an allocation routine
@@ -677,8 +695,8 @@
         {
           assert(adr->as_Proj()->_con == TypeFunc::Parms, "must be return value");
           const Node* call = adr->in(0);
-          if (call->is_CallStaticJava()) {
-            const CallStaticJavaNode* call_java = call->as_CallStaticJava();
+          if (call->is_CallJava()) {
+            const CallJavaNode* call_java = call->as_CallJava();
             const TypeTuple *r = call_java->tf()->range();
             assert(r->cnt() > TypeFunc::Parms, "must return value");
             const Type* ret_type = r->field_at(TypeFunc::Parms);
@@ -750,7 +768,7 @@
   case T_ADDRESS: return new (C, 3) LoadPNode(ctl, mem, adr, adr_type, rt->is_ptr()    );
   case T_OBJECT:
 #ifdef _LP64
-    if (adr->bottom_type()->is_narrow()) {
+    if (adr->bottom_type()->is_ptr_to_narrowoop()) {
       const TypeNarrowOop* narrowtype;
       if (rt->isa_narrowoop()) {
         narrowtype = rt->is_narrowoop();
@@ -762,10 +780,10 @@
       return DecodeNNode::decode(&gvn, load);
     } else
 #endif
-      {
-        assert(!adr->bottom_type()->is_narrow(), "should have got back a narrow oop");
-        return new (C, 3) LoadPNode(ctl, mem, adr, adr_type, rt->is_oopptr());
-      }
+    {
+      assert(!adr->bottom_type()->is_ptr_to_narrowoop(), "should have got back a narrow oop");
+      return new (C, 3) LoadPNode(ctl, mem, adr, adr_type, rt->is_oopptr());
+    }
   }
   ShouldNotReachHere();
   return (LoadNode*)NULL;
@@ -1119,6 +1137,127 @@
   return NULL;
 }
 
+//------------------------------split_through_phi------------------------------
+// Split instance field load through Phi.
+Node *LoadNode::split_through_phi(PhaseGVN *phase) {
+  Node* mem     = in(MemNode::Memory);
+  Node* address = in(MemNode::Address);
+  const TypePtr *addr_t = phase->type(address)->isa_ptr();
+  const TypeOopPtr *t_oop = addr_t->isa_oopptr();
+
+  assert(mem->is_Phi() && (t_oop != NULL) &&
+         t_oop->is_instance_field(), "invalide conditions");
+
+  Node *region = mem->in(0);
+  if (region == NULL) {
+    return NULL; // Wait stable graph
+  }
+  uint cnt = mem->req();
+  for( uint i = 1; i < cnt; i++ ) {
+    Node *in = mem->in(i);
+    if( in == NULL ) {
+      return NULL; // Wait stable graph
+    }
+  }
+  // Check for loop invariant.
+  if (cnt == 3) {
+    for( uint i = 1; i < cnt; i++ ) {
+      Node *in = mem->in(i);
+      Node* m = MemNode::optimize_memory_chain(in, addr_t, phase);
+      if (m == mem) {
+        set_req(MemNode::Memory, mem->in(cnt - i)); // Skip this phi.
+        return this;
+      }
+    }
+  }
+  // Split through Phi (see original code in loopopts.cpp).
+  assert(phase->C->have_alias_type(addr_t), "instance should have alias type");
+
+  // Do nothing here if Identity will find a value
+  // (to avoid infinite chain of value phis generation).
+  if ( !phase->eqv(this, this->Identity(phase)) )
+    return NULL;
+
+  // Skip the split if the region dominates some control edge of the address.
+  if (cnt == 3 && !MemNode::all_controls_dominate(address, region))
+    return NULL;
+
+  const Type* this_type = this->bottom_type();
+  int this_index  = phase->C->get_alias_index(addr_t);
+  int this_offset = addr_t->offset();
+  int this_iid    = addr_t->is_oopptr()->instance_id();
+  int wins = 0;
+  PhaseIterGVN *igvn = phase->is_IterGVN();
+  Node *phi = new (igvn->C, region->req()) PhiNode(region, this_type, NULL, this_iid, this_index, this_offset);
+  for( uint i = 1; i < region->req(); i++ ) {
+    Node *x;
+    Node* the_clone = NULL;
+    if( region->in(i) == phase->C->top() ) {
+      x = phase->C->top();      // Dead path?  Use a dead data op
+    } else {
+      x = this->clone();        // Else clone up the data op
+      the_clone = x;            // Remember for possible deletion.
+      // Alter data node to use pre-phi inputs
+      if( this->in(0) == region ) {
+        x->set_req( 0, region->in(i) );
+      } else {
+        x->set_req( 0, NULL );
+      }
+      for( uint j = 1; j < this->req(); j++ ) {
+        Node *in = this->in(j);
+        if( in->is_Phi() && in->in(0) == region )
+          x->set_req( j, in->in(i) ); // Use pre-Phi input for the clone
+      }
+    }
+    // Check for a 'win' on some paths
+    const Type *t = x->Value(igvn);
+
+    bool singleton = t->singleton();
+
+    // See comments in PhaseIdealLoop::split_thru_phi().
+    if( singleton && t == Type::TOP ) {
+      singleton &= region->is_Loop() && (i != LoopNode::EntryControl);
+    }
+
+    if( singleton ) {
+      wins++;
+      x = igvn->makecon(t);
+    } else {
+      // We now call Identity to try to simplify the cloned node.
+      // Note that some Identity methods call phase->type(this).
+      // Make sure that the type array is big enough for
+      // our new node, even though we may throw the node away.
+      // (This tweaking with igvn only works because x is a new node.)
+      igvn->set_type(x, t);
+      Node *y = x->Identity(igvn);
+      if( y != x ) {
+        wins++;
+        x = y;
+      } else {
+        y = igvn->hash_find(x);
+        if( y ) {
+          wins++;
+          x = y;
+        } else {
+          // Else x is a new node we are keeping
+          // We do not need register_new_node_with_optimizer
+          // because set_type has already been called.
+          igvn->_worklist.push(x);
+        }
+      }
+    }
+    if (x != the_clone && the_clone != NULL)
+      igvn->remove_dead_node(the_clone);
+    phi->set_req(i, x);
+  }
+  if( wins > 0 ) {
+    // Record Phi
+    igvn->register_new_node_with_optimizer(phi);
+    return phi;
+  }
+  igvn->remove_dead_node(phi);
+  return NULL;
+}
 
 //------------------------------Ideal------------------------------------------
 // If the load is from Field memory and the pointer is non-null, we can
@@ -1176,112 +1315,9 @@
     const TypeOopPtr *t_oop = addr_t->isa_oopptr();
     if (can_reshape && opt_mem->is_Phi() &&
         (t_oop != NULL) && t_oop->is_instance_field()) {
-      assert(t_oop->offset() != Type::OffsetBot && t_oop->offset() != Type::OffsetTop, "");
-      Node *region = opt_mem->in(0);
-      uint cnt = opt_mem->req();
-      for( uint i = 1; i < cnt; i++ ) {
-        Node *in = opt_mem->in(i);
-        if( in == NULL ) {
-          region = NULL; // Wait stable graph
-          break;
-        }
-      }
-      if (region != NULL) {
-        // Check for loop invariant.
-        if (cnt == 3) {
-          for( uint i = 1; i < cnt; i++ ) {
-            Node *in = opt_mem->in(i);
-            Node* m = MemNode::optimize_memory_chain(in, addr_t, phase);
-            if (m == opt_mem) {
-              set_req(MemNode::Memory, opt_mem->in(cnt - i)); // Skip this phi.
-              return this;
-            }
-          }
-        }
-        // Split through Phi (see original code in loopopts.cpp).
-        assert(phase->C->have_alias_type(addr_t), "instance should have alias type");
-
-        // Do nothing here if Identity will find a value
-        // (to avoid infinite chain of value phis generation).
-        if ( !phase->eqv(this, this->Identity(phase)) )
-          return NULL;
-
-        const Type* this_type = this->bottom_type();
-        int this_index  = phase->C->get_alias_index(addr_t);
-        int this_offset = addr_t->offset();
-        int this_iid    = addr_t->is_oopptr()->instance_id();
-        int wins = 0;
-        PhaseIterGVN *igvn = phase->is_IterGVN();
-        Node *phi = new (igvn->C, region->req()) PhiNode(region, this_type, NULL, this_iid, this_index, this_offset);
-        for( uint i = 1; i < region->req(); i++ ) {
-          Node *x;
-          Node* the_clone = NULL;
-          if( region->in(i) == phase->C->top() ) {
-            x = phase->C->top();      // Dead path?  Use a dead data op
-          } else {
-            x = this->clone();        // Else clone up the data op
-            the_clone = x;            // Remember for possible deletion.
-            // Alter data node to use pre-phi inputs
-            if( this->in(0) == region ) {
-              x->set_req( 0, region->in(i) );
-            } else {
-              x->set_req( 0, NULL );
-            }
-            for( uint j = 1; j < this->req(); j++ ) {
-              Node *in = this->in(j);
-              if( in->is_Phi() && in->in(0) == region )
-                x->set_req( j, in->in(i) ); // Use pre-Phi input for the clone
-            }
-          }
-          // Check for a 'win' on some paths
-          const Type *t = x->Value(igvn);
-
-          bool singleton = t->singleton();
-
-          // See comments in PhaseIdealLoop::split_thru_phi().
-          if( singleton && t == Type::TOP ) {
-            singleton &= region->is_Loop() && (i != LoopNode::EntryControl);
-          }
-
-          if( singleton ) {
-            wins++;
-            x = igvn->makecon(t);
-          } else {
-            // We now call Identity to try to simplify the cloned node.
-            // Note that some Identity methods call phase->type(this).
-            // Make sure that the type array is big enough for
-            // our new node, even though we may throw the node away.
-            // (This tweaking with igvn only works because x is a new node.)
-            igvn->set_type(x, t);
-            Node *y = x->Identity(igvn);
-            if( y != x ) {
-              wins++;
-              x = y;
-            } else {
-              y = igvn->hash_find(x);
-              if( y ) {
-                wins++;
-                x = y;
-              } else {
-                // Else x is a new node we are keeping
-                // We do not need register_new_node_with_optimizer
-                // because set_type has already been called.
-                igvn->_worklist.push(x);
-              }
-            }
-          }
-          if (x != the_clone && the_clone != NULL)
-            igvn->remove_dead_node(the_clone);
-          phi->set_req(i, x);
-        }
-        if( wins > 0 ) {
-          // Record Phi
-          igvn->register_new_node_with_optimizer(phi);
-          return phi;
-        } else {
-          igvn->remove_dead_node(phi);
-        }
-      }
+      // Split instance field load through Phi.
+      Node* result = split_through_phi(phase);
+      if (result != NULL) return result;
     }
   }
 
@@ -1585,8 +1621,31 @@
 }
 
 //=============================================================================
+//----------------------------LoadKlassNode::make------------------------------
+// Polymorphic factory method:
+Node *LoadKlassNode::make( PhaseGVN& gvn, Node *mem, Node *adr, const TypePtr* at, const TypeKlassPtr *tk ) {
+  Compile* C = gvn.C;
+  Node *ctl = NULL;
+  // sanity check the alias category against the created node type
+  const TypeOopPtr *adr_type = adr->bottom_type()->isa_oopptr();
+  assert(adr_type != NULL, "expecting TypeOopPtr");
+#ifdef _LP64
+  if (adr_type->is_ptr_to_narrowoop()) {
+    const TypeNarrowOop* narrowtype = tk->is_oopptr()->make_narrowoop();
+    Node* load_klass = gvn.transform(new (C, 3) LoadNKlassNode(ctl, mem, adr, at, narrowtype));
+    return DecodeNNode::decode(&gvn, load_klass);
+  }
+#endif
+  assert(!adr_type->is_ptr_to_narrowoop(), "should have got back a narrow oop");
+  return new (C, 3) LoadKlassNode(ctl, mem, adr, at, tk);
+}
+
 //------------------------------Value------------------------------------------
 const Type *LoadKlassNode::Value( PhaseTransform *phase ) const {
+  return klass_value_common(phase);
+}
+
+const Type *LoadNode::klass_value_common( PhaseTransform *phase ) const {
   // Either input is TOP ==> the result is TOP
   const Type *t1 = phase->type( in(MemNode::Memory) );
   if (t1 == Type::TOP)  return Type::TOP;
@@ -1718,6 +1777,10 @@
 // To clean up reflective code, simplify k.java_mirror.as_klass to plain k.
 // Also feed through the klass in Allocate(...klass...)._klass.
 Node* LoadKlassNode::Identity( PhaseTransform *phase ) {
+  return klass_identity_common(phase);
+}
+
+Node* LoadNode::klass_identity_common(PhaseTransform *phase ) {
   Node* x = LoadNode::Identity(phase);
   if (x != this)  return x;
 
@@ -1776,6 +1839,34 @@
   return this;
 }
 
+
+//------------------------------Value------------------------------------------
+const Type *LoadNKlassNode::Value( PhaseTransform *phase ) const {
+  const Type *t = klass_value_common(phase);
+
+  if (t == TypePtr::NULL_PTR) {
+    return TypeNarrowOop::NULL_PTR;
+  }
+  if (t != Type::TOP && !t->isa_narrowoop()) {
+    assert(t->is_oopptr(), "sanity");
+    t = t->is_oopptr()->make_narrowoop();
+  }
+  return t;
+}
+
+//------------------------------Identity---------------------------------------
+// To clean up reflective code, simplify k.java_mirror.as_klass to narrow k.
+// Also feed through the klass in Allocate(...klass...)._klass.
+Node* LoadNKlassNode::Identity( PhaseTransform *phase ) {
+  Node *x = klass_identity_common(phase);
+
+  const Type *t = phase->type( x );
+  if( t == Type::TOP ) return x;
+  if( t->isa_narrowoop()) return x;
+
+  return EncodePNode::encode(phase, x);
+}
+
 //------------------------------Value-----------------------------------------
 const Type *LoadRangeNode::Value( PhaseTransform *phase ) const {
   // Either input is TOP ==> the result is TOP
@@ -1836,7 +1927,7 @@
   case T_ADDRESS:
   case T_OBJECT:
 #ifdef _LP64
-    if (adr->bottom_type()->is_narrow() ||
+    if (adr->bottom_type()->is_ptr_to_narrowoop() ||
         (UseCompressedOops && val->bottom_type()->isa_klassptr() &&
          adr->bottom_type()->isa_rawptr())) {
       const TypePtr* type = val->bottom_type()->is_ptr();
@@ -2312,6 +2403,13 @@
   return remove_dead_region(phase, can_reshape) ? this : NULL;
 }
 
+//------------------------------Ideal------------------------------------------
+// Return a node which is more "ideal" than the current node.  Strip out
+// control copies
+Node *AryEqNode::Ideal(PhaseGVN *phase, bool can_reshape){
+  return remove_dead_region(phase, can_reshape) ? this : NULL;
+}
+
 
 //=============================================================================
 MemBarNode::MemBarNode(Compile* C, int alias_idx, Node* precedent)
--- a/hotspot/src/share/vm/opto/memnode.hpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/opto/memnode.hpp	Wed Jul 05 16:37:51 2017 +0200
@@ -72,7 +72,8 @@
   // This one should probably be a phase-specific function:
   static bool all_controls_dominate(Node* dom, Node* sub);
 
-  // Is this Node a MemNode or some descendent?  Default is YES.
+  // Find any cast-away of null-ness and keep its control.
+  static  Node *Ideal_common_DU_postCCP( PhaseCCP *ccp, Node* n, Node* adr );
   virtual Node *Ideal_DU_postCCP( PhaseCCP *ccp );
 
   virtual const class TypePtr *adr_type() const;  // returns bottom_type of address
@@ -150,6 +151,9 @@
   // zero out the control input.
   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
 
+  // Split instance field load through Phi.
+  Node* split_through_phi(PhaseGVN *phase);
+
   // Recover original value from boxed values
   Node *eliminate_autobox(PhaseGVN *phase);
 
@@ -157,6 +161,10 @@
   // then call the virtual add() to set the type.
   virtual const Type *Value( PhaseTransform *phase ) const;
 
+  // Common methods for LoadKlass and LoadNKlass nodes.
+  const Type *klass_value_common( PhaseTransform *phase ) const;
+  Node *klass_identity_common( PhaseTransform *phase );
+
   virtual uint ideal_reg() const;
   virtual const Type *bottom_type() const;
   // Following method is copied from TypeNode:
@@ -358,14 +366,35 @@
 // Load a Klass from an object
 class LoadKlassNode : public LoadPNode {
 public:
-  LoadKlassNode( Node *c, Node *mem, Node *adr, const TypePtr *at, const TypeKlassPtr *tk = TypeKlassPtr::OBJECT )
+  LoadKlassNode( Node *c, Node *mem, Node *adr, const TypePtr *at, const TypeKlassPtr *tk )
     : LoadPNode(c,mem,adr,at,tk) {}
   virtual int Opcode() const;
   virtual const Type *Value( PhaseTransform *phase ) const;
   virtual Node *Identity( PhaseTransform *phase );
   virtual bool depends_only_on_test() const { return true; }
+
+  // Polymorphic factory method:
+  static Node* make( PhaseGVN& gvn, Node *mem, Node *adr, const TypePtr* at,
+                     const TypeKlassPtr *tk = TypeKlassPtr::OBJECT );
 };
 
+//------------------------------LoadNKlassNode---------------------------------
+// Load a narrow Klass from an object.
+class LoadNKlassNode : public LoadNNode {
+public:
+  LoadNKlassNode( Node *c, Node *mem, Node *adr, const TypePtr *at, const TypeNarrowOop *tk )
+    : LoadNNode(c,mem,adr,at,tk) {}
+  virtual int Opcode() const;
+  virtual uint ideal_reg() const { return Op_RegN; }
+  virtual int store_Opcode() const { return Op_StoreN; }
+  virtual BasicType memory_type() const { return T_NARROWOOP; }
+
+  virtual const Type *Value( PhaseTransform *phase ) const;
+  virtual Node *Identity( PhaseTransform *phase );
+  virtual bool depends_only_on_test() const { return true; }
+};
+
+
 //------------------------------LoadSNode--------------------------------------
 // Load a short (16bits signed) from memory
 class LoadSNode : public LoadNode {
@@ -696,6 +725,18 @@
   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
 };
 
+//------------------------------AryEq---------------------------------------
+class AryEqNode: public Node {
+public:
+  AryEqNode(Node *control, Node* s1, Node* s2): Node(control, s1, s2) {};
+  virtual int Opcode() const;
+  virtual bool depends_only_on_test() const { return false; }
+  virtual const Type* bottom_type() const { return TypeInt::BOOL; }
+  virtual const TypePtr* adr_type() const { return TypeAryPtr::CHARS; }
+  virtual uint ideal_reg() const { return Op_RegI; }
+  virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
+};
+
 //------------------------------MemBar-----------------------------------------
 // There are different flavors of Memory Barriers to match the Java Memory
 // Model.  Monitor-enter and volatile-load act as Aquires: no following ref
--- a/hotspot/src/share/vm/opto/node.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/opto/node.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -1039,76 +1039,125 @@
 //--------------------------dominates------------------------------------------
 // Helper function for MemNode::all_controls_dominate().
 // Check if 'this' control node dominates or equal to 'sub' control node.
+// We already know that if any path back to Root or Start reaches 'this',
+// then all paths so, so this is a simple search for one example,
+// not an exhaustive search for a counterexample.
 bool Node::dominates(Node* sub, Node_List &nlist) {
   assert(this->is_CFG(), "expecting control");
   assert(sub != NULL && sub->is_CFG(), "expecting control");
 
+  // detect dead cycle without regions
+  int iterations_without_region_limit = DominatorSearchLimit;
+
   Node* orig_sub = sub;
+  Node* dom      = this;
+  bool  met_dom  = false;
   nlist.clear();
-  bool this_dominates = false;
-  uint region_input = 0;
-  while (sub != NULL) {        // walk 'sub' up the chain to 'this'
-    if (sub == this) {
+
+  // Walk 'sub' backward up the chain to 'dom', watching for regions.
+  // After seeing 'dom', continue up to Root or Start.
+  // If we hit a region (backward split point), it may be a loop head.
+  // Keep going through one of the region's inputs.  If we reach the
+  // same region again, go through a different input.  Eventually we
+  // will either exit through the loop head, or give up.
+  // (If we get confused, break out and return a conservative 'false'.)
+  while (sub != NULL) {
+    if (sub->is_top())  break; // Conservative answer for dead code.
+    if (sub == dom) {
       if (nlist.size() == 0) {
         // No Region nodes except loops were visited before and the EntryControl
         // path was taken for loops: it did not walk in a cycle.
         return true;
-      } else if (!this_dominates) {
+      } else if (met_dom) {
+        break;          // already met before: walk in a cycle
+      } else {
         // Region nodes were visited. Continue walk up to Start or Root
         // to make sure that it did not walk in a cycle.
-        this_dominates = true; // first time meet
-      } else {
-        return false;          // already met before: walk in a cycle
-      }
+        met_dom = true; // first time meet
+        iterations_without_region_limit = DominatorSearchLimit; // Reset
+     }
+    }
+    if (sub->is_Start() || sub->is_Root()) {
+      // Success if we met 'dom' along a path to Start or Root.
+      // We assume there are no alternative paths that avoid 'dom'.
+      // (This assumption is up to the caller to ensure!)
+      return met_dom;
     }
-    if (sub->is_Start() || sub->is_Root())
-      return this_dominates;
-
-    Node* up = sub->find_exact_control(sub->in(0));
-    if (up == NULL || up->is_top())
-      return false; // Conservative answer for dead code
-
+    Node* up = sub->in(0);
+    // Normalize simple pass-through regions and projections:
+    up = sub->find_exact_control(up);
+    // If sub == up, we found a self-loop.  Try to push past it.
     if (sub == up && sub->is_Loop()) {
-      up = sub->in(0); // in(LoopNode::EntryControl);
+      // Take loop entry path on the way up to 'dom'.
+      up = sub->in(1); // in(LoopNode::EntryControl);
+    } else if (sub == up && sub->is_Region() && sub->req() != 3) {
+      // Always take in(1) path on the way up to 'dom' for clone regions
+      // (with only one input) or regions which merge > 2 paths
+      // (usually used to merge fast/slow paths).
+      up = sub->in(1);
     } else if (sub == up && sub->is_Region()) {
-      uint i = 1;
-      if (nlist.size() == 0) {
-        // No Region nodes (except Loops) were visited before.
-        // Take first valid path on the way up to 'this'.
-      } else if (nlist.at(nlist.size() - 1) == sub) {
-        // This Region node was just visited. Take other path.
-        i = region_input + 1;
-        nlist.pop();
-      } else {
-        // Was this Region node visited before?
-        uint size = nlist.size();
-        for (uint j = 0; j < size; j++) {
-          if (nlist.at(j) == sub) {
-            return false; // The Region node was visited before. Give up.
+      // Try both paths for Regions with 2 input paths (it may be a loop head).
+      // It could give conservative 'false' answer without information
+      // which region's input is the entry path.
+      iterations_without_region_limit = DominatorSearchLimit; // Reset
+
+      bool region_was_visited_before = false;
+      // Was this Region node visited before?
+      // If so, we have reached it because we accidentally took a
+      // loop-back edge from 'sub' back into the body of the loop,
+      // and worked our way up again to the loop header 'sub'.
+      // So, take the first unexplored path on the way up to 'dom'.
+      for (int j = nlist.size() - 1; j >= 0; j--) {
+        intptr_t ni = (intptr_t)nlist.at(j);
+        Node* visited = (Node*)(ni & ~1);
+        bool  visited_twice_already = ((ni & 1) != 0);
+        if (visited == sub) {
+          if (visited_twice_already) {
+            // Visited 2 paths, but still stuck in loop body.  Give up.
+            return false;
           }
-        }
-        // The Region node was not visited before.
-        // Take first valid path on the way up to 'this'.
-      }
-      for (; i < sub->req(); i++) {
-        Node* in = sub->in(i);
-        if (in != NULL && !in->is_top() && in != sub) {
+          // The Region node was visited before only once.
+          // (We will repush with the low bit set, below.)
+          nlist.remove(j);
+          // We will find a new edge and re-insert.
+          region_was_visited_before = true;
           break;
         }
       }
-      if (i < sub->req()) {
-        nlist.push(sub);
-        up = sub->in(i);
-        region_input = i;
+
+      // Find an incoming edge which has not been seen yet; walk through it.
+      assert(up == sub, "");
+      uint skip = region_was_visited_before ? 1 : 0;
+      for (uint i = 1; i < sub->req(); i++) {
+        Node* in = sub->in(i);
+        if (in != NULL && !in->is_top() && in != sub) {
+          if (skip == 0) {
+            up = in;
+            break;
+          }
+          --skip;               // skip this nontrivial input
+        }
       }
+
+      // Set 0 bit to indicate that both paths were taken.
+      nlist.push((Node*)((intptr_t)sub + (region_was_visited_before ? 1 : 0)));
     }
-    if (sub == up)
-      return false;    // some kind of tight cycle
-    if (orig_sub == up)
-      return false;    // walk in a cycle
 
+    if (up == sub) {
+      break;    // some kind of tight cycle
+    }
+    if (up == orig_sub && met_dom) {
+      // returned back after visiting 'dom'
+      break;    // some kind of cycle
+    }
+    if (--iterations_without_region_limit < 0) {
+      break;    // dead cycle
+    }
     sub = up;
   }
+
+  // Did not meet Root or Start node in pred. chain.
+  // Conservative answer for dead code.
   return false;
 }
 
--- a/hotspot/src/share/vm/opto/node.hpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/opto/node.hpp	Wed Jul 05 16:37:51 2017 +0200
@@ -53,6 +53,8 @@
 class ConNode;
 class CountedLoopNode;
 class CountedLoopEndNode;
+class DecodeNNode;
+class EncodePNode;
 class FastLockNode;
 class FastUnlockNode;
 class IfNode;
@@ -438,6 +440,12 @@
 public:
   // Globally replace this node by a given new node, updating all uses.
   void replace_by(Node* new_node);
+  // Globally replace this node by a given new node, updating all uses
+  // and cutting input edges of old node.
+  void subsume_by(Node* new_node) {
+    replace_by(new_node);
+    disconnect_inputs(NULL);
+  }
   void set_req_X( uint i, Node *n, PhaseIterGVN *igvn );
   // Find the one non-null required input.  RegionNode only
   Node *nonnull_req() const;
@@ -577,6 +585,8 @@
       DEFINE_CLASS_ID(CheckCastPP, Type, 2)
       DEFINE_CLASS_ID(CMove, Type, 3)
       DEFINE_CLASS_ID(SafePointScalarObject, Type, 4)
+      DEFINE_CLASS_ID(DecodeN, Type, 5)
+      DEFINE_CLASS_ID(EncodeP, Type, 6)
 
     DEFINE_CLASS_ID(Mem,   Node, 6)
       DEFINE_CLASS_ID(Load,  Mem, 0)
@@ -685,6 +695,8 @@
   DEFINE_CLASS_QUERY(Cmp)
   DEFINE_CLASS_QUERY(CountedLoop)
   DEFINE_CLASS_QUERY(CountedLoopEnd)
+  DEFINE_CLASS_QUERY(DecodeN)
+  DEFINE_CLASS_QUERY(EncodeP)
   DEFINE_CLASS_QUERY(FastLock)
   DEFINE_CLASS_QUERY(FastUnlock)
   DEFINE_CLASS_QUERY(If)
--- a/hotspot/src/share/vm/opto/output.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/opto/output.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -48,6 +48,7 @@
   // Initialize the space for the BufferBlob used to find and verify
   // instruction size in MachNode::emit_size()
   init_scratch_buffer_blob();
+  if (failing())  return; // Out of memory
 
   // Make sure I can find the Start Node
   Block_Array& bbs = _cfg->_bbs;
--- a/hotspot/src/share/vm/opto/parse1.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/opto/parse1.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -1901,7 +1901,7 @@
   // finalization.  In general this will fold up since the concrete
   // class is often visible so the access flags are constant.
   Node* klass_addr = basic_plus_adr( receiver, receiver, oopDesc::klass_offset_in_bytes() );
-  Node* klass = _gvn.transform(new (C, 3) LoadKlassNode(NULL, immutable_memory(), klass_addr, TypeInstPtr::KLASS));
+  Node* klass = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), klass_addr, TypeInstPtr::KLASS) );
 
   Node* access_flags_addr = basic_plus_adr(klass, klass, Klass::access_flags_offset_in_bytes() + sizeof(oopDesc));
   Node* access_flags = make_load(NULL, access_flags_addr, TypeInt::INT, T_INT);
--- a/hotspot/src/share/vm/opto/parseHelper.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/opto/parseHelper.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -38,7 +38,7 @@
 
   // Get method
   const TypeInstPtr* method_type = TypeInstPtr::make(TypePtr::Constant, method->klass(), true, method, 0);
-  Node *method_node = _gvn.transform( new (C, 1) ConPNode(method_type) );
+  Node *method_node = _gvn.transform( ConNode::make(C, method_type) );
 
   kill_dead_locals();
 
@@ -143,7 +143,7 @@
   int klass_offset = oopDesc::klass_offset_in_bytes();
   Node* p = basic_plus_adr( ary, ary, klass_offset );
   // p's type is array-of-OOPS plus klass_offset
-  Node* array_klass = _gvn.transform(new (C, 3) LoadKlassNode(0, immutable_memory(), p, TypeInstPtr::KLASS));
+  Node* array_klass = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p, TypeInstPtr::KLASS) );
   // Get the array klass
   const TypeKlassPtr *tak = _gvn.type(array_klass)->is_klassptr();
 
@@ -189,7 +189,7 @@
   // Extract the array element class
   int element_klass_offset = objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc);
   Node *p2 = basic_plus_adr(array_klass, array_klass, element_klass_offset);
-  Node *a_e_klass = _gvn.transform(new (C, 3) LoadKlassNode(0, immutable_memory(), p2, tak));
+  Node *a_e_klass = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p2, tak) );
 
   // Check (the hard way) and throw if not a subklass.
   // Result is ignored, we just need the CFG effects.
--- a/hotspot/src/share/vm/opto/type.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/opto/type.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -311,8 +311,18 @@
   mreg2type[Op_RegFlags] = TypeInt::CC;
 
   TypeAryPtr::RANGE   = TypeAryPtr::make( TypePtr::BotPTR, TypeAry::make(Type::BOTTOM,TypeInt::POS), current->env()->Object_klass(), false, arrayOopDesc::length_offset_in_bytes());
-  // There is no shared klass for Object[].  See note in TypeAryPtr::klass().
-  TypeAryPtr::OOPS    = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeInstPtr::BOTTOM,TypeInt::POS), NULL /*ciArrayKlass::make(o)*/,  false,  Type::OffsetBot);
+
+  TypeAryPtr::NARROWOOPS = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeNarrowOop::BOTTOM, TypeInt::POS), NULL /*ciArrayKlass::make(o)*/,  false,  Type::OffsetBot);
+
+#ifdef _LP64
+  if (UseCompressedOops) {
+    TypeAryPtr::OOPS  = TypeAryPtr::NARROWOOPS;
+  } else
+#endif
+  {
+    // There is no shared klass for Object[].  See note in TypeAryPtr::klass().
+    TypeAryPtr::OOPS  = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeInstPtr::BOTTOM,TypeInt::POS), NULL /*ciArrayKlass::make(o)*/,  false,  Type::OffsetBot);
+  }
   TypeAryPtr::BYTES   = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeInt::BYTE      ,TypeInt::POS), ciTypeArrayKlass::make(T_BYTE),   true,  Type::OffsetBot);
   TypeAryPtr::SHORTS  = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeInt::SHORT     ,TypeInt::POS), ciTypeArrayKlass::make(T_SHORT),  true,  Type::OffsetBot);
   TypeAryPtr::CHARS   = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeInt::CHAR      ,TypeInt::POS), ciTypeArrayKlass::make(T_CHAR),   true,  Type::OffsetBot);
@@ -321,9 +331,10 @@
   TypeAryPtr::FLOATS  = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(Type::FLOAT        ,TypeInt::POS), ciTypeArrayKlass::make(T_FLOAT),  true,  Type::OffsetBot);
   TypeAryPtr::DOUBLES = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(Type::DOUBLE       ,TypeInt::POS), ciTypeArrayKlass::make(T_DOUBLE), true,  Type::OffsetBot);
 
-  TypeAryPtr::_array_body_type[T_NARROWOOP] = NULL; // what should this be?
+  // Nobody should ask _array_body_type[T_NARROWOOP]. Use NULL as assert.
+  TypeAryPtr::_array_body_type[T_NARROWOOP] = NULL;
   TypeAryPtr::_array_body_type[T_OBJECT]  = TypeAryPtr::OOPS;
-  TypeAryPtr::_array_body_type[T_ARRAY]   = TypeAryPtr::OOPS;   // arrays are stored in oop arrays
+  TypeAryPtr::_array_body_type[T_ARRAY]   = TypeAryPtr::OOPS; // arrays are stored in oop arrays
   TypeAryPtr::_array_body_type[T_BYTE]    = TypeAryPtr::BYTES;
   TypeAryPtr::_array_body_type[T_BOOLEAN] = TypeAryPtr::BYTES;  // boolean[] is a byte array
   TypeAryPtr::_array_body_type[T_SHORT]   = TypeAryPtr::SHORTS;
@@ -696,7 +707,7 @@
   ResourceMark rm;
   Dict d(cmpkey,hashkey);       // Stop recursive type dumping
   dump2(d,1, st);
-  if (isa_ptr() && is_ptr()->is_narrow()) {
+  if (is_ptr_to_narrowoop()) {
     st->print(" [narrow]");
   }
 }
@@ -929,6 +940,7 @@
   case InstPtr:
   case KlassPtr:
   case AryPtr:
+  case NarrowOop:
   case Int:
   case Long:
   case FloatTop:
@@ -1075,6 +1087,7 @@
   case InstPtr:
   case KlassPtr:
   case AryPtr:
+  case NarrowOop:
   case Long:
   case FloatTop:
   case FloatCon:
@@ -1082,7 +1095,6 @@
   case DoubleTop:
   case DoubleCon:
   case DoubleBot:
-  case NarrowOop:
   case Bottom:                  // Ye Olde Default
     return Type::BOTTOM;
   default:                      // All else is a mistake
@@ -1317,6 +1329,7 @@
   case InstPtr:
   case KlassPtr:
   case AryPtr:
+  case NarrowOop:
   case Int:
   case FloatTop:
   case FloatCon:
@@ -2146,6 +2159,67 @@
 // Convenience common pre-built type.
 const TypeOopPtr *TypeOopPtr::BOTTOM;
 
+//------------------------------TypeOopPtr-------------------------------------
+TypeOopPtr::TypeOopPtr( TYPES t, PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id )
+  : TypePtr(t, ptr, offset),
+    _const_oop(o), _klass(k),
+    _klass_is_exact(xk),
+    _is_ptr_to_narrowoop(false),
+    _instance_id(instance_id) {
+#ifdef _LP64
+  if (UseCompressedOops && _offset != 0) {
+    if (klass() == NULL) {
+      assert(this->isa_aryptr(), "only arrays without klass");
+      _is_ptr_to_narrowoop = true;
+    } else if (_offset == oopDesc::klass_offset_in_bytes()) {
+      _is_ptr_to_narrowoop = true;
+    } else if (this->isa_aryptr()) {
+      _is_ptr_to_narrowoop = (klass()->is_obj_array_klass() &&
+                             _offset != arrayOopDesc::length_offset_in_bytes());
+    } else if (klass() == ciEnv::current()->Class_klass() &&
+               (_offset == java_lang_Class::klass_offset_in_bytes() ||
+                _offset == java_lang_Class::array_klass_offset_in_bytes())) {
+      // Special hidden fields from the Class.
+      assert(this->isa_instptr(), "must be an instance ptr.");
+      _is_ptr_to_narrowoop = true;
+    } else if (klass()->is_instance_klass()) {
+      ciInstanceKlass* ik = klass()->as_instance_klass();
+      ciField* field = NULL;
+      if (this->isa_klassptr()) {
+        // Perm objects don't use compressed references, except for
+        // static fields which are currently compressed.
+        field = ik->get_field_by_offset(_offset, true);
+        if (field != NULL) {
+          BasicType basic_elem_type = field->layout_type();
+          _is_ptr_to_narrowoop = (basic_elem_type == T_OBJECT ||
+                                  basic_elem_type == T_ARRAY);
+        }
+      } else if (_offset == OffsetBot || _offset == OffsetTop) {
+        // unsafe access
+        _is_ptr_to_narrowoop = true;
+      } else { // exclude unsafe ops
+        assert(this->isa_instptr(), "must be an instance ptr.");
+        // Field which contains a compressed oop references.
+        field = ik->get_field_by_offset(_offset, false);
+        if (field != NULL) {
+          BasicType basic_elem_type = field->layout_type();
+          _is_ptr_to_narrowoop = (basic_elem_type == T_OBJECT ||
+                                  basic_elem_type == T_ARRAY);
+        } else if (klass()->equals(ciEnv::current()->Object_klass())) {
+          // Compile::find_alias_type() cast exactness on all types to verify
+          // that it does not affect alias type.
+          _is_ptr_to_narrowoop = true;
+        } else {
+          // Type for the copy start in LibraryCallKit::inline_native_clone().
+          assert(!klass_is_exact(), "only non-exact klass");
+          _is_ptr_to_narrowoop = true;
+        }
+      }
+    }
+  }
+#endif
+}
+
 //------------------------------make-------------------------------------------
 const TypeOopPtr *TypeOopPtr::make(PTR ptr,
                                    int offset) {
@@ -2593,9 +2667,13 @@
 //-----------------------------cast_to_instance-------------------------------
 const TypeOopPtr *TypeInstPtr::cast_to_instance(int instance_id) const {
   if( instance_id == _instance_id) return this;
-  bool exact = (instance_id == UNKNOWN_INSTANCE) ? _klass_is_exact : true;
-
-  return make(ptr(), klass(), exact, const_oop(), _offset, instance_id);
+  bool exact = true;
+  PTR  ptr_t = NotNull;
+  if (instance_id == UNKNOWN_INSTANCE) {
+    exact = _klass_is_exact;
+    ptr_t = _ptr;
+  }
+  return make(ptr_t, klass(), exact, const_oop(), _offset, instance_id);
 }
 
 //------------------------------xmeet_unloaded---------------------------------
@@ -3014,6 +3092,7 @@
 // Convenience common pre-built types.
 const TypeAryPtr *TypeAryPtr::RANGE;
 const TypeAryPtr *TypeAryPtr::OOPS;
+const TypeAryPtr *TypeAryPtr::NARROWOOPS;
 const TypeAryPtr *TypeAryPtr::BYTES;
 const TypeAryPtr *TypeAryPtr::SHORTS;
 const TypeAryPtr *TypeAryPtr::CHARS;
@@ -3063,8 +3142,13 @@
 //-----------------------------cast_to_instance-------------------------------
 const TypeOopPtr *TypeAryPtr::cast_to_instance(int instance_id) const {
   if( instance_id == _instance_id) return this;
-  bool exact = (instance_id == UNKNOWN_INSTANCE) ? _klass_is_exact : true;
-  return make(ptr(), const_oop(), _ary, klass(), exact, _offset, instance_id);
+  bool exact = true;
+  PTR  ptr_t = NotNull;
+  if (instance_id == UNKNOWN_INSTANCE) {
+    exact = _klass_is_exact;
+    ptr_t = _ptr;
+  }
+  return make(ptr_t, const_oop(), _ary, klass(), exact, _offset, instance_id);
 }
 
 //-----------------------------narrow_size_type-------------------------------
@@ -3547,7 +3631,7 @@
     k_ary = ciTypeArrayKlass::make(el->basic_type());
   }
 
-  if( this != TypeAryPtr::OOPS )
+  if( this != TypeAryPtr::OOPS ) {
     // The _klass field acts as a cache of the underlying
     // ciKlass for this array type.  In order to set the field,
     // we need to cast away const-ness.
@@ -3562,6 +3646,11 @@
     // a bit less efficient than caching, but calls to
     // TypeAryPtr::OOPS->klass() are not common enough to matter.
     ((TypeAryPtr*)this)->_klass = k_ary;
+    if (UseCompressedOops && k_ary != NULL && k_ary->is_obj_array_klass() &&
+        _offset != 0 && _offset != arrayOopDesc::length_offset_in_bytes()) {
+      ((TypeAryPtr*)this)->_is_ptr_to_narrowoop = true;
+    }
+  }
   return k_ary;
 }
 
--- a/hotspot/src/share/vm/opto/type.hpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/opto/type.hpp	Wed Jul 05 16:37:51 2017 +0200
@@ -191,9 +191,8 @@
   virtual const Type *filter( const Type *kills ) const;
 
   // Returns true if this pointer points at memory which contains a
-  // compressed oop references.  In 32-bit builds it's non-virtual
-  // since we don't support compressed oops at all in the mode.
-  LP64_ONLY(virtual) bool is_narrow() const { return false; }
+  // compressed oop references.
+  bool is_ptr_to_narrowoop() const;
 
   // Convenience access
   float getf() const;
@@ -213,8 +212,8 @@
   const TypePtr    *isa_ptr() const;             // Returns NULL if not ptr type
   const TypeRawPtr *isa_rawptr() const;          // NOT Java oop
   const TypeRawPtr *is_rawptr() const;           // Asserts is rawptr
-  const TypeNarrowOop  *is_narrowoop() const;        // Java-style GC'd pointer
-  const TypeNarrowOop  *isa_narrowoop() const;       // Returns NULL if not oop ptr type
+  const TypeNarrowOop  *is_narrowoop() const;    // Java-style GC'd pointer
+  const TypeNarrowOop  *isa_narrowoop() const;   // Returns NULL if not oop ptr type
   const TypeOopPtr   *isa_oopptr() const;        // Returns NULL if not oop ptr type
   const TypeOopPtr   *is_oopptr() const;         // Java-style GC'd pointer
   const TypeKlassPtr *isa_klassptr() const;      // Returns NULL if not KlassPtr
@@ -643,7 +642,7 @@
 // Some kind of oop (Java pointer), either klass or instance or array.
 class TypeOopPtr : public TypePtr {
 protected:
-  TypeOopPtr( TYPES t, PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id ) : TypePtr(t, ptr, offset), _const_oop(o), _klass(k), _klass_is_exact(xk), _instance_id(instance_id) { }
+  TypeOopPtr( TYPES t, PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id );
 public:
   virtual bool eq( const Type *t ) const;
   virtual int  hash() const;             // Type specific hashing
@@ -660,8 +659,9 @@
   ciKlass*      _klass;       // Klass object
   // Does the type exclude subclasses of the klass?  (Inexact == polymorphic.)
   bool          _klass_is_exact;
+  bool          _is_ptr_to_narrowoop;
 
-  int          _instance_id;   // if not UNKNOWN_INSTANCE, indicates that this is a particular instance
+  int           _instance_id;  // if not UNKNOWN_INSTANCE, indicates that this is a particular instance
                                // of this type which is distinct.  This is the  the node index of the
                                // node creating this instance
 
@@ -696,6 +696,11 @@
   ciObject* const_oop()    const { return _const_oop; }
   virtual ciKlass* klass() const { return _klass;     }
   bool klass_is_exact()    const { return _klass_is_exact; }
+
+  // Returns true if this pointer points at memory which contains a
+  // compressed oop references.
+  bool is_ptr_to_narrowoop_nv() const { return _is_ptr_to_narrowoop; }
+
   bool is_instance()       const { return _instance_id != UNKNOWN_INSTANCE; }
   uint instance_id()       const { return _instance_id; }
   bool is_instance_field() const { return _instance_id != UNKNOWN_INSTANCE && _offset >= 0; }
@@ -716,12 +721,6 @@
   // returns the equivalent compressed version of this pointer type
   virtual const TypeNarrowOop* make_narrowoop() const;
 
-#ifdef _LP64
-  virtual bool is_narrow() const {
-    return (UseCompressedOops && _offset != 0);
-  }
-#endif
-
   virtual const Type *xmeet( const Type *t ) const;
   virtual const Type *xdual() const;    // Compute dual right now.
 
@@ -843,15 +842,10 @@
   virtual const Type *xmeet( const Type *t ) const;
   virtual const Type *xdual() const;    // Compute dual right now.
 
-#ifdef _LP64
-  virtual bool is_narrow() const {
-    return (UseCompressedOops && klass() != NULL && _offset != 0);
-  }
-#endif
-
   // Convenience common pre-built types.
   static const TypeAryPtr *RANGE;
   static const TypeAryPtr *OOPS;
+  static const TypeAryPtr *NARROWOOPS;
   static const TypeAryPtr *BYTES;
   static const TypeAryPtr *SHORTS;
   static const TypeAryPtr *CHARS;
@@ -901,18 +895,6 @@
   virtual const Type    *xmeet( const Type *t ) const;
   virtual const Type    *xdual() const;      // Compute dual right now.
 
-#ifdef _LP64
-  // Perm objects don't use compressed references, except for static fields
-  // which are currently compressed
-  virtual bool is_narrow() const {
-    if (UseCompressedOops && _offset != 0 && _klass->is_instance_klass()) {
-      ciInstanceKlass* ik = _klass->as_instance_klass();
-      return ik != NULL && ik->get_field_by_offset(_offset, true) != NULL;
-    }
-    return false;
-  }
-#endif
-
   // Convenience common pre-built types.
   static const TypeKlassPtr* OBJECT; // Not-null object klass or below
   static const TypeKlassPtr* OBJECT_OR_NULL; // Maybe-null version of same
@@ -921,7 +903,7 @@
 #endif
 };
 
-//------------------------------TypeNarrowOop----------------------------------------
+//------------------------------TypeNarrowOop----------------------------------
 // A compressed reference to some kind of Oop.  This type wraps around
 // a preexisting TypeOopPtr and forwards most of it's operations to
 // the underlying type.  It's only real purpose is to track the
@@ -1013,6 +995,14 @@
 };
 
 //------------------------------accessors--------------------------------------
+inline bool Type::is_ptr_to_narrowoop() const {
+#ifdef _LP64
+  return (isa_oopptr() != NULL && is_oopptr()->is_ptr_to_narrowoop_nv());
+#else
+  return false;
+#endif
+}
+
 inline float Type::getf() const {
   assert( _base == FloatCon, "Not a FloatCon" );
   return ((TypeF*)this)->_f;
--- a/hotspot/src/share/vm/runtime/arguments.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/runtime/arguments.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -1174,9 +1174,11 @@
   // field offset to determine free list chunk markers.
   // Check that UseCompressedOops can be set with the max heap size allocated
   // by ergonomics.
-  if (!UseConcMarkSweepGC && MaxHeapSize <= max_heap_for_compressed_oops()) {
+  if (MaxHeapSize <= max_heap_for_compressed_oops()) {
     if (FLAG_IS_DEFAULT(UseCompressedOops)) {
-      FLAG_SET_ERGO(bool, UseCompressedOops, true);
+      // Leave compressed oops off by default. Uncomment
+      // the following line to return it to default status.
+      // FLAG_SET_ERGO(bool, UseCompressedOops, true);
     }
   } else {
     if (UseCompressedOops && !FLAG_IS_DEFAULT(UseCompressedOops)) {
@@ -1312,6 +1314,9 @@
   if (AggressiveOpts && FLAG_IS_DEFAULT(DoEscapeAnalysis)) {
     FLAG_SET_DEFAULT(DoEscapeAnalysis, true);
   }
+  if (AggressiveOpts && FLAG_IS_DEFAULT(SpecialArraysEquals)) {
+    FLAG_SET_DEFAULT(SpecialArraysEquals, true);
+  }
 #endif
 
   if (AggressiveOpts) {
--- a/hotspot/src/share/vm/runtime/globals.hpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/runtime/globals.hpp	Wed Jul 05 16:37:51 2017 +0200
@@ -291,6 +291,9 @@
             "Use 32-bit object references in 64-bit VM. "                   \
             "lp64_product means flag is always constant in 32 bit VM")      \
                                                                             \
+  lp64_product(bool, CheckCompressedOops, trueInDebug,                      \
+            "generate checks in encoding/decoding code")                    \
+                                                                            \
   /* UseMembar is theoretically a temp flag used for memory barrier         \
    * removal testing.  It was supposed to be removed before FCS but has     \
    * been re-added (see 6401008) */                                         \
@@ -457,6 +460,9 @@
   develop(bool, SpecialStringIndexOf, true,                                 \
           "special version of string indexOf")                              \
                                                                             \
+  product(bool, SpecialArraysEquals, false,                                 \
+          "special version of Arrays.equals(char[],char[])")                \
+                                                                            \
   develop(bool, TraceCallFixup, false,                                      \
           "traces all call fixups")                                         \
                                                                             \
@@ -2240,6 +2246,9 @@
   product(bool, AggressiveOpts, false,                                      \
           "Enable aggressive optimizations - see arguments.cpp")            \
                                                                             \
+  product(bool, UseStringCache, false,                                      \
+          "Enable String cache capabilities on String.java")                \
+                                                                            \
   /* statistics */                                                          \
   develop(bool, UseVTune, false,                                            \
           "enable support for Intel's VTune profiler")                      \
--- a/hotspot/src/share/vm/runtime/java.hpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/runtime/java.hpp	Wed Jul 05 16:37:51 2017 +0200
@@ -68,8 +68,24 @@
   static bool is_jdk13x_version()           { assert(is_jdk_version_initialized(), "must have been initialized"); return _jdk_version == 3; }
   static bool is_jdk14x_version()           { assert(is_jdk_version_initialized(), "must have been initialized"); return _jdk_version == 4; }
   static bool is_jdk15x_version()           { assert(is_jdk_version_initialized(), "must have been initialized"); return _jdk_version == 5; }
-  static bool is_jdk16x_version()           { assert(is_jdk_version_initialized(), "must have been initialized"); return _jdk_version == 6; }
-  static bool is_jdk17x_version()           { assert(is_jdk_version_initialized(), "must have been initialized"); return _jdk_version == 7; }
+
+  static bool is_jdk16x_version() {
+    if (is_jdk_version_initialized()) {
+      return _jdk_version == 6;
+    } else {
+      assert(is_pre_jdk16_version(), "must have been initialized");
+      return false;
+    }
+  }
+
+  static bool is_jdk17x_version() {
+    if (is_jdk_version_initialized()) {
+      return _jdk_version == 7;
+    } else {
+      assert(is_pre_jdk16_version(), "must have been initialized");
+      return false;
+    }
+  }
 
   static bool supports_thread_park_blocker() { return _version_info.thread_park_blocker; }
 
@@ -85,14 +101,22 @@
   }
   static bool is_gte_jdk16x_version() {
     // Keep the semantics of this that the version number is >= 1.6
-    assert(is_jdk_version_initialized(), "Not initialized");
-    return _jdk_version >= 6;
+    if (is_jdk_version_initialized()) {
+      return _jdk_version >= 6;
+    } else {
+      assert(is_pre_jdk16_version(), "Not initialized");
+      return false;
+    }
   }
 
   static bool is_gte_jdk17x_version() {
     // Keep the semantics of this that the version number is >= 1.7
-    assert(is_jdk_version_initialized(), "Not initialized");
-    return _jdk_version >= 7;
+    if (is_jdk_version_initialized()) {
+      return _jdk_version >= 7;
+    } else {
+      assert(is_pre_jdk16_version(), "Not initialized");
+      return false;
+    }
   }
 
   static bool is_jdk_version_initialized() {
--- a/hotspot/src/share/vm/runtime/thread.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/runtime/thread.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -2926,21 +2926,42 @@
     }
 
     if (AggressiveOpts) {
-      // Forcibly initialize java/util/HashMap and mutate the private
-      // static final "frontCacheEnabled" field before we start creating instances
+      {
+        // Forcibly initialize java/util/HashMap and mutate the private
+        // static final "frontCacheEnabled" field before we start creating instances
 #ifdef ASSERT
-      klassOop tmp_k = SystemDictionary::find(vmSymbolHandles::java_util_HashMap(), Handle(), Handle(), CHECK_0);
-      assert(tmp_k == NULL, "java/util/HashMap should not be loaded yet");
+        klassOop tmp_k = SystemDictionary::find(vmSymbolHandles::java_util_HashMap(), Handle(), Handle(), CHECK_0);
+        assert(tmp_k == NULL, "java/util/HashMap should not be loaded yet");
 #endif
-      klassOop k_o = SystemDictionary::resolve_or_null(vmSymbolHandles::java_util_HashMap(), Handle(), Handle(), CHECK_0);
-      KlassHandle k = KlassHandle(THREAD, k_o);
-      guarantee(k.not_null(), "Must find java/util/HashMap");
-      instanceKlassHandle ik = instanceKlassHandle(THREAD, k());
-      ik->initialize(CHECK_0);
-      fieldDescriptor fd;
-      // Possible we might not find this field; if so, don't break
-      if (ik->find_local_field(vmSymbols::frontCacheEnabled_name(), vmSymbols::bool_signature(), &fd)) {
-        k()->bool_field_put(fd.offset(), true);
+        klassOop k_o = SystemDictionary::resolve_or_null(vmSymbolHandles::java_util_HashMap(), Handle(), Handle(), CHECK_0);
+        KlassHandle k = KlassHandle(THREAD, k_o);
+        guarantee(k.not_null(), "Must find java/util/HashMap");
+        instanceKlassHandle ik = instanceKlassHandle(THREAD, k());
+        ik->initialize(CHECK_0);
+        fieldDescriptor fd;
+        // Possible we might not find this field; if so, don't break
+        if (ik->find_local_field(vmSymbols::frontCacheEnabled_name(), vmSymbols::bool_signature(), &fd)) {
+          k()->bool_field_put(fd.offset(), true);
+        }
+      }
+
+      if (UseStringCache) {
+        // Forcibly initialize java/lang/String and mutate the private
+        // static final "stringCacheEnabled" field before we start creating instances
+#ifdef ASSERT
+        klassOop tmp_k = SystemDictionary::find(vmSymbolHandles::java_lang_String(), Handle(), Handle(), CHECK_0);
+        assert(tmp_k == NULL, "java/lang/String should not be loaded yet");
+#endif
+        klassOop k_o = SystemDictionary::resolve_or_null(vmSymbolHandles::java_lang_String(), Handle(), Handle(), CHECK_0);
+        KlassHandle k = KlassHandle(THREAD, k_o);
+        guarantee(k.not_null(), "Must find java/lang/String");
+        instanceKlassHandle ik = instanceKlassHandle(THREAD, k());
+        ik->initialize(CHECK_0);
+        fieldDescriptor fd;
+        // Possible we might not find this field; if so, don't break
+        if (ik->find_local_field(vmSymbols::stringCacheEnabled_name(), vmSymbols::bool_signature(), &fd)) {
+          k()->bool_field_put(fd.offset(), true);
+        }
       }
     }
 
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -894,6 +894,7 @@
   /*******************************************************************/   \
                                                                           \
   declare_unsigned_integer_type(size_t)                                   \
+  declare_integer_type(ssize_t)                                           \
   declare_unsigned_integer_type(const size_t)                             \
   declare_integer_type(intx)                                              \
   declare_integer_type(intptr_t)                                          \
@@ -1694,7 +1695,12 @@
   declare_constant(markOopDesc::no_hash)                                  \
   declare_constant(markOopDesc::no_hash_in_place)                         \
   declare_constant(markOopDesc::no_lock_in_place)                         \
-  declare_constant(markOopDesc::max_age)
+  declare_constant(markOopDesc::max_age)                                  \
+                                                                          \
+  /* Constants in markOop used by CMS. */                                 \
+  declare_constant(markOopDesc::cms_shift)                                \
+  declare_constant(markOopDesc::cms_mask)                                 \
+  declare_constant(markOopDesc::size_shift)                               \
 
   /* NOTE that we do not use the last_entry() macro here; it is used   */
   /* in vmStructs_<os>_<cpu>.hpp's VM_LONG_CONSTANTS_OS_CPU macro (and */
@@ -1958,6 +1964,7 @@
                         GENERATE_STATIC_VM_STRUCT_ENTRY)
 
   VM_STRUCTS_CMS(GENERATE_NONSTATIC_VM_STRUCT_ENTRY, \
+                 GENERATE_NONSTATIC_VM_STRUCT_ENTRY, \
                  GENERATE_STATIC_VM_STRUCT_ENTRY)
 #endif // SERIALGC
 
@@ -2099,6 +2106,7 @@
              CHECK_STATIC_VM_STRUCT_ENTRY);
 
   VM_STRUCTS_CMS(CHECK_NONSTATIC_VM_STRUCT_ENTRY,
+             CHECK_VOLATILE_NONSTATIC_VM_STRUCT_ENTRY,
              CHECK_STATIC_VM_STRUCT_ENTRY);
 #endif // SERIALGC
 
@@ -2203,6 +2211,7 @@
   debug_only(VM_STRUCTS_PARALLELGC(ENSURE_FIELD_TYPE_PRESENT, \
                                    ENSURE_FIELD_TYPE_PRESENT));
   debug_only(VM_STRUCTS_CMS(ENSURE_FIELD_TYPE_PRESENT, \
+                            ENSURE_FIELD_TYPE_PRESENT, \
                             ENSURE_FIELD_TYPE_PRESENT));
 #endif // SERIALGC
   debug_only(VM_STRUCTS_CPU(ENSURE_FIELD_TYPE_PRESENT, \
--- a/hotspot/test/compiler/6659207/Test.java	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/test/compiler/6659207/Test.java	Wed Jul 05 16:37:51 2017 +0200
@@ -1,23 +1,24 @@
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
- * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
- *
+ * Copyright 1997-2002 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
  *
  */
 
--- a/hotspot/test/compiler/6661247/Test.java	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/test/compiler/6661247/Test.java	Wed Jul 05 16:37:51 2017 +0200
@@ -1,23 +1,24 @@
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
- * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
- *
+ * Copyright 1997-2002 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
  *
  */
 
--- a/hotspot/test/compiler/6663621/IVTest.java	Wed Jul 05 16:37:21 2017 +0200
+++ b/hotspot/test/compiler/6663621/IVTest.java	Wed Jul 05 16:37:51 2017 +0200
@@ -1,23 +1,24 @@
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
- * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
- *
+ * Copyright 1997-2002 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
  *
  */
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6689060/Test.java	Wed Jul 05 16:37:51 2017 +0200
@@ -0,0 +1,577 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ */
+
+/*
+ * @test
+ * @bug 6689060
+ * @summary Escape Analysis does not work with Compressed Oops
+ * @run main/othervm -Xbatch -XX:CompileCommand=exclude,Test.dummy -XX:+AggressiveOpts Test
+ */
+
+import java.lang.reflect.Array;
+
+class Point {
+  int x;
+  int y;
+  Point next;
+  int ax[];
+  int ay[];
+  Point pax[];
+  Point pay[];
+  public Point getNext() {
+    return next;
+  }
+}
+
+public class Test {
+
+  void dummy() {
+    // Empty method to verify correctness of DebugInfo.
+    // Use -XX:CompileCommand=exclude,Test.dummy
+  }
+
+  int ival(int i) {
+    return i*2;
+  }
+
+  int test80(int y, int l, int i) {
+    Point p = new Point();
+    p.ax = new int[2];
+    p.ay = new int[2];
+    int x = 3;
+    p.ax[0] = x;
+    p.ay[1] = 3 * x + y;
+    dummy();
+    return p.ax[0] * p.ay[1];
+  }
+
+  int test81(int y, int l, int i) {
+    Point p = new Point();
+    p.ax = new int[2];
+    p.ay = new int[2];
+    int x = 3;
+    p.ax[0] = x;
+    p.ay[1] = 3 * x + y;
+    dummy();
+    return p.ax[0] * p.ay[1];
+  }
+
+
+  int test44(int y) {
+    Point p1 = new Point();
+    p1.x = ival(3);
+    dummy();
+    p1.y = 3 * p1.x + y;
+    return p1.y;
+  }
+
+  int test43(int y) {
+    Point p1 = new Point();
+    if ( (y & 1) == 1 ) {
+      p1.x = ival(3);
+    } else {
+      p1.x = ival(5);
+    }
+    dummy();
+    p1.y = 3 * p1.x + y;
+    return p1.y;
+  }
+
+  int test42(int y) {
+    Point p1 = new Point();
+    p1.x = 3;
+    for (int i = 0; i < y; i++) {
+      if ( (i & 1) == 1 ) {
+        p1.x += 4;
+      }
+    }
+    p1.y = 3 * y + p1.x;
+    return p1.y;
+  }
+
+  int test40(int y) {
+    Point p1 = new Point();
+    if ( (y & 1) == 1 ) {
+      p1.x = 3;
+    } else {
+      p1.x = 5;
+    }
+    p1.y = 3 * p1.x + y;
+    return p1.y;
+  }
+
+  int test41(int y) {
+    Point p1 = new Point();
+    if ( (y & 1) == 1 ) {
+      p1.x += 4;
+    } else {
+      p1.x += 5;
+    }
+    p1.y = 3 * p1.x + y;
+    return p1.y;
+  }
+
+  Point test00(int y) {
+    int x = 3;
+    Point p = new Point();
+    p.x = x;
+    p.y = 3 * x + y;
+    return p;
+  }
+
+  Point test01(int y) {
+    int x = 3;
+    Point p = new Point();
+    p.x = x;
+    p.y = 3 * x + y;
+    dummy();
+    return p;
+  }
+
+  Point test02(int y) {
+    int x = 3;
+    Point p1 = null;
+    for (int i = 0; i < y; i++) {
+      Point p2 = new Point();
+      p2.x = x;
+      p2.y = 3 * y + x;
+      p2.next = p1;
+      p1 = p2;
+    }
+    return p1;
+  }
+
+  Point test03(int y) {
+    int x = 3;
+    Point p1 = null;
+    for (int i = 0; i < y; i++) {
+      Point p2 = new Point();
+      p2.x = x;
+      p2.y = 3 * y + x;
+      p2.next = p1;
+      p1 = p2;
+    }
+    dummy();
+    return p1;
+  }
+
+  Point test04(int y) {
+    int x = 3;
+    Point p1 = null;
+    for (int i = 0; i < y; i++) {
+      Point p2 = new Point();
+      p2.x = x;
+      p2.y = 3 * y + x;
+      p2.next = p1;
+      dummy();
+      p1 = p2;
+    }
+    return p1;
+  }
+
+  int test05(int y) {
+    int x = 3;
+    Point p1 = new Point();
+    for (int i = 0; i < y; i++) {
+      Point p2 = new Point();
+      p2.x = x;
+      p2.y = 3 * y + x;
+      p1.next = p2;
+      p1 = p2;
+    }
+    return p1.y;
+  }
+
+  int test0(int y) {
+    int x = 3;
+    Point p = new Point();
+    p.x = x;
+    p.y = 3 * x + y;
+    dummy();
+    return p.x * p.y;
+  }
+
+  int test1(int y) {
+    Point p = new Point();
+    if ( (y & 1) == 1 ) {
+      p = new Point(); // Kill previous
+    }
+    int x = 3;
+    p.x = x;
+    p.y = 3 * x + y;
+    dummy();
+    return p.x * p.y;
+  }
+
+  int test2(int y) {
+    Point p1 = new Point();
+    Point p2 = new Point();
+    p1.x = 3;
+    p2.x = 4;
+    p1.y = 3 * p2.x + y;
+    p2.y = 3 * p1.x + y;
+    dummy();
+    return p1.y * p2.y;
+  }
+
+  int test3(int y, Point p1) {
+    Point p2 = new Point();
+    p1.x = 3;
+    p2.x = 4;
+    p1.y = 3 * p2.x + y;
+    p2.y = 3 * p1.x + y;
+    dummy();
+    return p1.y * p2.y;
+  }
+
+  int test4(int y) {
+    Point p1 = new Point();
+    Point p2 = new Point();
+    if ( (y & 1) == 1 ) {
+      p1.x = 3;
+      p2.x = 4;
+    } else {
+      p1.x = 5;
+      p2.x = 6;
+    }
+    p1.y = 3 * p2.x + y;
+    p2.y = 3 * p1.x + y;
+    dummy();
+    return p1.y * p2.y;
+  }
+
+  int test5(int y, Point p1) {
+    Point p2 = new Point();
+    if ( (y & 1) == 1 ) {
+      p1.x = 3;
+      p2.x = 4;
+    } else {
+      p1.x = 5;
+      p2.x = 6;
+    }
+    p1.y = 3 * p2.x + y;
+    p2.y = 3 * p1.x + y;
+    dummy();
+    return p1.y * p2.y;
+  }
+
+  int test6(int y) {
+    Point p1 = new Point();
+    Point p2 = new Point();
+    p1.next = p2;
+    if ( (y & 1) == 1 ) {
+      p1.x = 3;
+      p1.getNext().x = 4;
+    } else {
+      p1.x = 5;
+      p1.getNext().x = 6;
+    }
+    p1.y = 3 * p2.x + y;
+    p2.y = 3 * p1.x + y;
+    dummy();
+    return p1.y * p2.y;
+  }
+
+  int test7(int y, Point p1) {
+    Point p2 = new Point();
+    p1.next = p2;
+    if ( (y & 1) == 1 ) {
+      p1.x = 3;
+      p1.getNext().x = 4;
+    } else {
+      p1.x = 5;
+      p1.getNext().x = 6;
+    }
+    p1.y = 3 * p2.x + y;
+    p2.y = 3 * p1.x + y;
+    dummy();
+    return p1.y * p2.y;
+  }
+
+  int test8(int y, int l, int i) {
+    Point p = new Point();
+    p.ax = new int[l];
+    p.ay = new int[l];
+    int x = 3;
+    p.ax[i] = x;
+    p.ay[i] = 3 * x + y;
+    dummy();
+    return p.ax[i] * p.ay[i];
+  }
+
+  int test9(int y, int l, int i) {
+    Point p = new Point();
+    p.pax = new Point[l];
+    p.pay = new Point[l];
+    p.pax[i] = new Point();
+    p.pay[i] = new Point();
+    p.pax[i].x = 3;
+    p.pay[i].x = 4;
+    p.pax[i].y = 3 * p.pay[i].x + y;
+    p.pay[i].y = 3 * p.pax[i].x + y;
+    dummy();
+    return p.pax[i].y * p.pay[i].y;
+  }
+
+  int test10(int y, int l, int i, Class cls) {
+    Point p = new Point();
+    try {
+      p.pax = (Point[])Array.newInstance(cls, l);
+      p.pax[i] = (Point)cls.newInstance();
+    }
+    catch(java.lang.InstantiationException ex) {
+      return 0;
+    }
+    catch(java.lang.IllegalAccessException ex) {
+      return 0;
+    }
+    p.pax[i].x = 3;
+    p.pax[i].y = 3 * p.pax[i].x + y;
+    dummy();
+    return p.pax[i].x * p.pax[i].y;
+  }
+
+  int test11(int y) {
+    Point p1 = new Point();
+    Point p2 = new Point();
+    p1.next = p2;
+    if ( (y & 1) == 1 ) {
+      p1.x = 3;
+      p1.next.x = 4;
+    } else {
+      p1.x = 5;
+      p1.next.x = 6;
+    }
+    p1.y = 3 * p1.next.x + y;
+    p1.next.y = 3 * p1.x + y;
+    dummy();
+    return p1.y * p1.next.y;
+  }
+
+  int test12(int y) {
+    Point p1 = new Point();
+    p1.next = p1;
+    if ( (y & 1) == 1 ) {
+      p1.x = 3;
+      p1.next.x = 4;
+    } else {
+      p1.x = 5;
+      p1.next.x = 6;
+    }
+    p1.y = 3 * p1.next.x + y;
+    p1.next.y = 3 * p1.x + y;
+    dummy();
+    return p1.y * p1.next.y;
+  }
+
+
+  public static void main(String args[]) {
+    Test tsr    = new Test();
+    Point p     = new Point();
+    Point ptmp  = p;
+    Class cls   = Point.class;
+    int y = 0;
+    for (int i=0; i<10000; i++) {
+      ptmp.next = tsr.test00(1);
+      ptmp.next = tsr.test01(1);
+      ptmp.next = tsr.test02(1);
+      ptmp.next = tsr.test03(1);
+      ptmp.next = tsr.test04(1);
+
+      y = tsr.test05(1);
+
+      y = tsr.test80(y, 1, 0);
+      y = tsr.test81(y, 1, 0);
+
+      y = tsr.test44(y);
+      y = tsr.test43(y);
+      y = tsr.test42(y);
+      y = tsr.test40(y);
+      y = tsr.test41(y);
+
+      y = tsr.test0(y);
+      y = tsr.test1(y);
+      y = tsr.test2(y);
+      y = tsr.test3(y, p);
+      y = tsr.test4(y);
+      y = tsr.test5(y, p);
+      y = tsr.test6(y);
+      y = tsr.test7(y, p);
+      y = tsr.test8(y, 1, 0);
+      y = tsr.test9(y, 1, 0);
+      y = tsr.test10(y, 1, 0, cls);
+      y = tsr.test11(y);
+      y = tsr.test12(y);
+    }
+    for (int i=0; i<10000; i++) {
+      ptmp.next = tsr.test00(1);
+      ptmp.next = tsr.test01(1);
+      ptmp.next = tsr.test02(1);
+      ptmp.next = tsr.test03(1);
+      ptmp.next = tsr.test04(1);
+
+      y = tsr.test05(1);
+
+      y = tsr.test80(y, 1, 0);
+      y = tsr.test81(y, 1, 0);
+
+      y = tsr.test44(y);
+      y = tsr.test43(y);
+      y = tsr.test42(y);
+      y = tsr.test40(y);
+      y = tsr.test41(y);
+
+      y = tsr.test0(y);
+      y = tsr.test1(y);
+      y = tsr.test2(y);
+      y = tsr.test3(y, p);
+      y = tsr.test4(y);
+      y = tsr.test5(y, p);
+      y = tsr.test6(y);
+      y = tsr.test7(y, p);
+      y = tsr.test8(y, 1, 0);
+      y = tsr.test9(y, 1, 0);
+      y = tsr.test10(y, 1, 0, cls);
+      y = tsr.test11(y);
+      y = tsr.test12(y);
+    }
+    for (int i=0; i<10000; i++) {
+      ptmp.next = tsr.test00(1);
+      ptmp.next = tsr.test01(1);
+      ptmp.next = tsr.test02(1);
+      ptmp.next = tsr.test03(1);
+      ptmp.next = tsr.test04(1);
+
+      y = tsr.test05(1);
+
+      y = tsr.test80(y, 1, 0);
+      y = tsr.test81(y, 1, 0);
+
+      y = tsr.test44(y);
+      y = tsr.test43(y);
+      y = tsr.test42(y);
+      y = tsr.test40(y);
+      y = tsr.test41(y);
+
+      y = tsr.test0(y);
+      y = tsr.test1(y);
+      y = tsr.test2(y);
+      y = tsr.test3(y, p);
+      y = tsr.test4(y);
+      y = tsr.test5(y, p);
+      y = tsr.test6(y);
+      y = tsr.test7(y, p);
+      y = tsr.test8(y, 1, 0);
+      y = tsr.test9(y, 1, 0);
+      y = tsr.test10(y, 1, 0, cls);
+      y = tsr.test11(y);
+      y = tsr.test12(y);
+    }
+
+    int z = 0;
+    y = tsr.test80(0, 1, 0);
+    z += y;
+    System.out.println("After 'test80' y=" + y);
+    y = tsr.test81(0, 1, 0);
+    z += y;
+    System.out.println("After 'test81' y=" + y);
+
+    y = tsr.test44(0);
+    z += y;
+    System.out.println("After 'test44' y=" + y);
+    y = tsr.test43(0);
+    z += y;
+    System.out.println("After 'test43' y=" + y);
+    y = tsr.test42(0);
+    z += y;
+    System.out.println("After 'test42' y=" + y);
+    y = tsr.test40(0);
+    z += y;
+    System.out.println("After 'test40' y=" + y);
+    y = tsr.test41(0);
+    z += y;
+    System.out.println("After 'test41' y=" + y);
+
+    ptmp.next = tsr.test00(1);
+    z += y;
+    System.out.println("After 'test00' p.y=" + ptmp.next.y);
+    ptmp.next = tsr.test01(1);
+    z += y;
+    System.out.println("After 'test01' p.y=" + ptmp.next.y);
+    ptmp.next = tsr.test02(1);
+    z += y;
+    System.out.println("After 'test02' p.y=" + ptmp.next.y);
+    ptmp.next = tsr.test03(1);
+    z += y;
+    System.out.println("After 'test03' p.y=" + ptmp.next.y);
+    ptmp.next = tsr.test04(1);
+    z += y;
+    System.out.println("After 'test04' p.y=" + ptmp.next.y);
+
+    y = tsr.test05(1);
+    z += y;
+    System.out.println("After 'test05' y=" + y);
+
+    y = tsr.test0(0);
+    z += y;
+    System.out.println("After 'test0' y=" + y);
+    y = tsr.test1(0);
+    z += y;
+    System.out.println("After 'test1' y=" + y);
+    y = tsr.test2(0);
+    z += y;
+    System.out.println("After 'test2' y=" + y);
+    y = tsr.test3(0, new Point());
+    z += y;
+    System.out.println("After 'test3' y=" + y);
+    y = tsr.test4(0);
+    z += y;
+    System.out.println("After 'test4' y=" + y);
+    y = tsr.test5(0, new Point());
+    z += y;
+    System.out.println("After 'test5' y=" + y);
+    y = tsr.test6(0);
+    z += y;
+    System.out.println("After 'test6' y=" + y);
+    y = tsr.test7(0, new Point());
+    z += y;
+    System.out.println("After 'test7' y=" + y);
+    y = tsr.test8(0, 1, 0);
+    z += y;
+    System.out.println("After 'test8' y=" + y);
+    y = tsr.test9(0, 1, 0);
+    z += y;
+    System.out.println("After 'test9' y=" + y);
+    y = tsr.test10(0, 1, 0, cls);
+    z += y;
+    System.out.println("After 'test10' y=" + y);
+    y = tsr.test11(0);
+    z += y;
+    System.out.println("After 'test11' y=" + y);
+    y = tsr.test12(0);
+    z += y;
+    System.out.println("After 'test12' y=" + y);
+    System.out.println("Sum of y =" + z);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6695810/Test.java	Wed Jul 05 16:37:51 2017 +0200
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ */
+
+/*
+ * @test
+ * @bug 6695810
+ * @summary null oop passed to encode_heap_oop_not_null
+ * @run main/othervm -Xbatch Test
+ */
+
+public class Test {
+    Test _t;
+
+    static void test(Test t1, Test t2) {
+        if (t2 != null)
+            t1._t = t2;
+
+        if (t2 != null)
+            t1._t = t2;
+    }
+
+    public static void main(String[] args) {
+        Test t = new Test();
+        for (int i = 0; i < 50; i++) {
+            for (int j = 0; j < 100; j++) {
+                test(t, t);
+            }
+            test(t, null);
+        }
+        for (int i = 0; i < 10000; i++) {
+            test(t, t);
+        }
+        test(t, null);
+    }
+}
--- a/jaxp/.hgtags	Wed Jul 05 16:37:21 2017 +0200
+++ b/jaxp/.hgtags	Wed Jul 05 16:37:51 2017 +0200
@@ -2,3 +2,4 @@
 a3b3ba7d6034dc754b51ddc3d281399ac1cae5f1 jdk7-b25
 da43cb85fac1646d6f97e4a35e510bbfdff97bdb jdk7-b26
 bafed478d67c3acf7744aaad88b9404261ea6739 jdk7-b27
+b996318955c0ad8e9fa0ffb56c74f626786e863f jdk7-b28
--- a/jaxws/.hgtags	Wed Jul 05 16:37:21 2017 +0200
+++ b/jaxws/.hgtags	Wed Jul 05 16:37:51 2017 +0200
@@ -2,3 +2,4 @@
 59fd8224ba2da5c2d8d4c68e33cf33ab41ce8de0 jdk7-b25
 debd37e1a422e580edb086c95d6e89199133a39c jdk7-b26
 27d8f42862c11b4ddc4af2dd2d2a3cd86cda04c2 jdk7-b27
+eefcd5204500a11d6aa802dca9f961cf10ab64c2 jdk7-b28
--- a/jdk/.hgtags	Wed Jul 05 16:37:21 2017 +0200
+++ b/jdk/.hgtags	Wed Jul 05 16:37:51 2017 +0200
@@ -2,3 +2,4 @@
 75fca0b0ab83ab1392e615910cea020f66535390 jdk7-b25
 fb57027902e04ecafceae31a605e69b436c23d57 jdk7-b26
 3e599d98875ddf919c8ea11cff9b3a99ba631a9b jdk7-b27
+02e4c5348592a8d7fc2cba28bc5f8e35c0e17277 jdk7-b28
--- a/jdk/make/common/Defs-solaris.gmk	Wed Jul 05 16:37:21 2017 +0200
+++ b/jdk/make/common/Defs-solaris.gmk	Wed Jul 05 16:37:51 2017 +0200
@@ -197,7 +197,6 @@
 
 # Lint Flags:
 #	-Xa			ANSI C plus K&R, favor ANSI rules
-#       -Xarch=XXX		Same as 'cc -xarch=XXX'
 #	-fd			report on old style func defs
 #	-errchk=structarg	report on 64bit struct args by value
 #	-errchk=longptr64	report on 64bit to 32bit issues (ignores casts)
@@ -206,6 +205,7 @@
 #	-x			suppress unused externs
 #	-u			suppress extern func/vars used/defined
 #	-errfmt=simple		use one line errors with position info
+#       $(LINT_XARCH_OPTION)    See Compiler-sun.gwk
 
 LINTFLAGS_COMMON  = -Xa
 LINTFLAGS_COMMON += -fd 
@@ -224,42 +224,12 @@
 #    Tell the compilers to never generate globalized names, all the time.
 CFLAGS_COMMON += -W0,-noglobal
 
-# Arch specific settings (determines type of .o files and instruction set)
-ifeq ($(ARCH_FAMILY), sparc)
-  ifdef VIS_NEEDED
-    XARCH_VALUE/32=v8plusa
-    XARCH_VALUE/64=v9a
-  else 
-    # Someday this should change to improve optimization on UltraSPARC
-    #    and abandon the old v8-only machines like the SPARCstation 10.
-    #    Indications with Mustang is that alacrity runs do not show a
-    #    big improvement using v8plus over v8, but other benchmarks might.
-    XARCH_VALUE/32=v8
-    XARCH_VALUE/64=v9
-  endif
-endif
-ifeq ($(ARCH_FAMILY), i586)
-  XARCH_VALUE/64=amd64
-  XARCH_VALUE/32=
-endif
-
-# Arch value based on current data model being built
-XARCH_VALUE=$(XARCH_VALUE/$(ARCH_DATA_MODEL))
-ifneq ($(XARCH_VALUE), )
-  # The actual compiler -xarch options to use
-  XARCH_OPTION/32 = -xarch=$(XARCH_VALUE/32)
-  XARCH_OPTION/64 = -xarch=$(XARCH_VALUE/64)
-  XARCH_OPTION    = $(XARCH_OPTION/$(ARCH_DATA_MODEL))
-endif
-
-# If we have a specific -xarch value to use, add it
-ifdef XARCH_OPTION
-  CFLAGS_COMMON    += $(XARCH_OPTION)
-  CXXFLAGS_COMMON  += $(XARCH_OPTION)
-  ASFLAGS_COMMON   += $(XARCH_OPTION)
-  EXTRA_LIBS       += $(XARCH_OPTION)
-  LINTFLAGS_COMMON += -Xarch=$(XARCH_VALUE)
-endif
+# If we have a specific arch value to use, add it
+CFLAGS_COMMON    += $(XARCH_OPTION)
+CXXFLAGS_COMMON  += $(XARCH_OPTION)
+ASFLAGS_COMMON   += $(AS_XARCH_OPTION)
+EXTRA_LIBS       += $(XARCH_OPTION)
+LINTFLAGS_COMMON += $(LINT_XARCH_OPTION)
 
 #
 # uncomment the following to build with PERTURBALOT set
--- a/jdk/make/common/Release.gmk	Wed Jul 05 16:37:21 2017 +0200
+++ b/jdk/make/common/Release.gmk	Wed Jul 05 16:37:51 2017 +0200
@@ -1236,7 +1236,6 @@
 	$(RM) $(TEMPDIR)/rebase.input
 endif
 	$(RM) -r $(JDK_IMAGE_DIR)
-	$(RM) -r $(JDK_DEBUG_IMAGE_DIR)
 	$(RM) -r $(JRE_IMAGE_DIR)
 
 images images-clobber::
--- a/jdk/make/common/shared/Compiler-sun.gmk	Wed Jul 05 16:37:21 2017 +0200
+++ b/jdk/make/common/shared/Compiler-sun.gmk	Wed Jul 05 16:37:51 2017 +0200
@@ -31,6 +31,9 @@
 
 # Sun Studio Compiler settings specific to Solaris
 ifeq ($(PLATFORM), solaris)
+  # FIXUP: Change to SS12 when validated
+  #COMPILER_VERSION=SS12
+  #REQUIRED_CC_VER=5.9
   COMPILER_VERSION=SS11
   REQUIRED_CC_VER=5.8
   CC             = $(COMPILER_PATH)cc
@@ -51,8 +54,8 @@
 # Sun Studio Compiler settings specific to Linux
 ifeq ($(PLATFORM), linux)
   # This has not been tested
-  COMPILER_VERSION=SS11
-  REQUIRED_CC_VER=5.8
+  COMPILER_VERSION=SS12
+  REQUIRED_CC_VER=5.9
   CC             = $(COMPILER_PATH)cc
   CPP            = $(COMPILER_PATH)cc -E
   CXX            = $(COMPILER_PATH)CC
@@ -74,3 +77,58 @@
 _CC_VER :=$(shell $(CC) -V 2>&1 | $(HEAD) -n 1)
 CC_VER  :=$(call GetVersion,"$(_CC_VER)")
 
+# Arch specific settings (determines type of .o files and instruction set)
+#  Starting in SS12 (5.9), the arch options changed.
+#  The assembler /usr/ccs/bin/as wants older SS11 (5.8) style options.
+#   Note: We need to have both 32 and 64 values at all times for awt Makefiles.
+#
+XARCH_OPTION_OLD/32 =
+XARCH_OPTION_OLD/64 =
+XARCH_OPTION_NEW/32 = -m32
+XARCH_OPTION_NEW/64 = -m64
+# Lint options are slightly different
+LINT_XARCH_OPTION_OLD/32 =
+LINT_XARCH_OPTION_OLD/64 =
+LINT_XARCH_OPTION_NEW/32 = -m32
+LINT_XARCH_OPTION_NEW/64 = -m64
+ifeq ($(ARCH_FAMILY), sparc)
+  ifdef VIS_NEEDED
+    XARCH_OPTION_OLD/32 += -xarch=v8plusa
+    XARCH_OPTION_OLD/64 += -xarch=v9a
+    XARCH_OPTION_NEW/32 += -xarch=sparcvis
+    XARCH_OPTION_NEW/64 += -xarch=sparcvis
+  else
+    # Someday this should change to improve optimization on UltraSPARC
+    #    and abandon v8, even change to sparcvis or sparcvis2, this
+    #    abandons machines like the SPARCstation 10.
+    #    Indications with jdk6 is that alacrity runs do not show a
+    #    big improvement using v8plus over v8, but other benchmarks might.
+    XARCH_OPTION_OLD/32 += -xarch=v8
+    XARCH_OPTION_OLD/64 += -xarch=v9
+    # Note that this new option (SS12+) effectively means v8plus
+    XARCH_OPTION_NEW/32 += -xarch=sparc
+    XARCH_OPTION_NEW/64 += -xarch=sparc
+  endif
+  LINT_XARCH_OPTION_OLD/64 += -Xarch=v9
+endif
+ifeq ($(ARCH_FAMILY), i586)
+  XARCH_OPTION_OLD/64      += -xarch=amd64
+  LINT_XARCH_OPTION_OLD/64 += -Xarch=amd64
+endif
+# Pick the options we want based on the compiler being used.
+ifeq ($(shell expr $(CC_VER) \>= 5.9), 1)
+  XARCH_OPTION/32 = $(XARCH_OPTION_NEW/32)
+  XARCH_OPTION/64 = $(XARCH_OPTION_NEW/64)
+  LINT_XARCH_OPTION/32 = $(LINT_XARCH_OPTION_NEW/32)
+  LINT_XARCH_OPTION/64 = $(LINT_XARCH_OPTION_NEW/64)
+else
+  XARCH_OPTION/32 = $(XARCH_OPTION_OLD/32)
+  XARCH_OPTION/64 = $(XARCH_OPTION_OLD/64)
+  LINT_XARCH_OPTION/32 = $(LINT_XARCH_OPTION_OLD/32)
+  LINT_XARCH_OPTION/64 = $(LINT_XARCH_OPTION_OLD/64)
+endif
+XARCH_OPTION = $(XARCH_OPTION/$(ARCH_DATA_MODEL))
+LINT_XARCH_OPTION = $(LINT_XARCH_OPTION/$(ARCH_DATA_MODEL))
+# The /usr/ccs/bin/as assembler always wants the older SS11 (5.8) options.
+AS_XARCH_OPTION = $(XARCH_OPTION_OLD/$(ARCH_DATA_MODEL))
+
--- a/jdk/make/jdk_generic_profile.sh	Wed Jul 05 16:37:21 2017 +0200
+++ b/jdk/make/jdk_generic_profile.sh	Wed Jul 05 16:37:51 2017 +0200
@@ -119,7 +119,7 @@
   # System place where JDK installed images are stored?
   jdk_instances=/usr/jdk/instances
 
-  # Get the SS11 compilers (and latest patches for them too)
+  # Get the Sun Studio compilers (and latest patches for them too)
   if [ "${ALT_COMPILER_PATH}" = "" ] ; then
     ALT_COMPILER_PATH=/opt/SUNWspro/bin
     export ALT_COMPILER_PATH
--- a/jdk/make/jprt.config	Wed Jul 05 16:37:21 2017 +0200
+++ b/jdk/make/jprt.config	Wed Jul 05 16:37:51 2017 +0200
@@ -133,9 +133,15 @@
 	solaris_arch=i386
     fi
 
-    # Get the SS11 compilers into path (make sure it matches ALT setting)
-    compiler_path=${jdk_devtools}/${solaris_arch}/SUNWspro/SS11/bin
-    compiler_name=SS11
+    # Get the compilers into path (make sure it matches ALT setting)
+    if [ "${JPRT_SOLARIS_COMPILER_NAME}" != "" ] ; then
+        compiler_name=${JPRT_SOLARIS_COMPILER_NAME}
+    else
+        # FIXUP: Change to SS12 when validated
+	#compiler_name=SS12
+	compiler_name=SS11
+    fi
+    compiler_path=${jdk_devtools}/${solaris_arch}/SUNWspro/${compiler_name}/bin
     ALT_COMPILER_PATH="${compiler_path}"
     export ALT_COMPILER_PATH
     dirMustExist "${compiler_path}" ALT_COMPILER_PATH
--- a/jdk/make/sun/jawt/Makefile	Wed Jul 05 16:37:21 2017 +0200
+++ b/jdk/make/sun/jawt/Makefile	Wed Jul 05 16:37:51 2017 +0200
@@ -93,7 +93,6 @@
 # Other extra flags needed for compiling.
 #
 CPPFLAGS += -I$(OPENWIN_HOME)/include \
-	    -I$(MOTIF_DIR)/include \
 	    -I$(SHARE_SRC)/native/$(PKGDIR)/debug \
             -I$(SHARE_SRC)/native/$(PKGDIR)/image \
 	    -I$(SHARE_SRC)/native/$(PKGDIR)/image/cvutils \
--- a/jdk/src/share/classes/java/awt/Component.java	Wed Jul 05 16:37:21 2017 +0200
+++ b/jdk/src/share/classes/java/awt/Component.java	Wed Jul 05 16:37:51 2017 +0200
@@ -3057,10 +3057,24 @@
             // services.  Additionally, the request is restricted to
             // the bounds of the component.
             if (parent != null) {
-                int px = this.x + ((x < 0) ? 0 : x);
-                int py = this.y + ((y < 0) ? 0 : y);
+                if (x < 0) {
+                    width += x;
+                    x = 0;
+                }
+                if (y < 0) {
+                    height += y;
+                    y = 0;
+                }
+
                 int pwidth = (width > this.width) ? this.width : width;
                 int pheight = (height > this.height) ? this.height : height;
+
+                if (pwidth <= 0 || pheight <= 0) {
+                    return;
+                }
+
+                int px = this.x + x;
+                int py = this.y + y;
                 parent.repaint(tm, px, py, pwidth, pheight);
             }
         } else {
--- a/jdk/src/share/classes/java/awt/dnd/DragSourceContext.java	Wed Jul 05 16:37:21 2017 +0200
+++ b/jdk/src/share/classes/java/awt/dnd/DragSourceContext.java	Wed Jul 05 16:37:51 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2008 Sun Microsystems, Inc.  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
@@ -485,7 +485,6 @@
 
         Cursor c = null;
 
-        targetAct = DnDConstants.ACTION_NONE;
         switch (status) {
             case ENTER:
             case OVER:
@@ -507,6 +506,10 @@
                     else
                         c = DragSource.DefaultCopyDrop;
                 }
+                break;
+            default:
+                targetAct = DnDConstants.ACTION_NONE;
+
         }
 
         setCursorImpl(c);
--- a/jdk/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java	Wed Jul 05 16:37:21 2017 +0200
+++ b/jdk/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java	Wed Jul 05 16:37:51 2017 +0200
@@ -1696,8 +1696,8 @@
             } catch (Exception e) {
                 // eat exceptions because interface doesn't have an
                 // exception on it
-                if (MODELMBEAN_LOGGER.isLoggable(Level.WARNING)) {
-                    MODELMBEAN_LOGGER.logp(Level.WARNING,
+                if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
+                    MODELMBEAN_LOGGER.logp(Level.FINER,
                             RequiredModelMBean.class.getName(),
                         "getAttributes(String[])",
                             "Failed to get \"" + attrNames[i] + "\": ", e);
@@ -1857,8 +1857,8 @@
                                             attrValue.getClass().getName() +
                                                            " received.");
                     } catch (ClassNotFoundException x) {
-                        if (MODELMBEAN_LOGGER.isLoggable(Level.WARNING)) {
-                            MODELMBEAN_LOGGER.logp(Level.WARNING,
+                        if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
+                            MODELMBEAN_LOGGER.logp(Level.FINER,
                                     RequiredModelMBean.class.getName(),
                                 "setAttribute(Attribute)","Class " +
                                     attrType + " for attribute "
@@ -2224,8 +2224,8 @@
                             ntfyObj.getMessage() + " Severity = " +
                             (String)ntfyDesc.getFieldValue("severity"));
                     } catch (Exception e) {
-                        if (MODELMBEAN_LOGGER.isLoggable(Level.WARNING)) {
-                            MODELMBEAN_LOGGER.logp(Level.WARNING,
+                        if (MODELMBEAN_LOGGER.isLoggable(Level.FINE)) {
+                            MODELMBEAN_LOGGER.logp(Level.FINE,
                                     RequiredModelMBean.class.getName(),
                                     "sendNotification(Notification)",
                                     "Failed to log " +
@@ -2618,8 +2618,8 @@
                            " Old value = " + oldv +
                            " New value = " + newv);
                     } catch (Exception e) {
-                        if (MODELMBEAN_LOGGER.isLoggable(Level.WARNING)) {
-                            MODELMBEAN_LOGGER.logp(Level.WARNING,
+                        if (MODELMBEAN_LOGGER.isLoggable(Level.FINE)) {
+                            MODELMBEAN_LOGGER.logp(Level.FINE,
                                     RequiredModelMBean.class.getName(),mth,
                                 "Failed to log " + ntfyObj.getType() +
                                     " notification: ", e);
@@ -2644,8 +2644,8 @@
                            " Old value = " + oldv +
                            " New value = " + newv);
                     } catch (Exception e) {
-                        if (MODELMBEAN_LOGGER.isLoggable(Level.WARNING)) {
-                            MODELMBEAN_LOGGER.logp(Level.WARNING,
+                        if (MODELMBEAN_LOGGER.isLoggable(Level.FINE)) {
+                            MODELMBEAN_LOGGER.logp(Level.FINE,
                                     RequiredModelMBean.class.getName(),mth,
                                 "Failed to log " + ntfyObj.getType() +
                                     " notification: ", e);
--- a/jdk/src/share/classes/sun/security/provider/certpath/OCSPChecker.java	Wed Jul 05 16:37:21 2017 +0200
+++ b/jdk/src/share/classes/sun/security/provider/certpath/OCSPChecker.java	Wed Jul 05 16:37:51 2017 +0200
@@ -102,7 +102,7 @@
      */
     public void init(boolean forward) throws CertPathValidatorException {
         if (!forward) {
-            remainingCerts = certs.length;
+            remainingCerts = certs.length + 1;
         } else {
             throw new CertPathValidatorException(
                 "Forward checking not supported");
@@ -131,14 +131,22 @@
 
         InputStream in = null;
         OutputStream out = null;
+
+        // Decrement the certificate counter
+        remainingCerts--;
+
         try {
-            // Examine OCSP properties
             X509Certificate responderCert = null;
             boolean seekResponderCert = false;
             X500Principal responderSubjectName = null;
             X500Principal responderIssuerName = null;
             BigInteger responderSerialNumber = null;
 
+            boolean seekIssuerCert = true;
+            X509CertImpl issuerCertImpl = null;
+            X509CertImpl currCertImpl =
+                X509CertImpl.toImpl((X509Certificate)cert);
+
             /*
              * OCSP security property values, in the following order:
              *   1. ocsp.responderURL
@@ -148,6 +156,9 @@
              */
             String[] properties = getOCSPProperties();
 
+            // Check whether OCSP is feasible before seeking cert information
+            URL url = getOCSPServerURL(currCertImpl, properties);
+
             // When responder's subject name is set then the issuer/serial
             // properties are ignored
             if (properties[1] != null) {
@@ -172,14 +183,9 @@
                 seekResponderCert = true;
             }
 
-            boolean seekIssuerCert = true;
-            X509CertImpl issuerCertImpl = null;
-            X509CertImpl currCertImpl =
-                X509CertImpl.toImpl((X509Certificate)cert);
-            remainingCerts--;
-
-            // Set the issuer certificate
-            if (remainingCerts != 0) {
+            // Set the issuer certificate to the next cert in the chain
+            // (unless we're processing the final cert).
+            if (remainingCerts < certs.length) {
                 issuerCertImpl = X509CertImpl.toImpl(certs[remainingCerts]);
                 seekIssuerCert = false; // done
 
@@ -312,7 +318,8 @@
             // Construct an OCSP Request
             OCSPRequest ocspRequest =
                 new OCSPRequest(currCertImpl, issuerCertImpl);
-            URL url = getOCSPServerURL(currCertImpl, properties);
+
+            // Use the URL to the OCSP service that was created earlier
             HttpURLConnection con = (HttpURLConnection)url.openConnection();
             if (DEBUG != null) {
                 DEBUG.println("connecting to OCSP service at: " + url);
--- a/jdk/src/solaris/native/java/net/PlainSocketImpl.c	Wed Jul 05 16:37:21 2017 +0200
+++ b/jdk/src/solaris/native/java/net/PlainSocketImpl.c	Wed Jul 05 16:37:51 2017 +0200
@@ -358,15 +358,28 @@
              * See 6343810.
              */
             while (1) {
-                fd_set wr, ex;
+#ifndef USE_SELECT
+                {
+fprintf(stdout,"\nNATIVE: fd = %d] ", fd);
+                    struct pollfd pfd;
+                    pfd.fd = fd;
+                    pfd.events = POLLOUT;
 
-                FD_ZERO(&wr);
-                FD_SET(fd, &wr);
-                FD_ZERO(&ex);
-                FD_SET(fd, &ex);
+                    connect_rv = NET_Poll(&pfd, 1, -1);
+                }
+#else
+                {
+                    fd_set wr, ex;
 
-                errno = 0;
-                connect_rv = NET_Select(fd+1, 0, &wr, &ex, 0);
+                    FD_ZERO(&wr);
+                    FD_SET(fd, &wr);
+                    FD_ZERO(&ex);
+                    FD_SET(fd, &ex);
+
+                    connect_rv = NET_Select(fd+1, 0, &wr, &ex, 0);
+                }
+#endif
+
                 if (connect_rv == JVM_IO_ERR) {
                     if (errno == EINTR) {
                         continue;
--- a/jdk/src/windows/native/sun/windows/awt_Component.cpp	Wed Jul 05 16:37:21 2017 +0200
+++ b/jdk/src/windows/native/sun/windows/awt_Component.cpp	Wed Jul 05 16:37:51 2017 +0200
@@ -3464,6 +3464,21 @@
     return java_awt_event_KeyEvent_VK_UNDEFINED;
 }
 
+BOOL AwtComponent::IsNavigationKey(UINT wkey) {
+    switch (wkey) {
+      case VK_END:
+      case VK_PRIOR:  // PageUp
+      case VK_NEXT:  // PageDown
+      case VK_HOME:
+      case VK_LEFT:
+      case VK_UP:
+      case VK_RIGHT:
+      case VK_DOWN:
+          return TRUE;
+    }
+    return FALSE;
+}
+
 // determine if a key is a numpad key (distinguishes the numpad
 // arrow keys from the non-numpad arrow keys, for example).
 BOOL AwtComponent::IsNumPadKey(UINT vkey, BOOL extended)
@@ -3563,7 +3578,10 @@
         // fix for 4623376,4737679,4501485,4740906,4708221 (4173679/4122715)
         // Here we try to resolve a conflict with ::ToAsciiEx's translating
         // ALT+number key combinations. kdm@sarc.spb.su
-        keyboardState[VK_MENU] &= ~KEY_STATE_DOWN;
+        // yan: Do it for navigation keys only, otherwise some AltGr deadkeys fail.
+        if( IsNavigationKey(wkey) ) {
+            keyboardState[VK_MENU] &= ~KEY_STATE_DOWN;
+        }
 
         if (ctrlIsDown)
         {
--- a/jdk/src/windows/native/sun/windows/awt_Component.h	Wed Jul 05 16:37:21 2017 +0200
+++ b/jdk/src/windows/native/sun/windows/awt_Component.h	Wed Jul 05 16:37:51 2017 +0200
@@ -823,6 +823,7 @@
 private:
     AwtComponent* SearchChild(UINT id);
     void RemoveChild(UINT id) ;
+    static BOOL IsNavigationKey(UINT wkey);
 
     ChildListItem* m_childList;
 
--- a/jdk/test/javax/management/Introspector/LegacyIntrospectorTest.java	Wed Jul 05 16:37:21 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-/*
- * Copyright 2005 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-/*
- * @test
- * @bug 6316460
- * @summary Test that the legacy com.sun.management.jmx.Introspector
- * methods work.
- * @author Eamonn McManus
- * @run clean LegacyIntrospectorTest
- * @run build LegacyIntrospectorTest
- * @run main LegacyIntrospectorTest
- */
-
-import javax.management.*;
-import com.sun.management.jmx.*;
-
-public class LegacyIntrospectorTest {
-    public static interface TestMBean {
-        public int getWhatever();
-    }
-    public static class Test implements TestMBean {
-        public int getWhatever() {return 0;}
-    }
-
-    @SuppressWarnings("deprecation")
-    public static void main(String[] args) throws Exception {
-        MBeanInfo mbi = Introspector.testCompliance(Test.class);
-        MBeanAttributeInfo mbai = mbi.getAttributes()[0];
-        if (!mbai.getName().equals("Whatever"))
-            throw new Exception("Wrong attribute name: " + mbai.getName());
-        Class c = Introspector.getMBeanInterface(Test.class);
-        if (c != TestMBean.class)
-            throw new Exception("Wrong interface: " + c);
-
-        MBeanServer mbs1 = new MBeanServerImpl();
-        if (!mbs1.getDefaultDomain().equals("DefaultDomain"))
-            throw new Exception("Wrong default domain: " + mbs1.getDefaultDomain());
-
-        MBeanServer mbs2 = new MBeanServerImpl("Foo");
-        if (!mbs2.getDefaultDomain().equals("Foo"))
-            throw new Exception("Wrong default domain: " + mbs2.getDefaultDomain());
-
-        ObjectName delegateName =
-            new ObjectName("JMImplementation:type=MBeanServerDelegate");
-        MBeanInfo delegateInfo = mbs2.getMBeanInfo(delegateName);
-        MBeanInfo refDelegateInfo =
-            MBeanServerFactory.newMBeanServer().getMBeanInfo(delegateName);
-        if (!delegateInfo.equals(refDelegateInfo))
-            throw new Exception("Wrong delegate info from MBeanServerImpl: " +
-                                delegateInfo);
-
-        System.out.println("TEST PASSED");
-    }
-}
--- a/jdk/test/sun/security/pkcs11/Cipher/TestSymmCiphers.java	Wed Jul 05 16:37:21 2017 +0200
+++ b/jdk/test/sun/security/pkcs11/Cipher/TestSymmCiphers.java	Wed Jul 05 16:37:51 2017 +0200
@@ -2,32 +2,22 @@
  * Copyright 2008 Sun Microsystems, Inc.  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 modi
-fy it
- * under the terms of the GNU General Public License version 2 onl
-y, as
+ * 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, bu
-t WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABIL
-ITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public L
-icense
- * version 2 for more details (a copy is included in the LICENSE f
-ile that
+ * 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 Licen
-se version
- * 2 along with this work; if not, write to the Free Software Foun
-dation,
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, San
-ta Clara,
- * CA 95054 USA or visit www.sun.com if you need additional inform
-ation or
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
  * have any questions.
  */
 
--- a/jdk/test/sun/security/tools/keytool/autotest.sh	Wed Jul 05 16:37:21 2017 +0200
+++ b/jdk/test/sun/security/tools/keytool/autotest.sh	Wed Jul 05 16:37:51 2017 +0200
@@ -1,5 +1,5 @@
 #
-# Copyright 2006 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2006-2008 Sun Microsystems, Inc.  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
@@ -90,7 +90,8 @@
 
 echo | ${TESTJAVA}${FS}bin${FS}java -Dfile -Dnss \
    -Dnss.lib=${NSS}${FS}lib${FS}${PF}${FS}${LIBNAME} \
-   KeyToolTest || exit 12
+   KeyToolTest
+status=$?
 
 rm -f p11-nss.txt
 rm -f cert8.db
@@ -101,4 +102,5 @@
 rm KeyToolTest.class
 rm TestException.class 
 
-exit $?
+exit $status
+
--- a/langtools/.hgtags	Wed Jul 05 16:37:21 2017 +0200
+++ b/langtools/.hgtags	Wed Jul 05 16:37:51 2017 +0200
@@ -2,3 +2,4 @@
 58039502942e52f4144a33f36290a2bd2f3581e6 jdk7-b25
 c46d25a2350ac147d0121d9c9725af6fcb1b4dbe jdk7-b26
 a17265993253d61becd04fe7d96d1fe8b4bd6dff jdk7-b27
+4ef4bd31856949554967fbf22783babb21a62a0e jdk7-b28
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java	Wed Jul 05 16:37:21 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java	Wed Jul 05 16:37:51 2017 +0200
@@ -301,7 +301,11 @@
                 : isSubtypeUnchecked(elemtype(t), elemtype(s), warn);
         } else if (isSubtype(t, s)) {
             return true;
-        } else if (!s.isRaw()) {
+        }
+        else if (t.tag == TYPEVAR) {
+            return isSubtypeUnchecked(t.getUpperBound(), s, warn);
+        }
+        else if (!s.isRaw()) {
             Type t2 = asSuper(t, s.tsym);
             if (t2 != null && t2.isRaw()) {
                 if (isReifiable(s))
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Wed Jul 05 16:37:21 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Wed Jul 05 16:37:51 2017 +0200
@@ -454,6 +454,8 @@
     void attribTypeVariables(List<JCTypeParameter> typarams, Env<AttrContext> env) {
         for (JCTypeParameter tvar : typarams) {
             TypeVar a = (TypeVar)tvar.type;
+            a.tsym.flags_field |= UNATTRIBUTED;
+            a.bound = Type.noType;
             if (!tvar.bounds.isEmpty()) {
                 List<Type> bounds = List.of(attribType(tvar.bounds.head, env));
                 for (JCExpression bound : tvar.bounds.tail)
@@ -464,13 +466,14 @@
                 // java.lang.Object.
                 types.setBounds(a, List.of(syms.objectType));
             }
+            a.tsym.flags_field &= ~UNATTRIBUTED;
         }
-    }
-
-    void attribBounds(List<JCTypeParameter> typarams, Env<AttrContext> env) {
         for (JCTypeParameter tvar : typarams)
             chk.checkNonCyclic(tvar.pos(), (TypeVar)tvar.type);
         attribStats(typarams, env);
+    }
+
+    void attribBounds(List<JCTypeParameter> typarams) {
         for (JCTypeParameter typaram : typarams) {
             Type bound = typaram.type.getUpperBound();
             if (bound != null && bound.tsym instanceof ClassSymbol) {
@@ -581,7 +584,7 @@
         try {
             chk.checkDeprecatedAnnotation(tree.pos(), m);
 
-            attribBounds(tree.typarams, env);
+            attribBounds(tree.typarams);
 
             // If we override any other methods, check that we do so properly.
             // JLS ???
@@ -2689,7 +2692,7 @@
         chk.validateAnnotations(tree.mods.annotations, c);
 
         // Validate type parameters, supertype and interfaces.
-        attribBounds(tree.typarams, env);
+        attribBounds(tree.typarams);
         chk.validateTypeParams(tree.typarams);
         chk.validate(tree.extending);
         chk.validate(tree.implementing);
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java	Wed Jul 05 16:37:21 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java	Wed Jul 05 16:37:51 2017 +0200
@@ -1486,6 +1486,8 @@
 
     private void checkNonCyclic1(DiagnosticPosition pos, Type t, Set<TypeVar> seen) {
         final TypeVar tv;
+        if  (t.tag == TYPEVAR && (t.tsym.flags() & UNATTRIBUTED) != 0)
+            return;
         if (seen.contains(t)) {
             tv = (TypeVar)t;
             tv.bound = new ErrorType();
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Wed Jul 05 16:37:21 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Wed Jul 05 16:37:51 2017 +0200
@@ -228,7 +228,7 @@
                 // another symbol which is a member of `site'
                 // (because, if it is overridden, `sym' is not strictly
                 // speaking a member of `site'.)
-                (sym.kind != MTH || sym.isConstructor() ||
+                (sym.kind != MTH || sym.isConstructor() || sym.isStatic() ||
                  ((MethodSymbol)sym).implementation(site.tsym, types, true) == sym);
         default: // this case includes erroneous combinations as well
             return isAccessible(env, site);
--- a/langtools/src/share/classes/com/sun/tools/javac/util/JavacFileManager.java	Wed Jul 05 16:37:21 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/JavacFileManager.java	Wed Jul 05 16:37:51 2017 +0200
@@ -1606,7 +1606,7 @@
         /** @deprecated see bug 6410637 */
         @Deprecated
         public String getPath() {
-            return entry.getName() + "(" + entry + ")";
+            return zipName + "(" + entry.getName() + ")";
         }
 
         public long getLastModified() {
--- a/langtools/src/share/classes/com/sun/tools/javac/zip/ZipFileIndex.java	Wed Jul 05 16:37:21 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/zip/ZipFileIndex.java	Wed Jul 05 16:37:51 2017 +0200
@@ -1,3 +1,28 @@
+/*
+ * Copyright 2007-2008 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
 package com.sun.tools.javac.zip;
 
 import java.io.*;
--- a/langtools/src/share/classes/com/sun/tools/javac/zip/ZipFileIndexEntry.java	Wed Jul 05 16:37:21 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/zip/ZipFileIndexEntry.java	Wed Jul 05 16:37:51 2017 +0200
@@ -1,3 +1,28 @@
+/*
+ * Copyright 2007-2008 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
 package com.sun.tools.javac.zip;
 
 import java.io.File;
--- a/langtools/src/share/classes/sun/tools/javap/ClassData.java	Wed Jul 05 16:37:21 2017 +0200
+++ b/langtools/src/share/classes/sun/tools/javap/ClassData.java	Wed Jul 05 16:37:51 2017 +0200
@@ -58,7 +58,7 @@
     private String superclassname;
     private int source_cpx=0;
     private byte tags[];
-    private Hashtable indexHashAscii = new Hashtable();
+    private Hashtable<Object,Integer> indexHashAscii = new Hashtable<Object,Integer>();
     private String pkgPrefix="";
     private int pkgPrefixLen=0;
 
@@ -167,19 +167,19 @@
             switch(tags[i] = tag) {
             case CONSTANT_UTF8:
                 String str=in.readUTF();
-                indexHashAscii.put(cpool[i] = str, new Integer(i));
+                indexHashAscii.put(cpool[i] = str, i);
                 break;
             case CONSTANT_INTEGER:
-                cpool[i] = new Integer(in.readInt());
+                cpool[i] = Integer.valueOf(in.readInt());
                 break;
             case CONSTANT_FLOAT:
-                cpool[i] = new Float(in.readFloat());
+                cpool[i] = Float.valueOf(in.readFloat());
                 break;
             case CONSTANT_LONG:
-                cpool[i++] = new Long(in.readLong());
+                cpool[i++] = Long.valueOf(in.readLong());
                 break;
             case CONSTANT_DOUBLE:
-                cpool[i++] = new Double(in.readDouble());
+                cpool[i++] = Double.valueOf(in.readDouble());
                 break;
             case CONSTANT_CLASS:
             case CONSTANT_STRING:
@@ -365,7 +365,7 @@
      * Returns the access of this class or interface.
      */
     public String[] getAccess(){
-        Vector v = new Vector();
+        Vector<String> v = new Vector<String>();
         if ((access & ACC_PUBLIC)   !=0) v.addElement("public");
         if ((access & ACC_FINAL)    !=0) v.addElement("final");
         if ((access & ACC_ABSTRACT) !=0) v.addElement("abstract");
--- a/langtools/src/share/classes/sun/tools/javap/FieldData.java	Wed Jul 05 16:37:21 2017 +0200
+++ b/langtools/src/share/classes/sun/tools/javap/FieldData.java	Wed Jul 05 16:37:51 2017 +0200
@@ -45,7 +45,7 @@
     int value_cpx=0;
     boolean isSynthetic=false;
     boolean isDeprecated=false;
-    Vector attrs;
+    Vector<AttrData> attrs;
 
     public FieldData(ClassData cls){
         this.cls=cls;
@@ -60,7 +60,7 @@
         descriptor_index = in.readUnsignedShort();
         // Read the attributes
         int attributes_count = in.readUnsignedShort();
-        attrs=new Vector(attributes_count);
+        attrs=new Vector<AttrData>(attributes_count);
         for (int i = 0; i < attributes_count; i++) {
             int attr_name_index=in.readUnsignedShort();
             if (cls.getTag(attr_name_index)!=CONSTANT_UTF8) continue;
@@ -99,7 +99,7 @@
      * Returns access of a field.
      */
     public String[] getAccess(){
-        Vector v = new Vector();
+        Vector<String> v = new Vector<String>();
         if ((access & ACC_PUBLIC)   !=0) v.addElement("public");
         if ((access & ACC_PRIVATE)   !=0) v.addElement("private");
         if ((access & ACC_PROTECTED)   !=0) v.addElement("protected");
--- a/langtools/src/share/classes/sun/tools/javap/InnerClassData.java	Wed Jul 05 16:37:21 2017 +0200
+++ b/langtools/src/share/classes/sun/tools/javap/InnerClassData.java	Wed Jul 05 16:37:51 2017 +0200
@@ -63,7 +63,7 @@
      * Returns the access of this class or interface.
      */
     public String[] getAccess(){
-        Vector v = new Vector();
+        Vector<String> v = new Vector<String>();
         if ((access & ACC_PUBLIC)   !=0) v.addElement("public");
         if ((access & ACC_FINAL)    !=0) v.addElement("final");
         if ((access & ACC_ABSTRACT) !=0) v.addElement("abstract");
--- a/langtools/src/share/classes/sun/tools/javap/JavapPrinter.java	Wed Jul 05 16:37:21 2017 +0200
+++ b/langtools/src/share/classes/sun/tools/javap/JavapPrinter.java	Wed Jul 05 16:37:51 2017 +0200
@@ -653,7 +653,7 @@
         case CONSTANT_METHOD:
         case CONSTANT_INTERFACEMETHOD:
         case CONSTANT_FIELD: {
-            CPX2 x = (CPX2)(cls.getCpoolEntry(cpx));
+            CPX2 x = cls.getCpoolEntry(cpx);
             if (x.cpx1 == cls.getthis_cpx()) {
                 // don't print class part for local references
                 cpx=x.cpx2;
@@ -851,7 +851,7 @@
         case CONSTANT_INTERFACEMETHOD:
         case CONSTANT_FIELD: {
             // CPX2 x=(CPX2)(cpool[cpx]);
-            CPX2 x = (CPX2)(cls.getCpoolEntry(cpx));
+            CPX2 x = cls.getCpoolEntry(cpx);
             if (x.cpx1 == cls.getthis_cpx()) {
                 // don't print class part for local references
                 cpx=x.cpx2;
--- a/langtools/src/share/classes/sun/tools/javap/Main.java	Wed Jul 05 16:37:21 2017 +0200
+++ b/langtools/src/share/classes/sun/tools/javap/Main.java	Wed Jul 05 16:37:51 2017 +0200
@@ -35,9 +35,9 @@
  *
  * @author  Sucheta Dambalkar (Adopted code from old javap)
  */
-public class Main{
+public class Main {
 
-    private Vector classList = new Vector();
+    private Vector<String> classList = new Vector<String>();
     private PrintWriter out;
     JavapEnvironment env = new JavapEnvironment();
     private static boolean errorOccurred = false;
@@ -201,7 +201,7 @@
      */
     private void displayResults() {
         for (int i = 0; i < classList.size() ; i++ ) {
-            String Name = (String)classList.elementAt(i);
+            String Name = classList.elementAt(i);
             InputStream classin = env.getFileInputStream(Name);
 
             try {
--- a/langtools/src/share/classes/sun/tools/javap/MethodData.java	Wed Jul 05 16:37:21 2017 +0200
+++ b/langtools/src/share/classes/sun/tools/javap/MethodData.java	Wed Jul 05 16:37:51 2017 +0200
@@ -43,14 +43,14 @@
     int descriptor_index;
     int attributes_count;
     byte[] code;
-    Vector exception_table = new Vector(0);
-    Vector lin_num_tb = new Vector(0);
-    Vector loc_var_tb = new Vector(0);
+    Vector<TrapData> exception_table = new Vector<TrapData>(0);
+    Vector<LineNumData> lin_num_tb = new Vector<LineNumData>(0);
+    Vector<LocVarData> loc_var_tb = new Vector<LocVarData>(0);
     StackMapTableData[] stackMapTable;
     StackMapData[] stackMap;
     int[] exc_index_table=null;
-    Vector attrs=new Vector(0);
-    Vector code_attrs=new Vector(0);
+    Vector<AttrData> attrs=new Vector<AttrData>(0);
+    Vector<AttrData> code_attrs=new Vector<AttrData>(0);
     int max_stack,  max_locals;
     boolean isSynthetic=false;
     boolean isDeprecated=false;
@@ -165,7 +165,7 @@
      */
     void readExceptionTable (DataInputStream in) throws IOException {
         int exception_table_len=in.readUnsignedShort();
-        exception_table=new Vector(exception_table_len);
+        exception_table=new Vector<TrapData>(exception_table_len);
         for (int l = 0; l < exception_table_len; l++) {
             exception_table.addElement(new TrapData(in, l));
         }
@@ -177,7 +177,7 @@
     void readLineNumTable (DataInputStream in) throws IOException {
         int attr_len = in.readInt(); // attr_length
         int lin_num_tb_len = in.readUnsignedShort();
-        lin_num_tb=new Vector(lin_num_tb_len);
+        lin_num_tb=new Vector<LineNumData>(lin_num_tb_len);
         for (int l = 0; l < lin_num_tb_len; l++) {
             lin_num_tb.addElement(new LineNumData(in));
         }
@@ -189,7 +189,7 @@
     void readLocVarTable (DataInputStream in) throws IOException {
         int attr_len=in.readInt(); // attr_length
         int loc_var_tb_len = in.readUnsignedShort();
-        loc_var_tb = new Vector(loc_var_tb_len);
+        loc_var_tb = new Vector<LocVarData>(loc_var_tb_len);
         for (int l = 0; l < loc_var_tb_len; l++) {
             loc_var_tb.addElement(new LocVarData(in));
         }
@@ -237,7 +237,7 @@
      */
     public String[] getAccess(){
 
-        Vector v = new Vector();
+        Vector<String> v = new Vector<String>();
         if ((access & ACC_PUBLIC)   !=0) v.addElement("public");
         if ((access & ACC_PRIVATE)   !=0) v.addElement("private");
         if ((access & ACC_PROTECTED)   !=0) v.addElement("protected");
--- a/langtools/src/share/classes/sun/tools/javap/Tables.java	Wed Jul 05 16:37:21 2017 +0200
+++ b/langtools/src/share/classes/sun/tools/javap/Tables.java	Wed Jul 05 16:37:51 2017 +0200
@@ -26,8 +26,6 @@
 
 package sun.tools.javap;
 
-import java.io.IOException;
-import java.io.InputStream;
 import java.util.Hashtable;
 import java.util.Vector;
 
@@ -36,14 +34,14 @@
     /**
      * Define mnemocodes table.
      */
-  static  Hashtable mnemocodes = new Hashtable(301, 0.5f);
+  static  Hashtable<String,Integer> mnemocodes = new Hashtable<String,Integer>(301, 0.5f);
   static  String opcExtNamesTab[]=new String[128];
   static  String opcPrivExtNamesTab[]=new String[128];
   static  void defineNonPriv(int opc, String mnem) {
-        mnemocodes.put(opcExtNamesTab[opc]=mnem, new Integer(opc_nonpriv*256+opc));
+        mnemocodes.put(opcExtNamesTab[opc]=mnem, opc_nonpriv*256+opc);
   }
   static  void definePriv(int opc, String mnem) {
-        mnemocodes.put(opcPrivExtNamesTab[opc]="priv_"+mnem, new Integer(opc_priv*256+opc));
+        mnemocodes.put(opcPrivExtNamesTab[opc]="priv_"+mnem, opc_priv*256+opc);
   }
   static  void defineExt(int opc, String mnem) {
         defineNonPriv(opc, mnem);
@@ -51,28 +49,28 @@
   }
   static { int k;
         for (k=0; k<opc_wide; k++) {
-                mnemocodes.put(opcNamesTab[k], new Integer(k));
+                mnemocodes.put(opcNamesTab[k], k);
         }
         for (k=opc_wide+1; k<opcNamesTab.length; k++) {
-                mnemocodes.put(opcNamesTab[k], new Integer(k));
+                mnemocodes.put(opcNamesTab[k], k);
         }
-        mnemocodes.put("invokenonvirtual", new Integer(opc_invokespecial));
+        mnemocodes.put("invokenonvirtual", opc_invokespecial);
 
-        mnemocodes.put("iload_w", new Integer(opc_iload_w));
-        mnemocodes.put("lload_w", new Integer(opc_lload_w));
-        mnemocodes.put("fload_w", new Integer(opc_fload_w));
-        mnemocodes.put("dload_w", new Integer(opc_dload_w));
-        mnemocodes.put("aload_w", new Integer(opc_aload_w));
-        mnemocodes.put("istore_w", new Integer(opc_istore_w));
-        mnemocodes.put("lstore_w", new Integer(opc_lstore_w));
-        mnemocodes.put("fstore_w", new Integer(opc_fstore_w));
-        mnemocodes.put("dstore_w", new Integer(opc_dstore_w));
-        mnemocodes.put("astore_w", new Integer(opc_astore_w));
-        mnemocodes.put("ret_w", new Integer(opc_ret_w));
-        mnemocodes.put("iinc_w", new Integer(opc_iinc_w));
+        mnemocodes.put("iload_w", opc_iload_w);
+        mnemocodes.put("lload_w", opc_lload_w);
+        mnemocodes.put("fload_w", opc_fload_w);
+        mnemocodes.put("dload_w", opc_dload_w);
+        mnemocodes.put("aload_w", opc_aload_w);
+        mnemocodes.put("istore_w", opc_istore_w);
+        mnemocodes.put("lstore_w", opc_lstore_w);
+        mnemocodes.put("fstore_w", opc_fstore_w);
+        mnemocodes.put("dstore_w", opc_dstore_w);
+        mnemocodes.put("astore_w", opc_astore_w);
+        mnemocodes.put("ret_w", opc_ret_w);
+        mnemocodes.put("iinc_w", opc_iinc_w);
 
-        mnemocodes.put("nonpriv", new Integer(opc_nonpriv));
-        mnemocodes.put("priv", new Integer(opc_priv));
+        mnemocodes.put("nonpriv", opc_nonpriv);
+        mnemocodes.put("priv", opc_priv);
 
         defineExt(0, "load_ubyte");
         defineExt(1, "load_byte");
@@ -183,7 +181,7 @@
   }
 
   public static int opcode(String mnem) {
-        Integer Val=(Integer)(mnemocodes.get(mnem));
+        Integer Val=mnemocodes.get(mnem);
         if (Val == null) return -1;
         return Val.intValue();
   }
@@ -191,7 +189,7 @@
     /**
      * Initialized keyword and token Hashtables
      */
-  static Vector keywordNames = new Vector(40);
+  static Vector<String> keywordNames = new Vector<String>(40);
   private static void defineKeywordName(String id, int token) {
 
         if (token>=keywordNames.size()) {
@@ -202,7 +200,7 @@
   public static String keywordName(int token) {
         if (token==-1) return "EOF";
         if (token>=keywordNames.size()) return null;
-        return (String)keywordNames.elementAt(token);
+        return keywordNames.elementAt(token);
   }
   static {
         defineKeywordName("ident", IDENT);
@@ -217,15 +215,15 @@
         defineKeywordName("RBRACE", RBRACE);
   }
 
-  static Hashtable keywords = new Hashtable(40);
+  static Hashtable<String,Integer> keywords = new Hashtable<String,Integer>(40);
   public static int keyword(String idValue) {
-        Integer Val=(Integer)(keywords.get(idValue));
-        if (Val == null) return IDENT;
-        return Val.intValue();
+        Integer val=keywords.get(idValue);
+        if (val == null) return IDENT;
+        return val.intValue();
   }
 
   private static void defineKeyword(String id, int token) {
-        keywords.put(id, new Integer(token));
+        keywords.put(id, token);
         defineKeywordName(id, token);
   }
   static {
@@ -275,8 +273,8 @@
    /**
      * Define tag table.
      */
-  private static Vector tagNames = new Vector(10);
-  private static Hashtable Tags = new Hashtable(10);
+  private static Vector<String> tagNames = new Vector<String>(10);
+  private static Hashtable<String,Integer> Tags = new Hashtable<String,Integer>(10);
   static {
         defineTag("Asciz",CONSTANT_UTF8);
         defineTag("int",CONSTANT_INTEGER);
@@ -291,7 +289,7 @@
         defineTag("NameAndType",CONSTANT_NAMEANDTYPE);
   }
   private static void defineTag(String id, int val) {
-        Tags.put(id, new Integer(val));
+        Tags.put(id, val);
         if (val>=tagNames.size()) {
                 tagNames.setSize(val+1);
         }
@@ -299,10 +297,10 @@
   }
   public static String tagName(int tag) {
         if (tag>=tagNames.size()) return null;
-        return (String)tagNames.elementAt(tag);
+        return tagNames.elementAt(tag);
   }
   public static int tagValue(String idValue) {
-        Integer Val=(Integer)(Tags.get(idValue));
+        Integer Val=Tags.get(idValue);
         if (Val == null) return 0;
         return Val.intValue();
   }
@@ -310,8 +308,8 @@
    /**
      * Define type table. These types used in "newarray" instruction only.
      */
-  private static Vector typeNames = new Vector(10);
-  private static Hashtable Types = new Hashtable(10);
+  private static Vector<String> typeNames = new Vector<String>(10);
+  private static Hashtable<String,Integer> Types = new Hashtable<String,Integer>(10);
   static {
         defineType("int",T_INT);
         defineType("long",T_LONG);
@@ -324,28 +322,28 @@
         defineType("short",T_SHORT);
   }
   private static void defineType(String id, int val) {
-        Types.put(id, new Integer(val));
+        Types.put(id, val);
         if (val>=typeNames.size()) {
                 typeNames.setSize(val+1);
         }
         typeNames.setElementAt(id, val);
   }
   public static int typeValue(String idValue) {
-        Integer Val=(Integer)(Types.get(idValue));
+        Integer Val=Types.get(idValue);
         if (Val == null) return -1;
         return Val.intValue();
   }
   public static String typeName(int type) {
         if (type>=typeNames.size()) return null;
-        return (String)typeNames.elementAt(type);
+        return typeNames.elementAt(type);
   }
 
    /**
      * Define MapTypes table.
      * These constants used in stackmap tables only.
      */
-  private static Vector mapTypeNames = new Vector(10);
-  private static Hashtable MapTypes = new Hashtable(10);
+  private static Vector<String> mapTypeNames = new Vector<String>(10);
+  private static Hashtable<String,Integer> MapTypes = new Hashtable<String,Integer>(10);
   static {
         defineMapType("bogus",             ITEM_Bogus);
         defineMapType("int",               ITEM_Integer);
@@ -358,20 +356,20 @@
         defineMapType("uninitialized",     ITEM_NewObject);
   }
   private static void defineMapType(String id, int val) {
-        MapTypes.put(id, new Integer(val));
+        MapTypes.put(id, val);
         if (val>=mapTypeNames.size()) {
                 mapTypeNames.setSize(val+1);
         }
         mapTypeNames.setElementAt(id, val);
   }
   public static int mapTypeValue(String idValue) {
-        Integer Val=(Integer)(MapTypes.get(idValue));
+        Integer Val=MapTypes.get(idValue);
         if (Val == null) return -1;
         return Val.intValue();
   }
   public static String mapTypeName(int type) {
         if (type>=mapTypeNames.size()) return null;
-        return (String)mapTypeNames.elementAt(type);
+        return mapTypeNames.elementAt(type);
   }
 
 }
--- a/langtools/src/share/classes/sun/tools/javap/TypeSignature.java	Wed Jul 05 16:37:21 2017 +0200
+++ b/langtools/src/share/classes/sun/tools/javap/TypeSignature.java	Wed Jul 05 16:37:51 2017 +0200
@@ -79,7 +79,7 @@
      * Returns java type signature of a parameter.
      */
     public String getParametersHelper(String parameterdes){
-        Vector parameters = new Vector();
+        Vector<String> parameters = new Vector<String>();
         int startindex = -1;
         int endindex = -1;
         String param = "";
@@ -187,7 +187,7 @@
         int i;
 
         for(i = 0; i < parameters.size(); i++){
-            parametersignature += (String)parameters.elementAt(i);
+            parametersignature += parameters.elementAt(i);
             if(i != parameters.size()-1){
                 parametersignature += ", ";
             }
--- a/langtools/test/tools/javac/6589361/T6589361.java	Wed Jul 05 16:37:21 2017 +0200
+++ b/langtools/test/tools/javac/6589361/T6589361.java	Wed Jul 05 16:37:51 2017 +0200
@@ -24,7 +24,7 @@
             Iterable<JavaFileObject> files = fm.list(StandardLocation.PLATFORM_CLASS_PATH, "java.lang", set, false);
             for (JavaFileObject file : files) {
 
-                if (file.toString().startsWith("java" + File.separator + "lang" + File.separator + "Object.class")) {
+                if (file.toString().contains("java" + File.separator + "lang" + File.separator + "Object.class")) {
                     String str = fm.inferBinaryName(StandardLocation.CLASS_PATH, file);
                     if (!str.equals("java.lang.Object")) {
                         throw new AssertionError("Error in JavacFileManager.inferBinaryName method!");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T6705935.java	Wed Jul 05 16:37:51 2017 +0200
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6705935
+ * @summary javac reports path name of entry in ZipFileIndex incorectly
+ */
+
+import java.io.*;
+import java.util.*;
+import javax.tools.*;
+import com.sun.tools.javac.util.*;
+
+public class T6705935 {
+    public static void main(String... args) throws Exception {
+        new T6705935().run();
+    }
+
+    public void run() throws Exception {
+        File java_home = new File(System.getProperty("java.home"));
+        if (java_home.getName().equals("jre"))
+            java_home = java_home.getParentFile();
+
+        JavaCompiler c = ToolProvider.getSystemJavaCompiler();
+        JavaFileManager fm = c.getStandardFileManager(null, null, null);
+        for (JavaFileObject fo: fm.list(StandardLocation.PLATFORM_CLASS_PATH,
+                                        "java.lang",
+                                        Collections.singleton(JavaFileObject.Kind.CLASS),
+                                        false)) {
+            String p = ((BaseFileObject)fo).getPath();
+            int bra = p.indexOf("(");
+            int ket = p.indexOf(")");
+            //System.err.println(bra + "," + ket + "," + p.length());
+            if (bra == -1 || ket != p.length() -1)
+                throw new Exception("unexpected path: " + p + "[" + bra + "," + ket + "," + p.length());
+            String part1 = p.substring(0, bra);
+            String part2 = p.substring(bra + 1, ket);
+            //System.err.println("[" + part1 + "|" + part2 + "]" + " " + java_home);
+            if (part1.equals(part2) || !part1.startsWith(java_home.getPath()))
+                throw new Exception("bad path: " + p);
+
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6677785/T6677785.java	Wed Jul 05 16:37:51 2017 +0200
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug     6677785
+ * @summary REGRESSION: StackOverFlowError with Cyclic Class level Type Parameters when used in constructors
+ * @author Maurizio Cimadamore
+ * @compile/fail/ref=T6677785.out -XDstdout -XDrawDiagnostics T6677785.java
+ */
+public class T6677785<E extends T, T extends E> {
+     T6677785() {}
+     T6677785(E e) {}
+     T6677785(E e, T t) {}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6677785/T6677785.out	Wed Jul 05 16:37:51 2017 +0200
@@ -0,0 +1,2 @@
+T6677785.java:31:23: compiler.err.cyclic.inheritance: E
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/T6507024.java	Wed Jul 05 16:37:51 2017 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug     6507024
+ * @summary unchecked conversion between arrays fails after capture conversion
+ * @author Maurizio Cimadamore
+ *
+ * @compile T6507024.java
+ */
+
+public class T6507024<T> {
+    <Z> void m(T6507024<Z>[] results) {
+        T6507024<Z>[] r = results.getClass().cast(null);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/staticImport/6665223/T6665223.java	Wed Jul 05 16:37:51 2017 +0200
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6665223
+ * @summary Static import of inherited protected method causes compiler exception
+ * @author Maurizio Cimadamore
+ *
+ * @compile pkg/A.java
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/staticImport/6665223/pkg/A.java	Wed Jul 05 16:37:51 2017 +0200
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package pkg;
+
+import static pkg.B.b;
+
+class A {
+    public static void main(String[] args) {
+        b();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/staticImport/6665223/pkg/B.java	Wed Jul 05 16:37:51 2017 +0200
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package pkg;
+
+class B extends B2 {}
+
+abstract class B2 {
+    protected static void b() {}
+}
--- a/make/Defs-internal.gmk	Wed Jul 05 16:37:21 2017 +0200
+++ b/make/Defs-internal.gmk	Wed Jul 05 16:37:51 2017 +0200
@@ -225,7 +225,10 @@
     JDK_MKTG_VERSION=$(JDK_MKTG_VERSION) \
     JDK_MAJOR_VERSION=$(JDK_MAJOR_VERSION) \
     JDK_MINOR_VERSION=$(JDK_MINOR_VERSION) \
-    JDK_MICRO_VERSION=$(JDK_MICRO_VERSION)
+    JDK_MICRO_VERSION=$(JDK_MICRO_VERSION) \
+    PREVIOUS_MAJOR_VERSION=$(PREVIOUS_MAJOR_VERSION) \
+    PREVIOUS_MINOR_VERSION=$(PREVIOUS_MINOR_VERSION) \
+    PREVIOUS_MICRO_VERSION=$(PREVIOUS_MICRO_VERSION)
 
 ifdef ARCH_DATA_MODEL
   COMMON_BUILD_ARGUMENTS += ARCH_DATA_MODEL=$(ARCH_DATA_MODEL)