changeset 4129:658d1b92c389

Merge
author duke
date Wed, 05 Jul 2017 17:02:50 +0200
parents 2180f3e03264 f1e79535f5ed
children 08d5964ec7d4
files jdk/make/tools/fontchecker/Makefile jdk/make/tools/src/build/tools/fontchecker/FontCheckDummy.java jdk/make/tools/src/build/tools/fontchecker/FontChecker.java jdk/make/tools/src/build/tools/fontchecker/FontCheckerConstants.java jdk/make/tools/src/build/tools/fontchecker/FontFileFilter.java jdk/make/tools/src/build/tools/fontchecker/README.txt jdk/src/share/classes/java/nio/ByteBufferAs-X-Buffer.java jdk/src/share/classes/java/nio/Direct-X-Buffer-bin.java jdk/src/share/classes/java/nio/Direct-X-Buffer.java jdk/src/share/classes/java/nio/Heap-X-Buffer.java jdk/src/share/classes/java/nio/X-Buffer-bin.java jdk/src/share/classes/java/nio/X-Buffer.java jdk/src/share/classes/java/nio/charset/Charset-X-Coder.java jdk/src/share/classes/sun/misc/Version-template.java jdk/src/share/classes/sun/tools/jconsole/Version-template.java jdk/test/java/nio/Buffer/Basic-X.java jdk/test/java/nio/Buffer/CopyDirect-X-Memory.java
diffstat 150 files changed, 14631 insertions(+), 6742 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags-top-repo	Sun Nov 08 14:49:40 2009 -0800
+++ b/.hgtags-top-repo	Wed Jul 05 17:02:50 2017 +0200
@@ -49,3 +49,4 @@
 0d7e03b426df27c21dcc44ffb9178eacd1b04f10 jdk7-b72
 3ac6dcf7823205546fbbc3d4ea59f37358d0b0d4 jdk7-b73
 2c88089b6e1c053597418099a14232182c387edc jdk7-b74
+d1516b9f23954b29b8e76e6f4efc467c08c78133 jdk7-b75
--- a/README-builds.html	Sun Nov 08 14:49:40 2009 -0800
+++ b/README-builds.html	Wed Jul 05 17:02:50 2017 +0200
@@ -545,7 +545,11 @@
                 </li>
                 <li>
                     <strong>Windows:</strong>
-                    Make sure you start your build inside a bash/sh/ksh shell.
+                    Make sure you start your build inside a bash/sh/ksh shell
+                    and are using a <tt>make.exe</tt> utility built for that
+                    environment (a cygwin <tt>make.exe</tt> is not the same
+                    as a <tt>make.exe</tt> built for something like
+                    <a href="http://www.mkssoftware.com/">MKS</a>). 
                     <br>
                     <b>WARNING:</b> Watch out for make version 3.81, it may
                     not work due to a lack of support for MS-DOS drive letter paths
@@ -826,7 +830,8 @@
                 All OpenJDK builds require access to the previously released 
                 JDK 6, this is often called a bootstrap JDK.
                 The JDK 6 binaries can be downloaded from Sun's 
-                <a href="http://java.sun.com/javase/1.6.0/download.html" target="_blank">JDK 6 download site</a>.
+                <a href="http://java.sun.com/javase/downloads/index.jsp"
+		target="_blank">JDK 6 download site</a>.
                 For build performance reasons
                 is very important that this bootstrap JDK be made available on the
                 local disk of the machine doing the build.
--- a/hotspot/.hgtags	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/.hgtags	Wed Jul 05 17:02:50 2017 +0200
@@ -49,3 +49,4 @@
 a94714c550658fd6741793ef036cb9625dc2ab1a jdk7-b72
 faf94d94786b621f8e13cbcc941ca69c6d967c3f jdk7-b73
 f4b900403d6e4b0af51447bd13bbe23fe3a1dac7 jdk7-b74
+d8dd291a362acb656026a9c0a9da48501505a1e7 jdk7-b75
--- a/hotspot/agent/make/saenv.sh	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/agent/make/saenv.sh	Wed Jul 05 17:02:50 2017 +0200
@@ -48,8 +48,16 @@
      CPU=i386
    fi
 else
-   LD_AUDIT_32=$STARTDIR/../src/os/solaris/proc/`uname -p`/libsaproc_audit.so
-   export LD_AUDIT_32
+   # configure audit helper library if SA_ALTROOT is set
+   if [ -n "$SA_ALTROOT" ]; then
+     LD_AUDIT_32=$STARTDIR/../src/os/solaris/proc/`uname -p`/libsaproc_audit.so
+     export LD_AUDIT_32
+     if [ ! -f $LD_AUDIT_32 ]; then
+       echo "SA_ALTROOT is set and can't find libsaproc_audit.so."
+       echo "Make sure to build it with 'make natives'."
+       exit 1
+     fi
+   fi
    SA_LIBPATH=$STARTDIR/../src/os/solaris/proc/`uname -p`:$STARTDIR/solaris/`uname -p`
    OPTIONS="-Dsa.library.path=$SA_LIBPATH -Dsun.jvm.hotspot.debugger.useProcDebugger"
    CPU=sparc
--- a/hotspot/agent/make/saenv64.sh	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/agent/make/saenv64.sh	Wed Jul 05 17:02:50 2017 +0200
@@ -43,8 +43,16 @@
   fi
 fi
 
-LD_AUDIT_64=$STARTDIR/../src/os/solaris/proc/$CPU/libsaproc_audit.so
-export LD_AUDIT_64
+# configure audit helper library if SA_ALTROOT is set
+if [ -n "$SA_ALTROOT" ]; then
+  LD_AUDIT_64=$STARTDIR/../src/os/solaris/proc/$CPU/libsaproc_audit.so
+  export LD_AUDIT_64
+  if [ ! -f $LD_AUDIT_64 ]; then
+      echo "SA_ALTROOT is set and can't find libsaproc_audit.so."
+      echo "Make sure to build it with 'make natives'."
+      exit 1
+  fi
+fi
 SA_LIBPATH=$STARTDIR/../src/os/solaris/proc/$CPU:$STARTDIR/solaris/$CPU
 
 OPTIONS="-Dsa.library.path=$SA_LIBPATH -Dsun.jvm.hotspot.debugger.useProcDebugger"
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java	Wed Jul 05 17:02:50 2017 +0200
@@ -926,6 +926,28 @@
                 }
             }
         },
+        new Command("dumpcodecache", "dumpcodecache", false) {
+            public void doit(Tokens t) {
+                if (t.countTokens() != 0) {
+                    usage();
+                } else {
+                    final PrintStream fout = out;
+                    final HTMLGenerator gen = new HTMLGenerator(false);
+                    CodeCacheVisitor v = new CodeCacheVisitor() {
+                            public void prologue(Address start, Address end) {
+                            }
+                            public void visit(CodeBlob blob) {
+                                fout.println(gen.genHTML(blob.instructionsBegin()));
+                            }
+                            public void epilogue() {
+                            }
+
+
+                        };
+                    VM.getVM().getCodeCache().iterate(v);
+                }
+            }
+        },
         new Command("where", "where { -a | id }", false) {
             public void doit(Tokens t) {
                 if (t.countTokens() != 1) {
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/code/CodeCache.java	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/code/CodeCache.java	Wed Jul 05 17:02:50 2017 +0200
@@ -173,7 +173,8 @@
     CodeBlob lastBlob = null;
     while (ptr != null && ptr.lessThan(end)) {
       try {
-        CodeBlob blob = findBlobUnsafe(ptr);
+        // Use findStart to get a pointer inside blob other findBlob asserts
+        CodeBlob blob = findBlobUnsafe(heap.findStart(ptr));
         if (blob != null) {
           visitor.visit(blob);
           if (blob == lastBlob) {
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/code/NMethod.java	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/code/NMethod.java	Wed Jul 05 17:02:50 2017 +0200
@@ -42,7 +42,7 @@
   /** To support simple linked-list chaining of nmethods */
   private static AddressField  osrLinkField;
   private static AddressField  scavengeRootLinkField;
-  private static CIntegerField scavengeRootStateField;
+  private static JByteField    scavengeRootStateField;
 
   /** Offsets for different nmethod parts */
   private static CIntegerField exceptionOffsetField;
@@ -92,7 +92,7 @@
     entryBCIField               = type.getCIntegerField("_entry_bci");
     osrLinkField                = type.getAddressField("_osr_link");
     scavengeRootLinkField       = type.getAddressField("_scavenge_root_link");
-    scavengeRootStateField      = type.getCIntegerField("_scavenge_root_state");
+    scavengeRootStateField      = type.getJByteField("_scavenge_root_state");
 
     exceptionOffsetField        = type.getCIntegerField("_exception_offset");
     deoptOffsetField            = type.getCIntegerField("_deoptimize_offset");
@@ -274,7 +274,7 @@
     if (Assert.ASSERTS_ENABLED) {
       Assert.that(pd != null, "scope must be present");
     }
-    return new ScopeDesc(this, pd.getScopeDecodeOffset(), pd.getReexecute());
+    return new ScopeDesc(this, pd.getScopeDecodeOffset(), pd.getObjDecodeOffset(), pd.getReexecute());
   }
 
   /** This is only for use by the debugging system, and is only
@@ -306,11 +306,11 @@
   public ScopeDesc getScopeDescNearDbg(Address pc) {
     PCDesc pd = getPCDescNearDbg(pc);
     if (pd == null) return null;
-    return new ScopeDesc(this, pd.getScopeDecodeOffset(), pd.getReexecute());
+    return new ScopeDesc(this, pd.getScopeDecodeOffset(), pd.getObjDecodeOffset(), pd.getReexecute());
   }
 
-  public Map/*<Address, PcDesc>*/ getSafepoints() {
-    Map safepoints = new HashMap(); // Map<Address, PcDesc>
+  public Map/*<Address, PCDesc>*/ getSafepoints() {
+    Map safepoints = new HashMap(); // Map<Address, PCDesc>
     sun.jvm.hotspot.debugger.Address p = null;
     for (p = scopesPCsBegin(); p.lessThan(scopesPCsEnd());
          p = p.addOffsetTo(pcDescSize)) {
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/code/PCDesc.java	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/code/PCDesc.java	Wed Jul 05 17:02:50 2017 +0200
@@ -36,6 +36,7 @@
 public class PCDesc extends VMObject {
   private static CIntegerField pcOffsetField;
   private static CIntegerField scopeDecodeOffsetField;
+  private static CIntegerField objDecodeOffsetField;
   private static CIntegerField pcFlagsField;
 
   static {
@@ -51,6 +52,7 @@
 
     pcOffsetField          = type.getCIntegerField("_pc_offset");
     scopeDecodeOffsetField = type.getCIntegerField("_scope_decode_offset");
+    objDecodeOffsetField   = type.getCIntegerField("_obj_decode_offset");
     pcFlagsField           = type.getCIntegerField("_flags");
   }
 
@@ -68,6 +70,10 @@
     return ((int) scopeDecodeOffsetField.getValue(addr));
   }
 
+  public int getObjDecodeOffset() {
+    return ((int) objDecodeOffsetField.getValue(addr));
+  }
+
   public Address getRealPC(NMethod code) {
     return code.instructionsBegin().addOffsetTo(getPCOffset());
   }
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/code/ScopeDesc.java	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/code/ScopeDesc.java	Wed Jul 05 17:02:50 2017 +0200
@@ -51,11 +51,10 @@
   /** Scalar replaced bjects pool */
   private List    objects; // ArrayList<ScopeValue>
 
-
-  public ScopeDesc(NMethod code, int decodeOffset, boolean reexecute) {
+  private ScopeDesc(NMethod code, int decodeOffset, List objects, boolean reexecute) {
     this.code = code;
     this.decodeOffset = decodeOffset;
-    this.objects      = decodeObjectValues(DebugInformationRecorder.SERIALIZED_NULL);
+    this.objects      = objects;
     this.reexecute    = reexecute;
 
     // Decode header
@@ -108,7 +107,7 @@
     return decodeMonitorValues(monitorsDecodeOffset);
   }
 
-  /** Returns a List&lt;MonitorValue&gt; */
+  /** Returns a List&lt;ObjectValue&gt; */
   public List getObjects() {
     return objects;
   }
@@ -119,7 +118,7 @@
       return null;
     }
 
-    return new ScopeDesc(code, senderDecodeOffset, false);
+    return new ScopeDesc(code, senderDecodeOffset, objects, false);
   }
 
   /** Returns where the scope was decoded */
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java	Wed Jul 05 17:02:50 2017 +0200
@@ -807,6 +807,9 @@
             Interpreter interp = VM.getVM().getInterpreter();
             if (interp.contains(pc)) {
                InterpreterCodelet codelet = interp.getCodeletContaining(pc);
+               if (codelet == null) {
+                  return "Unknown location in the Interpreter: " + pc;
+               }
                return genHTML(codelet);
             }
             return genHTML(blob);
@@ -969,16 +972,24 @@
    }
 
    protected String genSafepointInfo(NMethod nm, PCDesc pcDesc) {
-      ScopeDesc sd = nm.getScopeDescAt(pcDesc.getRealPC(nm));
-      Formatter buf = new Formatter(genHTML);
-      Formatter tabs = new Formatter(genHTML);
+       ScopeDesc sd = nm.getScopeDescAt(pcDesc.getRealPC(nm));
+       Formatter buf = new Formatter(genHTML);
+       Formatter tabs = new Formatter(genHTML);
+       tabs.append(tab + tab + tab); // Initial indent for debug info
 
-      buf.beginTag("pre");
-      genScope(buf, tabs, sd);
-      buf.endTag("pre");
-      buf.append(genOopMapInfo(nm, pcDesc));
+       buf.beginTag("pre");
+       genScope(buf, tabs, sd);
 
-      return buf.toString();
+       // Reset indent for scalar replaced objects
+       tabs = new Formatter(genHTML);
+       tabs.append(tab + tab + tab); // Initial indent for debug info
+
+       genScObjInfo(buf, tabs, sd);
+       buf.endTag("pre");
+
+       buf.append(genOopMapInfo(nm, pcDesc));
+
+       return buf.toString();
    }
 
     protected void genScope(Formatter buf, Formatter tabs, ScopeDesc sd) {
@@ -1022,8 +1033,95 @@
             buf.append(genHTMLForMonitors(sd, monitors));
         }
 
+        buf.br();
         tabs.append(tab);
-        buf.br();
+    }
+
+    protected void genScObjInfo(Formatter buf, Formatter tabs, ScopeDesc sd) {
+        if (sd == null) {
+            return;
+        }
+
+        List objects = sd.getObjects();
+        if (objects == null) {
+            return;
+        }
+        int length = objects.size();
+        for (int i = 0; i < length; i++) {
+            buf.append(tabs);
+            ObjectValue ov = (ObjectValue)objects.get(i);
+            buf.append("ScObj" + i);
+            ScopeValue sv = ov.getKlass();
+            if (Assert.ASSERTS_ENABLED) {
+                Assert.that(sv.isConstantOop(), "scalar replaced object klass must be constant oop");
+            }
+            ConstantOopReadValue klv = (ConstantOopReadValue)sv;
+            OopHandle klHandle = klv.getValue();
+            if (Assert.ASSERTS_ENABLED) {
+                Assert.that(klHandle != null, "scalar replaced object klass must be not NULL");
+            }
+            Oop obj = VM.getVM().getObjectHeap().newOop(klHandle);
+            if (obj instanceof InstanceKlass) {
+                InstanceKlass kls = (InstanceKlass) obj;
+                buf.append(" " + kls.getName().asString() + "={");
+                int flen = ov.fieldsSize();
+
+                TypeArray klfields = kls.getFields();
+                int klen = (int) klfields.getLength();
+
+                ConstantPool cp = kls.getConstants();
+                int findex = 0;
+                for (int index = 0; index < klen; index += kls.NEXT_OFFSET) {
+                    int accsFlags = klfields.getShortAt(index + kls.ACCESS_FLAGS_OFFSET);
+                    int nameIndex = klfields.getShortAt(index + kls.NAME_INDEX_OFFSET);
+                    AccessFlags access = new AccessFlags(accsFlags);
+                    if (!access.isStatic()) {
+                        ScopeValue svf = ov.getFieldAt(findex++);
+                        String    fstr = scopeValueAsString(sd, svf);
+                        Symbol f_name  = cp.getSymbolAt(nameIndex);
+                        buf.append(" [" + f_name.asString() + " :"+ index + "]=(#" + fstr + ")");
+                    }
+                }
+                buf.append(" }");
+            } else {
+                buf.append(" ");
+                int flen = ov.fieldsSize();
+                if (obj instanceof TypeArrayKlass) {
+                    TypeArrayKlass kls = (TypeArrayKlass) obj;
+                    buf.append(kls.getElementTypeName() + "[" + flen + "]");
+                } else if (obj instanceof ObjArrayKlass) {
+                    ObjArrayKlass kls = (ObjArrayKlass) obj;
+                    Klass elobj = kls.getBottomKlass();
+                    if (elobj instanceof InstanceKlass) {
+                        buf.append(elobj.getName().asString());
+                    } else if (elobj instanceof TypeArrayKlass) {
+                        TypeArrayKlass elkls = (TypeArrayKlass) elobj;
+                        buf.append(elkls.getElementTypeName());
+                    } else {
+                        if (Assert.ASSERTS_ENABLED) {
+                            Assert.that(false, "unknown scalar replaced object klass!");
+                        }
+                    }
+                    buf.append("[" + flen + "]");
+                    int ndim = (int) kls.getDimension();
+                    while (--ndim > 0) {
+                        buf.append("[]");
+                    }
+                } else {
+                    if (Assert.ASSERTS_ENABLED) {
+                        Assert.that(false, "unknown scalar replaced object klass!");
+                    }
+                }
+                buf.append("={");
+                for (int findex = 0; findex < flen; findex++) {
+                    ScopeValue svf = ov.getFieldAt(findex);
+                    String fstr = scopeValueAsString(sd, svf);
+                    buf.append(" [" + findex + "]=(#" + fstr + ")");
+                }
+                buf.append(" }");
+            }
+            buf.br();
+        }
     }
 
    protected String genHTMLForOopMap(OopMap map) {
@@ -1037,8 +1135,6 @@
             tmpBuf.beginTag("tr");
             tmpBuf.beginTag("td");
             tmpBuf.append(type);
-            tmpBuf.endTag("td");
-            tmpBuf.endTag("tr");
             for (; ! oms.isDone(); oms.next()) {
                OopMapValue omv = oms.getCurrent();
                if (omv == null) {
@@ -1048,7 +1144,7 @@
                VMReg vmReg = omv.getReg();
                int reg = vmReg.getValue();
                if (reg < stack0) {
-                  tmpBuf.append(VMRegImpl.getRegisterName(vmReg.getValue()));
+                  tmpBuf.append(VMRegImpl.getRegisterName(reg));
                } else {
                   tmpBuf.append('[');
                   tmpBuf.append(Integer.toString((reg - stack0) * 4));
@@ -1058,7 +1154,13 @@
                   tmpBuf.append(" = ");
                   VMReg vmContentReg = omv.getContentReg();
                   int contentReg = vmContentReg.getValue();
-                  tmpBuf.append(VMRegImpl.getRegisterName(vmContentReg.getValue()));
+                  if (contentReg < stack0) {
+                     tmpBuf.append(VMRegImpl.getRegisterName(contentReg));
+                  } else {
+                     tmpBuf.append('[');
+                     tmpBuf.append(Integer.toString((contentReg - stack0) * 4));
+                     tmpBuf.append(']');
+                  }
                }
                tmpBuf.append(spaces);
             }
@@ -1072,19 +1174,19 @@
 
       OopMapValueIterator omvIterator = new OopMapValueIterator();
       OopMapStream oms = new OopMapStream(map, OopMapValue.OopTypes.OOP_VALUE);
-      buf.append(omvIterator.iterate(oms, "Oop:", false));
+      buf.append(omvIterator.iterate(oms, "Oops:", false));
+
+      oms = new OopMapStream(map, OopMapValue.OopTypes.NARROWOOP_VALUE);
+      buf.append(omvIterator.iterate(oms, "narrowOops:", false));
 
       oms = new OopMapStream(map, OopMapValue.OopTypes.VALUE_VALUE);
-      buf.append(omvIterator.iterate(oms, "Value:", false));
-
-      oms = new OopMapStream(map, OopMapValue.OopTypes.NARROWOOP_VALUE);
-      buf.append(omvIterator.iterate(oms, "Oop:", false));
+      buf.append(omvIterator.iterate(oms, "Values:", false));
 
       oms = new OopMapStream(map, OopMapValue.OopTypes.CALLEE_SAVED_VALUE);
       buf.append(omvIterator.iterate(oms, "Callee saved:",  true));
 
       oms = new OopMapStream(map, OopMapValue.OopTypes.DERIVED_OOP_VALUE);
-      buf.append(omvIterator.iterate(oms, "Derived oop:", true));
+      buf.append(omvIterator.iterate(oms, "Derived oops:", true));
 
       buf.endTag("table");
       return buf.toString();
@@ -1093,6 +1195,8 @@
 
    protected String genOopMapInfo(NMethod nmethod, PCDesc pcDesc) {
       OopMapSet mapSet = nmethod.getOopMaps();
+      if (mapSet == null || (mapSet.getSize() <= 0))
+        return "";
       int pcOffset = pcDesc.getPCOffset();
       OopMap map = mapSet.findMapAtOffset(pcOffset, VM.getVM().isDebugging());
       if (map == null) {
@@ -1106,6 +1210,7 @@
      Formatter buf = new Formatter(genHTML);
      buf.beginTag("pre");
      buf.append("OopMap: ");
+     buf.br();
      buf.append(genHTMLForOopMap(map));
      buf.endTag("pre");
 
@@ -1154,7 +1259,7 @@
       return buf.toString();
    }
 
-   private String scopeValueAsString(ScopeValue sv) {
+   private String scopeValueAsString(ScopeDesc sd, ScopeValue sv) {
       Formatter buf = new Formatter(genHTML);
       if (sv.isConstantInt()) {
          buf.append("int ");
@@ -1187,6 +1292,11 @@
          } else {
             buf.append("null");
          }
+      } else if (sv.isObject()) {
+         ObjectValue ov = (ObjectValue)sv;
+         buf.append("#ScObj" + sd.getObjects().indexOf(ov));
+      } else {
+         buf.append("unknown scope value " + sv);
       }
       return buf.toString();
    }
@@ -1219,7 +1329,7 @@
          }
 
          buf.append(", ");
-         buf.append(scopeValueAsString(sv));
+         buf.append(scopeValueAsString(sd, sv));
          buf.append(") ");
       }
 
@@ -1246,7 +1356,7 @@
          buf.append("(owner = ");
          ScopeValue owner = mv.owner();
          if (owner != null) {
-            buf.append(scopeValueAsString(owner));
+            buf.append(scopeValueAsString(sd, owner));
          } else {
             buf.append("null");
          }
@@ -1324,11 +1434,11 @@
                   buf.append(instr.asString(currentPc, symFinder));
                }
 
+               buf.br();
                if (isSafepoint && !prevWasCall) {
-                  buf.append(genSafepointInfo(nmethod, pcDesc));
+                 buf.append(genSafepointInfo(nmethod, pcDesc));
                }
 
-               buf.br();
                prevWasCall = instr.isCall();
             }
 
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js	Wed Jul 05 17:02:50 2017 +0200
@@ -1047,7 +1047,7 @@
    } else {
       // some type names have ':'. replace to make it as a 
       // JavaScript identifier
-      tmp.name = tmp.name.replace(':', '_');
+      tmp.name = tmp.name.replace(':', '_').replace('<', '_').replace('>', '_').replace('*', '_').replace(' ', '_');
       eval("function read" + tmp.name + "(addr) {" +
            "   return readVMType('" + tmp.name + "', addr);}"); 
       eval("function print" + tmp.name + "(addr) {" + 
--- a/hotspot/make/hotspot_version	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/make/hotspot_version	Wed Jul 05 17:02:50 2017 +0200
@@ -35,7 +35,7 @@
 
 HS_MAJOR_VER=17
 HS_MINOR_VER=0
-HS_BUILD_NUMBER=04
+HS_BUILD_NUMBER=05
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=7
--- a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Wed Jul 05 17:02:50 2017 +0200
@@ -3213,9 +3213,8 @@
   Register        Oreturn0           = O0;
   Register        Oreturn1           = O1;
   Register        O2UnrollBlock      = O2;
-  Register        O3tmp              = O3;
-  Register        I5exception_tmp    = I5;
-  Register        G4exception_tmp    = G4_scratch;
+  Register        L0deopt_mode       = L0;
+  Register        G4deopt_mode       = G4_scratch;
   int             frame_size_words;
   Address         saved_Freturn0_addr(FP, -sizeof(double) + STACK_BIAS);
 #if !defined(_LP64) && defined(COMPILER2)
@@ -3265,7 +3264,7 @@
 
   map = RegisterSaver::save_live_registers(masm, 0, &frame_size_words);
   __ ba(false, cont);
-  __ delayed()->mov(Deoptimization::Unpack_deopt, I5exception_tmp);
+  __ delayed()->mov(Deoptimization::Unpack_deopt, L0deopt_mode);
 
   int exception_offset = __ offset() - start;
 
@@ -3316,7 +3315,7 @@
 #endif
 
   __ ba(false, cont);
-  __ delayed()->mov(Deoptimization::Unpack_exception, I5exception_tmp);;
+  __ delayed()->mov(Deoptimization::Unpack_exception, L0deopt_mode);;
 
   //
   // Reexecute entry, similar to c2 uncommon trap
@@ -3326,7 +3325,7 @@
   // No need to update oop_map  as each call to save_live_registers will produce identical oopmap
   (void) RegisterSaver::save_live_registers(masm, 0, &frame_size_words);
 
-  __ mov(Deoptimization::Unpack_reexecute, I5exception_tmp);
+  __ mov(Deoptimization::Unpack_reexecute, L0deopt_mode);
 
   __ bind(cont);
 
@@ -3349,14 +3348,14 @@
   // NOTE: we know that only O0/O1 will be reloaded by restore_result_registers
   // so this move will survive
 
-  __ mov(I5exception_tmp, G4exception_tmp);
+  __ mov(L0deopt_mode, G4deopt_mode);
 
   __ mov(O0, O2UnrollBlock->after_save());
 
   RegisterSaver::restore_result_registers(masm);
 
   Label noException;
-  __ cmp(G4exception_tmp, Deoptimization::Unpack_exception);   // Was exception pending?
+  __ cmp(G4deopt_mode, Deoptimization::Unpack_exception);   // Was exception pending?
   __ br(Assembler::notEqual, false, Assembler::pt, noException);
   __ delayed()->nop();
 
@@ -3390,10 +3389,10 @@
   }
 #endif
   __ set_last_Java_frame(SP, noreg);
-  __ call_VM_leaf(L7_thread_cache, CAST_FROM_FN_PTR(address, Deoptimization::unpack_frames), G2_thread, G4exception_tmp);
+  __ call_VM_leaf(L7_thread_cache, CAST_FROM_FN_PTR(address, Deoptimization::unpack_frames), G2_thread, G4deopt_mode);
 #else
   // LP64 uses g4 in set_last_Java_frame
-  __ mov(G4exception_tmp, O1);
+  __ mov(G4deopt_mode, O1);
   __ set_last_Java_frame(SP, G0);
   __ call_VM_leaf(L7_thread_cache, CAST_FROM_FN_PTR(address, Deoptimization::unpack_frames), G2_thread, O1);
 #endif
@@ -3446,7 +3445,6 @@
 #endif
   MacroAssembler* masm               = new MacroAssembler(&buffer);
   Register        O2UnrollBlock      = O2;
-  Register        O3tmp              = O3;
   Register        O2klass_index      = O2;
 
   //
--- a/hotspot/src/cpu/sparc/vm/sparc.ad	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/src/cpu/sparc/vm/sparc.ad	Wed Jul 05 17:02:50 2017 +0200
@@ -9419,8 +9419,9 @@
   // x |= (x >> 8);
   // x |= (x >> 16);
   // return (WORDBITS - popc(x));
-  format %{ "SRL     $src,1,$dst\t! count leading zeros (int)\n\t"
-            "OR      $src,$tmp,$dst\n\t"
+  format %{ "SRL     $src,1,$tmp\t! count leading zeros (int)\n\t"
+            "SRL     $src,0,$dst\t! 32-bit zero extend\n\t"
+            "OR      $dst,$tmp,$dst\n\t"
             "SRL     $dst,2,$tmp\n\t"
             "OR      $dst,$tmp,$dst\n\t"
             "SRL     $dst,4,$tmp\n\t"
@@ -9437,7 +9438,8 @@
     Register Rsrc = $src$$Register;
     Register Rtmp = $tmp$$Register;
     __ srl(Rsrc, 1, Rtmp);
-    __ or3(Rsrc, Rtmp, Rdst);
+    __ srl(Rsrc, 0, Rdst);
+    __ or3(Rdst, Rtmp, Rdst);
     __ srl(Rdst, 2, Rtmp);
     __ or3(Rdst, Rtmp, Rdst);
     __ srl(Rdst, 4, Rtmp);
@@ -9465,7 +9467,7 @@
   // x |= (x >> 16);
   // x |= (x >> 32);
   // return (WORDBITS - popc(x));
-  format %{ "SRLX    $src,1,$dst\t! count leading zeros (long)\n\t"
+  format %{ "SRLX    $src,1,$tmp\t! count leading zeros (long)\n\t"
             "OR      $src,$tmp,$dst\n\t"
             "SRLX    $dst,2,$tmp\n\t"
             "OR      $dst,$tmp,$dst\n\t"
--- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp	Wed Jul 05 17:02:50 2017 +0200
@@ -8214,6 +8214,15 @@
   }
 }
 
+// Used for storing NULLs.
+void MacroAssembler::store_heap_oop_null(Address dst) {
+  if (UseCompressedOops) {
+    movl(dst, (int32_t)NULL_WORD);
+  } else {
+    movslq(dst, (int32_t)NULL_WORD);
+  }
+}
+
 // Algorithm must match oop.inline.hpp encode_heap_oop.
 void MacroAssembler::encode_heap_oop(Register r) {
   assert (UseCompressedOops, "should be compressed");
--- a/hotspot/src/cpu/x86/vm/assembler_x86.hpp	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.hpp	Wed Jul 05 17:02:50 2017 +0200
@@ -1682,6 +1682,17 @@
 
   void load_heap_oop(Register dst, Address src);
   void store_heap_oop(Address dst, Register src);
+
+  // This dummy is to prevent a call to store_heap_oop from
+  // converting a zero (like NULL) into a Register by giving
+  // the compiler two choices it can't resolve
+
+  void store_heap_oop(Address dst, void* dummy);
+
+  // Used for storing NULL. All other oop constants should be
+  // stored using routines that take a jobject.
+  void store_heap_oop_null(Address dst);
+
   void encode_heap_oop(Register r);
   void decode_heap_oop(Register r);
   void encode_heap_oop_not_null(Register r);
--- a/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp	Wed Jul 05 17:02:50 2017 +0200
@@ -271,9 +271,15 @@
 void trace_method_handle_stub(const char* adaptername,
                               oopDesc* mh,
                               intptr_t* entry_sp,
-                              intptr_t* saved_sp) {
+                              intptr_t* saved_sp,
+                              intptr_t* saved_bp) {
   // called as a leaf from native code: do not block the JVM!
-  printf("MH %s "PTR_FORMAT" "PTR_FORMAT" "INTX_FORMAT"\n", adaptername, (void*)mh, entry_sp, entry_sp - saved_sp);
+  intptr_t* last_sp = (intptr_t*) saved_bp[frame::interpreter_frame_last_sp_offset];
+  intptr_t* base_sp = (intptr_t*) saved_bp[frame::interpreter_frame_monitor_block_top_offset];
+  printf("MH %s mh="INTPTR_FORMAT" sp=("INTPTR_FORMAT"+"INTX_FORMAT") stack_size="INTX_FORMAT" bp="INTPTR_FORMAT"\n",
+         adaptername, (intptr_t)mh, (intptr_t)entry_sp, (intptr_t)(saved_sp - entry_sp), (intptr_t)(base_sp - last_sp), (intptr_t)saved_bp);
+  if (last_sp != saved_sp)
+    printf("*** last_sp="INTPTR_FORMAT"\n", (intptr_t)last_sp);
 }
 #endif //PRODUCT
 
@@ -293,6 +299,10 @@
   Register rbx_temp    = rbx;
   Register rdx_temp    = rdx;
 
+  // This guy is set up by prepare_to_jump_from_interpreted (from interpreted calls)
+  // and gen_c2i_adapter (from compiled calls):
+  Register saved_last_sp = LP64_ONLY(r13) NOT_LP64(rsi);
+
   guarantee(java_dyn_MethodHandle::vmentry_offset_in_bytes() != 0, "must have offsets");
 
   // some handy addresses
@@ -315,6 +325,8 @@
     assert(tag_offset = wordSize, "stack grows as expected");
   }
 
+  const int java_mirror_offset = klassOopDesc::klass_part_offset_in_bytes() + Klass::java_mirror_offset_in_bytes();
+
   if (have_entry(ek)) {
     __ nop();                   // empty stubs make SG sick
     return;
@@ -328,45 +340,65 @@
     __ push(rax); __ push(rbx); __ push(rcx); __ push(rdx); __ push(rsi); __ push(rdi);
     __ lea(rax, Address(rsp, wordSize*6)); // entry_sp
     // arguments:
+    __ push(rbp);               // interpreter frame pointer
     __ push(rsi);               // saved_sp
     __ push(rax);               // entry_sp
     __ push(rcx);               // mh
     __ push(rcx);
     __ movptr(Address(rsp, 0), (intptr_t)entry_name(ek));
-    __ call_VM_leaf(CAST_FROM_FN_PTR(address, trace_method_handle_stub), 4);
+    __ call_VM_leaf(CAST_FROM_FN_PTR(address, trace_method_handle_stub), 5);
     __ pop(rdi); __ pop(rsi); __ pop(rdx); __ pop(rcx); __ pop(rbx); __ pop(rax);
   }
 #endif //PRODUCT
 
   switch ((int) ek) {
-  case _check_mtype:
+  case _raise_exception:
     {
-      // this stub is special, because it requires a live mtype argument
-      Register rax_mtype = rax;
+      // Not a real MH entry, but rather shared code for raising an exception.
+      // Extra local arguments are pushed on stack, as required type at TOS+8,
+      // failing object (or NULL) at TOS+4, failing bytecode type at TOS.
+      // Beyond those local arguments are the PC, of course.
+      Register rdx_code = rdx_temp;
+      Register rcx_fail = rcx_recv;
+      Register rax_want = rax_argslot;
+      Register rdi_pc   = rdi;
+      __ pop(rdx_code);  // TOS+0
+      __ pop(rcx_fail);  // TOS+4
+      __ pop(rax_want);  // TOS+8
+      __ pop(rdi_pc);    // caller PC
 
-      // emit WrongMethodType path first, to enable jccb back-branch
-      Label wrong_method_type;
-      __ bind(wrong_method_type);
-      __ movptr(rdx_temp, ExternalAddress((address) &_entries[_wrong_method_type]));
-      __ jmp(Address(rdx_temp, MethodHandleEntry::from_interpreted_entry_offset_in_bytes()));
-      __ hlt();
+      __ mov(rsp, rsi);   // cut the stack back to where the caller started
 
-      interp_entry = __ pc();
-      __ check_method_handle_type(rax_mtype, rcx_recv, rdx_temp, wrong_method_type);
-      // now rax_mtype is dead; subsequent stubs will use it as a temp
+      // Repush the arguments as if coming from the interpreter.
+      if (TaggedStackInterpreter)  __ push(frame::tag_for_basic_type(T_INT));
+      __ push(rdx_code);
+      if (TaggedStackInterpreter)  __ push(frame::tag_for_basic_type(T_OBJECT));
+      __ push(rcx_fail);
+      if (TaggedStackInterpreter)  __ push(frame::tag_for_basic_type(T_OBJECT));
+      __ push(rax_want);
 
-      __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
-    }
-    break;
+      Register rbx_method = rbx_temp;
+      Label no_method;
+      // FIXME: fill in _raise_exception_method with a suitable sun.dyn method
+      __ movptr(rbx_method, ExternalAddress((address) &_raise_exception_method));
+      __ testptr(rbx_method, rbx_method);
+      __ jcc(Assembler::zero, no_method);
+      int jobject_oop_offset = 0;
+      __ movptr(rbx_method, Address(rbx_method, jobject_oop_offset));  // dereference the jobject
+      __ testptr(rbx_method, rbx_method);
+      __ jcc(Assembler::zero, no_method);
+      __ verify_oop(rbx_method);
+      __ push(rdi_pc);          // and restore caller PC
+      __ jmp(rbx_method_fie);
 
-  case _wrong_method_type:
-    {
-      // this stub is special, because it requires a live mtype argument
-      Register rax_mtype = rax;
-
-      interp_entry = __ pc();
-      __ push(rax_mtype);       // required mtype
-      __ push(rcx_recv);        // random mh (1st stacked argument)
+      // If we get here, the Java runtime did not do its job of creating the exception.
+      // Do something that is at least causes a valid throw from the interpreter.
+      __ bind(no_method);
+      __ pop(rax_want);
+      if (TaggedStackInterpreter)  __ pop(rcx_fail);
+      __ pop(rcx_fail);
+      __ push(rax_want);
+      __ push(rcx_fail);
       __ jump(ExternalAddress(Interpreter::throw_WrongMethodType_entry()));
     }
     break;
@@ -442,7 +474,7 @@
       __ load_klass(rax_klass, rcx_recv);
       __ verify_oop(rax_klass);
 
-      Register rcx_temp   = rcx_recv;
+      Register rdi_temp   = rdi;
       Register rbx_method = rbx_index;
 
       // get interface klass
@@ -451,7 +483,7 @@
       __ lookup_interface_method(rax_klass, rdx_intf,
                                  // note: next two args must be the same:
                                  rbx_index, rbx_method,
-                                 rcx_temp,
+                                 rdi_temp,
                                  no_such_interface);
 
       __ verify_oop(rbx_method);
@@ -461,7 +493,10 @@
       __ bind(no_such_interface);
       // Throw an exception.
       // For historical reasons, it will be IncompatibleClassChangeError.
-      __ should_not_reach_here(); // %%% FIXME NYI
+      __ pushptr(Address(rdx_intf, java_mirror_offset));  // required interface
+      __ push(rcx_recv);        // bad receiver
+      __ push((int)Bytecodes::_invokeinterface);  // who is complaining?
+      __ jump(ExternalAddress(from_interpreted_entry(_raise_exception)));
     }
     break;
 
@@ -524,6 +559,7 @@
     break;
 
   case _adapter_retype_only:
+  case _adapter_retype_raw:
     // immediately jump to the next MH layer:
     __ movptr(rcx_recv, rcx_mh_vmtarget);
     __ verify_oop(rcx_recv);
@@ -545,10 +581,6 @@
       __ movptr(rbx_klass, rcx_amh_argument); // this is a Class object!
       __ movptr(rbx_klass, Address(rbx_klass, java_lang_Class::klass_offset_in_bytes()));
 
-      // get the new MH:
-      __ movptr(rcx_recv, rcx_mh_vmtarget);
-      // (now we are done with the old MH)
-
       Label done;
       __ movptr(rdx_temp, vmarg);
       __ testl(rdx_temp, rdx_temp);
@@ -558,17 +590,23 @@
       // live at this point:
       // - rbx_klass:  klass required by the target method
       // - rdx_temp:   argument klass to test
-      // - rcx_recv:   method handle to invoke (after cast succeeds)
+      // - rcx_recv:   adapter method handle
       __ check_klass_subtype(rdx_temp, rbx_klass, rax_argslot, done);
 
       // If we get here, the type check failed!
       // Call the wrong_method_type stub, passing the failing argument type in rax.
       Register rax_mtype = rax_argslot;
-      __ push(rbx_klass);       // missed klass (required type)
-      __ push(rdx_temp);        // bad actual type (1st stacked argument)
-      __ jump(ExternalAddress(Interpreter::throw_WrongMethodType_entry()));
+      __ movl(rax_argslot, rcx_amh_vmargslot);  // reload argslot field
+      __ movptr(rdx_temp, vmarg);
+
+      __ pushptr(rcx_amh_argument); // required class
+      __ push(rdx_temp);            // bad object
+      __ push((int)Bytecodes::_checkcast);  // who is complaining?
+      __ jump(ExternalAddress(from_interpreted_entry(_raise_exception)));
 
       __ bind(done);
+      // get the new MH:
+      __ movptr(rcx_recv, rcx_mh_vmtarget);
       __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
     }
     break;
@@ -1107,11 +1145,17 @@
 
       __ bind(bad_array_klass);
       UNPUSH_RSI_RDI;
-      __ stop("bad array klass NYI");
+      __ pushptr(Address(rdx_array_klass, java_mirror_offset)); // required type
+      __ pushptr(vmarg);                // bad array
+      __ push((int)Bytecodes::_aaload); // who is complaining?
+      __ jump(ExternalAddress(from_interpreted_entry(_raise_exception)));
 
       __ bind(bad_array_length);
       UNPUSH_RSI_RDI;
-      __ stop("bad array length NYI");
+      __ push(rcx_recv);        // AMH requiring a certain length
+      __ pushptr(vmarg);        // bad array
+      __ push((int)Bytecodes::_arraylength); // who is complaining?
+      __ jump(ExternalAddress(from_interpreted_entry(_raise_exception)));
 
 #undef UNPUSH_RSI_RDI
     }
--- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp	Wed Jul 05 17:02:50 2017 +0200
@@ -92,8 +92,7 @@
   return entry;
 }
 
-// Arguments are: required type at TOS+8, failing object (or NULL) at TOS+4.
-// pc at TOS (just for debugging)
+// Arguments are: required type at TOS+4, failing object (or NULL) at TOS.
 address TemplateInterpreterGenerator::generate_WrongMethodType_handler() {
   address entry = __ pc();
 
--- a/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp	Wed Jul 05 17:02:50 2017 +0200
@@ -139,7 +139,7 @@
         }
         __ g1_write_barrier_pre(rdx, r8, rbx, val != noreg);
         if (val == noreg) {
-          __ store_heap_oop(Address(rdx, 0), NULL_WORD);
+          __ store_heap_oop_null(Address(rdx, 0));
         } else {
           __ store_heap_oop(Address(rdx, 0), val);
           __ g1_write_barrier_post(rdx, val, r8, rbx);
@@ -152,7 +152,7 @@
     case BarrierSet::CardTableExtension:
       {
         if (val == noreg) {
-          __ store_heap_oop(obj, NULL_WORD);
+          __ store_heap_oop_null(obj);
         } else {
           __ store_heap_oop(obj, val);
           // flatten object address if needed
@@ -168,7 +168,7 @@
     case BarrierSet::ModRef:
     case BarrierSet::Other:
       if (val == noreg) {
-        __ store_heap_oop(obj, NULL_WORD);
+        __ store_heap_oop_null(obj);
       } else {
         __ store_heap_oop(obj, val);
       }
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/src/share/vm/classfile/javaClasses.hpp	Wed Jul 05 17:02:50 2017 +0200
@@ -903,19 +903,20 @@
   // Relevant integer codes (keep these in synch. with MethodHandleNatives.Constants):
   enum {
     OP_RETYPE_ONLY   = 0x0, // no argument changes; straight retype
-    OP_CHECK_CAST    = 0x1, // ref-to-ref conversion; requires a Class argument
-    OP_PRIM_TO_PRIM  = 0x2, // converts from one primitive to another
-    OP_REF_TO_PRIM   = 0x3, // unboxes a wrapper to produce a primitive
-    OP_PRIM_TO_REF   = 0x4, // boxes a primitive into a wrapper (NYI)
-    OP_SWAP_ARGS     = 0x5, // swap arguments (vminfo is 2nd arg)
-    OP_ROT_ARGS      = 0x6, // rotate arguments (vminfo is displaced arg)
-    OP_DUP_ARGS      = 0x7, // duplicates one or more arguments (at TOS)
-    OP_DROP_ARGS     = 0x8, // remove one or more argument slots
-    OP_COLLECT_ARGS  = 0x9, // combine one or more arguments into a varargs (NYI)
-    OP_SPREAD_ARGS   = 0xA, // expand in place a varargs array (of known size)
-    OP_FLYBY         = 0xB, // operate first on reified argument list (NYI)
-    OP_RICOCHET      = 0xC, // run an adapter chain on the return value (NYI)
-    CONV_OP_LIMIT    = 0xD, // limit of CONV_OP enumeration
+    OP_RETYPE_RAW    = 0x1, // straight retype, trusted (void->int, Object->T)
+    OP_CHECK_CAST    = 0x2, // ref-to-ref conversion; requires a Class argument
+    OP_PRIM_TO_PRIM  = 0x3, // converts from one primitive to another
+    OP_REF_TO_PRIM   = 0x4, // unboxes a wrapper to produce a primitive
+    OP_PRIM_TO_REF   = 0x5, // boxes a primitive into a wrapper (NYI)
+    OP_SWAP_ARGS     = 0x6, // swap arguments (vminfo is 2nd arg)
+    OP_ROT_ARGS      = 0x7, // rotate arguments (vminfo is displaced arg)
+    OP_DUP_ARGS      = 0x8, // duplicates one or more arguments (at TOS)
+    OP_DROP_ARGS     = 0x9, // remove one or more argument slots
+    OP_COLLECT_ARGS  = 0xA, // combine one or more arguments into a varargs (NYI)
+    OP_SPREAD_ARGS   = 0xB, // expand in place a varargs array (of known size)
+    OP_FLYBY         = 0xC, // operate first on reified argument list (NYI)
+    OP_RICOCHET      = 0xD, // run an adapter chain on the return value (NYI)
+    CONV_OP_LIMIT    = 0xE, // limit of CONV_OP enumeration
 
     CONV_OP_MASK     = 0xF00, // this nybble contains the conversion op field
     CONV_VMINFO_MASK = 0x0FF, // LSB is reserved for JVM use
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp	Wed Jul 05 17:02:50 2017 +0200
@@ -1963,7 +1963,7 @@
   WKID meth_group_end   = WK_KLASS_ENUM_NAME(WrongMethodTypeException_klass);
   initialize_wk_klasses_until(meth_group_start, scan, CHECK);
   if (EnableMethodHandles) {
-    initialize_wk_klasses_through(meth_group_start, scan, CHECK);
+    initialize_wk_klasses_through(meth_group_end, scan, CHECK);
   }
   if (_well_known_klasses[meth_group_start] == NULL) {
     // Skip the rest of the method handle classes, if MethodHandle is not loaded.
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Wed Jul 05 17:02:50 2017 +0200
@@ -667,39 +667,6 @@
 // Called at the first checkpoint.
 //
 
-#define PRINT_REACHABLE_AT_INITIAL_MARK 0
-#if PRINT_REACHABLE_AT_INITIAL_MARK
-static FILE* reachable_file = NULL;
-
-class PrintReachableClosure: public OopsInGenClosure {
-  CMBitMap* _bm;
-  int _level;
-public:
-  PrintReachableClosure(CMBitMap* bm) :
-    _bm(bm), _level(0) {
-    guarantee(reachable_file != NULL, "pre-condition");
-  }
-  void do_oop(oop* p) {
-    oop obj = *p;
-    HeapWord* obj_addr = (HeapWord*)obj;
-    if (obj == NULL) return;
-    fprintf(reachable_file, "%d: "PTR_FORMAT" -> "PTR_FORMAT" (%d)\n",
-            _level, p, (void*) obj, _bm->isMarked(obj_addr));
-    if (!_bm->isMarked(obj_addr)) {
-      _bm->mark(obj_addr);
-      _level++;
-      obj->oop_iterate(this);
-      _level--;
-    }
-  }
-};
-#endif // PRINT_REACHABLE_AT_INITIAL_MARK
-
-#define SEND_HEAP_DUMP_TO_FILE 0
-#if SEND_HEAP_DUMP_TO_FILE
-static FILE* heap_dump_file = NULL;
-#endif // SEND_HEAP_DUMP_TO_FILE
-
 void ConcurrentMark::clearNextBitmap() {
    guarantee(!G1CollectedHeap::heap()->mark_in_progress(), "Precondition.");
 
@@ -737,32 +704,9 @@
 
   _has_aborted = false;
 
-  // Find all the reachable objects...
-#if PRINT_REACHABLE_AT_INITIAL_MARK
-  guarantee(reachable_file == NULL, "Protocol");
-  char fn_buf[100];
-  sprintf(fn_buf, "/tmp/reachable.txt.%d", os::current_process_id());
-  reachable_file = fopen(fn_buf, "w");
-  // clear the mark bitmap (no grey objects to start with)
-  _nextMarkBitMap->clearAll();
-  PrintReachableClosure prcl(_nextMarkBitMap);
-  g1h->process_strong_roots(true,    // activate StrongRootsScope
-                            false,   // fake perm gen collection
-                            SharedHeap::SO_AllClasses,
-                            &prcl, // Regular roots
-                            NULL,  // do not visit active blobs
-                            &prcl    // Perm Gen Roots
-                            );
-  // The root iteration above "consumed" dirty cards in the perm gen.
-  // Therefore, as a shortcut, we dirty all such cards.
-  g1h->rem_set()->invalidate(g1h->perm_gen()->used_region(), false);
-  fclose(reachable_file);
-  reachable_file = NULL;
-  // clear the mark bitmap again.
-  _nextMarkBitMap->clearAll();
-  COMPILER2_PRESENT(DerivedPointerTable::update_pointers());
-  COMPILER2_PRESENT(DerivedPointerTable::clear());
-#endif // PRINT_REACHABLE_AT_INITIAL_MARK
+  if (G1PrintReachableAtInitialMark) {
+    print_reachable(true, "before");
+  }
 
   // Initialise marking structures. This has to be done in a STW phase.
   reset();
@@ -1965,15 +1909,21 @@
 #endif
 }
 
+#ifndef PRODUCT
+
 class ReachablePrinterOopClosure: public OopClosure {
 private:
   G1CollectedHeap* _g1h;
   CMBitMapRO*      _bitmap;
   outputStream*    _out;
+  bool             _use_prev_marking;
 
 public:
-  ReachablePrinterOopClosure(CMBitMapRO* bitmap, outputStream* out) :
-    _bitmap(bitmap), _g1h(G1CollectedHeap::heap()), _out(out) { }
+  ReachablePrinterOopClosure(CMBitMapRO*   bitmap,
+                             outputStream* out,
+                             bool          use_prev_marking) :
+    _g1h(G1CollectedHeap::heap()),
+    _bitmap(bitmap), _out(out), _use_prev_marking(use_prev_marking) { }
 
   void do_oop(narrowOop* p) { do_oop_work(p); }
   void do_oop(      oop* p) { do_oop_work(p); }
@@ -1988,14 +1938,23 @@
     else {
       HeapRegion* hr  = _g1h->heap_region_containing(obj);
       guarantee(hr != NULL, "invariant");
-      if (hr->obj_allocated_since_prev_marking(obj)) {
+      bool over_tams = false;
+      if (_use_prev_marking) {
+        over_tams = hr->obj_allocated_since_prev_marking(obj);
+      } else {
+        over_tams = hr->obj_allocated_since_next_marking(obj);
+      }
+
+      if (over_tams) {
         str = "over TAMS";
-        if (_bitmap->isMarked((HeapWord*) obj))
+        if (_bitmap->isMarked((HeapWord*) obj)) {
           str2 = " AND MARKED";
-      } else if (_bitmap->isMarked((HeapWord*) obj))
+        }
+      } else if (_bitmap->isMarked((HeapWord*) obj)) {
         str = "marked";
-      else
+      } else {
         str = "#### NOT MARKED ####";
+      }
     }
 
     _out->print_cr("    "PTR_FORMAT" contains "PTR_FORMAT" %s%s",
@@ -2005,16 +1964,19 @@
 
 class ReachablePrinterClosure: public BitMapClosure {
 private:
-  CMBitMapRO* _bitmap;
+  CMBitMapRO*   _bitmap;
   outputStream* _out;
+  bool          _use_prev_marking;
 
 public:
-  ReachablePrinterClosure(CMBitMapRO* bitmap, outputStream* out) :
-    _bitmap(bitmap), _out(out) { }
+  ReachablePrinterClosure(CMBitMapRO*   bitmap,
+                          outputStream* out,
+                          bool          use_prev_marking) :
+    _bitmap(bitmap), _out(out), _use_prev_marking(use_prev_marking) { }
 
   bool do_bit(size_t offset) {
     HeapWord* addr = _bitmap->offsetToHeapWord(offset);
-    ReachablePrinterOopClosure oopCl(_bitmap, _out);
+    ReachablePrinterOopClosure oopCl(_bitmap, _out, _use_prev_marking);
 
     _out->print_cr("  obj "PTR_FORMAT", offset %10d (marked)", addr, offset);
     oop(addr)->oop_iterate(&oopCl);
@@ -2026,76 +1988,111 @@
 
 class ObjInRegionReachablePrinterClosure : public ObjectClosure {
 private:
-  CMBitMapRO* _bitmap;
+  CMBitMapRO*   _bitmap;
   outputStream* _out;
+  bool          _use_prev_marking;
 
 public:
+  ObjInRegionReachablePrinterClosure(CMBitMapRO*   bitmap,
+                                     outputStream* out,
+                                     bool          use_prev_marking) :
+    _bitmap(bitmap), _out(out), _use_prev_marking(use_prev_marking) { }
+
   void do_object(oop o) {
-    ReachablePrinterOopClosure oopCl(_bitmap, _out);
+    ReachablePrinterOopClosure oopCl(_bitmap, _out, _use_prev_marking);
 
     _out->print_cr("  obj "PTR_FORMAT" (over TAMS)", (void*) o);
     o->oop_iterate(&oopCl);
     _out->print_cr("");
   }
-
-  ObjInRegionReachablePrinterClosure(CMBitMapRO* bitmap, outputStream* out) :
-    _bitmap(bitmap), _out(out) { }
 };
 
 class RegionReachablePrinterClosure : public HeapRegionClosure {
 private:
-  CMBitMapRO* _bitmap;
+  CMBitMapRO*   _bitmap;
   outputStream* _out;
+  bool          _use_prev_marking;
 
 public:
   bool doHeapRegion(HeapRegion* hr) {
     HeapWord* b = hr->bottom();
     HeapWord* e = hr->end();
     HeapWord* t = hr->top();
-    HeapWord* p = hr->prev_top_at_mark_start();
+    HeapWord* p = NULL;
+    if (_use_prev_marking) {
+      p = hr->prev_top_at_mark_start();
+    } else {
+      p = hr->next_top_at_mark_start();
+    }
     _out->print_cr("** ["PTR_FORMAT", "PTR_FORMAT"] top: "PTR_FORMAT" "
-                   "PTAMS: "PTR_FORMAT, b, e, t, p);
+                   "TAMS: "PTR_FORMAT, b, e, t, p);
     _out->print_cr("");
 
-    ObjInRegionReachablePrinterClosure ocl(_bitmap, _out);
+    ObjInRegionReachablePrinterClosure ocl(_bitmap, _out, _use_prev_marking);
     hr->object_iterate_mem_careful(MemRegion(p, t), &ocl);
 
     return false;
   }
 
-  RegionReachablePrinterClosure(CMBitMapRO* bitmap,
-                                outputStream* out) :
-    _bitmap(bitmap), _out(out) { }
+  RegionReachablePrinterClosure(CMBitMapRO*   bitmap,
+                                outputStream* out,
+                                bool          use_prev_marking) :
+    _bitmap(bitmap), _out(out), _use_prev_marking(use_prev_marking) { }
 };
 
-void ConcurrentMark::print_prev_bitmap_reachable() {
-  outputStream* out = gclog_or_tty;
-
-#if SEND_HEAP_DUMP_TO_FILE
-  guarantee(heap_dump_file == NULL, "Protocol");
-  char fn_buf[100];
-  sprintf(fn_buf, "/tmp/dump.txt.%d", os::current_process_id());
-  heap_dump_file = fopen(fn_buf, "w");
-  fileStream fstream(heap_dump_file);
-  out = &fstream;
-#endif // SEND_HEAP_DUMP_TO_FILE
-
-  RegionReachablePrinterClosure rcl(_prevMarkBitMap, out);
-  out->print_cr("--- ITERATING OVER REGIONS WITH PTAMS < TOP");
+void ConcurrentMark::print_reachable(bool use_prev_marking, const char* str) {
+  gclog_or_tty->print_cr("== Doing reachable object dump... ");
+
+  if (G1PrintReachableBaseFile == NULL) {
+    gclog_or_tty->print_cr("  #### error: no base file defined");
+    return;
+  }
+
+  if (strlen(G1PrintReachableBaseFile) + 1 + strlen(str) >
+      (JVM_MAXPATHLEN - 1)) {
+    gclog_or_tty->print_cr("  #### error: file name too long");
+    return;
+  }
+
+  char file_name[JVM_MAXPATHLEN];
+  sprintf(file_name, "%s.%s", G1PrintReachableBaseFile, str);
+  gclog_or_tty->print_cr("  dumping to file %s", file_name);
+
+  fileStream fout(file_name);
+  if (!fout.is_open()) {
+    gclog_or_tty->print_cr("  #### error: could not open file");
+    return;
+  }
+
+  outputStream* out = &fout;
+
+  CMBitMapRO* bitmap = NULL;
+  if (use_prev_marking) {
+    bitmap = _prevMarkBitMap;
+  } else {
+    bitmap = _nextMarkBitMap;
+  }
+
+  out->print_cr("-- USING %s", (use_prev_marking) ? "PTAMS" : "NTAMS");
+  out->cr();
+
+  RegionReachablePrinterClosure rcl(bitmap, out, use_prev_marking);
+  out->print_cr("--- ITERATING OVER REGIONS WITH TAMS < TOP");
+  out->cr();
   _g1h->heap_region_iterate(&rcl);
-  out->print_cr("");
-
-  ReachablePrinterClosure cl(_prevMarkBitMap, out);
-  out->print_cr("--- REACHABLE OBJECTS ON THE BITMAP");
-  _prevMarkBitMap->iterate(&cl);
-  out->print_cr("");
-
-#if SEND_HEAP_DUMP_TO_FILE
-  fclose(heap_dump_file);
-  heap_dump_file = NULL;
-#endif // SEND_HEAP_DUMP_TO_FILE
+  out->cr();
+
+  ReachablePrinterClosure cl(bitmap, out, use_prev_marking);
+  out->print_cr("--- ITERATING OVER MARKED OBJECTS ON THE BITMAP");
+  out->cr();
+  bitmap->iterate(&cl);
+  out->cr();
+
+  gclog_or_tty->print_cr("  done");
 }
 
+#endif // PRODUCT
+
 // This note is for drainAllSATBBuffers and the code in between.
 // In the future we could reuse a task to do this work during an
 // evacuation pause (since now tasks are not active and can be claimed
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp	Wed Jul 05 17:02:50 2017 +0200
@@ -612,10 +612,11 @@
   // we do nothing.
   void markAndGrayObjectIfNecessary(oop p);
 
-  // This iterates over the bitmap of the previous marking and prints
-  // out all objects that are marked on the bitmap and indicates
-  // whether what they point to is also marked or not.
-  void print_prev_bitmap_reachable();
+  // This iterates over the marking bitmap (either prev or next) and
+  // prints out all objects that are marked on the bitmap and indicates
+  // whether what they point to is also marked or not. It also iterates
+  // the objects over TAMS (either prev or next).
+  void print_reachable(bool use_prev_marking, const char* str);
 
   // Clear the next marking bitmap (will be called concurrently).
   void clearNextBitmap();
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Wed Jul 05 17:02:50 2017 +0200
@@ -2371,8 +2371,9 @@
       gclog_or_tty->print_cr("Heap:");
       print_on(gclog_or_tty, true /* extended */);
       gclog_or_tty->print_cr("");
-      if (VerifyDuringGC && G1VerifyConcMarkPrintReachable) {
-        concurrent_mark()->print_prev_bitmap_reachable();
+      if (VerifyDuringGC && G1VerifyDuringGCPrintReachable) {
+        concurrent_mark()->print_reachable(use_prev_marking,
+                                           "failed-verification");
       }
       gclog_or_tty->flush();
     }
@@ -3135,7 +3136,7 @@
          _evac_failure_scan_stack->length() == 0,
          "Postcondition");
   assert(!_drain_in_progress, "Postcondition");
-  // Don't have to delete, since the scan stack is a resource object.
+  delete _evac_failure_scan_stack;
   _evac_failure_scan_stack = NULL;
 }
 
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Wed Jul 05 17:02:50 2017 +0200
@@ -1516,7 +1516,8 @@
       (end_time_sec - _recent_prev_end_times_for_all_gcs_sec->oldest()) * 1000.0;
     update_recent_gc_times(end_time_sec, elapsed_ms);
     _recent_avg_pause_time_ratio = _recent_gc_times_ms->sum()/interval_ms;
-    assert(recent_avg_pause_time_ratio() < 1.00, "All GC?");
+    // using 1.01 to account for floating point inaccuracies
+    assert(recent_avg_pause_time_ratio() < 1.01, "All GC?");
   }
 
   if (G1PolicyVerbose > 1) {
--- a/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp	Wed Jul 05 17:02:50 2017 +0200
@@ -55,8 +55,14 @@
   develop(intx, G1MarkingVerboseLevel, 0,                                   \
           "Level (0-4) of verboseness of the marking code")                 \
                                                                             \
-  develop(bool, G1VerifyConcMarkPrintReachable, false,                      \
-          "If conc mark verification fails, print reachable objects")       \
+  develop(bool, G1PrintReachableAtInitialMark, false,                       \
+          "Reachable object dump at the initial mark pause")                \
+                                                                            \
+  develop(bool, G1VerifyDuringGCPrintReachable, false,                      \
+          "If conc mark verification fails, dump reachable objects")        \
+                                                                            \
+  develop(ccstr, G1PrintReachableBaseFile, NULL,                            \
+          "The base file name for the reachable object dumps")              \
                                                                             \
   develop(bool, G1TraceMarkStackOverflow, false,                            \
           "If true, extra debugging code for CM restart for ovflw.")        \
--- a/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.cpp	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.cpp	Wed Jul 05 17:02:50 2017 +0200
@@ -135,7 +135,6 @@
   _occupied_entries(0), _occupied_cards(0),
   _entries(NEW_C_HEAP_ARRAY(SparsePRTEntry, capacity)),
   _buckets(NEW_C_HEAP_ARRAY(int, capacity)),
-  _next_deleted(NULL), _deleted(false),
   _free_list(NullEntry), _free_region(0)
 {
   clear();
@@ -296,40 +295,6 @@
   assert(e2->num_valid_cards() > 0, "Postcondition.");
 }
 
-RSHashTable* RSHashTable::_head_deleted_list = NULL;
-
-void RSHashTable::add_to_deleted_list(RSHashTable* rsht) {
-  assert(!rsht->deleted(), "Should delete only once.");
-  rsht->set_deleted(true);
-  RSHashTable* hd = _head_deleted_list;
-  while (true) {
-    rsht->_next_deleted = hd;
-    RSHashTable* res =
-      (RSHashTable*)
-      Atomic::cmpxchg_ptr(rsht, &_head_deleted_list, hd);
-    if (res == hd) return;
-    else hd = res;
-  }
-}
-
-RSHashTable* RSHashTable::get_from_deleted_list() {
-  RSHashTable* hd = _head_deleted_list;
-  while (hd != NULL) {
-    RSHashTable* next = hd->next_deleted();
-    RSHashTable* res =
-      (RSHashTable*)
-      Atomic::cmpxchg_ptr(next, &_head_deleted_list, hd);
-    if (res == hd) {
-      hd->set_next_deleted(NULL);
-      hd->set_deleted(false);
-      return hd;
-    } else {
-      hd = res;
-    }
-  }
-  return NULL;
-}
-
 CardIdx_t /* RSHashTable:: */ RSHashTableIter::find_first_card_in_list() {
   CardIdx_t res;
   while (_bl_ind != RSHashTable::NullEntry) {
@@ -442,15 +407,6 @@
     sprt->cleanup();
     sprt = get_from_expanded_list();
   }
-  // Now delete all deleted RSHashTables.
-  RSHashTable* rsht = RSHashTable::get_from_deleted_list();
-  while (rsht != NULL) {
-#if SPARSE_PRT_VERBOSE
-    gclog_or_tty->print_cr("About to delete RSHT " PTR_FORMAT ".", rsht);
-#endif
-    delete rsht;
-    rsht = RSHashTable::get_from_deleted_list();
-  }
 }
 
 
@@ -511,8 +467,10 @@
 }
 
 void SparsePRT::cleanup() {
-  // Make sure that the current and next tables agree.  (Another mechanism
-  // takes care of deleting now-unused tables.)
+  // Make sure that the current and next tables agree.
+  if (_cur != _next) {
+    delete _cur;
+  }
   _cur = _next;
   set_expanded(false);
 }
@@ -535,7 +493,8 @@
       _next->add_entry(e);
     }
   }
-  if (last != _cur)
-    RSHashTable::add_to_deleted_list(last);
+  if (last != _cur) {
+    delete last;
+  }
   add_to_expanded_list(this);
 }
--- a/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.hpp	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.hpp	Wed Jul 05 17:02:50 2017 +0200
@@ -102,13 +102,6 @@
   int  _free_region;
   int  _free_list;
 
-  static RSHashTable* _head_deleted_list;
-  RSHashTable* _next_deleted;
-  RSHashTable* next_deleted() { return _next_deleted; }
-  void set_next_deleted(RSHashTable* rsht) { _next_deleted = rsht; }
-  bool _deleted;
-  void set_deleted(bool b) { _deleted = b; }
-
   // Requires that the caller hold a lock preventing parallel modifying
   // operations, and that the the table be less than completely full.  If
   // an entry for "region_ind" is already in the table, finds it and
@@ -154,14 +147,10 @@
   size_t occupied_entries() const { return _occupied_entries; }
   size_t occupied_cards() const   { return _occupied_cards;   }
   size_t mem_size() const;
-  bool deleted() { return _deleted; }
 
   SparsePRTEntry* entry(int i) const { return &_entries[i]; }
 
   void print();
-
-  static void add_to_deleted_list(RSHashTable* rsht);
-  static RSHashTable* get_from_deleted_list();
 };
 
 // ValueObj because will be embedded in HRRS iterator.
--- a/hotspot/src/share/vm/memory/compactingPermGenGen.cpp	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/src/share/vm/memory/compactingPermGenGen.cpp	Wed Jul 05 17:02:50 2017 +0200
@@ -352,15 +352,19 @@
 }
 
 
+// Do not use in time-critical operations due to the possibility of paging
+// in otherwise untouched or previously unread portions of the perm gen,
+// for instance, the shared spaces. NOTE: Because CompactingPermGenGen
+// derives from OneContigSpaceCardGeneration which is supposed to have a
+// single space, and does not override its object_iterate() method,
+// object iteration via that interface does not look at the objects in
+// the shared spaces when using CDS. This should be fixed; see CR 6897798.
 void CompactingPermGenGen::space_iterate(SpaceClosure* blk, bool usedOnly) {
   OneContigSpaceCardGeneration::space_iterate(blk, usedOnly);
   if (spec()->enable_shared_spaces()) {
-#ifdef PRODUCT
     // Making the rw_space walkable will page in the entire space, and
-    // is to be avoided. However, this is required for Verify options.
-    ShouldNotReachHere();
-#endif
-
+    // is to be avoided in the case of time-critical operations.
+    // However, this is required for Verify and heap dump operations.
     blk->do_space(ro_space());
     blk->do_space(rw_space());
   }
--- a/hotspot/src/share/vm/memory/compactingPermGenGen.hpp	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/src/share/vm/memory/compactingPermGenGen.hpp	Wed Jul 05 17:02:50 2017 +0200
@@ -29,6 +29,9 @@
 class PermanentGenerationSpec;
 
 // This is the "generation" view of a CompactingPermGen.
+// NOTE: the shared spaces used for CDS are here handled in
+// a somewhat awkward and potentially buggy fashion, see CR 6801625.
+// This infelicity should be fixed, see CR 6897789.
 class CompactingPermGenGen: public OneContigSpaceCardGeneration {
   friend class VMStructs;
   // Abstractly, this is a subtype that gets access to protected fields.
@@ -47,7 +50,7 @@
   OffsetTableContigSpace* _ro_space;
   OffsetTableContigSpace* _rw_space;
 
-  // With shared spaces there is a dicotomy in the use of the
+  // With shared spaces there is a dichotomy in the use of the
   // _virtual_space of the generation.  There is a portion of the
   // _virtual_space that is used for the unshared part of the
   // permanent generation and a portion that is reserved for the shared part.
--- a/hotspot/src/share/vm/memory/generation.cpp	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/src/share/vm/memory/generation.cpp	Wed Jul 05 17:02:50 2017 +0200
@@ -606,6 +606,13 @@
 void OneContigSpaceCardGeneration::prepare_for_verify() {}
 
 
+// Override for a card-table generation with one contiguous
+// space. NOTE: For reasons that are lost in the fog of history,
+// this code is used when you iterate over perm gen objects,
+// even when one uses CDS, where the perm gen has a couple of
+// other spaces; this is because CompactingPermGenGen derives
+// from OneContigSpaceCardGeneration. This should be cleaned up,
+// see CR 6897789..
 void OneContigSpaceCardGeneration::object_iterate(ObjectClosure* blk) {
   _the_space->object_iterate(blk);
 }
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp	Wed Jul 05 17:02:50 2017 +0200
@@ -1900,7 +1900,7 @@
   }
 }
 
-char* instanceKlass::signature_name() const {
+const char* instanceKlass::signature_name() const {
   const char* src = (const char*) (name()->as_C_string());
   const int src_length = (int)strlen(src);
   char* dest = NEW_RESOURCE_ARRAY(char, src_length + 3);
@@ -2259,6 +2259,10 @@
     st->print(BULLET"fake entry for array: ");
     array_klass->print_value_on(st);
     st->cr();
+  } else if (as_klassOop() == SystemDictionary::MethodType_klass()) {
+    st->print(BULLET"signature: ");
+    java_dyn_MethodType::print_signature(obj, st);
+    st->cr();
   }
 }
 
@@ -2284,6 +2288,9 @@
       const char* tname = type2name(java_lang_Class::primitive_type(obj));
       st->print("%s", tname ? tname : "type?");
     }
+  } else if (as_klassOop() == SystemDictionary::MethodType_klass()) {
+    st->print(" = ");
+    java_dyn_MethodType::print_signature(obj, st);
   } else if (java_lang_boxing_object::is_instance(obj)) {
     st->print(" = ");
     java_lang_boxing_object::print(obj, st);
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp	Wed Jul 05 17:02:50 2017 +0200
@@ -722,7 +722,7 @@
 #endif // SERIALGC
 
   // Naming
-  char* signature_name() const;
+  const char* signature_name() const;
 
   // Iterators
   int oop_oop_iterate(oop obj, OopClosure* blk) {
--- a/hotspot/src/share/vm/oops/klass.cpp	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/src/share/vm/oops/klass.cpp	Wed Jul 05 17:02:50 2017 +0200
@@ -496,11 +496,13 @@
       return result;
     }
   }
+  if (name() == NULL)  return "<unknown>";
   return name()->as_klass_external_name();
 }
 
 
-char* Klass::signature_name() const {
+const char* Klass::signature_name() const {
+  if (name() == NULL)  return "<unknown>";
   return name()->as_C_string();
 }
 
--- a/hotspot/src/share/vm/oops/klass.hpp	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/src/share/vm/oops/klass.hpp	Wed Jul 05 17:02:50 2017 +0200
@@ -546,7 +546,7 @@
   // For arrays, this returns the name of the element with a leading '['.
   // For classes, this returns the name with a leading 'L' and a trailing ';'
   //     and the package separators as '/'.
-  virtual char* signature_name() const;
+  virtual const char* signature_name() const;
 
   // garbage collection support
   virtual void oop_follow_contents(oop obj) = 0;
--- a/hotspot/src/share/vm/oops/markOop.cpp	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/src/share/vm/oops/markOop.cpp	Wed Jul 05 17:02:50 2017 +0200
@@ -31,8 +31,9 @@
     st->print("locked(0x%lx)->", value());
     markOop(*(markOop*)value())->print_on(st);
   } else {
-    assert(is_unlocked(), "just checking");
+    assert(is_unlocked() || has_bias_pattern(), "just checking");
     st->print("mark(");
+    if (has_bias_pattern())  st->print("biased,");
     st->print("hash %#lx,", hash());
     st->print("age %d)", age());
   }
--- a/hotspot/src/share/vm/oops/methodOop.cpp	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/src/share/vm/oops/methodOop.cpp	Wed Jul 05 17:02:50 2017 +0200
@@ -881,7 +881,7 @@
   assert((oop)p == method_type(), "pointer chase is correct");
 #endif
 
-  if (TraceMethodHandles)
+  if (TraceMethodHandles && (Verbose || WizardMode))
     m->print_on(tty);
 
   return m;
--- a/hotspot/src/share/vm/opto/callnode.cpp	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/src/share/vm/opto/callnode.cpp	Wed Jul 05 17:02:50 2017 +0200
@@ -421,21 +421,23 @@
         iklass = cik->as_instance_klass();
       } else if (cik->is_type_array_klass()) {
         cik->as_array_klass()->base_element_type()->print_name_on(st);
-        st->print("[%d]=", spobj->n_fields());
+        st->print("[%d]", spobj->n_fields());
       } else if (cik->is_obj_array_klass()) {
-        ciType* cie = cik->as_array_klass()->base_element_type();
-        int ndim = 1;
-        while (cie->is_obj_array_klass()) {
-          ndim += 1;
-          cie = cie->as_array_klass()->base_element_type();
+        ciKlass* cie = cik->as_obj_array_klass()->base_element_klass();
+        if (cie->is_instance_klass()) {
+          cie->print_name_on(st);
+        } else if (cie->is_type_array_klass()) {
+          cie->as_array_klass()->base_element_type()->print_name_on(st);
+        } else {
+          ShouldNotReachHere();
         }
-        cie->print_name_on(st);
+        st->print("[%d]", spobj->n_fields());
+        int ndim = cik->as_array_klass()->dimension() - 1;
         while (ndim-- > 0) {
           st->print("[]");
         }
-        st->print("[%d]=", spobj->n_fields());
       }
-      st->print("{");
+      st->print("={");
       uint nf = spobj->n_fields();
       if (nf > 0) {
         uint first_ind = spobj->first_index();
--- a/hotspot/src/share/vm/prims/jni.cpp	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/src/share/vm/prims/jni.cpp	Wed Jul 05 17:02:50 2017 +0200
@@ -2116,7 +2116,7 @@
   DT_RETURN_MARK(GetObjectArrayElement, jobject, (const jobject&)ret);
   objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
   if (a->is_within_bounds(index)) {
-    jobject ret = JNIHandles::make_local(env, a->obj_at(index));
+    ret = JNIHandles::make_local(env, a->obj_at(index));
     return ret;
   } else {
     char buf[jintAsStringSize];
@@ -2150,14 +2150,14 @@
 
 #define DEFINE_NEWSCALARARRAY(Return,Allocator,Result) \
 \
-  DT_RETURN_MARK_DECL_FOR(Result, New##Result##Array, Return);\
+  DT_RETURN_MARK_DECL(New##Result##Array, Return);\
 \
 JNI_ENTRY(Return, \
           jni_New##Result##Array(JNIEnv *env, jsize len)) \
   JNIWrapper("New" XSTR(Result) "Array"); \
   DTRACE_PROBE2(hotspot_jni, New##Result##Array__entry, env, len);\
   Return ret = NULL;\
-  DT_RETURN_MARK_FOR(Result, New##Result##Array, Return, (const Return&)ret);\
+  DT_RETURN_MARK(New##Result##Array, Return, (const Return&)ret);\
 \
   oop obj= oopFactory::Allocator(len, CHECK_0); \
   ret = (Return) JNIHandles::make_local(env, obj); \
--- a/hotspot/src/share/vm/prims/methodHandles.cpp	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/src/share/vm/prims/methodHandles.cpp	Wed Jul 05 17:02:50 2017 +0200
@@ -33,8 +33,7 @@
 
 MethodHandleEntry* MethodHandles::_entries[MethodHandles::_EK_LIMIT] = {NULL};
 const char*        MethodHandles::_entry_names[_EK_LIMIT+1] = {
-  "check_mtype",
-  "wrong_method_type",          // what happens when there is a type mismatch
+  "raise_exception",
   "invokestatic",               // how a MH emulates invokestatic
   "invokespecial",              // ditto for the other invokes...
   "invokevirtual",
@@ -48,6 +47,7 @@
 
   // starting at _adapter_mh_first:
   "adapter_retype_only",       // these are for AMH...
+  "adapter_retype_raw",
   "adapter_check_cast",
   "adapter_prim_to_prim",
   "adapter_ref_to_prim",
@@ -82,6 +82,8 @@
   NULL
 };
 
+jobject MethodHandles::_raise_exception_method;
+
 #ifdef ASSERT
 bool MethodHandles::spot_check_entry_names() {
   assert(!strcmp(entry_name(_invokestatic_mh), "invokestatic"), "");
@@ -157,7 +159,8 @@
 }
 
 methodOop MethodHandles::decode_BoundMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result) {
-  assert(mh->klass() == SystemDictionary::BoundMethodHandle_klass(), "");
+  assert(sun_dyn_BoundMethodHandle::is_instance(mh), "");
+  assert(mh->klass() != SystemDictionary::AdapterMethodHandle_klass(), "");
   for (oop bmh = mh;;) {
     // Bound MHs can be stacked to bind several arguments.
     oop target = java_dyn_MethodHandle::vmtarget(bmh);
@@ -174,10 +177,9 @@
       } else {
         // Optimized case:  binding a receiver to a non-dispatched DMH
         // short-circuits directly to the methodOop.
+        // (It might be another argument besides a receiver also.)
         assert(target->is_method(), "must be a simple method");
         methodOop m = (methodOop) target;
-        DEBUG_ONLY(int argslot = sun_dyn_BoundMethodHandle::vmargslot(bmh));
-        assert(argslot == m->size_of_parameters() - 1, "must be initial argument (receiver)");
         decode_flags_result |= MethodHandles::_dmf_binds_method;
         return m;
       }
@@ -214,6 +216,9 @@
     return decode_BoundMethodHandle(mh, receiver_limit_result, decode_flags_result);
   } else if (mhk == SystemDictionary::AdapterMethodHandle_klass()) {
     return decode_AdapterMethodHandle(mh, receiver_limit_result, decode_flags_result);
+  } else if (sun_dyn_BoundMethodHandle::is_subclass(mhk)) {
+    // could be a JavaMethodHandle (but not an adapter MH)
+    return decode_BoundMethodHandle(mh, receiver_limit_result, decode_flags_result);
   } else {
     assert(false, "cannot parse this MH");
     return NULL;              // random MH?
@@ -366,7 +371,13 @@
   oop vmtarget = sun_dyn_MemberName::vmtarget(mname);
   int vmindex  = sun_dyn_MemberName::vmindex(mname);
   if (vmindex == VM_INDEX_UNINITIALIZED)  return NULL; // not resolved
-  return decode_vmtarget(vmtarget, vmindex, NULL, receiver_limit_result, decode_flags_result);
+  methodOop m = decode_vmtarget(vmtarget, vmindex, NULL, receiver_limit_result, decode_flags_result);
+  oop clazz = sun_dyn_MemberName::clazz(mname);
+  if (clazz != NULL && java_lang_Class::is_instance(clazz)) {
+    klassOop klass = java_lang_Class::as_klassOop(clazz);
+    if (klass != NULL)  receiver_limit_result = klass;
+  }
+  return m;
 }
 
 // An unresolved member name is a mere symbolic reference.
@@ -789,6 +800,30 @@
   THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), msg);
 }
 
+static const char* always_null_names[] = {
+  "java/lang/Void",
+  "java/lang/Null",
+  //"java/lang/Nothing",
+  "sun/dyn/empty/Empty",
+  NULL
+};
+
+static bool is_always_null_type(klassOop klass) {
+  if (!Klass::cast(klass)->oop_is_instance())  return false;
+  instanceKlass* ik = instanceKlass::cast(klass);
+  // Must be on the boot class path:
+  if (ik->class_loader() != NULL)  return false;
+  // Check the name.
+  symbolOop name = ik->name();
+  for (int i = 0; ; i++) {
+    const char* test_name = always_null_names[i];
+    if (test_name == NULL)  break;
+    if (name->equals(test_name, (int) strlen(test_name)))
+      return true;
+  }
+  return false;
+}
+
 bool MethodHandles::class_cast_needed(klassOop src, klassOop dst) {
   if (src == dst || dst == SystemDictionary::object_klass())
     return false;                               // quickest checks
@@ -805,6 +840,12 @@
     //srck = Klass::cast(SystemDictionary::object_klass());
     return true;
   }
+  if (is_always_null_type(src)) {
+    // some source types are known to be never instantiated;
+    // they represent references which are always null
+    // such null references never fail to convert safely
+    return false;
+  }
   return !srck->is_subclass_of(dstk->as_klassOop());
 }
 
@@ -814,9 +855,15 @@
 
 bool MethodHandles::same_basic_type_for_arguments(BasicType src,
                                                   BasicType dst,
+                                                  bool raw,
                                                   bool for_return) {
-  // return values can always be forgotten:
-  if (for_return && dst == T_VOID)  return true;
+  if (for_return) {
+    // return values can always be forgotten:
+    if (dst == T_VOID)  return true;
+    if (src == T_VOID)  return raw && (dst == T_INT);
+    // We allow caller to receive a garbage int, which is harmless.
+    // This trick is pulled by trusted code (see VerifyType.canPassRaw).
+  }
   assert(src != T_VOID && dst != T_VOID, "should not be here");
   if (src == dst)  return true;
   if (type2size[src] != type2size[dst])  return false;
@@ -929,8 +976,8 @@
   const char* err = NULL;
 
   int first_ptype_pos = m_needs_receiver ? 1 : 0;
-  if (has_bound_recv && err == NULL) {
-    first_ptype_pos -= 1;
+  if (has_bound_recv) {
+    first_ptype_pos -= 1;  // ptypes do not include the bound argument; start earlier in them
     if (m_needs_receiver && bound_recv_type.is_null())
       { err = "bound receiver is not an object"; goto die; }
   }
@@ -939,10 +986,10 @@
     objArrayOop ptypes = java_dyn_MethodType::ptypes(mtype());
     if (ptypes->length() < first_ptype_pos)
       { err = "receiver argument is missing"; goto die; }
-    if (first_ptype_pos == -1)
+    if (has_bound_recv)
       err = check_method_receiver(m(), bound_recv_type->as_klassOop());
     else
-      err = check_method_receiver(m(), java_lang_Class::as_klassOop(ptypes->obj_at(0)));
+      err = check_method_receiver(m(), java_lang_Class::as_klassOop(ptypes->obj_at(first_ptype_pos-1)));
     if (err != NULL)  goto die;
   }
 
@@ -983,7 +1030,8 @@
                                                     int insert_argnum, oop insert_type,
                                                     int change_argnum, oop change_type,
                                                     int delete_argnum,
-                                                    oop dst_mtype, int dst_beg, int dst_end) {
+                                                    oop dst_mtype, int dst_beg, int dst_end,
+                                                    bool raw) {
   objArrayOop src_ptypes = java_dyn_MethodType::ptypes(src_mtype);
   objArrayOop dst_ptypes = java_dyn_MethodType::ptypes(dst_mtype);
 
@@ -1042,7 +1090,7 @@
     if (src_type != dst_type) {
       if (src_type == NULL)  return "not enough arguments";
       if (dst_type == NULL)  return "too many arguments";
-      err = check_argument_type_change(src_type, dst_type, dst_idx);
+      err = check_argument_type_change(src_type, dst_type, dst_idx, raw);
       if (err != NULL)  return err;
     }
   }
@@ -1051,7 +1099,7 @@
   oop src_rtype = java_dyn_MethodType::rtype(src_mtype);
   oop dst_rtype = java_dyn_MethodType::rtype(dst_mtype);
   if (src_rtype != dst_rtype) {
-    err = check_return_type_change(dst_rtype, src_rtype); // note reversal!
+    err = check_return_type_change(dst_rtype, src_rtype, raw); // note reversal!
     if (err != NULL)  return err;
   }
 
@@ -1061,38 +1109,45 @@
 
 
 const char* MethodHandles::check_argument_type_change(BasicType src_type,
-                                                     klassOop src_klass,
-                                                     BasicType dst_type,
-                                                     klassOop dst_klass,
-                                                     int argnum) {
+                                                      klassOop src_klass,
+                                                      BasicType dst_type,
+                                                      klassOop dst_klass,
+                                                      int argnum,
+                                                      bool raw) {
   const char* err = NULL;
+  bool for_return = (argnum < 0);
 
   // just in case:
   if (src_type == T_ARRAY)  src_type = T_OBJECT;
   if (dst_type == T_ARRAY)  dst_type = T_OBJECT;
 
   // Produce some nice messages if VerifyMethodHandles is turned on:
-  if (!same_basic_type_for_arguments(src_type, dst_type, (argnum < 0))) {
+  if (!same_basic_type_for_arguments(src_type, dst_type, raw, for_return)) {
     if (src_type == T_OBJECT) {
+      if (raw && dst_type == T_INT && is_always_null_type(src_klass))
+        return NULL;    // OK to convert a null pointer to a garbage int
       err = ((argnum >= 0)
              ? "type mismatch: passing a %s for method argument #%d, which expects primitive %s"
              : "type mismatch: returning a %s, but caller expects primitive %s");
     } else if (dst_type == T_OBJECT) {
-      err = ((argnum < 0)
+      err = ((argnum >= 0)
              ? "type mismatch: passing a primitive %s for method argument #%d, which expects %s"
              : "type mismatch: returning a primitive %s, but caller expects %s");
     } else {
-      err = ((argnum < 0)
+      err = ((argnum >= 0)
              ? "type mismatch: passing a %s for method argument #%d, which expects %s"
              : "type mismatch: returning a %s, but caller expects %s");
     }
-  } else if (src_type == T_OBJECT && class_cast_needed(src_klass, dst_klass)) {
+  } else if (src_type == T_OBJECT && dst_type == T_OBJECT &&
+             class_cast_needed(src_klass, dst_klass)) {
     if (!class_cast_needed(dst_klass, src_klass)) {
-      err = ((argnum < 0)
+      if (raw)
+        return NULL;    // reverse cast is OK; the MH target is trusted to enforce it
+      err = ((argnum >= 0)
              ? "cast required: passing a %s for method argument #%d, which expects %s"
              : "cast required: returning a %s, but caller expects %s");
     } else {
-      err = ((argnum < 0)
+      err = ((argnum >= 0)
              ? "reference mismatch: passing a %s for method argument #%d, which expects %s"
              : "reference mismatch: returning a %s, but caller expects %s");
     }
@@ -1429,10 +1484,10 @@
       assert(this_pushes == slots_pushed, "BMH pushes one or two stack slots");
       assert(slots_pushed <= MethodHandlePushLimit, "");
     } else {
-      int prev_pushes = decode_MethodHandle_stack_pushes(target());
-      assert(this_pushes == slots_pushed + prev_pushes, "BMH stack motion must be correct");
+      int target_pushes = decode_MethodHandle_stack_pushes(target());
+      assert(this_pushes == slots_pushed + target_pushes, "BMH stack motion must be correct");
       // do not blow the stack; use a Java-based adapter if this limit is exceeded
-      if (slots_pushed + prev_pushes > MethodHandlePushLimit)
+      if (slots_pushed + target_pushes > MethodHandlePushLimit)
         err = "too many bound parameters";
     }
   }
@@ -1588,6 +1643,11 @@
   if (err == NULL) {
     // Check that the src/dest types are supplied if needed.
     switch (ek) {
+    case _adapter_check_cast:
+      if (src != T_OBJECT || dest != T_OBJECT) {
+        err = "adapter requires object src/dest conversion subfields";
+      }
+      break;
     case _adapter_prim_to_prim:
       if (!is_java_primitive(src) || !is_java_primitive(dest) || src == dest) {
         err = "adapter requires primitive src/dest conversion subfields"; break;
@@ -1616,9 +1676,9 @@
           err = "adapter requires src/dest conversion subfields for swap"; break;
         }
         int swap_size = type2size[src];
-        oop src_mtype  = sun_dyn_AdapterMethodHandle::type(target());
-        oop dest_mtype = sun_dyn_AdapterMethodHandle::type(mh());
-        int slot_limit = sun_dyn_AdapterMethodHandle::vmslots(src_mtype);
+        oop src_mtype  = sun_dyn_AdapterMethodHandle::type(mh());
+        oop dest_mtype = sun_dyn_AdapterMethodHandle::type(target());
+        int slot_limit = sun_dyn_AdapterMethodHandle::vmslots(target());
         int src_slot   = argslot;
         int dest_slot  = vminfo;
         bool rotate_up = (src_slot > dest_slot); // upward rotation
@@ -1729,22 +1789,22 @@
     // Make sure this adapter does not push too deeply.
     int slots_pushed = stack_move / stack_move_unit();
     int this_vmslots = java_dyn_MethodHandle::vmslots(mh());
-    int prev_vmslots = java_dyn_MethodHandle::vmslots(target());
-    if (slots_pushed != (this_vmslots - prev_vmslots)) {
+    int target_vmslots = java_dyn_MethodHandle::vmslots(target());
+    if (slots_pushed != (target_vmslots - this_vmslots)) {
       err = "stack_move inconsistent with previous and current MethodType vmslots";
     } else if (slots_pushed > 0)  {
       // verify stack_move against MethodHandlePushLimit
-      int prev_pushes = decode_MethodHandle_stack_pushes(target());
+      int target_pushes = decode_MethodHandle_stack_pushes(target());
       // do not blow the stack; use a Java-based adapter if this limit is exceeded
-      if (slots_pushed + prev_pushes > MethodHandlePushLimit) {
+      if (slots_pushed + target_pushes > MethodHandlePushLimit) {
         err = "adapter pushes too many parameters";
       }
     }
 
     // While we're at it, check that the stack motion decoder works:
-    DEBUG_ONLY(int prev_pushes = decode_MethodHandle_stack_pushes(target()));
+    DEBUG_ONLY(int target_pushes = decode_MethodHandle_stack_pushes(target()));
     DEBUG_ONLY(int this_pushes = decode_MethodHandle_stack_pushes(mh()));
-    assert(this_pushes == slots_pushed + prev_pushes, "AMH stack motion must be correct");
+    assert(this_pushes == slots_pushed + target_pushes, "AMH stack motion must be correct");
   }
 
   if (err == NULL && vminfo != 0) {
@@ -1761,7 +1821,11 @@
   if (err == NULL) {
     switch (ek) {
     case _adapter_retype_only:
-      err = check_method_type_passthrough(src_mtype(), dst_mtype());
+      err = check_method_type_passthrough(src_mtype(), dst_mtype(), false);
+      break;
+
+    case _adapter_retype_raw:
+      err = check_method_type_passthrough(src_mtype(), dst_mtype(), true);
       break;
 
     case _adapter_check_cast:
@@ -1821,6 +1885,7 @@
   // Now it's time to finish the case analysis and pick a MethodHandleEntry.
   switch (ek_orig) {
   case _adapter_retype_only:
+  case _adapter_retype_raw:
   case _adapter_check_cast:
   case _adapter_dup_args:
   case _adapter_drop_args:
@@ -1888,8 +1953,7 @@
   case _adapter_rot_args:
     {
       int swap_slots = type2size[src];
-      oop mtype      = sun_dyn_AdapterMethodHandle::type(mh());
-      int slot_limit = sun_dyn_AdapterMethodHandle::vmslots(mtype);
+      int slot_limit = sun_dyn_AdapterMethodHandle::vmslots(mh());
       int src_slot   = argslot;
       int dest_slot  = vminfo;
       int rotate     = (ek_orig == _adapter_swap_args) ? 0 : (src_slot > dest_slot) ? 1 : -1;
@@ -2133,7 +2197,7 @@
     guarantee(MethodHandlePushLimit >= 2 && MethodHandlePushLimit <= 0xFF,
               "MethodHandlePushLimit parameter must be in valid range");
     return MethodHandlePushLimit;
-  case MethodHandles::GC_JVM_STACK_MOVE_LIMIT:
+  case MethodHandles::GC_JVM_STACK_MOVE_UNIT:
     // return number of words per slot, signed according to stack direction
     return MethodHandles::stack_move_unit();
   }
@@ -2144,7 +2208,7 @@
 #ifndef PRODUCT
 #define EACH_NAMED_CON(template) \
     template(MethodHandles,GC_JVM_PUSH_LIMIT) \
-    template(MethodHandles,GC_JVM_STACK_MOVE_LIMIT) \
+    template(MethodHandles,GC_JVM_STACK_MOVE_UNIT) \
     template(MethodHandles,ETF_HANDLE_OR_METHOD_NAME) \
     template(MethodHandles,ETF_DIRECT_HANDLE) \
     template(MethodHandles,ETF_METHOD_NAME) \
@@ -2157,6 +2221,7 @@
     template(sun_dyn_MemberName,MN_SEARCH_INTERFACES) \
     template(sun_dyn_MemberName,VM_INDEX_UNINITIALIZED) \
     template(sun_dyn_AdapterMethodHandle,OP_RETYPE_ONLY) \
+    template(sun_dyn_AdapterMethodHandle,OP_RETYPE_RAW) \
     template(sun_dyn_AdapterMethodHandle,OP_CHECK_CAST) \
     template(sun_dyn_AdapterMethodHandle,OP_PRIM_TO_PRIM) \
     template(sun_dyn_AdapterMethodHandle,OP_REF_TO_PRIM) \
@@ -2345,10 +2410,12 @@
   // note: this explicit warning-producing stuff will be replaced by auto-detection of the JSR 292 classes
 
   if (!EnableMethodHandles) {
-    warning("JSR 292 method handles are disabled in this JVM.  Use -XX:+EnableMethodHandles to enable.");
+    warning("JSR 292 method handles are disabled in this JVM.  Use -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles to enable.");
     return;  // bind nothing
   }
 
+  bool enable_MH = true;
+
   {
     ThreadToNativeFromVM ttnfv(thread);
 
@@ -2356,14 +2423,33 @@
     if (env->ExceptionOccurred()) {
       MethodHandles::set_enabled(false);
       warning("JSR 292 method handle code is mismatched to this JVM.  Disabling support.");
+      enable_MH = false;
       env->ExceptionClear();
-    } else {
-      MethodHandles::set_enabled(true);
     }
   }
 
+  if (enable_MH) {
+    KlassHandle MHI_klass = SystemDictionaryHandles::MethodHandleImpl_klass();
+    if (MHI_klass.not_null()) {
+      symbolHandle raiseException_name = oopFactory::new_symbol_handle("raiseException", CHECK);
+      symbolHandle raiseException_sig  = oopFactory::new_symbol_handle("(ILjava/lang/Object;Ljava/lang/Object;)V", CHECK);
+      methodOop raiseException_method  = instanceKlass::cast(MHI_klass->as_klassOop())
+                    ->find_method(raiseException_name(), raiseException_sig());
+      if (raiseException_method != NULL && raiseException_method->is_static()) {
+        MethodHandles::set_raise_exception_method(raiseException_method);
+      } else {
+        warning("JSR 292 method handle code is mismatched to this JVM.  Disabling support.");
+        enable_MH = false;
+      }
+    }
+  }
+
+  if (enable_MH) {
+    MethodHandles::set_enabled(true);
+  }
+
   if (!EnableInvokeDynamic) {
-    warning("JSR 292 invokedynamic is disabled in this JVM.  Use -XX:+EnableInvokeDynamic to enable.");
+    warning("JSR 292 invokedynamic is disabled in this JVM.  Use -XX:+UnlockExperimentalVMOptions -XX:+EnableInvokeDynamic to enable.");
     return;  // bind nothing
   }
 
--- a/hotspot/src/share/vm/prims/methodHandles.hpp	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/src/share/vm/prims/methodHandles.hpp	Wed Jul 05 17:02:50 2017 +0200
@@ -32,8 +32,7 @@
   // See also  javaClasses for layouts java_dyn_Method{Handle,Type,Type::Form}.
  public:
   enum EntryKind {
-    _check_mtype,               // how a caller calls a MH
-    _wrong_method_type,         // what happens when there is a type mismatch
+    _raise_exception,           // stub for error generation from other stubs
     _invokestatic_mh,           // how a MH emulates invokestatic
     _invokespecial_mh,          // ditto for the other invokes...
     _invokevirtual_mh,
@@ -47,6 +46,7 @@
 
     _adapter_mh_first,     // adapter sequence goes here...
     _adapter_retype_only   = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_RETYPE_ONLY,
+    _adapter_retype_raw    = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_RETYPE_RAW,
     _adapter_check_cast    = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_CHECK_CAST,
     _adapter_prim_to_prim  = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_PRIM_TO_PRIM,
     _adapter_ref_to_prim   = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_REF_TO_PRIM,
@@ -113,6 +113,8 @@
   static bool _enabled;
   static MethodHandleEntry* _entries[_EK_LIMIT];
   static const char*        _entry_names[_EK_LIMIT+1];
+  static jobject            _raise_exception_method;
+
   static bool ek_valid(EntryKind ek)            { return (uint)ek < (uint)_EK_LIMIT; }
   static bool conv_op_valid(int op)             { return (uint)op < (uint)CONV_OP_LIMIT; }
 
@@ -131,6 +133,16 @@
     _entries[ek] = me;
   }
 
+  static methodOop raise_exception_method() {
+    oop rem = JNIHandles::resolve(_raise_exception_method);
+    assert(rem == NULL || rem->is_method(), "");
+    return (methodOop) rem;
+  }
+  static void set_raise_exception_method(methodOop rem) {
+    assert(_raise_exception_method == NULL, "");
+    _raise_exception_method = JNIHandles::make_global(Handle(rem));
+  }
+
   static jint adapter_conversion(int conv_op, BasicType src, BasicType dest,
                                  int stack_move = 0, int vminfo = 0) {
     assert(conv_op_valid(conv_op), "oob");
@@ -243,7 +255,7 @@
   enum {
     // format of query to getConstant:
     GC_JVM_PUSH_LIMIT = 0,
-    GC_JVM_STACK_MOVE_LIMIT = 1,
+    GC_JVM_STACK_MOVE_UNIT = 1,
 
     // format of result from getTarget / encode_target:
     ETF_HANDLE_OR_METHOD_NAME = 0, // all available data (immediate MH or method)
@@ -261,7 +273,8 @@
                                               int insert_argnum, oop insert_type,
                                               int change_argnum, oop change_type,
                                               int delete_argnum,
-                                              oop dst_mtype, int dst_beg, int dst_end);
+                                              oop dst_mtype, int dst_beg, int dst_end,
+                                              bool raw = false);
   static const char* check_method_type_insertion(oop src_mtype,
                                                  int insert_argnum, oop insert_type,
                                                  oop dst_mtype) {
@@ -278,29 +291,29 @@
                                     change_argnum, change_type,
                                     -1, dst_mtype, 0, -1);
   }
-  static const char* check_method_type_passthrough(oop src_mtype, oop dst_mtype) {
+  static const char* check_method_type_passthrough(oop src_mtype, oop dst_mtype, bool raw) {
     oop no_ref = NULL;
     return check_method_type_change(src_mtype, 0, -1,
                                     -1, no_ref, -1, no_ref, -1,
-                                    dst_mtype, 0, -1);
+                                    dst_mtype, 0, -1, raw);
   }
 
   // These checkers operate on pairs of argument or return types:
   static const char* check_argument_type_change(BasicType src_type, klassOop src_klass,
                                                 BasicType dst_type, klassOop dst_klass,
-                                                int argnum);
+                                                int argnum, bool raw = false);
 
   static const char* check_argument_type_change(oop src_type, oop dst_type,
-                                                int argnum) {
+                                                int argnum, bool raw = false) {
     klassOop src_klass = NULL, dst_klass = NULL;
     BasicType src_bt = java_lang_Class::as_BasicType(src_type, &src_klass);
     BasicType dst_bt = java_lang_Class::as_BasicType(dst_type, &dst_klass);
     return check_argument_type_change(src_bt, src_klass,
-                                      dst_bt, dst_klass, argnum);
+                                      dst_bt, dst_klass, argnum, raw);
   }
 
-  static const char* check_return_type_change(oop src_type, oop dst_type) {
-    return check_argument_type_change(src_type, dst_type, -1);
+  static const char* check_return_type_change(oop src_type, oop dst_type, bool raw = false) {
+    return check_argument_type_change(src_type, dst_type, -1, raw);
   }
 
   static const char* check_return_type_change(BasicType src_type, klassOop src_klass,
@@ -357,9 +370,10 @@
                                               TRAPS);
 
   static bool same_basic_type_for_arguments(BasicType src, BasicType dst,
+                                            bool raw = false,
                                             bool for_return = false);
-  static bool same_basic_type_for_returns(BasicType src, BasicType dst) {
-    return same_basic_type_for_arguments(src, dst, true);
+  static bool same_basic_type_for_returns(BasicType src, BasicType dst, bool raw = false) {
+    return same_basic_type_for_arguments(src, dst, raw, true);
   }
 
   enum {                        // arg_mask values
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp	Wed Jul 05 17:02:50 2017 +0200
@@ -594,6 +594,7 @@
                                                                                                                                      \
   nonstatic_field(PcDesc,                      _pc_offset,                                    int)                                   \
   nonstatic_field(PcDesc,                      _scope_decode_offset,                          int)                                   \
+  nonstatic_field(PcDesc,                      _obj_decode_offset,                            int)                                   \
   nonstatic_field(PcDesc,                      _flags,                        PcDesc::PcDescFlags)                                   \
                                                                                                                                      \
   /***************************************************/                                                                              \
--- a/hotspot/src/share/vm/services/heapDumper.cpp	Sun Nov 08 14:49:40 2009 -0800
+++ b/hotspot/src/share/vm/services/heapDumper.cpp	Wed Jul 05 17:02:50 2017 +0200
@@ -1913,8 +1913,9 @@
     if (use_default_filename) {
       char fn[32];
       sprintf(fn, "java_pid%d", os::current_process_id());
-      assert(strlen(base_path) + strlen(fn) < sizeof(base_path), "HeapDumpPath too long");
+      assert(strlen(base_path) + strlen(fn) + strlen(".hprof") < sizeof(base_path), "HeapDumpPath too long");
       strcat(base_path, fn);
+      strcat(base_path, ".hprof");
     }
     assert(strlen(base_path) < sizeof(my_path), "Buffer too small");
     strcpy(my_path, base_path);
@@ -1927,8 +1928,6 @@
     strcat(my_path, fn);
   }
   dump_file_seq++;   // increment seq number for next time we dump
-  assert(strlen(".hprof") + strlen(my_path) < sizeof(my_path), "HeapDumpPath too long");
-  strcat(my_path, ".hprof");
 
   HeapDumper dumper(false /* no GC before heap dump */,
                     true  /* send to tty */);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6891750/Test6891750.java	Wed Jul 05 17:02:50 2017 +0200
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2009 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 6891750
+ * @summary deopt blob kills values in O5
+ *
+ * @run main Test6891750
+ */
+
+abstract class Base6891750 extends Thread {
+    abstract public long m();
+}
+class Other6891750 extends Base6891750 {
+    public long m() {
+        return 0;
+    }
+}
+
+public class Test6891750 extends Base6891750 {
+    Base6891750 d;
+    volatile long  value = 9;
+
+    static int limit = 400000;
+
+    Test6891750() {
+        d = this;
+
+    }
+    public long m() {
+        return value;
+    }
+
+    public long test(boolean doit) {
+        if (doit) {
+            long total0 = 0;
+            long total1 = 0;
+            long total2 = 0;
+            long total3 = 0;
+            long total4 = 0;
+            long total5 = 0;
+            long total6 = 0;
+            long total7 = 0;
+            long total8 = 0;
+            long total9 = 0;
+            for (int i = 0; i < limit; i++) {
+                total0 += d.m();
+                total1 += d.m();
+                total2 += d.m();
+                total3 += d.m();
+                total4 += d.m();
+                total5 += d.m();
+                total6 += d.m();
+                total7 += d.m();
+                total8 += d.m();
+                total9 += d.m();
+            }
+            return total0 + total1 + total2 + total3 + total4 + total5 + total6 + total7 + total8 + total9;
+        }
+        return 0;
+    }
+
+    public void run() {
+        long result = test(true);
+        for (int i = 0; i < 300; i++) {
+            long result2 = test(true);
+            if (result != result2) {
+                throw new InternalError(result + " != " + result2);
+            }
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        Test6891750 Test6891750 = new Test6891750();
+        // warm it up
+        for (int i = 0; i < 200000; i++) {
+            Test6891750.test(false);
+        }
+        // set in off running
+        Test6891750.start();
+        Thread.sleep(2000);
+
+        // Load a class to invalidate CHA
+        new Other6891750();
+    }
+}
--- a/jdk/.hgtags	Sun Nov 08 14:49:40 2009 -0800
+++ b/jdk/.hgtags	Wed Jul 05 17:02:50 2017 +0200
@@ -49,3 +49,4 @@
 460639b036f327282832a4fe52b7aa45688afd50 jdk7-b72
 f708138c9aca4b389872838fe6773872fce3609e jdk7-b73
 eacb36e30327e7ae33baa068e82ddccbd91eaae2 jdk7-b74
+8885b22565077236a927e824ef450742e434a230 jdk7-b75
--- a/jdk/make/common/Defs-linux.gmk	Sun Nov 08 14:49:40 2009 -0800
+++ b/jdk/make/common/Defs-linux.gmk	Wed Jul 05 17:02:50 2017 +0200
@@ -116,8 +116,16 @@
 LDFLAGS_COMMON_sparcv9  += -m64 -mcpu=v9
 CFLAGS_REQUIRED_sparc   += -m32 -mcpu=v9
 LDFLAGS_COMMON_sparc    += -m32 -mcpu=v9
-CFLAGS_REQUIRED         =  $(CFLAGS_REQUIRED_$(ARCH))
-LDFLAGS_COMMON          += $(LDFLAGS_COMMON_$(ARCH))
+ifeq ($(ZERO_BUILD), true)
+  CFLAGS_REQUIRED       =  $(ZERO_ARCHFLAG)
+  ifeq ($(ZERO_ENDIANNESS), little)
+    CFLAGS_REQUIRED     += -D_LITTLE_ENDIAN
+  endif
+  LDFLAGS_COMMON        += $(ZERO_ARCHFLAG)
+else
+  CFLAGS_REQUIRED       =  $(CFLAGS_REQUIRED_$(ARCH))
+  LDFLAGS_COMMON        += $(LDFLAGS_COMMON_$(ARCH))
+endif
 
 # If this is a --hash-style=gnu system, use --hash-style=both
 #   The gnu .hash section won't work on some Linux systems like SuSE 10.
@@ -217,7 +225,7 @@
 
 EXTRA_LIBS += -lc
 
-LDFLAGS_DEFS_OPTION  = -z defs
+LDFLAGS_DEFS_OPTION  = -Xlinker -z -Xlinker defs
 LDFLAGS_COMMON  += $(LDFLAGS_DEFS_OPTION)
 
 #
--- a/jdk/make/common/Defs.gmk	Sun Nov 08 14:49:40 2009 -0800
+++ b/jdk/make/common/Defs.gmk	Wed Jul 05 17:02:50 2017 +0200
@@ -667,12 +667,7 @@
 LINTFLAGS       = $(LINTFLAGS_$(VARIANT)) $(LINTFLAGS_COMMON) \
 		  $(OTHER_LINTFLAGS)
 
-# this should be moved into Defs-<platform>.gmk.....
-ifeq ($(PLATFORM), windows)
-  VERSION_DEFINES = -DRELEASE="\"$(RELEASE)\""
-else
-  VERSION_DEFINES = -DRELEASE='"$(RELEASE)"'
-endif
+VERSION_DEFINES = -DRELEASE='"$(RELEASE)"'
 
 # Note: As a rule, GNU Make rules should not appear in any of the 
 # Defs*.gmk files. These were added for Kestrel-Solaris and do address
--- a/jdk/make/common/Program.gmk	Sun Nov 08 14:49:40 2009 -0800
+++ b/jdk/make/common/Program.gmk	Wed Jul 05 17:02:50 2017 +0200
@@ -85,7 +85,7 @@
 	endif
     endif
     ifeq ($(PLATFORM), linux)
-	LDFLAGS += -z origin
+	LDFLAGS += -Wl,-z -Wl,origin
 	LDFLAGS += -Wl,--allow-shlib-undefined
 	LDFLAGS += -Wl,-rpath -Wl,\$$ORIGIN/../lib/$(LIBARCH)/jli
 	LDFLAGS += -Wl,-rpath -Wl,\$$ORIGIN/../jre/lib/$(LIBARCH)/jli
@@ -236,13 +236,13 @@
 endif # INCREMENTAL_BUILD
 
 ifdef JAVA_ARGS
-OTHER_CPPFLAGS += -DJAVA_ARGS=$(JAVA_ARGS)
-OTHER_CPPFLAGS += -DLAUNCHER_NAME=\"$(LAUNCHER_NAME)\"
+OTHER_CPPFLAGS += -DJAVA_ARGS='$(JAVA_ARGS)'
+OTHER_CPPFLAGS += -DLAUNCHER_NAME='"$(LAUNCHER_NAME)"'
 endif
 
 ifeq ($(PLATFORM), windows)
 ifdef RELEASE
-OTHER_CPPFLAGS += -DVERSION="$(RELEASE)"
+OTHER_CPPFLAGS += -DVERSION='"$(RELEASE)"'
 endif
 endif
 
@@ -258,14 +258,8 @@
 OTHER_INCLUDES += -I$(LAUNCHER_SHARE_SRC)/bin -I$(LAUNCHER_PLATFORM_SRC)/bin
 OTHER_INCLUDES += -I$(SHARE_SRC)/native/java/util/zip/zlib-1.1.3
 
-# this may not be necessary...
-ifeq ($(PLATFORM), windows)
-OTHER_CPPFLAGS += -DPROGNAME="\"$(PROGRAM)\""
-VERSION_DEFINES += -DFULL_VERSION="\"$(FULL_VERSION)\""
-else
 OTHER_CPPFLAGS += -DPROGNAME='"$(PROGRAM)"'
 VERSION_DEFINES += -DFULL_VERSION='"$(FULL_VERSION)"'
-endif
 
 VERSION_DEFINES += -DJDK_MAJOR_VERSION='"$(JDK_MAJOR_VERSION)"' \
 		   -DJDK_MINOR_VERSION='"$(JDK_MINOR_VERSION)"'
@@ -279,8 +273,14 @@
 
 #
 # How to install jvm.cfg. 
-# 
-$(JVMCFG): $(LAUNCHER_PLATFORM_SRC)/bin/$(ARCH)/jvm.cfg 
+#
+ifeq ($(ZERO_BUILD), true)
+JVMCFG_ARCH = zero
+else
+JVMCFG_ARCH = $(ARCH)
+endif
+
+$(JVMCFG): $(LAUNCHER_PLATFORM_SRC)/bin/$(JVMCFG_ARCH)/jvm.cfg 
 	$(install-file)
 
 #
--- a/jdk/make/common/Release.gmk	Sun Nov 08 14:49:40 2009 -0800
+++ b/jdk/make/common/Release.gmk	Wed Jul 05 17:02:50 2017 +0200
@@ -330,7 +330,7 @@
 #
 # Specific files and directories that will be filtered out from above areas.
 #
-SOURCE_FILTERs = $(SCM_DIRs) 'X-*' '*-X-*' '*-template.java' ',*'
+SOURCE_FILTERs = $(SCM_DIRs) ',*'
 SOURCE_FILES_filter = $(SOURCE_FILTERs:%=-name % -prune -o)
 
 #
--- a/jdk/make/common/Rules.gmk	Sun Nov 08 14:49:40 2009 -0800
+++ b/jdk/make/common/Rules.gmk	Wed Jul 05 17:02:50 2017 +0200
@@ -63,7 +63,7 @@
 # If AUTO_FILES_PROPERTIES_DIRS used, automatically find properties files
 #
 ifdef AUTO_FILES_PROPERTIES_DIRS
-  AUTO_FILES_PROPERTIES_FILTERS1  = $(SCM_DIRs) 'X-*' '*-X-*' ',*'
+  AUTO_FILES_PROPERTIES_FILTERS1  = $(SCM_DIRs) ',*'
   AUTO_FILES_PROPERTIES_FILTERS1 += $(AUTO_PROPERTIES_PRUNE)
   FILES_properties_find_filters1 = $(AUTO_FILES_PROPERTIES_FILTERS1:%=-name % -prune -o)
   FILES_properties_auto1 := \
@@ -111,7 +111,7 @@
 
 ifdef AUTO_FILES_JAVA_DIRS
   # Filter out these files or directories
-  AUTO_FILES_JAVA_SOURCE_FILTERS1  = $(SCM_DIRs) 'X-*' '*-X-*' '*-template.java' ',*'
+  AUTO_FILES_JAVA_SOURCE_FILTERS1  = $(SCM_DIRs) ',*'
   AUTO_FILES_JAVA_SOURCE_FILTERS2  = 
   AUTO_FILES_JAVA_SOURCE_FILTERS1 += $(AUTO_JAVA_PRUNE)
   AUTO_FILES_JAVA_SOURCE_FILTERS2 += $(AUTO_JAVA_PRUNE)
--- a/jdk/make/java/instrument/Makefile	Sun Nov 08 14:49:40 2009 -0800
+++ b/jdk/make/java/instrument/Makefile	Wed Jul 05 17:02:50 2017 +0200
@@ -109,7 +109,7 @@
     LDFLAGS += -R \$$ORIGIN/jli
   endif
   ifeq ($(PLATFORM), linux)
-    LDFLAGS += -z origin
+    LDFLAGS += -Wl,-z -Wl,origin
     LDFLAGS += -Wl,--allow-shlib-undefined
     LDFLAGS += -Wl,-rpath -Wl,\$$ORIGIN/jli
   endif
--- a/jdk/make/java/java/FILES_java.gmk	Sun Nov 08 14:49:40 2009 -0800
+++ b/jdk/make/java/java/FILES_java.gmk	Wed Jul 05 17:02:50 2017 +0200
@@ -286,11 +286,18 @@
     java/util/concurrent/ExecutorService.java \
     java/util/concurrent/ExecutorCompletionService.java \
     java/util/concurrent/Executors.java \
+    java/util/concurrent/ForkJoinPool.java \
+    java/util/concurrent/ForkJoinTask.java \
+    java/util/concurrent/ForkJoinWorkerThread.java \
     java/util/concurrent/Future.java \
     java/util/concurrent/FutureTask.java \
     java/util/concurrent/LinkedBlockingDeque.java \
     java/util/concurrent/LinkedBlockingQueue.java \
+    java/util/concurrent/LinkedTransferQueue.java \
+    java/util/concurrent/Phaser.java \
     java/util/concurrent/PriorityBlockingQueue.java \
+    java/util/concurrent/RecursiveAction.java \
+    java/util/concurrent/RecursiveTask.java \
     java/util/concurrent/RejectedExecutionException.java \
     java/util/concurrent/RejectedExecutionHandler.java \
     java/util/concurrent/RunnableFuture.java \
@@ -301,9 +308,11 @@
     java/util/concurrent/Semaphore.java \
     java/util/concurrent/SynchronousQueue.java \
     java/util/concurrent/ThreadFactory.java \
+    java/util/concurrent/ThreadLocalRandom.java \
     java/util/concurrent/ThreadPoolExecutor.java \
     java/util/concurrent/TimeUnit.java \
     java/util/concurrent/TimeoutException.java \
+    java/util/concurrent/TransferQueue.java \
     java/util/concurrent/atomic/AtomicBoolean.java \
     java/util/concurrent/atomic/AtomicInteger.java \
     java/util/concurrent/atomic/AtomicIntegerArray.java \
--- a/jdk/make/java/jli/Makefile	Sun Nov 08 14:49:40 2009 -0800
+++ b/jdk/make/java/jli/Makefile	Wed Jul 05 17:02:50 2017 +0200
@@ -48,11 +48,15 @@
 LAUNCHER_SHARE_SRC = $(SHARE_SRC)/bin
 LAUNCHER_PLATFORM_SRC = $(PLATFORM_SRC)/bin
 
+ifeq ($(ZERO_BUILD), true)
+ERGO_FAMILY=zero
+else
 ifeq ($(ARCH_FAMILY), amd64)
 ERGO_FAMILY=i586
 else
 ERGO_FAMILY=$(ARCH_FAMILY)
 endif
+endif
 
 
 #
--- a/jdk/make/java/main/java/Makefile	Sun Nov 08 14:49:40 2009 -0800
+++ b/jdk/make/java/main/java/Makefile	Wed Jul 05 17:02:50 2017 +0200
@@ -57,7 +57,7 @@
 #
 include $(BUILDDIR)/common/Program.gmk
 OTHER_CPPFLAGS += -DEXPAND_CLASSPATH_WILDCARDS
-OTHER_CPPFLAGS += -DLAUNCHER_NAME=\"$(LAUNCHER_NAME)\"
+OTHER_CPPFLAGS += -DLAUNCHER_NAME='"$(LAUNCHER_NAME)"'
 
 ifeq ($(PLATFORM), solaris)
 LDFLAGS += -R$(OPENWIN_LIB)
--- a/jdk/make/java/main/javaw/Makefile	Sun Nov 08 14:49:40 2009 -0800
+++ b/jdk/make/java/main/javaw/Makefile	Wed Jul 05 17:02:50 2017 +0200
@@ -62,4 +62,5 @@
 #
 include $(BUILDDIR)/common/Program.gmk
 OTHER_CPPFLAGS += -DEXPAND_CLASSPATH_WILDCARDS
-OTHER_CPPFLAGS += -DLAUNCHER_NAME=\"$(LAUNCHER_NAME)\"
+OTHER_CPPFLAGS += -DLAUNCHER_NAME='"$(LAUNCHER_NAME)"'
+
--- a/jdk/make/java/nio/Makefile	Sun Nov 08 14:49:40 2009 -0800
+++ b/jdk/make/java/nio/Makefile	Wed Jul 05 17:02:50 2017 +0200
@@ -335,6 +335,15 @@
 SCS_SRC=$(SNIO_SRC)/cs
 SFS_SRC=$(SNIO_SRC)/fs
 
+# Template files
+HEAP_X_BUF_TEMPLATE=$(BUF_SRC)/Heap-X-Buffer.java.template
+BYTE_X_BUF_TEMPLATE=$(BUF_SRC)/ByteBufferAs-X-Buffer.java.template
+X_BUF_TEMPLATE=$(BUF_SRC)/X-Buffer.java.template
+X_BUF_BIN_TEMPLATE=$(BUF_SRC)/X-Buffer-bin.java.template
+DIRECT_X_BUF_TEMPLATE=$(BUF_SRC)/Direct-X-Buffer.java.template
+DIRECT_X_BUF_BIN_TEMPLATE=$(BUF_SRC)/Direct-X-Buffer-bin.java.template
+CHARSET_X_CODER_TEMPLATE=$(CS_SRC)/Charset-X-Coder.java.template
+
 BUF_GEN=$(NIO_GEN)
 CH_GEN=$(NIO_GEN)/channels
 CS_GEN=$(NIO_GEN)/charset
@@ -357,39 +366,39 @@
 
 # Public abstract buffer classes
 #
-$(BUF_GEN)/ByteBuffer.java: $(BUF_SRC)/X-Buffer.java \
-			    $(BUF_SRC)/X-Buffer-bin.java \
+$(BUF_GEN)/ByteBuffer.java: $(X_BUF_TEMPLATE) \
+			    $(X_BUF_BIN_TEMPLATE) \
 			    $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=byte BIN=1 SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/CharBuffer.java: $(BUF_SRC)/X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/CharBuffer.java: $(X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=char SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/ShortBuffer.java: $(BUF_SRC)/X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/ShortBuffer.java: $(X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=short SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/IntBuffer.java: $(BUF_SRC)/X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/IntBuffer.java: $(X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=int SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/LongBuffer.java: $(BUF_SRC)/X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/LongBuffer.java: $(X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=long SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/FloatBuffer.java: $(BUF_SRC)/X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/FloatBuffer.java: $(X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=float SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/DoubleBuffer.java: $(BUF_SRC)/X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/DoubleBuffer.java: $(X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=double SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
@@ -397,72 +406,72 @@
 
 # Buffers whose contents are heap-allocated
 # 
-$(BUF_GEN)/HeapByteBuffer.java: $(BUF_SRC)/Heap-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/HeapByteBuffer.java: $(HEAP_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=byte SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/HeapByteBuffer%.java: $(BUF_SRC)/Heap-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/HeapByteBuffer%.java: $(HEAP_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=byte RW=$* SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/HeapCharBuffer.java: $(BUF_SRC)/Heap-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/HeapCharBuffer.java: $(HEAP_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=char SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/HeapCharBuffer%.java: $(BUF_SRC)/Heap-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/HeapCharBuffer%.java: $(HEAP_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=char RW=$* SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/HeapShortBuffer.java: $(BUF_SRC)/Heap-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/HeapShortBuffer.java: $(HEAP_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=short SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/HeapShortBuffer%.java: $(BUF_SRC)/Heap-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/HeapShortBuffer%.java: $(HEAP_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=short RW=$* SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/HeapIntBuffer.java: $(BUF_SRC)/Heap-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/HeapIntBuffer.java: $(HEAP_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=int SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/HeapIntBuffer%.java: $(BUF_SRC)/Heap-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/HeapIntBuffer%.java: $(HEAP_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=int RW=$* SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/HeapLongBuffer.java: $(BUF_SRC)/Heap-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/HeapLongBuffer.java: $(HEAP_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=long SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/HeapLongBuffer%.java: $(BUF_SRC)/Heap-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/HeapLongBuffer%.java: $(HEAP_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=long RW=$* SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/HeapFloatBuffer.java: $(BUF_SRC)/Heap-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/HeapFloatBuffer.java: $(HEAP_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=float SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/HeapFloatBuffer%.java: $(BUF_SRC)/Heap-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/HeapFloatBuffer%.java: $(HEAP_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=float RW=$* SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/HeapDoubleBuffer.java: $(BUF_SRC)/Heap-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/HeapDoubleBuffer.java: $(HEAP_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=double SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/HeapDoubleBuffer%.java: $(BUF_SRC)/Heap-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/HeapDoubleBuffer%.java: $(HEAP_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=double RW=$* SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
@@ -470,15 +479,15 @@
 
 # Direct byte buffer
 # 
-$(BUF_GEN)/DirectByteBuffer.java: $(BUF_SRC)/Direct-X-Buffer.java \
-				  $(BUF_SRC)/Direct-X-Buffer.java \
+$(BUF_GEN)/DirectByteBuffer.java: $(DIRECT_X_BUF_TEMPLATE) \
+				  $(DIRECT_X_BUF_TEMPLATE) \
 				  $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=byte BIN=1 SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/DirectByteBuffer%.java: $(BUF_SRC)/Direct-X-Buffer.java \
-				   $(BUF_SRC)/Direct-X-Buffer.java \
+$(BUF_GEN)/DirectByteBuffer%.java: $(DIRECT_X_BUF_TEMPLATE) \
+				   $(DIRECT_X_BUF_TEMPLATE) \
 				   $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
@@ -487,62 +496,62 @@
 
 # Unswapped views of direct byte buffers
 #
-$(BUF_GEN)/DirectCharBufferU.java: $(BUF_SRC)/Direct-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/DirectCharBufferU.java: $(DIRECT_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=char BO=U SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/DirectCharBuffer%U.java: $(BUF_SRC)/Direct-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/DirectCharBuffer%U.java: $(DIRECT_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=char RW=$* BO=U SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/DirectShortBufferU.java: $(BUF_SRC)/Direct-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/DirectShortBufferU.java: $(DIRECT_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=short BO=U SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/DirectShortBuffer%U.java: $(BUF_SRC)/Direct-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/DirectShortBuffer%U.java: $(DIRECT_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=short RW=$* BO=U SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/DirectIntBufferU.java: $(BUF_SRC)/Direct-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/DirectIntBufferU.java: $(DIRECT_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=int BO=U SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/DirectIntBuffer%U.java: $(BUF_SRC)/Direct-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/DirectIntBuffer%U.java: $(DIRECT_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=int RW=$* BO=U SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/DirectLongBufferU.java: $(BUF_SRC)/Direct-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/DirectLongBufferU.java: $(DIRECT_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=long BO=U SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/DirectLongBuffer%U.java: $(BUF_SRC)/Direct-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/DirectLongBuffer%U.java: $(DIRECT_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=long RW=$* BO=U SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/DirectFloatBufferU.java: $(BUF_SRC)/Direct-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/DirectFloatBufferU.java: $(DIRECT_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=float BO=U SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/DirectFloatBuffer%U.java: $(BUF_SRC)/Direct-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/DirectFloatBuffer%U.java: $(DIRECT_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=float RW=$* BO=U SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/DirectDoubleBufferU.java: $(BUF_SRC)/Direct-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/DirectDoubleBufferU.java: $(DIRECT_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=double BO=U SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/DirectDoubleBuffer%U.java: $(BUF_SRC)/Direct-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/DirectDoubleBuffer%U.java: $(DIRECT_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=double RW=$* BO=U SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
@@ -550,62 +559,62 @@
 
 # Swapped views of direct byte buffers
 #
-$(BUF_GEN)/DirectCharBufferS.java: $(BUF_SRC)/Direct-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/DirectCharBufferS.java: $(DIRECT_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=char BO=S SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/DirectCharBuffer%S.java: $(BUF_SRC)/Direct-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/DirectCharBuffer%S.java: $(DIRECT_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=char RW=$* BO=S SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/DirectShortBufferS.java: $(BUF_SRC)/Direct-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/DirectShortBufferS.java: $(DIRECT_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=short BO=S SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/DirectShortBuffer%S.java: $(BUF_SRC)/Direct-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/DirectShortBuffer%S.java: $(DIRECT_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=short RW=$* BO=S SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/DirectIntBufferS.java: $(BUF_SRC)/Direct-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/DirectIntBufferS.java: $(DIRECT_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=int BO=S SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/DirectIntBuffer%S.java: $(BUF_SRC)/Direct-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/DirectIntBuffer%S.java: $(DIRECT_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=int RW=$* BO=S SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/DirectLongBufferS.java: $(BUF_SRC)/Direct-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/DirectLongBufferS.java: $(DIRECT_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=long BO=S SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/DirectLongBuffer%S.java: $(BUF_SRC)/Direct-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/DirectLongBuffer%S.java: $(DIRECT_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=long RW=$* BO=S SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/DirectFloatBufferS.java: $(BUF_SRC)/Direct-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/DirectFloatBufferS.java: $(DIRECT_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=float BO=S SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/DirectFloatBuffer%S.java: $(BUF_SRC)/Direct-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/DirectFloatBuffer%S.java: $(DIRECT_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=float RW=$* BO=S SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/DirectDoubleBufferS.java: $(BUF_SRC)/Direct-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/DirectDoubleBufferS.java: $(DIRECT_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=double BO=S SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/DirectDoubleBuffer%S.java: $(BUF_SRC)/Direct-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/DirectDoubleBuffer%S.java: $(DIRECT_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=double RW=$* BO=S SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
@@ -613,62 +622,62 @@
 
 # Big-endian views of byte buffers
 #
-$(BUF_GEN)/ByteBufferAsCharBufferB.java: $(BUF_SRC)/ByteBufferAs-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/ByteBufferAsCharBufferB.java: $(BYTE_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=char BO=B SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/ByteBufferAsCharBuffer%B.java: $(BUF_SRC)/ByteBufferAs-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/ByteBufferAsCharBuffer%B.java: $(BYTE_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=char RW=$* BO=B SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/ByteBufferAsShortBufferB.java: $(BUF_SRC)/ByteBufferAs-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/ByteBufferAsShortBufferB.java: $(BYTE_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=short BO=B SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/ByteBufferAsShortBuffer%B.java: $(BUF_SRC)/ByteBufferAs-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/ByteBufferAsShortBuffer%B.java: $(BYTE_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=short RW=$* BO=B SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/ByteBufferAsIntBufferB.java: $(BUF_SRC)/ByteBufferAs-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/ByteBufferAsIntBufferB.java: $(BYTE_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=int BO=B SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/ByteBufferAsIntBuffer%B.java: $(BUF_SRC)/ByteBufferAs-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/ByteBufferAsIntBuffer%B.java: $(BYTE_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=int RW=$* BO=B SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/ByteBufferAsLongBufferB.java: $(BUF_SRC)/ByteBufferAs-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/ByteBufferAsLongBufferB.java: $(BYTE_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=long BO=B SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/ByteBufferAsLongBuffer%B.java: $(BUF_SRC)/ByteBufferAs-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/ByteBufferAsLongBuffer%B.java: $(BYTE_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=long RW=$* BO=B SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/ByteBufferAsFloatBufferB.java: $(BUF_SRC)/ByteBufferAs-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/ByteBufferAsFloatBufferB.java: $(BYTE_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=float BO=B SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/ByteBufferAsFloatBuffer%B.java: $(BUF_SRC)/ByteBufferAs-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/ByteBufferAsFloatBuffer%B.java: $(BYTE_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=float RW=$* BO=B SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/ByteBufferAsDoubleBufferB.java: $(BUF_SRC)/ByteBufferAs-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/ByteBufferAsDoubleBufferB.java: $(BYTE_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=double BO=B SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/ByteBufferAsDoubleBuffer%B.java: $(BUF_SRC)/ByteBufferAs-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/ByteBufferAsDoubleBuffer%B.java: $(BYTE_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=double RW=$* BO=B SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
@@ -676,62 +685,62 @@
 
 # Little-endian views of byte buffers
 #
-$(BUF_GEN)/ByteBufferAsCharBufferL.java: $(BUF_SRC)/ByteBufferAs-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/ByteBufferAsCharBufferL.java: $(BYTE_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=char BO=L SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/ByteBufferAsCharBuffer%L.java: $(BUF_SRC)/ByteBufferAs-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/ByteBufferAsCharBuffer%L.java: $(BYTE_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=char RW=$* BO=L SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/ByteBufferAsShortBufferL.java: $(BUF_SRC)/ByteBufferAs-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/ByteBufferAsShortBufferL.java: $(BYTE_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=short BO=L SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/ByteBufferAsShortBuffer%L.java: $(BUF_SRC)/ByteBufferAs-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/ByteBufferAsShortBuffer%L.java: $(BYTE_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=short RW=$* BO=L SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/ByteBufferAsIntBufferL.java: $(BUF_SRC)/ByteBufferAs-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/ByteBufferAsIntBufferL.java: $(BYTE_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=int BO=L SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/ByteBufferAsIntBuffer%L.java: $(BUF_SRC)/ByteBufferAs-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/ByteBufferAsIntBuffer%L.java: $(BYTE_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=int RW=$* BO=L SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/ByteBufferAsLongBufferL.java: $(BUF_SRC)/ByteBufferAs-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/ByteBufferAsLongBufferL.java: $(BYTE_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=long BO=L SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/ByteBufferAsLongBuffer%L.java: $(BUF_SRC)/ByteBufferAs-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/ByteBufferAsLongBuffer%L.java: $(BYTE_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=long RW=$* BO=L SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/ByteBufferAsFloatBufferL.java: $(BUF_SRC)/ByteBufferAs-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/ByteBufferAsFloatBufferL.java: $(BYTE_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=float BO=L SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/ByteBufferAsFloatBuffer%L.java: $(BUF_SRC)/ByteBufferAs-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/ByteBufferAsFloatBuffer%L.java: $(BYTE_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=float RW=$* BO=L SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/ByteBufferAsDoubleBufferL.java: $(BUF_SRC)/ByteBufferAs-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/ByteBufferAsDoubleBufferL.java: $(BYTE_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=double BO=L SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
 	$(MV) $@.temp $@
-$(BUF_GEN)/ByteBufferAsDoubleBuffer%L.java: $(BUF_SRC)/ByteBufferAs-X-Buffer.java $(GEN_BUFFER_SH)
+$(BUF_GEN)/ByteBufferAsDoubleBuffer%L.java: $(BYTE_X_BUF_TEMPLATE) $(GEN_BUFFER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	TYPE=double RW=$* BO=L SRC=$< DST=$@.temp $(GEN_BUFFER_CMD)
@@ -745,13 +754,13 @@
 
 GEN_CODER_CMD = SPP="$(SPP_CMD)" SED="$(SED)" NAWK="$(NAWK)" SH="$(SH)" $(SH) $(GEN_CODER_SH)
 
-$(CS_GEN)/CharsetDecoder.java: $(CS_SRC)/Charset-X-Coder.java $(GEN_CODER_SH)
+$(CS_GEN)/CharsetDecoder.java: $(CHARSET_X_CODER_TEMPLATE) $(GEN_CODER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	$(GEN_CODER_CMD) decoder $< $@.temp
 	$(MV) $@.temp $@
 
-$(CS_GEN)/CharsetEncoder.java: $(CS_SRC)/Charset-X-Coder.java $(GEN_CODER_SH)
+$(CS_GEN)/CharsetEncoder.java: $(CHARSET_X_CODER_TEMPLATE) $(GEN_CODER_SH)
 	$(prep-target)
 	@$(RM) $@.temp
 	$(GEN_CODER_CMD) encoder $< $@.temp
--- a/jdk/make/java/nio/genBuffer.sh	Sun Nov 08 14:49:40 2009 -0800
+++ b/jdk/make/java/nio/genBuffer.sh	Wed Jul 05 17:02:50 2017 +0200
@@ -154,7 +154,7 @@
   mv $DST $DST.tmp
   sed -e '/#BIN/,$d' <$DST.tmp >$DST
   rm -f $DST.tmp
-  binops=`dirname $SRC`/`basename $SRC .java`-bin.java
+  binops=`dirname $SRC`/`basename $SRC .java.template`-bin.java.template
   genBinOps char character 1 two one $binops >>$DST
   genBinOps short short 1 two one $binops >>$DST
   genBinOps int integer 2 four three $binops >>$DST
--- a/jdk/make/java/redist/Makefile	Sun Nov 08 14:49:40 2009 -0800
+++ b/jdk/make/java/redist/Makefile	Wed Jul 05 17:02:50 2017 +0200
@@ -94,11 +94,13 @@
   endif
 endif # INCLUDE_SA
 
-# Hotspot client is only available on 32-bit builds
+# Hotspot client is only available on 32-bit non-Zero builds
+ifneq ($(ZERO_BUILD), true)
 ifeq ($(ARCH_DATA_MODEL), 32)
   IMPORT_LIST += $(LIB_LOCATION)/$(CLIENT_LOCATION)/$(JVM_NAME) \
                  $(LIB_LOCATION)/$(CLIENT_LOCATION)/Xusage.txt
 endif
+endif
 
 ifeq ($(PLATFORM), windows)
 #  Windows     vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv  Windows
@@ -171,6 +173,7 @@
   IMPORT_LIST += $(LIB_LOCATION)/$(SERVER_LOCATION)/$(JVMDB_NAME)
 endif 
 
+ifneq ($(ZERO_BUILD), true)
 ifeq ($(ARCH_DATA_MODEL), 32)
 
 IMPORT_LIST += $(LIB_LOCATION)/$(CLIENT_LOCATION)/$(LIBJSIG_NAME)
@@ -201,6 +204,8 @@
 
 endif # 32bit
 
+endif # ZERO_BUILD
+
 #  NOT Windows ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ NOT Windows
 
 endif # PLATFORM
--- a/jdk/make/java/version/Makefile	Sun Nov 08 14:49:40 2009 -0800
+++ b/jdk/make/java/version/Makefile	Wed Jul 05 17:02:50 2017 +0200
@@ -33,7 +33,7 @@
 all build: $(GENSRCDIR)/sun/misc/Version.java
 
 $(GENSRCDIR)/sun/misc/Version.java: \
-		$(SHARE_SRC)/classes/sun/misc/Version-template.java
+		$(SHARE_SRC)/classes/sun/misc/Version.java.template
 	$(prep-target)
 	$(RM) $@.temp
 	$(SED) -e 's/@@launcher_name@@/$(LAUNCHER_NAME)/g' \
--- a/jdk/make/javax/sound/Makefile	Sun Nov 08 14:49:40 2009 -0800
+++ b/jdk/make/javax/sound/Makefile	Wed Jul 05 17:02:50 2017 +0200
@@ -128,7 +128,7 @@
 
 # for dynamic inclusion of extra sound libs: these
 # JNI libs will be loaded from Platform.java
-CPPFLAGS += -DEXTRA_SOUND_JNI_LIBS="\"$(EXTRA_SOUND_JNI_LIBS)\""
+CPPFLAGS += -DEXTRA_SOUND_JNI_LIBS='"$(EXTRA_SOUND_JNI_LIBS)"'
 
 # integrate MIDI i/o in jsound lib
 ifeq ($(INCLUDE_MIDI),TRUE)
--- a/jdk/make/javax/sound/SoundDefs.gmk	Sun Nov 08 14:49:40 2009 -0800
+++ b/jdk/make/javax/sound/SoundDefs.gmk	Wed Jul 05 17:02:50 2017 +0200
@@ -55,21 +55,25 @@
 
 endif # PLATFORM solaris
 
-ifeq ($(ARCH), i586)
-  CPPFLAGS += -DX_ARCH=X_I586
-endif # ARCH i586
+ifeq ($(ZERO_BUILD), true)
+  CPPFLAGS += -DX_ARCH=X_ZERO
+else
+  ifeq ($(ARCH), i586)
+    CPPFLAGS += -DX_ARCH=X_I586
+  endif # ARCH i586
 
-ifeq ($(ARCH), sparc)
-  CPPFLAGS += -DX_ARCH=X_SPARC
-endif # ARCH sparc
+  ifeq ($(ARCH), sparc)
+    CPPFLAGS += -DX_ARCH=X_SPARC
+  endif # ARCH sparc
 
-ifeq ($(ARCH), sparcv9)
-  CPPFLAGS += -DX_ARCH=X_SPARCV9
-endif # ARCH sparcv9
+  ifeq ($(ARCH), sparcv9)
+    CPPFLAGS += -DX_ARCH=X_SPARCV9
+  endif # ARCH sparcv9
 
-ifeq ($(ARCH), amd64)
-  CPPFLAGS += -DX_ARCH=X_AMD64
-endif # ARCH amd64
+  ifeq ($(ARCH), amd64)
+    CPPFLAGS += -DX_ARCH=X_AMD64
+  endif # ARCH amd64
+endif
 
 
 # files needed for MIDI i/o
--- a/jdk/make/jdk_generic_profile.sh	Sun Nov 08 14:49:40 2009 -0800
+++ b/jdk/make/jdk_generic_profile.sh	Wed Jul 05 17:02:50 2017 +0200
@@ -339,3 +339,82 @@
 PATH="${path4sdk}"
 export PATH
 
+# Export variables required for Zero
+if [ "${ZERO_BUILD}" = true ] ; then
+  # ZERO_LIBARCH is the name of the architecture-specific
+  # subdirectory under $JAVA_HOME/jre/lib
+  arch=$(uname -m)
+  case "${arch}" in
+    x86_64)  ZERO_LIBARCH=amd64     ;;
+    i?86)    ZERO_LIBARCH=i386      ;;
+    sparc64) ZERO_LIBARCH=sparcv9   ;;
+    arm*)    ZERO_LIBARCH=arm       ;;
+    *)       ZERO_LIBARCH="$(arch)"
+  esac
+  export ZERO_LIBARCH
+
+  # ARCH_DATA_MODEL is the number of bits in a pointer
+  case "${ZERO_LIBARCH}" in
+    i386|ppc|s390|sparc|arm)
+      ARCH_DATA_MODEL=32
+      ;;
+    amd64|ppc64|s390x|sparcv9|ia64|alpha)
+      ARCH_DATA_MODEL=64
+      ;;
+    *)
+      echo "ERROR: Unable to determine ARCH_DATA_MODEL for ${ZERO_LIBARCH}"
+      exit 1
+  esac
+  export ARCH_DATA_MODEL
+
+  # ZERO_ENDIANNESS is the endianness of the processor
+  case "${ZERO_LIBARCH}" in
+    i386|amd64|ia64)
+      ZERO_ENDIANNESS=little
+      ;;
+    ppc*|s390*|sparc*|alpha)
+      ZERO_ENDIANNESS=big
+      ;;
+    *)
+      echo "ERROR: Unable to determine ZERO_ENDIANNESS for ${ZERO_LIBARCH}"
+      exit 1
+  esac
+  export ZERO_ENDIANNESS
+
+  # ZERO_ARCHDEF is used to enable architecture-specific code
+  case "${ZERO_LIBARCH}" in
+    i386)   ZERO_ARCHDEF=IA32  ;;
+    ppc*)   ZERO_ARCHDEF=PPC   ;;
+    s390*)  ZERO_ARCHDEF=S390  ;;
+    sparc*) ZERO_ARCHDEF=SPARC ;;
+    *)      ZERO_ARCHDEF=$(echo "${ZERO_LIBARCH}" | tr a-z A-Z)
+  esac
+  export ZERO_ARCHDEF
+
+  # ZERO_ARCHFLAG tells the compiler which mode to build for
+  case "${ZERO_LIBARCH}" in
+    s390)
+      ZERO_ARCHFLAG="-m31"
+      ;;
+    *)
+      ZERO_ARCHFLAG="-m${ARCH_DATA_MODEL}"
+  esac
+  export ZERO_ARCHFLAG
+
+  # LIBFFI_CFLAGS and LIBFFI_LIBS tell the compiler how to compile and
+  # link against libffi
+  pkgconfig=$(which pkg-config 2>/dev/null)
+  if [ -x "${pkgconfig}" ] ; then
+    if [ "${LIBFFI_CFLAGS}" = "" ] ; then
+      LIBFFI_CFLAGS=$("${pkgconfig}" --cflags libffi)
+    fi
+    if [ "${LIBFFI_LIBS}" = "" ] ; then
+      LIBFFI_LIBS=$("${pkgconfig}" --libs libffi)
+    fi
+  fi
+  if [ "${LIBFFI_LIBS}" = "" ] ; then
+      LIBFFI_LIBS="-lffi"
+  fi
+  export LIBFFI_CFLAGS
+  export LIBFFI_LIBS
+fi
--- a/jdk/make/launchers/Makefile.launcher	Sun Nov 08 14:49:40 2009 -0800
+++ b/jdk/make/launchers/Makefile.launcher	Wed Jul 05 17:02:50 2017 +0200
@@ -137,15 +137,15 @@
   #   PROGRAM, JAVA_ARGS, and APP_CLASSPATH are used in src/share/bin/java.c
   #   SA is currently not available on windows (for any ARCH), or linux-ia64:
   ifneq ($(ARCH), ia64)
-    JDB_CLASSPATH = "{ \"/lib/tools.jar\", \"/lib/sa-jdi.jar\", \"/classes\" }"
-    OTHER_CPPFLAGS += -DAPP_CLASSPATH=$(JDB_CLASSPATH)
+    JDB_CLASSPATH = { "/lib/tools.jar", "/lib/sa-jdi.jar", "/classes" }
+    OTHER_CPPFLAGS += -DAPP_CLASSPATH='$(JDB_CLASSPATH)'
   endif
 endif
 
 # jconsole only
 ifeq ($(PROGRAM),jconsole)
-  JCONSOLE_CLASSPATH = "{ \"/lib/jconsole.jar\", \"/lib/tools.jar\", \"/classes\" }"
-  OTHER_CPPFLAGS += -DAPP_CLASSPATH=$(JCONSOLE_CLASSPATH)
+  JCONSOLE_CLASSPATH = { "/lib/jconsole.jar", "/lib/tools.jar", "/classes" }
+  OTHER_CPPFLAGS += -DAPP_CLASSPATH='$(JCONSOLE_CLASSPATH)'
   ifeq ($(PLATFORM), windows)
     OTHER_CPPFLAGS += -DJAVAW
     LDLIBS_COMMON  += user32.lib
@@ -163,8 +163,8 @@
 
 # SA tools need special app classpath
 ifeq ($(SA_TOOL),true)
-  SA_CLASSPATH = "{ \"/lib/tools.jar\", \"/lib/sa-jdi.jar\", \"/classes\"}"
-  OTHER_CPPFLAGS += -DAPP_CLASSPATH=$(SA_CLASSPATH)
+  SA_CLASSPATH = { "/lib/tools.jar", "/lib/sa-jdi.jar", "/classes" }
+  OTHER_CPPFLAGS += -DAPP_CLASSPATH='$(SA_CLASSPATH)'
 endif
 
 # Wildcards
@@ -173,11 +173,11 @@
 endif
 
 # Always tell native code what the main class is
-OTHER_CPPFLAGS += -DMAIN_CLASS=\"$(MAIN_CLASS)\"
+OTHER_CPPFLAGS += -DMAIN_CLASS='"$(MAIN_CLASS)"'
 
 # Construct initializer for initial arguments to java
 ALL_ARGS = -J-ms8m $(MAIN_JAVA_ARGS) $(MAIN_CLASS) $(MAIN_ARGS)
-JAVA_ARGS = "{ $(ALL_ARGS:%=\"%\",)  }"
+JAVA_ARGS = { $(ALL_ARGS:%="%",)  }
 
 # Always report launcher info
 build: launcher_info
--- a/jdk/make/netbeans/jconsole/build.properties	Sun Nov 08 14:49:40 2009 -0800
+++ b/jdk/make/netbeans/jconsole/build.properties	Wed Jul 05 17:02:50 2017 +0200
@@ -33,7 +33,7 @@
     com/sun/tools/jconsole/ \
     sun/tools/jconsole/
 excludes=\
-    sun/tools/jconsole/Version-template.java
+    sun/tools/jconsole/Version.java.template
 jtreg.tests=\
     sun/tools/jconsole/
 javadoc.packagenames=\
--- a/jdk/make/netbeans/jconsole/build.xml	Sun Nov 08 14:49:40 2009 -0800
+++ b/jdk/make/netbeans/jconsole/build.xml	Wed Jul 05 17:02:50 2017 +0200
@@ -35,7 +35,7 @@
 
     <target name="-pre-compile">
         <copy
-            file="${root}/src/share/classes/sun/tools/jconsole/Version-template.java"
+            file="${root}/src/share/classes/sun/tools/jconsole/Version.java.template"
             tofile="${gensrc.dir}/sun/tools/jconsole/Version.java"/>
         <replace
             file="${gensrc.dir}/sun/tools/jconsole/Version.java"
--- a/jdk/make/sun/jconsole/Makefile	Sun Nov 08 14:49:40 2009 -0800
+++ b/jdk/make/sun/jconsole/Makefile	Wed Jul 05 17:02:50 2017 +0200
@@ -70,7 +70,7 @@
 build: $(FILES_png) $(FILES_gif) $(TEMPDIR)/manifest $(JARFILE)
 
 $(GENSRCDIR)/sun/tools/jconsole/Version.java: \
-                $(SHARE_SRC)/classes/sun/tools/jconsole/Version-template.java
+                $(SHARE_SRC)/classes/sun/tools/jconsole/Version.java.template
 	$(MKDIR) -p $(@D)
 	$(SED) -e 's/@@jconsole_version@@/$(FULL_VERSION)/g' $< > $@
 
--- a/jdk/make/sun/nio/Makefile	Sun Nov 08 14:49:40 2009 -0800
+++ b/jdk/make/sun/nio/Makefile	Wed Jul 05 17:02:50 2017 +0200
@@ -44,14 +44,6 @@
 include FILES_java.gmk
 AUTO_FILES_JAVA_DIRS = sun/nio/cs/ext
 
-# Exclude a few sources on windows
-ifeq ($(PLATFORM), windows)
-  AUTO_JAVA_PRUNE = sun/nio/cs/ext/COMPOUND_TEXT.java         \
-                    sun/nio/cs/ext/COMPOUND_TEXT_Decoder.java \
-                    sun/nio/cs/ext/COMPOUND_TEXT_Encoder.java \
-                    sun/nio/cs/ext/CompoundTextSupport.java
-endif # PLATFORM
-
 # For Cygwin, command line arguments that are paths must be converted to
 # windows style paths. These paths cannot be used as targets, however, because 
 # the ":" in them  will interfere with GNU Make rules, generating "multiple
--- a/jdk/make/tools/Makefile	Sun Nov 08 14:49:40 2009 -0800
+++ b/jdk/make/tools/Makefile	Wed Jul 05 17:02:50 2017 +0200
@@ -38,7 +38,6 @@
   compile_properties        \
   dir_diff                  \
   dtdbuilder                \
-  fontchecker               \
   freetypecheck             \
   generate_break_iterator   \
   GenerateCharacter         \
--- a/jdk/make/tools/fontchecker/Makefile	Sun Nov 08 14:49:40 2009 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-#
-# Copyright 1998-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.  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.
-#
-
-#
-# Makefile for building the fontchecker tool
-#
-
-BUILDDIR = ../..
-PACKAGE = build.tools.fontchecker
-PRODUCT = tools
-PROGRAM = fontchecker
-include $(BUILDDIR)/common/Defs.gmk
-
-BUILDTOOL_SOURCE_ROOT = $(BUILDDIR)/tools/src
-BUILDTOOL_MAIN        = $(PKGDIR)/FontChecker.java
-
-#
-# Build tool jar rules.
-#
-include $(BUILDDIR)/common/BuildToolJar.gmk
-
--- a/jdk/make/tools/src/build/tools/fontchecker/FontCheckDummy.java	Sun Nov 08 14:49:40 2009 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,175 +0,0 @@
-/*
- * Copyright 2002-2004 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 build.tools.fontchecker;
-
-import java.awt.*;
-import java.awt.image.*;
-import java.io.*;
-
-/**
- * FontCheckDummy (not unlike Crash Test Dummy).
- *
- * <PRE>
- * FontCheckDummy is the "child" process. Its task is to verify
- * integrity of system fonts. Since unexpected crashes are known
- * to occur when certain fonts are manipulated, the process is
- * "monitored" by the parent process, which might have to restart
- * the "child" if it crashes.
- * </PRE>
- *
- * @author Ilya Bagrak
- */
-public class FontCheckDummy implements FontCheckerConstants {
-
-    /**
-     * Input stream from parent process.
-     */
-    private BufferedReader is;
-
-    /**
-     * Output stream to parent process.
-     */
-    private BufferedOutputStream os;
-
-    /**
-     * Image on which font characters will be drawn.
-     */
-    private BufferedImage bi;
-
-    /**
-     * graphics object on which characters will be drawn.
-     */
-    private Graphics graphics;
-
-    /**
-     * This constructor wraps the process's standard output and input streams
-     * to enable easier communication with parent process. It also initializes
-     * the graphics object used for drawing font characters.
-     * <BR><BR>
-     * @see FontCheckerConstants
-     */
-    public FontCheckDummy() {
-        is = new BufferedReader(new InputStreamReader(System.in));
-        os = new BufferedOutputStream(System.out);
-        /* make suffficient space for 12 point font */
-        bi = new BufferedImage(40, 40, BufferedImage.TYPE_INT_RGB);
-        graphics = bi.getGraphics();
-        try {
-            os.write(CHILD_STARTED_OK);
-            os.flush();
-        } catch (IOException e) {
-            System.exit(-1);
-        }
-    }
-
-    /**
-     * Initializes an instance of Font from given font path.
-     * <BR>
-     * This methods attempts to create an instance of font from
-     * a string that represents path to the font file.
-     * <BR><BR>
-     * @param fontPath string representing path to font file
-     * @param flag indicating whether or not checking of non-TrueType fonts
-     * is necessary
-     */
-    private void testFont(String fontPath, boolean checkNonTTF) {
-
-        FontFileFilter fff = new FontFileFilter(checkNonTTF);
-        File fontFile = new File(fontPath);
-        if (!fontFile.canRead()) {
-            try {
-                os.write(ERR_FONT_NOT_FOUND);
-                os.flush();
-            } catch (IOException e) {
-                System.exit(-1);
-            }
-        }
-        Font font = null;
-        try {
-            File file = new File(fontPath);
-            font = Font.createFont(fff.getFontType(fontPath), file);
-        } catch (FontFormatException e1) {
-        } catch (IOException e2) {
-        }
-        if (font == null) {
-             return;
-        }
-        font = font.deriveFont(Font.PLAIN, 12);
-        String name = font.getFontName();
-        String family = font.getFamily();
-
-        char[] testChars = { '0' };
-        if (font.canDisplay(testChars[0])) {
-            graphics.setFont(font);
-            graphics.drawChars(testChars, 0, 1, 20, 20);
-        }
-        try {
-            os.write(ERR_FONT_OK);
-            os.flush();
-        } catch (IOException e) {
-            System.exit(-1);
-        }
-    }
-
-    /**
-     * Begins synchronous communication betweeen parent and child processes.
-     * <BR>
-     * This method begins communication between parent and child processes.
-     * FontCheckDummy reads a line of text from input stream (@see #is).
-     */
-    public void run() {
-        String command = null;
-        while (true) {
-            try {
-                command = is.readLine();
-            } catch (IOException e) {
-                System.exit(-1);
-            }
-            if (command != null && command.length() >= 1) {
-                int cmd = Integer.parseInt(command.substring(0,1));
-                if (cmd == EXITCOMMAND) {
-                    return;
-                }
-                boolean checkNonTTF = ((cmd == 1) ? true : false);
-                String fontPath = command.substring(1);
-                testFont(fontPath, checkNonTTF);
-            } else {
-                return;
-            }
-        }
-    }
-
-    public static void main(String[] args) {
-        try {
-            /* Background app. */
-            System.setProperty("java.awt.headless", "true");
-            System.setProperty("sun.java2d.noddraw", "true");
-            new FontCheckDummy().run();
-        } catch (Throwable t) {
-        }
-        System.exit(0);
-    }
-}
--- a/jdk/make/tools/src/build/tools/fontchecker/FontChecker.java	Sun Nov 08 14:49:40 2009 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,452 +0,0 @@
-/*
- * Copyright 2002-2004 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 build.tools.fontchecker;
-
-import java.io.*;
-import java.util.*;
-import java.awt.event.*;
-import sun.font.FontManager;
-
-/**
- * FontChecker.
- *
- * <PRE>
- * This is a FontChecker program. This class is a "parent" process
- * which invokes a "child" process. The child process will test
- * series of fonts and may crash as it encounters invalid fonts.
- * The "parent" process must then interpret error codes passed to it
- * by the "child" process and restart the "child" process if necessary.
- *
- * usage: java FontChecker [-v] -o outputfile
- *
- *        -o is the name of the file to contains canonical path names of
- *           bad fonts that are identified. This file is not created if
- *           no bad fonts are found.
- *        -v verbose: prints progress messages.
- *
- * </PRE>
- *
- * @author Ilya Bagrak
- */
-public class FontChecker implements ActionListener, FontCheckerConstants {
-
-    /**
-     * Output stream to subprocess.
-     * Corresponds to the subprocess's System.in".
-     */
-    private PrintWriter procPipeOut;
-
-    /**
-     * Input stream from subprocess.
-     * Corresponds to the subprocess's System.out".
-     */
-    private BufferedInputStream procPipeIn;
-
-    /**
-     * Child process.
-     */
-    private Process childProc;
-
-    /**
-     * Name of output file to write file names of bad fonts
-     */
-    private String outputFile;
-
-    /**
-     * Reference to currently executing thread.
-     */
-    private Thread currThread;
-
-    /**
-     * Timeout timer for a single font check
-     */
-    private javax.swing.Timer timeOne;
-
-    /**
-     * Timeout timer for all font checks
-     */
-    private javax.swing.Timer timeAll;
-
-    /**
-     * max time (in milliseconds) allowed for checking a single font.
-     */
-    private static int timeoutOne = 10000;
-
-    /**
-     * max time (in milliseconds) allowed for checking all fonts.
-     */
-    private static int timeoutAll = 120000;
-
-    /**
-     * Boolean flag indicating whether FontChecker is required to
-     * check non-TrueType fonts.
-     */
-    private boolean checkNonTTF = false;
-
-    /**
-     * List of bad fonts found in the system.
-     */
-    private Vector badFonts = new Vector();
-
-    /**
-     * whether to print warnings messges etc to stdout/err
-     * default is false
-     */
-    private static boolean verbose = false;
-
-    /* Command to use to exec sub-process. */
-    private static String javaCmd = "java";
-
-    static void printlnMessage(String s) {
-        if (verbose) {
-            System.out.println(s);
-        }
-    }
-
-    /**
-     * Event handler for timer event.
-     * <BR>
-     * Stops the timer and interrupts the current thread which is
-     * still waiting on I/O from the child process.
-     * <BR><BR>
-     * @param evt timer event
-     */
-    public void actionPerformed(ActionEvent evt) {
-        if (evt.getSource() == timeOne) {
-            timeOne.stop();
-            printlnMessage("Child timed out: killing");
-            childProc.destroy();
-        } else {
-            doExit(); // went on too long (ie timeAll timed out).
-        }
-    }
-
-    /**
-     * Initializes a FontChecker.
-     * <BR>
-     * This method is usually called after an unrecoverable error has
-     * been detected and a child process has  either crashed or is in bad
-     * state. The method creates a new child process from
-     * scratch and initializes it's input/output streams.
-     */
-    public void initialize() {
-        try {
-            if (childProc != null) {
-                childProc.destroy();
-            }
-            String fileSeparator = System.getProperty("file.separator");
-            String javaHome = System.getProperty("java.home");
-            String classPath =  System.getProperty("java.class.path");
-            classPath = "\"" + classPath + "\"";
-            String opt = "-cp " + classPath + " -Dsun.java2d.fontpath=\"" +
-                javaHome + fileSeparator + "lib" + fileSeparator + "fonts\"";
-
-            /* command to exec the child process with the same JRE */
-            String cmd =
-                new String(javaHome + fileSeparator + "bin" +
-                           fileSeparator + javaCmd +
-                           " -XXsuppressExitMessage " + opt +
-                           " com.sun.java2d.fontchecker.FontCheckDummy");
-            printlnMessage("cmd="+cmd);
-            childProc = Runtime.getRuntime().exec(cmd);
-
-        } catch (IOException e) {
-            printlnMessage("can't execute child process");
-            System.exit(0);
-        } catch (SecurityException e) {
-            printlnMessage("Error: access denied");
-            System.exit(0);
-        }
-
-        /* initialize input/output streams to/from child process */
-        procPipeOut = new PrintWriter(childProc.getOutputStream());
-        procPipeIn = new BufferedInputStream(childProc.getInputStream());
-
-        try {
-            int code = procPipeIn.read();
-            if (code != CHILD_STARTED_OK) {
-                printlnMessage("bad child process start status="+code);
-                doExit();
-            }
-        } catch (IOException e) {
-            printlnMessage("can't read child process start status unknown");
-            doExit();
-        }
-    }
-
-    private void doExit() {
-        try {
-            if (procPipeOut != null) {
-                /* Tell the child to exit */
-                procPipeOut.write(EXITCOMMAND+System.getProperty("line.separator"));
-                procPipeOut.flush();
-                procPipeOut.close();
-            }
-        } catch (Throwable t) {
-        }
-        System.exit(0);
-    }
-
-    /**
-     * Tries to verify integrity of a font specified by a path.
-     * <BR>
-     * This method is used to test whether a font specified by the given
-     * path is valid and does not crash the system.
-     * <BR><BR>
-     * @param fontPath a string representation of font path
-     * to standard out during while this font is tried
-     * @return returns <code>true</code> if font is OK, and
-     * <code>false</code> otherwise.
-     */
-    public boolean tryFont(File fontFile) {
-        int bytesRead = 0;
-        String fontPath = fontFile.getAbsolutePath();
-
-        printlnMessage("Checking font "+fontPath);
-
-        /* store reference to the current thread, so that when the timer
-         * fires it can be interrupted
-         */
-        currThread = Thread.currentThread();
-        timeOne.restart();
-
-        /* write a string command out to child process
-         * The command is formed by appending whether to test non-TT fonts
-         * and font path to be tested
-         */
-        String command = Integer.toString(checkNonTTF ? 1 : 0) +
-                         fontPath +
-                         System.getProperty("line.separator");
-        procPipeOut.write(command);
-        procPipeOut.flush();
-
-        /* check if underlying stream has encountered an error after
-         * command has been issued
-         */
-        if (procPipeOut.checkError()){
-            printlnMessage("Error: font crashed");
-            initialize();
-            return false;
-        }
-
-        /* trying reading error code back from child process */
-        try {
-            bytesRead = procPipeIn.read();
-        } catch(InterruptedIOException e) {
-            /* A timeout timer fired before the operation completed */
-            printlnMessage("Error: timeout occured");
-            initialize();
-            return false;
-        } catch(IOException e) {
-            /* there was an error reading from the stream */
-            timeOne.stop();
-            printlnMessage("Error: font crashed");
-            initialize();
-            return false;
-        } catch (Throwable t) {
-            bytesRead = ERR_FONT_READ_EXCPT;
-        } finally {
-          timeOne.stop();
-        }
-
-        if (bytesRead == ERR_FONT_OK) {
-            printlnMessage("Font integrity verified");
-            return true;
-        } else if (bytesRead > 0) {
-
-            switch(bytesRead){
-            case ERR_FONT_NOT_FOUND:
-                printlnMessage("Error: font not found!");
-                break;
-            case ERR_FONT_BAD_FORMAT:
-                printlnMessage("Error: incorrect font format");
-                break;
-            case ERR_FONT_READ_EXCPT:
-                printlnMessage("Error: exception reading font");
-                break;
-            case ERR_FONT_DISPLAY:
-                printlnMessage("Error: can't display characters");
-                break;
-            case ERR_FONT_CRASH:
-                printlnMessage("Error: font crashed");
-                break;
-            default:
-                printlnMessage("Error: invalid error code:"+bytesRead);
-                break;
-
-            }
-        } else if (bytesRead == ERR_FONT_EOS) {
-            printlnMessage("Error: end of stream marker encountered");
-        } else {
-            printlnMessage("Error: invalid error code:"+bytesRead);
-        }
-
-        /* if we still haven't returned from this method, some error
-         * condition has occured and it is safer to re-initialize
-         */
-        initialize();
-        return false;
-    }
-
-    /**
-     * Checks the integrity of all system fonts.
-     * <BR>
-     * This method goes through every font in system's font path and verifies
-     * its integrity via the tryFont method.
-     * <BR><BR>
-     * @param restart <code>true</code> if checking of fonts should continue
-     * after the first  bad font is found, and <code>false</code> otherwise
-     * @return returns <code>true</code> if all fonts are valid,
-     * <code>false</code> otherwise
-     * @see #tryFont(String, boolean, boolean)
-     */
-    public boolean checkFonts(boolean restart) {
-
-        /* file filter to filter out none-truetype font files */
-        FontFileFilter fff = new FontFileFilter(checkNonTTF);
-        boolean checkOk = true;
-
-        /* get platform-independent font path. Note that this bypasses
-         * the normal GraphicsEnvironment initialisation. In conjunction with
-         * the headless setting above, so we want to add
-         * java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment();
-         * to trigger a more normal initialisation.
-         */
-        java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment();
-        String fontPath = FontManager.getFontPath(true);
-        StringTokenizer st =
-            new StringTokenizer(fontPath,
-                                System.getProperty("path.separator"));
-
-        /* some systems may have multiple font paths separated by
-         * platform-dependent characters, so fontPath string needs to be
-         * parsed
-         */
-        timeOne = new javax.swing.Timer(timeoutOne, this);
-        timeAll = new javax.swing.Timer(timeoutAll, this);
-        timeAll.restart();
-        while (st.hasMoreTokens()) {
-            File fontRoot = new File(st.nextToken());
-            File[] fontFiles = fontRoot.listFiles(fff);
-
-            for (int i = 0; i < fontFiles.length; i++) {
-                /* for each font file that is not a directory and passes
-                 * through the font filter run the test
-                 */
-                if (!fontFiles[i].isDirectory() &&
-                    !tryFont(fontFiles[i])) {
-
-                    checkOk = false;
-                    badFonts.add(fontFiles[i].getAbsolutePath());
-                    if (!restart) {
-                        break;
-                    }
-                }
-            }
-        }
-
-        /* Tell the child to exit */
-        procPipeOut.write(EXITCOMMAND+System.getProperty("line.separator"));
-        procPipeOut.flush();
-        procPipeOut.close();
-
-        return checkOk;
-    }
-
-    public static void main(String args[]){
-        try {
-            /* Background app. */
-            System.setProperty("java.awt.headless", "true");
-            System.setProperty("sun.java2d.noddraw", "true");
-
-            boolean restart = true;
-            boolean errorFlag = false;
-
-            FontChecker fc = new FontChecker();
-            int arg = 0;
-
-            while (arg < args.length && errorFlag == false) {
-                if (args[arg].equals("-v")) {
-                    verbose = true;
-                }
-                else if (args[arg].equals("-w") &&
-                         System.getProperty("os.name", "unknown").
-                         startsWith("Windows")) {
-                    javaCmd = "javaw";
-                }
-                else if (args[arg].equals("-o")) {
-                    /* set output file */
-                    if (++arg < args.length)
-                        fc.outputFile = args[arg];
-                    else {
-                        /* invalid argument format */
-                        printlnMessage("Error: invalid argument format");
-                        errorFlag = true;
-                    }
-                }
-                else {
-                    /* invalid command line argument */
-                    printlnMessage("Error: invalid argument value");
-                    errorFlag = true;
-                }
-                arg++;
-            }
-
-            if (errorFlag || fc.outputFile == null) {
-                System.exit(0);
-            }
-
-            File outfile = new File(fc.outputFile);
-            if (outfile.exists()) {
-                outfile.delete();
-            }
-
-            fc.initialize();
-
-            if (!fc.checkFonts(restart)) {
-                String[] badFonts = (String[])fc.badFonts.toArray(new String[0]);
-                if (badFonts.length > 0) {
-                    printlnMessage("Bad Fonts:");
-                    try {
-                        FileOutputStream fos =
-                            new FileOutputStream(fc.outputFile);
-                        PrintStream ps = new  PrintStream(fos);
-                        for (int i = 0; i < badFonts.length; i++) {
-                            ps.println(badFonts[i]);
-                            printlnMessage(badFonts[i]);
-                        }
-                        fos.close();
-                    } catch (IOException e) {
-                    }
-                }
-            } else {
-                printlnMessage("No bad fonts found.");
-        }
-        } catch (Throwable t) {
-        }
-        System.exit(0);
-    }
-}
--- a/jdk/make/tools/src/build/tools/fontchecker/FontCheckerConstants.java	Sun Nov 08 14:49:40 2009 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-/*
- * Copyright 2002-2004 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 build.tools.fontchecker;
-
-public interface FontCheckerConstants {
-
-    /* code sent to indicate child process started OK */
-    public static final int CHILD_STARTED_OK   = 100;
-
-    /* error codes returned from child process */
-    public static final int ERR_FONT_OK         = 65;
-    public static final int ERR_FONT_NOT_FOUND  = 60;
-    public static final int ERR_FONT_BAD_FORMAT = 61;
-    public static final int ERR_FONT_READ_EXCPT = 62;
-    public static final int ERR_FONT_DISPLAY    = 64;
-    public static final int ERR_FONT_EOS        = -1;
-    /* nl char sent after child crashes */
-    public static final int ERR_FONT_CRASH      = 10;
-
-    /* 0 and 1 are reserved, and commands can only be a single digit integer */
-    public static final int EXITCOMMAND = 2;
-}
--- a/jdk/make/tools/src/build/tools/fontchecker/FontFileFilter.java	Sun Nov 08 14:49:40 2009 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-/*
- * Copyright 2002-2003 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.
- */
-
-/*
- * <PRE>
- * This class filters TrueType font files from other file
- * found in the font path.
- *
- * </PRE>
- *
- * @author Ilya Bagrak
- */
-
-package build.tools.fontchecker;
-
-import java.awt.*;
-import java.io.*;
-
-public class FontFileFilter implements java.io.FileFilter, FontCheckerConstants {
-
-    /**
-     * Boolean flag indicating whether this filter filters out
-     * non-TrueType fonts.
-     */
-    private boolean checkNonTTF;
-
-    public FontFileFilter() {
-        this(false);
-    }
-
-    public FontFileFilter(boolean checkNonTTF) {
-        super();
-        this.checkNonTTF = checkNonTTF;
-    }
-
-    /**
-     * Checks whether a file is accepted by this filter.
-     * <BR>
-     * This method checks whehter a file is accepted by this filter.
-     * This filter is made to accept all the file whose extension is
-     * either .ttf or .TTF. These files are assumed to be TrueType fonts.
-     * <BR><BR>
-     * @return returns a boolean value indicating whether or not a file is
-     * accepted
-     */
-    public boolean accept(File pathname) {
-
-        String name = pathname.getName();
-        return (name.endsWith(".ttf") ||
-                name.endsWith(".TTF") ||
-                name.endsWith(".ttc") ||
-                name.endsWith(".TTC"))  ||
-            (name.endsWith(".pfb") ||
-             name.endsWith(".PFB") ||
-             name.endsWith(".pfa") ||
-             name.endsWith(".PFA") &&
-             checkNonTTF == true);
-    }
-
-    public static int getFontType(String filename) {
-        if (filename.endsWith(".ttf") ||
-            filename.endsWith(".TTF") ||
-            filename.endsWith(".ttc") ||
-            filename.endsWith(".TTC"))
-            return Font.TRUETYPE_FONT;
-        else if (filename.endsWith(".pfb") ||
-                 filename.endsWith(".PFB") ||
-                 filename.endsWith(".pfa") ||
-                 filename.endsWith(".PFA"))
-            return Font.TYPE1_FONT;
-        else
-            return 999;
-    }
-
-}
--- a/jdk/make/tools/src/build/tools/fontchecker/README.txt	Sun Nov 08 14:49:40 2009 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-/*
- * Copyright 2002-2003 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.
- */
-Instructions for running FontChecker 
-------------------------------------
-
-FontChecker is a program designed to identify fonts that may cause JRE
-crashes. Such fonts may be corrupted files, or badly constructed fonts.
-Some crashes may also be due to bugs in the JRE's font code.
-This test is designed to run quickly and silently as part of the JRE
-installation process. It will only benefit users who install the JRE
-via that mechanism. It cannot guarantee to identify all "bad fonts" because
-the tests are minimal. Nor can it prevent problems due to fonts installed
-subsequently to the JRE's installation. However it does ensure that the
-vast majority of problem fonts are identified. This is important
-"RAS" functionality. It is targeted at the consumer/plugin market where
-there is substantial likelihood of end-users having installed software
-packages which may be delivered with fonts that are not up to commercial
-standards.
-
-The test is designed to be "fail safe". If the program fails to run
-properly it has no impact on the installer or on JRE execution.
-Thus there is no need to monitor successful execution of the test.
-
-The test is not a new "tool" in the sense of "javah" etc.
-The test is not designed to be user executable or visible, and should
-be unpacked by the installer into a temporary location, and executed
-once the rest of the JRE is installed (ie as a postinstall step), and
-can then be deleted from the temporary location once installation is
-complete. Not deleting the jar file before execution is complete is
-probably the sole reason that the installer may want to wait for
-the program to complete.
-
-The FontChecker application can be run directly from the jar 
-file with this command: 
-	%java -jar fontchecker.jar -o <file>
-
-The output file is a required parameter in this version of the application.
-The JRE installer should use the above form, and use it to create an
-output file which must be named "badfonts.txt" and be placed into
-the JRE's lib\fonts directory eg:-
-
-        java -jar fontchecker.jar -o "C:\Program Files\jre\lib\fonts\badfonts.txt"
-
-Note the lower case "badfonts.txt", and the string quotes because of the spaces
-in the path name.
-The location given here is an example and needs to be calculated at install
-time as $JREHOME\lib\fonts\badfonts.txt
-The location and name are important, because the JRE at runtime will
-look for this exactly located name and file.
-This location is private to that JRE instance. It will not affect
-any other JRE installed on the system.
-
-If running from a different directory than that containing the jar file,
-use the form containing the full path to the jar file, eg :
-
-	java -jar C:\fc\fontchecker.jar -o "C:\Program Files\jre\lib\fonts\badfonts.txt"
-
-FontChecker application accepts following command line flags. 
-usage: java -jar fontchecker.jar -o outputfile
-	                -v 
-
-       -o is the name of the file to contains canonical path names of
-          bad fonts that are identified. This file is not created if
-          no bad fonts are found.
-
-       -v verbose mode: print progress/warning messages. Not recommended
-         for installer use.
-
-       -w if running on Windows, use "javaw" to exec the sub-process.
--- a/jdk/src/share/classes/java/nio/ByteBufferAs-X-Buffer.java	Sun Nov 08 14:49:40 2009 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,219 +0,0 @@
-/*
- * Copyright 2000-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.
- */
-
-#warn This file is preprocessed before being compiled
-
-package java.nio;
-
-
-class ByteBufferAs$Type$Buffer$RW$$BO$                  // package-private
-    extends {#if[ro]?ByteBufferAs}$Type$Buffer{#if[ro]?$BO$}
-{
-
-#if[rw]
-
-    protected final ByteBuffer bb;
-    protected final int offset;
-
-#end[rw]
-
-    ByteBufferAs$Type$Buffer$RW$$BO$(ByteBuffer bb) {   // package-private
-#if[rw]
-        super(-1, 0,
-              bb.remaining() >> $LG_BYTES_PER_VALUE$,
-              bb.remaining() >> $LG_BYTES_PER_VALUE$);
-        this.bb = bb;
-        // enforce limit == capacity
-        int cap = this.capacity();
-        this.limit(cap);
-        int pos = this.position();
-        assert (pos <= cap);
-        offset = pos;
-#else[rw]
-        super(bb);
-#end[rw]
-    }
-
-    ByteBufferAs$Type$Buffer$RW$$BO$(ByteBuffer bb,
-                                     int mark, int pos, int lim, int cap,
-                                     int off)
-    {
-#if[rw]
-        super(mark, pos, lim, cap);
-        this.bb = bb;
-        offset = off;
-#else[rw]
-        super(bb, mark, pos, lim, cap, off);
-#end[rw]
-    }
-
-    public $Type$Buffer slice() {
-        int pos = this.position();
-        int lim = this.limit();
-        assert (pos <= lim);
-        int rem = (pos <= lim ? lim - pos : 0);
-        int off = (pos << $LG_BYTES_PER_VALUE$) + offset;
-        assert (off >= 0);
-        return new ByteBufferAs$Type$Buffer$RW$$BO$(bb, -1, 0, rem, rem, off);
-    }
-
-    public $Type$Buffer duplicate() {
-        return new ByteBufferAs$Type$Buffer$RW$$BO$(bb,
-                                                    this.markValue(),
-                                                    this.position(),
-                                                    this.limit(),
-                                                    this.capacity(),
-                                                    offset);
-    }
-
-    public $Type$Buffer asReadOnlyBuffer() {
-#if[rw]
-        return new ByteBufferAs$Type$BufferR$BO$(bb,
-                                                 this.markValue(),
-                                                 this.position(),
-                                                 this.limit(),
-                                                 this.capacity(),
-                                                 offset);
-#else[rw]
-        return duplicate();
-#end[rw]
-    }
-
-#if[rw]
-
-    protected int ix(int i) {
-        return (i << $LG_BYTES_PER_VALUE$) + offset;
-    }
-
-    public $type$ get() {
-        return Bits.get$Type$$BO$(bb, ix(nextGetIndex()));
-    }
-
-    public $type$ get(int i) {
-        return Bits.get$Type$$BO$(bb, ix(checkIndex(i)));
-    }
-
-#end[rw]
-
-    public $Type$Buffer put($type$ x) {
-#if[rw]
-        Bits.put$Type$$BO$(bb, ix(nextPutIndex()), x);
-        return this;
-#else[rw]
-        throw new ReadOnlyBufferException();
-#end[rw]
-    }
-
-    public $Type$Buffer put(int i, $type$ x) {
-#if[rw]
-        Bits.put$Type$$BO$(bb, ix(checkIndex(i)), x);
-        return this;
-#else[rw]
-        throw new ReadOnlyBufferException();
-#end[rw]
-    }
-
-    public $Type$Buffer compact() {
-#if[rw]
-        int pos = position();
-        int lim = limit();
-        assert (pos <= lim);
-        int rem = (pos <= lim ? lim - pos : 0);
-
-        ByteBuffer db = bb.duplicate();
-        db.limit(ix(lim));
-        db.position(ix(0));
-        ByteBuffer sb = db.slice();
-        sb.position(pos << $LG_BYTES_PER_VALUE$);
-        sb.compact();
-        position(rem);
-        limit(capacity());
-        discardMark();
-        return this;
-#else[rw]
-        throw new ReadOnlyBufferException();
-#end[rw]
-    }
-
-    public boolean isDirect() {
-        return bb.isDirect();
-    }
-
-    public boolean isReadOnly() {
-        return {#if[rw]?false:true};
-    }
-
-#if[char]
-
-    public String toString(int start, int end) {
-        if ((end > limit()) || (start > end))
-            throw new IndexOutOfBoundsException();
-        try {
-            int len = end - start;
-            char[] ca = new char[len];
-            CharBuffer cb = CharBuffer.wrap(ca);
-            CharBuffer db = this.duplicate();
-            db.position(start);
-            db.limit(end);
-            cb.put(db);
-            return new String(ca);
-        } catch (StringIndexOutOfBoundsException x) {
-            throw new IndexOutOfBoundsException();
-        }
-    }
-
-
-    // --- Methods to support CharSequence ---
-
-    public CharBuffer subSequence(int start, int end) {
-        int pos = position();
-        int lim = limit();
-        assert (pos <= lim);
-        pos = (pos <= lim ? pos : lim);
-        int len = lim - pos;
-
-        if ((start < 0) || (end > len) || (start > end))
-            throw new IndexOutOfBoundsException();
-        return new ByteBufferAsCharBuffer$RW$$BO$(bb,
-                                                  -1,
-                                                  pos + start,
-                                                  pos + end,
-                                                  capacity(),
-                                                  offset);
-    }
-
-#end[char]
-
-
-    public ByteOrder order() {
-#if[boB]
-        return ByteOrder.BIG_ENDIAN;
-#end[boB]
-#if[boL]
-        return ByteOrder.LITTLE_ENDIAN;
-#end[boL]
-    }
-
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/nio/ByteBufferAs-X-Buffer.java.template	Wed Jul 05 17:02:50 2017 +0200
@@ -0,0 +1,219 @@
+/*
+ * Copyright 2000-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.
+ */
+
+#warn This file is preprocessed before being compiled
+
+package java.nio;
+
+
+class ByteBufferAs$Type$Buffer$RW$$BO$                  // package-private
+    extends {#if[ro]?ByteBufferAs}$Type$Buffer{#if[ro]?$BO$}
+{
+
+#if[rw]
+
+    protected final ByteBuffer bb;
+    protected final int offset;
+
+#end[rw]
+
+    ByteBufferAs$Type$Buffer$RW$$BO$(ByteBuffer bb) {   // package-private
+#if[rw]
+        super(-1, 0,
+              bb.remaining() >> $LG_BYTES_PER_VALUE$,
+              bb.remaining() >> $LG_BYTES_PER_VALUE$);
+        this.bb = bb;
+        // enforce limit == capacity
+        int cap = this.capacity();
+        this.limit(cap);
+        int pos = this.position();
+        assert (pos <= cap);
+        offset = pos;
+#else[rw]
+        super(bb);
+#end[rw]
+    }
+
+    ByteBufferAs$Type$Buffer$RW$$BO$(ByteBuffer bb,
+                                     int mark, int pos, int lim, int cap,
+                                     int off)
+    {
+#if[rw]
+        super(mark, pos, lim, cap);
+        this.bb = bb;
+        offset = off;
+#else[rw]
+        super(bb, mark, pos, lim, cap, off);
+#end[rw]
+    }
+
+    public $Type$Buffer slice() {
+        int pos = this.position();
+        int lim = this.limit();
+        assert (pos <= lim);
+        int rem = (pos <= lim ? lim - pos : 0);
+        int off = (pos << $LG_BYTES_PER_VALUE$) + offset;
+        assert (off >= 0);
+        return new ByteBufferAs$Type$Buffer$RW$$BO$(bb, -1, 0, rem, rem, off);
+    }
+
+    public $Type$Buffer duplicate() {
+        return new ByteBufferAs$Type$Buffer$RW$$BO$(bb,
+                                                    this.markValue(),
+                                                    this.position(),
+                                                    this.limit(),
+                                                    this.capacity(),
+                                                    offset);
+    }
+
+    public $Type$Buffer asReadOnlyBuffer() {
+#if[rw]
+        return new ByteBufferAs$Type$BufferR$BO$(bb,
+                                                 this.markValue(),
+                                                 this.position(),
+                                                 this.limit(),
+                                                 this.capacity(),
+                                                 offset);
+#else[rw]
+        return duplicate();
+#end[rw]
+    }
+
+#if[rw]
+
+    protected int ix(int i) {
+        return (i << $LG_BYTES_PER_VALUE$) + offset;
+    }
+
+    public $type$ get() {
+        return Bits.get$Type$$BO$(bb, ix(nextGetIndex()));
+    }
+
+    public $type$ get(int i) {
+        return Bits.get$Type$$BO$(bb, ix(checkIndex(i)));
+    }
+
+#end[rw]
+
+    public $Type$Buffer put($type$ x) {
+#if[rw]
+        Bits.put$Type$$BO$(bb, ix(nextPutIndex()), x);
+        return this;
+#else[rw]
+        throw new ReadOnlyBufferException();
+#end[rw]
+    }
+
+    public $Type$Buffer put(int i, $type$ x) {
+#if[rw]
+        Bits.put$Type$$BO$(bb, ix(checkIndex(i)), x);
+        return this;
+#else[rw]
+        throw new ReadOnlyBufferException();
+#end[rw]
+    }
+
+    public $Type$Buffer compact() {
+#if[rw]
+        int pos = position();
+        int lim = limit();
+        assert (pos <= lim);
+        int rem = (pos <= lim ? lim - pos : 0);
+
+        ByteBuffer db = bb.duplicate();
+        db.limit(ix(lim));
+        db.position(ix(0));
+        ByteBuffer sb = db.slice();
+        sb.position(pos << $LG_BYTES_PER_VALUE$);
+        sb.compact();
+        position(rem);
+        limit(capacity());
+        discardMark();
+        return this;
+#else[rw]
+        throw new ReadOnlyBufferException();
+#end[rw]
+    }
+
+    public boolean isDirect() {
+        return bb.isDirect();
+    }
+
+    public boolean isReadOnly() {
+        return {#if[rw]?false:true};
+    }
+
+#if[char]
+
+    public String toString(int start, int end) {
+        if ((end > limit()) || (start > end))
+            throw new IndexOutOfBoundsException();
+        try {
+            int len = end - start;
+            char[] ca = new char[len];
+            CharBuffer cb = CharBuffer.wrap(ca);
+            CharBuffer db = this.duplicate();
+            db.position(start);
+            db.limit(end);
+            cb.put(db);
+            return new String(ca);
+        } catch (StringIndexOutOfBoundsException x) {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+
+
+    // --- Methods to support CharSequence ---
+
+    public CharBuffer subSequence(int start, int end) {
+        int pos = position();
+        int lim = limit();
+        assert (pos <= lim);
+        pos = (pos <= lim ? pos : lim);
+        int len = lim - pos;
+
+        if ((start < 0) || (end > len) || (start > end))
+            throw new IndexOutOfBoundsException();
+        return new ByteBufferAsCharBuffer$RW$$BO$(bb,
+                                                  -1,
+                                                  pos + start,
+                                                  pos + end,
+                                                  capacity(),
+                                                  offset);
+    }
+
+#end[char]
+
+
+    public ByteOrder order() {
+#if[boB]
+        return ByteOrder.BIG_ENDIAN;
+#end[boB]
+#if[boL]
+        return ByteOrder.LITTLE_ENDIAN;
+#end[boL]
+    }
+
+}
--- a/jdk/src/share/classes/java/nio/Direct-X-Buffer-bin.java	Sun Nov 08 14:49:40 2009 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,124 +0,0 @@
-/*
- * Copyright 2000-2003 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.
- */
-
-#warn This file is preprocessed before being compiled
-
-class XXX {
-
-#begin
-
-#if[rw]
-
-    private $type$ get$Type$(long a) {
-        if (unaligned) {
-            $memtype$ x = unsafe.get$Memtype$(a);
-            return $fromBits$(nativeByteOrder ? x : Bits.swap(x));
-        }
-        return Bits.get$Type$(a, bigEndian);
-    }
-
-    public $type$ get$Type$() {
-        return get$Type$(ix(nextGetIndex($BYTES_PER_VALUE$)));
-    }
-
-    public $type$ get$Type$(int i) {
-        return get$Type$(ix(checkIndex(i, $BYTES_PER_VALUE$)));
-    }
-
-#end[rw]
-
-    private ByteBuffer put$Type$(long a, $type$ x) {
-#if[rw]
-        if (unaligned) {
-            $memtype$ y = $toBits$(x);
-            unsafe.put$Memtype$(a, (nativeByteOrder ? y : Bits.swap(y)));
-        } else {
-            Bits.put$Type$(a, x, bigEndian);
-        }
-        return this;
-#else[rw]
-        throw new ReadOnlyBufferException();
-#end[rw]
-    }
-
-    public ByteBuffer put$Type$($type$ x) {
-#if[rw]
-        put$Type$(ix(nextPutIndex($BYTES_PER_VALUE$)), x);
-        return this;
-#else[rw]
-        throw new ReadOnlyBufferException();
-#end[rw]
-    }
-
-    public ByteBuffer put$Type$(int i, $type$ x) {
-#if[rw]
-        put$Type$(ix(checkIndex(i, $BYTES_PER_VALUE$)), x);
-        return this;
-#else[rw]
-        throw new ReadOnlyBufferException();
-#end[rw]
-    }
-
-    public $Type$Buffer as$Type$Buffer() {
-        int off = this.position();
-        int lim = this.limit();
-        assert (off <= lim);
-        int rem = (off <= lim ? lim - off : 0);
-
-        int size = rem >> $LG_BYTES_PER_VALUE$;
-        if (!unaligned && ((address + off) % $BYTES_PER_VALUE$ != 0)) {
-            return (bigEndian
-                    ? ($Type$Buffer)(new ByteBufferAs$Type$Buffer$RW$B(this,
-                                                                       -1,
-                                                                       0,
-                                                                       size,
-                                                                       size,
-                                                                       off))
-                    : ($Type$Buffer)(new ByteBufferAs$Type$Buffer$RW$L(this,
-                                                                       -1,
-                                                                       0,
-                                                                       size,
-                                                                       size,
-                                                                       off)));
-        } else {
-            return (nativeByteOrder
-                    ? ($Type$Buffer)(new Direct$Type$Buffer$RW$U(this,
-                                                                 -1,
-                                                                 0,
-                                                                 size,
-                                                                 size,
-                                                                 off))
-                    : ($Type$Buffer)(new Direct$Type$Buffer$RW$S(this,
-                                                                 -1,
-                                                                 0,
-                                                                 size,
-                                                                 size,
-                                                                 off)));
-        }
-    }
-
-#end
-
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/nio/Direct-X-Buffer-bin.java.template	Wed Jul 05 17:02:50 2017 +0200
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2000-2003 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.
+ */
+
+#warn This file is preprocessed before being compiled
+
+class XXX {
+
+#begin
+
+#if[rw]
+
+    private $type$ get$Type$(long a) {
+        if (unaligned) {
+            $memtype$ x = unsafe.get$Memtype$(a);
+            return $fromBits$(nativeByteOrder ? x : Bits.swap(x));
+        }
+        return Bits.get$Type$(a, bigEndian);
+    }
+
+    public $type$ get$Type$() {
+        return get$Type$(ix(nextGetIndex($BYTES_PER_VALUE$)));
+    }
+
+    public $type$ get$Type$(int i) {
+        return get$Type$(ix(checkIndex(i, $BYTES_PER_VALUE$)));
+    }
+
+#end[rw]
+
+    private ByteBuffer put$Type$(long a, $type$ x) {
+#if[rw]
+        if (unaligned) {
+            $memtype$ y = $toBits$(x);
+            unsafe.put$Memtype$(a, (nativeByteOrder ? y : Bits.swap(y)));
+        } else {
+            Bits.put$Type$(a, x, bigEndian);
+        }
+        return this;
+#else[rw]
+        throw new ReadOnlyBufferException();
+#end[rw]
+    }
+
+    public ByteBuffer put$Type$($type$ x) {
+#if[rw]
+        put$Type$(ix(nextPutIndex($BYTES_PER_VALUE$)), x);
+        return this;
+#else[rw]
+        throw new ReadOnlyBufferException();
+#end[rw]
+    }
+
+    public ByteBuffer put$Type$(int i, $type$ x) {
+#if[rw]
+        put$Type$(ix(checkIndex(i, $BYTES_PER_VALUE$)), x);
+        return this;
+#else[rw]
+        throw new ReadOnlyBufferException();
+#end[rw]
+    }
+
+    public $Type$Buffer as$Type$Buffer() {
+        int off = this.position();
+        int lim = this.limit();
+        assert (off <= lim);
+        int rem = (off <= lim ? lim - off : 0);
+
+        int size = rem >> $LG_BYTES_PER_VALUE$;
+        if (!unaligned && ((address + off) % $BYTES_PER_VALUE$ != 0)) {
+            return (bigEndian
+                    ? ($Type$Buffer)(new ByteBufferAs$Type$Buffer$RW$B(this,
+                                                                       -1,
+                                                                       0,
+                                                                       size,
+                                                                       size,
+                                                                       off))
+                    : ($Type$Buffer)(new ByteBufferAs$Type$Buffer$RW$L(this,
+                                                                       -1,
+                                                                       0,
+                                                                       size,
+                                                                       size,
+                                                                       off)));
+        } else {
+            return (nativeByteOrder
+                    ? ($Type$Buffer)(new Direct$Type$Buffer$RW$U(this,
+                                                                 -1,
+                                                                 0,
+                                                                 size,
+                                                                 size,
+                                                                 off))
+                    : ($Type$Buffer)(new Direct$Type$Buffer$RW$S(this,
+                                                                 -1,
+                                                                 0,
+                                                                 size,
+                                                                 size,
+                                                                 off)));
+        }
+    }
+
+#end
+
+}
--- a/jdk/src/share/classes/java/nio/Direct-X-Buffer.java	Sun Nov 08 14:49:40 2009 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,464 +0,0 @@
-/*
- * Copyright 2000-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.
- */
-
-#warn This file is preprocessed before being compiled
-
-package java.nio;
-
-import sun.misc.Cleaner;
-import sun.misc.Unsafe;
-import sun.nio.ch.DirectBuffer;
-
-
-class Direct$Type$Buffer$RW$$BO$
-#if[rw]
-    extends {#if[byte]?Mapped$Type$Buffer:$Type$Buffer}
-#else[rw]
-    extends Direct$Type$Buffer$BO$
-#end[rw]
-    implements DirectBuffer
-{
-
-#if[rw]
-
-    // Cached unsafe-access object
-    protected static final Unsafe unsafe = Bits.unsafe();
-
-    // Cached array base offset
-    private static final long arrayBaseOffset = (long)unsafe.arrayBaseOffset($type$[].class);
-
-    // Cached unaligned-access capability
-    protected static final boolean unaligned = Bits.unaligned();
-
-    // Base address, used in all indexing calculations
-    // NOTE: moved up to Buffer.java for speed in JNI GetDirectBufferAddress
-    //    protected long address;
-
-    // If this buffer is a view of another buffer then we keep a reference to
-    // that buffer so that its memory isn't freed before we're done with it
-    protected Object viewedBuffer = null;
-
-    public Object viewedBuffer() {
-        return viewedBuffer;
-    }
-
-#if[byte]
-
-    private static class Deallocator
-        implements Runnable
-    {
-
-        private static Unsafe unsafe = Unsafe.getUnsafe();
-
-        private long address;
-        private long size;
-        private int capacity;
-
-        private Deallocator(long address, long size, int capacity) {
-            assert (address != 0);
-            this.address = address;
-            this.size = size;
-            this.capacity = capacity;
-        }
-
-        public void run() {
-            if (address == 0) {
-                // Paranoia
-                return;
-            }
-            unsafe.freeMemory(address);
-            address = 0;
-            Bits.unreserveMemory(size, capacity);
-        }
-
-    }
-
-    private final Cleaner cleaner;
-
-    public Cleaner cleaner() { return cleaner; }
-
-#else[byte]
-
-    public Cleaner cleaner() { return null; }
-
-#end[byte]
-
-#end[rw]
-
-#if[byte]
-
-    // Primary constructor
-    //
-    Direct$Type$Buffer$RW$(int cap) {                   // package-private
-#if[rw]
-        super(-1, 0, cap, cap, false);
-        int ps = Bits.pageSize();
-        int size = cap + ps;
-        Bits.reserveMemory(size, cap);
-
-        long base = 0;
-        try {
-            base = unsafe.allocateMemory(size);
-        } catch (OutOfMemoryError x) {
-            Bits.unreserveMemory(size, cap);
-            throw x;
-        }
-        unsafe.setMemory(base, size, (byte) 0);
-        if (base % ps != 0) {
-            // Round up to page boundary
-            address = base + ps - (base & (ps - 1));
-        } else {
-            address = base;
-        }
-        cleaner = Cleaner.create(this, new Deallocator(base, size, cap));
-#else[rw]
-        super(cap);
-#end[rw]
-    }
-
-#if[rw]
-
-    // Invoked only by JNI: NewDirectByteBuffer(void*, long)
-    //
-    private Direct$Type$Buffer(long addr, int cap) {
-        super(-1, 0, cap, cap, false);
-        address = addr;
-        cleaner = null;
-    }
-
-#end[rw]
-
-    // For memory-mapped buffers -- invoked by FileChannelImpl via reflection
-    //
-    protected Direct$Type$Buffer$RW$(int cap, long addr, Runnable unmapper) {
-#if[rw]
-        super(-1, 0, cap, cap, true);
-        address = addr;
-        viewedBuffer = null;
-        cleaner = Cleaner.create(this, unmapper);
-#else[rw]
-        super(cap, addr, unmapper);
-#end[rw]
-    }
-
-#end[byte]
-
-    // For duplicates and slices
-    //
-    Direct$Type$Buffer$RW$$BO$(DirectBuffer db,         // package-private
-                               int mark, int pos, int lim, int cap,
-                               int off)
-    {
-#if[rw]
-        super(mark, pos, lim, cap);
-        address = db.address() + off;
-        viewedBuffer = db;
-#if[byte]
-        cleaner = null;
-#end[byte]
-#else[rw]
-        super(db, mark, pos, lim, cap, off);
-#end[rw]
-    }
-
-    public $Type$Buffer slice() {
-        int pos = this.position();
-        int lim = this.limit();
-        assert (pos <= lim);
-        int rem = (pos <= lim ? lim - pos : 0);
-        int off = (pos << $LG_BYTES_PER_VALUE$);
-        assert (off >= 0);
-        return new Direct$Type$Buffer$RW$$BO$(this, -1, 0, rem, rem, off);
-    }
-
-    public $Type$Buffer duplicate() {
-        return new Direct$Type$Buffer$RW$$BO$(this,
-                                              this.markValue(),
-                                              this.position(),
-                                              this.limit(),
-                                              this.capacity(),
-                                              0);
-    }
-
-    public $Type$Buffer asReadOnlyBuffer() {
-#if[rw]
-        return new Direct$Type$BufferR$BO$(this,
-                                           this.markValue(),
-                                           this.position(),
-                                           this.limit(),
-                                           this.capacity(),
-                                           0);
-#else[rw]
-        return duplicate();
-#end[rw]
-    }
-
-#if[rw]
-
-    public long address() {
-        return address;
-    }
-
-    private long ix(int i) {
-        return address + (i << $LG_BYTES_PER_VALUE$);
-    }
-
-    public $type$ get() {
-        return $fromBits$($swap$(unsafe.get$Swaptype$(ix(nextGetIndex()))));
-    }
-
-    public $type$ get(int i) {
-        return $fromBits$($swap$(unsafe.get$Swaptype$(ix(checkIndex(i)))));
-    }
-
-    public $Type$Buffer get($type$[] dst, int offset, int length) {
-#if[rw]
-        if ((length << $LG_BYTES_PER_VALUE$) > Bits.JNI_COPY_TO_ARRAY_THRESHOLD) {
-            checkBounds(offset, length, dst.length);
-            int pos = position();
-            int lim = limit();
-            assert (pos <= lim);
-            int rem = (pos <= lim ? lim - pos : 0);
-            if (length > rem)
-                throw new BufferUnderflowException();
-
-#if[!byte]
-            if (order() != ByteOrder.nativeOrder())
-                Bits.copyTo$Memtype$Array(ix(pos), dst,
-                                          offset << $LG_BYTES_PER_VALUE$,
-                                          length << $LG_BYTES_PER_VALUE$);
-            else
-#end[!byte]
-                Bits.copyToArray(ix(pos), dst, arrayBaseOffset,
-                                 offset << $LG_BYTES_PER_VALUE$,
-                                 length << $LG_BYTES_PER_VALUE$);
-            position(pos + length);
-        } else {
-            super.get(dst, offset, length);
-        }
-        return this;
-#else[rw]
-        throw new ReadOnlyBufferException();
-#end[rw]
-    }
-
-#end[rw]
-
-    public $Type$Buffer put($type$ x) {
-#if[rw]
-        unsafe.put$Swaptype$(ix(nextPutIndex()), $swap$($toBits$(x)));
-        return this;
-#else[rw]
-        throw new ReadOnlyBufferException();
-#end[rw]
-    }
-
-    public $Type$Buffer put(int i, $type$ x) {
-#if[rw]
-        unsafe.put$Swaptype$(ix(checkIndex(i)), $swap$($toBits$(x)));
-        return this;
-#else[rw]
-        throw new ReadOnlyBufferException();
-#end[rw]
-    }
-
-    public $Type$Buffer put($Type$Buffer src) {
-#if[rw]
-        if (src instanceof Direct$Type$Buffer$BO$) {
-            if (src == this)
-                throw new IllegalArgumentException();
-            Direct$Type$Buffer$RW$$BO$ sb = (Direct$Type$Buffer$RW$$BO$)src;
-
-            int spos = sb.position();
-            int slim = sb.limit();
-            assert (spos <= slim);
-            int srem = (spos <= slim ? slim - spos : 0);
-
-            int pos = position();
-            int lim = limit();
-            assert (pos <= lim);
-            int rem = (pos <= lim ? lim - pos : 0);
-
-            if (srem > rem)
-                throw new BufferOverflowException();
-            unsafe.copyMemory(sb.ix(spos), ix(pos), srem << $LG_BYTES_PER_VALUE$);
-            sb.position(spos + srem);
-            position(pos + srem);
-        } else if (src.hb != null) {
-
-            int spos = src.position();
-            int slim = src.limit();
-            assert (spos <= slim);
-            int srem = (spos <= slim ? slim - spos : 0);
-
-            put(src.hb, src.offset + spos, srem);
-            src.position(spos + srem);
-
-        } else {
-            super.put(src);
-        }
-        return this;
-#else[rw]
-        throw new ReadOnlyBufferException();
-#end[rw]
-    }
-
-    public $Type$Buffer put($type$[] src, int offset, int length) {
-#if[rw]
-        if ((length << $LG_BYTES_PER_VALUE$) > Bits.JNI_COPY_FROM_ARRAY_THRESHOLD) {
-            checkBounds(offset, length, src.length);
-            int pos = position();
-            int lim = limit();
-            assert (pos <= lim);
-            int rem = (pos <= lim ? lim - pos : 0);
-            if (length > rem)
-                throw new BufferOverflowException();
-
-#if[!byte]
-            if (order() != ByteOrder.nativeOrder())
-                Bits.copyFrom$Memtype$Array(src, offset << $LG_BYTES_PER_VALUE$,
-                                            ix(pos), length << $LG_BYTES_PER_VALUE$);
-            else
-#end[!byte]
-                Bits.copyFromArray(src, arrayBaseOffset, offset << $LG_BYTES_PER_VALUE$,
-                                   ix(pos), length << $LG_BYTES_PER_VALUE$);
-            position(pos + length);
-        } else {
-            super.put(src, offset, length);
-        }
-        return this;
-#else[rw]
-        throw new ReadOnlyBufferException();
-#end[rw]
-    }
-
-    public $Type$Buffer compact() {
-#if[rw]
-        int pos = position();
-        int lim = limit();
-        assert (pos <= lim);
-        int rem = (pos <= lim ? lim - pos : 0);
-
-        unsafe.copyMemory(ix(pos), ix(0), rem << $LG_BYTES_PER_VALUE$);
-        position(rem);
-        limit(capacity());
-        discardMark();
-        return this;
-#else[rw]
-        throw new ReadOnlyBufferException();
-#end[rw]
-    }
-
-    public boolean isDirect() {
-        return true;
-    }
-
-    public boolean isReadOnly() {
-        return {#if[rw]?false:true};
-    }
-
-
-#if[char]
-
-    public String toString(int start, int end) {
-        if ((end > limit()) || (start > end))
-            throw new IndexOutOfBoundsException();
-        try {
-            int len = end - start;
-            char[] ca = new char[len];
-            CharBuffer cb = CharBuffer.wrap(ca);
-            CharBuffer db = this.duplicate();
-            db.position(start);
-            db.limit(end);
-            cb.put(db);
-            return new String(ca);
-        } catch (StringIndexOutOfBoundsException x) {
-            throw new IndexOutOfBoundsException();
-        }
-    }
-
-
-    // --- Methods to support CharSequence ---
-
-    public CharBuffer subSequence(int start, int end) {
-        int pos = position();
-        int lim = limit();
-        assert (pos <= lim);
-        pos = (pos <= lim ? pos : lim);
-        int len = lim - pos;
-
-        if ((start < 0) || (end > len) || (start > end))
-            throw new IndexOutOfBoundsException();
-        return new DirectCharBuffer$RW$$BO$(this,
-                                            -1,
-                                            pos + start,
-                                            pos + end,
-                                            capacity(),
-                                            offset);
-    }
-
-#end[char]
-
-
-
-#if[!byte]
-
-    public ByteOrder order() {
-#if[boS]
-        return ((ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN)
-                ? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN);
-#end[boS]
-#if[boU]
-        return ((ByteOrder.nativeOrder() != ByteOrder.BIG_ENDIAN)
-                ? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN);
-#end[boU]
-    }
-
-#end[!byte]
-
-
-
-#if[byte]
-
-    byte _get(int i) {                          // package-private
-        return unsafe.getByte(address + i);
-    }
-
-    void _put(int i, byte b) {                  // package-private
-#if[rw]
-        unsafe.putByte(address + i, b);
-#else[rw]
-        throw new ReadOnlyBufferException();
-#end[rw]
-    }
-
-    // #BIN
-    //
-    // Binary-data access methods  for short, char, int, long, float,
-    // and double will be inserted here
-
-#end[byte]
-
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/nio/Direct-X-Buffer.java.template	Wed Jul 05 17:02:50 2017 +0200
@@ -0,0 +1,464 @@
+/*
+ * Copyright 2000-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.
+ */
+
+#warn This file is preprocessed before being compiled
+
+package java.nio;
+
+import sun.misc.Cleaner;
+import sun.misc.Unsafe;
+import sun.nio.ch.DirectBuffer;
+
+
+class Direct$Type$Buffer$RW$$BO$
+#if[rw]
+    extends {#if[byte]?Mapped$Type$Buffer:$Type$Buffer}
+#else[rw]
+    extends Direct$Type$Buffer$BO$
+#end[rw]
+    implements DirectBuffer
+{
+
+#if[rw]
+
+    // Cached unsafe-access object
+    protected static final Unsafe unsafe = Bits.unsafe();
+
+    // Cached array base offset
+    private static final long arrayBaseOffset = (long)unsafe.arrayBaseOffset($type$[].class);
+
+    // Cached unaligned-access capability
+    protected static final boolean unaligned = Bits.unaligned();
+
+    // Base address, used in all indexing calculations
+    // NOTE: moved up to Buffer.java for speed in JNI GetDirectBufferAddress
+    //    protected long address;
+
+    // If this buffer is a view of another buffer then we keep a reference to
+    // that buffer so that its memory isn't freed before we're done with it
+    protected Object viewedBuffer = null;
+
+    public Object viewedBuffer() {
+        return viewedBuffer;
+    }
+
+#if[byte]
+
+    private static class Deallocator
+        implements Runnable
+    {
+
+        private static Unsafe unsafe = Unsafe.getUnsafe();
+
+        private long address;
+        private long size;
+        private int capacity;
+
+        private Deallocator(long address, long size, int capacity) {
+            assert (address != 0);
+            this.address = address;
+            this.size = size;
+            this.capacity = capacity;
+        }
+
+        public void run() {
+            if (address == 0) {
+                // Paranoia
+                return;
+            }
+            unsafe.freeMemory(address);
+            address = 0;
+            Bits.unreserveMemory(size, capacity);
+        }
+
+    }
+
+    private final Cleaner cleaner;
+
+    public Cleaner cleaner() { return cleaner; }
+
+#else[byte]
+
+    public Cleaner cleaner() { return null; }
+
+#end[byte]
+
+#end[rw]
+
+#if[byte]
+
+    // Primary constructor
+    //
+    Direct$Type$Buffer$RW$(int cap) {                   // package-private
+#if[rw]
+        super(-1, 0, cap, cap, false);
+        int ps = Bits.pageSize();
+        int size = cap + ps;
+        Bits.reserveMemory(size, cap);
+
+        long base = 0;
+        try {
+            base = unsafe.allocateMemory(size);
+        } catch (OutOfMemoryError x) {
+            Bits.unreserveMemory(size, cap);
+            throw x;
+        }
+        unsafe.setMemory(base, size, (byte) 0);
+        if (base % ps != 0) {
+            // Round up to page boundary
+            address = base + ps - (base & (ps - 1));
+        } else {
+            address = base;
+        }
+        cleaner = Cleaner.create(this, new Deallocator(base, size, cap));
+#else[rw]
+        super(cap);
+#end[rw]
+    }
+
+#if[rw]
+
+    // Invoked only by JNI: NewDirectByteBuffer(void*, long)
+    //
+    private Direct$Type$Buffer(long addr, int cap) {
+        super(-1, 0, cap, cap, false);
+        address = addr;
+        cleaner = null;
+    }
+
+#end[rw]
+
+    // For memory-mapped buffers -- invoked by FileChannelImpl via reflection
+    //
+    protected Direct$Type$Buffer$RW$(int cap, long addr, Runnable unmapper) {
+#if[rw]
+        super(-1, 0, cap, cap, true);
+        address = addr;
+        viewedBuffer = null;
+        cleaner = Cleaner.create(this, unmapper);
+#else[rw]
+        super(cap, addr, unmapper);
+#end[rw]
+    }
+
+#end[byte]
+
+    // For duplicates and slices
+    //
+    Direct$Type$Buffer$RW$$BO$(DirectBuffer db,         // package-private
+                               int mark, int pos, int lim, int cap,
+                               int off)
+    {
+#if[rw]
+        super(mark, pos, lim, cap);
+        address = db.address() + off;
+        viewedBuffer = db;
+#if[byte]
+        cleaner = null;
+#end[byte]
+#else[rw]
+        super(db, mark, pos, lim, cap, off);
+#end[rw]
+    }
+
+    public $Type$Buffer slice() {
+        int pos = this.position();
+        int lim = this.limit();
+        assert (pos <= lim);
+        int rem = (pos <= lim ? lim - pos : 0);
+        int off = (pos << $LG_BYTES_PER_VALUE$);
+        assert (off >= 0);
+        return new Direct$Type$Buffer$RW$$BO$(this, -1, 0, rem, rem, off);
+    }
+
+    public $Type$Buffer duplicate() {
+        return new Direct$Type$Buffer$RW$$BO$(this,
+                                              this.markValue(),
+                                              this.position(),
+                                              this.limit(),
+                                              this.capacity(),
+                                              0);
+    }
+
+    public $Type$Buffer asReadOnlyBuffer() {
+#if[rw]
+        return new Direct$Type$BufferR$BO$(this,
+                                           this.markValue(),
+                                           this.position(),
+                                           this.limit(),
+                                           this.capacity(),
+                                           0);
+#else[rw]
+        return duplicate();
+#end[rw]
+    }
+
+#if[rw]
+
+    public long address() {
+        return address;
+    }
+
+    private long ix(int i) {
+        return address + (i << $LG_BYTES_PER_VALUE$);
+    }
+
+    public $type$ get() {
+        return $fromBits$($swap$(unsafe.get$Swaptype$(ix(nextGetIndex()))));
+    }
+
+    public $type$ get(int i) {
+        return $fromBits$($swap$(unsafe.get$Swaptype$(ix(checkIndex(i)))));
+    }
+
+    public $Type$Buffer get($type$[] dst, int offset, int length) {
+#if[rw]
+        if ((length << $LG_BYTES_PER_VALUE$) > Bits.JNI_COPY_TO_ARRAY_THRESHOLD) {
+            checkBounds(offset, length, dst.length);
+            int pos = position();
+            int lim = limit();
+            assert (pos <= lim);
+            int rem = (pos <= lim ? lim - pos : 0);
+            if (length > rem)
+                throw new BufferUnderflowException();
+
+#if[!byte]
+            if (order() != ByteOrder.nativeOrder())
+                Bits.copyTo$Memtype$Array(ix(pos), dst,
+                                          offset << $LG_BYTES_PER_VALUE$,
+                                          length << $LG_BYTES_PER_VALUE$);
+            else
+#end[!byte]
+                Bits.copyToArray(ix(pos), dst, arrayBaseOffset,
+                                 offset << $LG_BYTES_PER_VALUE$,
+                                 length << $LG_BYTES_PER_VALUE$);
+            position(pos + length);
+        } else {
+            super.get(dst, offset, length);
+        }
+        return this;
+#else[rw]
+        throw new ReadOnlyBufferException();
+#end[rw]
+    }
+
+#end[rw]
+
+    public $Type$Buffer put($type$ x) {
+#if[rw]
+        unsafe.put$Swaptype$(ix(nextPutIndex()), $swap$($toBits$(x)));
+        return this;
+#else[rw]
+        throw new ReadOnlyBufferException();
+#end[rw]
+    }
+
+    public $Type$Buffer put(int i, $type$ x) {
+#if[rw]
+        unsafe.put$Swaptype$(ix(checkIndex(i)), $swap$($toBits$(x)));
+        return this;
+#else[rw]
+        throw new ReadOnlyBufferException();
+#end[rw]
+    }
+
+    public $Type$Buffer put($Type$Buffer src) {
+#if[rw]
+        if (src instanceof Direct$Type$Buffer$BO$) {
+            if (src == this)
+                throw new IllegalArgumentException();
+            Direct$Type$Buffer$RW$$BO$ sb = (Direct$Type$Buffer$RW$$BO$)src;
+
+            int spos = sb.position();
+            int slim = sb.limit();
+            assert (spos <= slim);
+            int srem = (spos <= slim ? slim - spos : 0);
+
+            int pos = position();
+            int lim = limit();
+            assert (pos <= lim);
+            int rem = (pos <= lim ? lim - pos : 0);
+
+            if (srem > rem)
+                throw new BufferOverflowException();
+            unsafe.copyMemory(sb.ix(spos), ix(pos), srem << $LG_BYTES_PER_VALUE$);
+            sb.position(spos + srem);
+            position(pos + srem);
+        } else if (src.hb != null) {
+
+            int spos = src.position();
+            int slim = src.limit();
+            assert (spos <= slim);
+            int srem = (spos <= slim ? slim - spos : 0);
+
+            put(src.hb, src.offset + spos, srem);
+            src.position(spos + srem);
+
+        } else {
+            super.put(src);
+        }
+        return this;
+#else[rw]
+        throw new ReadOnlyBufferException();
+#end[rw]
+    }
+
+    public $Type$Buffer put($type$[] src, int offset, int length) {
+#if[rw]
+        if ((length << $LG_BYTES_PER_VALUE$) > Bits.JNI_COPY_FROM_ARRAY_THRESHOLD) {
+            checkBounds(offset, length, src.length);
+            int pos = position();
+            int lim = limit();
+            assert (pos <= lim);
+            int rem = (pos <= lim ? lim - pos : 0);
+            if (length > rem)
+                throw new BufferOverflowException();
+
+#if[!byte]
+            if (order() != ByteOrder.nativeOrder())
+                Bits.copyFrom$Memtype$Array(src, offset << $LG_BYTES_PER_VALUE$,
+                                            ix(pos), length << $LG_BYTES_PER_VALUE$);
+            else
+#end[!byte]
+                Bits.copyFromArray(src, arrayBaseOffset, offset << $LG_BYTES_PER_VALUE$,
+                                   ix(pos), length << $LG_BYTES_PER_VALUE$);
+            position(pos + length);
+        } else {
+            super.put(src, offset, length);
+        }
+        return this;
+#else[rw]
+        throw new ReadOnlyBufferException();
+#end[rw]
+    }
+
+    public $Type$Buffer compact() {
+#if[rw]
+        int pos = position();
+        int lim = limit();
+        assert (pos <= lim);
+        int rem = (pos <= lim ? lim - pos : 0);
+
+        unsafe.copyMemory(ix(pos), ix(0), rem << $LG_BYTES_PER_VALUE$);
+        position(rem);
+        limit(capacity());
+        discardMark();
+        return this;
+#else[rw]
+        throw new ReadOnlyBufferException();
+#end[rw]
+    }
+
+    public boolean isDirect() {
+        return true;
+    }
+
+    public boolean isReadOnly() {
+        return {#if[rw]?false:true};
+    }
+
+
+#if[char]
+
+    public String toString(int start, int end) {
+        if ((end > limit()) || (start > end))
+            throw new IndexOutOfBoundsException();
+        try {
+            int len = end - start;
+            char[] ca = new char[len];
+            CharBuffer cb = CharBuffer.wrap(ca);
+            CharBuffer db = this.duplicate();
+            db.position(start);
+            db.limit(end);
+            cb.put(db);
+            return new String(ca);
+        } catch (StringIndexOutOfBoundsException x) {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+
+
+    // --- Methods to support CharSequence ---
+
+    public CharBuffer subSequence(int start, int end) {
+        int pos = position();
+        int lim = limit();
+        assert (pos <= lim);
+        pos = (pos <= lim ? pos : lim);
+        int len = lim - pos;
+
+        if ((start < 0) || (end > len) || (start > end))
+            throw new IndexOutOfBoundsException();
+        return new DirectCharBuffer$RW$$BO$(this,
+                                            -1,
+                                            pos + start,
+                                            pos + end,
+                                            capacity(),
+                                            offset);
+    }
+
+#end[char]
+
+
+
+#if[!byte]
+
+    public ByteOrder order() {
+#if[boS]
+        return ((ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN)
+                ? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN);
+#end[boS]
+#if[boU]
+        return ((ByteOrder.nativeOrder() != ByteOrder.BIG_ENDIAN)
+                ? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN);
+#end[boU]
+    }
+
+#end[!byte]
+
+
+
+#if[byte]
+
+    byte _get(int i) {                          // package-private
+        return unsafe.getByte(address + i);
+    }
+
+    void _put(int i, byte b) {                  // package-private
+#if[rw]
+        unsafe.putByte(address + i, b);
+#else[rw]
+        throw new ReadOnlyBufferException();
+#end[rw]
+    }
+
+    // #BIN
+    //
+    // Binary-data access methods  for short, char, int, long, float,
+    // and double will be inserted here
+
+#end[byte]
+
+}
--- a/jdk/src/share/classes/java/nio/Heap-X-Buffer.java	Sun Nov 08 14:49:40 2009 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,595 +0,0 @@
-/*
- * Copyright 2000-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.
- */
-
-#warn This file is preprocessed before being compiled
-
-package java.nio;
-
-
-/**
-#if[rw]
- * A read/write Heap$Type$Buffer.
-#else[rw]
- * A read-only Heap$Type$Buffer.  This class extends the corresponding
- * read/write class, overriding the mutation methods to throw a {@link
- * ReadOnlyBufferException} and overriding the view-buffer methods to return an
- * instance of this class rather than of the superclass.
-#end[rw]
- */
-
-class Heap$Type$Buffer$RW$
-    extends {#if[ro]?Heap}$Type$Buffer
-{
-
-    // For speed these fields are actually declared in X-Buffer;
-    // these declarations are here as documentation
-    /*
-#if[rw]
-    protected final $type$[] hb;
-    protected final int offset;
-#end[rw]
-    */
-
-    Heap$Type$Buffer$RW$(int cap, int lim) {            // package-private
-#if[rw]
-        super(-1, 0, lim, cap, new $type$[cap], 0);
-        /*
-        hb = new $type$[cap];
-        offset = 0;
-        */
-#else[rw]
-        super(cap, lim);
-        this.isReadOnly = true;
-#end[rw]
-    }
-
-    Heap$Type$Buffer$RW$($type$[] buf, int off, int len) { // package-private
-#if[rw]
-        super(-1, off, off + len, buf.length, buf, 0);
-        /*
-        hb = buf;
-        offset = 0;
-        */
-#else[rw]
-        super(buf, off, len);
-        this.isReadOnly = true;
-#end[rw]
-    }
-
-    protected Heap$Type$Buffer$RW$($type$[] buf,
-                                   int mark, int pos, int lim, int cap,
-                                   int off)
-    {
-#if[rw]
-        super(mark, pos, lim, cap, buf, off);
-        /*
-        hb = buf;
-        offset = off;
-        */
-#else[rw]
-        super(buf, mark, pos, lim, cap, off);
-        this.isReadOnly = true;
-#end[rw]
-    }
-
-    public $Type$Buffer slice() {
-        return new Heap$Type$Buffer$RW$(hb,
-                                        -1,
-                                        0,
-                                        this.remaining(),
-                                        this.remaining(),
-                                        this.position() + offset);
-    }
-
-    public $Type$Buffer duplicate() {
-        return new Heap$Type$Buffer$RW$(hb,
-                                        this.markValue(),
-                                        this.position(),
-                                        this.limit(),
-                                        this.capacity(),
-                                        offset);
-    }
-
-    public $Type$Buffer asReadOnlyBuffer() {
-#if[rw]
-        return new Heap$Type$BufferR(hb,
-                                     this.markValue(),
-                                     this.position(),
-                                     this.limit(),
-                                     this.capacity(),
-                                     offset);
-#else[rw]
-        return duplicate();
-#end[rw]
-    }
-
-#if[rw]
-
-    protected int ix(int i) {
-        return i + offset;
-    }
-
-    public $type$ get() {
-        return hb[ix(nextGetIndex())];
-    }
-
-    public $type$ get(int i) {
-        return hb[ix(checkIndex(i))];
-    }
-
-    public $Type$Buffer get($type$[] dst, int offset, int length) {
-        checkBounds(offset, length, dst.length);
-        if (length > remaining())
-            throw new BufferUnderflowException();
-        System.arraycopy(hb, ix(position()), dst, offset, length);
-        position(position() + length);
-        return this;
-    }
-
-    public boolean isDirect() {
-        return false;
-    }
-
-#end[rw]
-
-    public boolean isReadOnly() {
-        return {#if[rw]?false:true};
-    }
-
-    public $Type$Buffer put($type$ x) {
-#if[rw]
-        hb[ix(nextPutIndex())] = x;
-        return this;
-#else[rw]
-        throw new ReadOnlyBufferException();
-#end[rw]
-    }
-
-    public $Type$Buffer put(int i, $type$ x) {
-#if[rw]
-        hb[ix(checkIndex(i))] = x;
-        return this;
-#else[rw]
-        throw new ReadOnlyBufferException();
-#end[rw]
-    }
-
-    public $Type$Buffer put($type$[] src, int offset, int length) {
-#if[rw]
-        checkBounds(offset, length, src.length);
-        if (length > remaining())
-            throw new BufferOverflowException();
-        System.arraycopy(src, offset, hb, ix(position()), length);
-        position(position() + length);
-        return this;
-#else[rw]
-        throw new ReadOnlyBufferException();
-#end[rw]
-    }
-
-    public $Type$Buffer put($Type$Buffer src) {
-#if[rw]
-        if (src instanceof Heap$Type$Buffer) {
-            if (src == this)
-                throw new IllegalArgumentException();
-            Heap$Type$Buffer sb = (Heap$Type$Buffer)src;
-            int n = sb.remaining();
-            if (n > remaining())
-                throw new BufferOverflowException();
-            System.arraycopy(sb.hb, sb.ix(sb.position()),
-                             hb, ix(position()), n);
-            sb.position(sb.position() + n);
-            position(position() + n);
-        } else if (src.isDirect()) {
-            int n = src.remaining();
-            if (n > remaining())
-                throw new BufferOverflowException();
-            src.get(hb, ix(position()), n);
-            position(position() + n);
-        } else {
-            super.put(src);
-        }
-        return this;
-#else[rw]
-        throw new ReadOnlyBufferException();
-#end[rw]
-    }
-
-    public $Type$Buffer compact() {
-#if[rw]
-        System.arraycopy(hb, ix(position()), hb, ix(0), remaining());
-        position(remaining());
-        limit(capacity());
-        discardMark();
-        return this;
-#else[rw]
-        throw new ReadOnlyBufferException();
-#end[rw]
-    }
-
-
-
-#if[byte]
-
-    byte _get(int i) {                          // package-private
-        return hb[i];
-    }
-
-    void _put(int i, byte b) {                  // package-private
-#if[rw]
-        hb[i] = b;
-#else[rw]
-        throw new ReadOnlyBufferException();
-#end[rw]
-    }
-
-    // char
-
-#if[rw]
-
-    public char getChar() {
-        return Bits.getChar(this, ix(nextGetIndex(2)), bigEndian);
-    }
-
-    public char getChar(int i) {
-        return Bits.getChar(this, ix(checkIndex(i, 2)), bigEndian);
-    }
-
-#end[rw]
-
-    public $Type$Buffer putChar(char x) {
-#if[rw]
-        Bits.putChar(this, ix(nextPutIndex(2)), x, bigEndian);
-        return this;
-#else[rw]
-        throw new ReadOnlyBufferException();
-#end[rw]
-    }
-
-    public $Type$Buffer putChar(int i, char x) {
-#if[rw]
-        Bits.putChar(this, ix(checkIndex(i, 2)), x, bigEndian);
-        return this;
-#else[rw]
-        throw new ReadOnlyBufferException();
-#end[rw]
-    }
-
-    public CharBuffer asCharBuffer() {
-        int size = this.remaining() >> 1;
-        int off = offset + position();
-        return (bigEndian
-                ? (CharBuffer)(new ByteBufferAsCharBuffer$RW$B(this,
-                                                               -1,
-                                                               0,
-                                                               size,
-                                                               size,
-                                                               off))
-                : (CharBuffer)(new ByteBufferAsCharBuffer$RW$L(this,
-                                                               -1,
-                                                               0,
-                                                               size,
-                                                               size,
-                                                               off)));
-    }
-
-
-    // short
-
-#if[rw]
-
-    public short getShort() {
-        return Bits.getShort(this, ix(nextGetIndex(2)), bigEndian);
-    }
-
-    public short getShort(int i) {
-        return Bits.getShort(this, ix(checkIndex(i, 2)), bigEndian);
-    }
-
-#end[rw]
-
-    public $Type$Buffer putShort(short x) {
-#if[rw]
-        Bits.putShort(this, ix(nextPutIndex(2)), x, bigEndian);
-        return this;
-#else[rw]
-        throw new ReadOnlyBufferException();
-#end[rw]
-    }
-
-    public $Type$Buffer putShort(int i, short x) {
-#if[rw]
-        Bits.putShort(this, ix(checkIndex(i, 2)), x, bigEndian);
-        return this;
-#else[rw]
-        throw new ReadOnlyBufferException();
-#end[rw]
-    }
-
-    public ShortBuffer asShortBuffer() {
-        int size = this.remaining() >> 1;
-        int off = offset + position();
-        return (bigEndian
-                ? (ShortBuffer)(new ByteBufferAsShortBuffer$RW$B(this,
-                                                                 -1,
-                                                                 0,
-                                                                 size,
-                                                                 size,
-                                                                 off))
-                : (ShortBuffer)(new ByteBufferAsShortBuffer$RW$L(this,
-                                                                 -1,
-                                                                 0,
-                                                                 size,
-                                                                 size,
-                                                                 off)));
-    }
-
-
-    // int
-
-#if[rw]
-
-    public int getInt() {
-        return Bits.getInt(this, ix(nextGetIndex(4)), bigEndian);
-    }
-
-    public int getInt(int i) {
-        return Bits.getInt(this, ix(checkIndex(i, 4)), bigEndian);
-    }
-
-#end[rw]
-
-    public $Type$Buffer putInt(int x) {
-#if[rw]
-        Bits.putInt(this, ix(nextPutIndex(4)), x, bigEndian);
-        return this;
-#else[rw]
-        throw new ReadOnlyBufferException();
-#end[rw]
-    }
-
-    public $Type$Buffer putInt(int i, int x) {
-#if[rw]
-        Bits.putInt(this, ix(checkIndex(i, 4)), x, bigEndian);
-        return this;
-#else[rw]
-        throw new ReadOnlyBufferException();
-#end[rw]
-    }
-
-    public IntBuffer asIntBuffer() {
-        int size = this.remaining() >> 2;
-        int off = offset + position();
-        return (bigEndian
-                ? (IntBuffer)(new ByteBufferAsIntBuffer$RW$B(this,
-                                                             -1,
-                                                             0,
-                                                             size,
-                                                             size,
-                                                             off))
-                : (IntBuffer)(new ByteBufferAsIntBuffer$RW$L(this,
-                                                             -1,
-                                                             0,
-                                                             size,
-                                                             size,
-                                                             off)));
-    }
-
-
-    // long
-
-#if[rw]
-
-    public long getLong() {
-        return Bits.getLong(this, ix(nextGetIndex(8)), bigEndian);
-    }
-
-    public long getLong(int i) {
-        return Bits.getLong(this, ix(checkIndex(i, 8)), bigEndian);
-    }
-
-#end[rw]
-
-    public $Type$Buffer putLong(long x) {
-#if[rw]
-        Bits.putLong(this, ix(nextPutIndex(8)), x, bigEndian);
-        return this;
-#else[rw]
-        throw new ReadOnlyBufferException();
-#end[rw]
-    }
-
-    public $Type$Buffer putLong(int i, long x) {
-#if[rw]
-        Bits.putLong(this, ix(checkIndex(i, 8)), x, bigEndian);
-        return this;
-#else[rw]
-        throw new ReadOnlyBufferException();
-#end[rw]
-    }
-
-    public LongBuffer asLongBuffer() {
-        int size = this.remaining() >> 3;
-        int off = offset + position();
-        return (bigEndian
-                ? (LongBuffer)(new ByteBufferAsLongBuffer$RW$B(this,
-                                                               -1,
-                                                               0,
-                                                               size,
-                                                               size,
-                                                               off))
-                : (LongBuffer)(new ByteBufferAsLongBuffer$RW$L(this,
-                                                               -1,
-                                                               0,
-                                                               size,
-                                                               size,
-                                                               off)));
-    }
-
-
-    // float
-
-#if[rw]
-
-    public float getFloat() {
-        return Bits.getFloat(this, ix(nextGetIndex(4)), bigEndian);
-    }
-
-    public float getFloat(int i) {
-        return Bits.getFloat(this, ix(checkIndex(i, 4)), bigEndian);
-    }
-
-#end[rw]
-
-    public $Type$Buffer putFloat(float x) {
-#if[rw]
-        Bits.putFloat(this, ix(nextPutIndex(4)), x, bigEndian);
-        return this;
-#else[rw]
-        throw new ReadOnlyBufferException();
-#end[rw]
-    }
-
-    public $Type$Buffer putFloat(int i, float x) {
-#if[rw]
-        Bits.putFloat(this, ix(checkIndex(i, 4)), x, bigEndian);
-        return this;
-#else[rw]
-        throw new ReadOnlyBufferException();
-#end[rw]
-    }
-
-    public FloatBuffer asFloatBuffer() {
-        int size = this.remaining() >> 2;
-        int off = offset + position();
-        return (bigEndian
-                ? (FloatBuffer)(new ByteBufferAsFloatBuffer$RW$B(this,
-                                                                 -1,
-                                                                 0,
-                                                                 size,
-                                                                 size,
-                                                                 off))
-                : (FloatBuffer)(new ByteBufferAsFloatBuffer$RW$L(this,
-                                                                 -1,
-                                                                 0,
-                                                                 size,
-                                                                 size,
-                                                                 off)));
-    }
-
-
-    // double
-
-#if[rw]
-
-    public double getDouble() {
-        return Bits.getDouble(this, ix(nextGetIndex(8)), bigEndian);
-    }
-
-    public double getDouble(int i) {
-        return Bits.getDouble(this, ix(checkIndex(i, 8)), bigEndian);
-    }
-
-#end[rw]
-
-    public $Type$Buffer putDouble(double x) {
-#if[rw]
-        Bits.putDouble(this, ix(nextPutIndex(8)), x, bigEndian);
-        return this;
-#else[rw]
-        throw new ReadOnlyBufferException();
-#end[rw]
-    }
-
-    public $Type$Buffer putDouble(int i, double x) {
-#if[rw]
-        Bits.putDouble(this, ix(checkIndex(i, 8)), x, bigEndian);
-        return this;
-#else[rw]
-        throw new ReadOnlyBufferException();
-#end[rw]
-    }
-
-    public DoubleBuffer asDoubleBuffer() {
-        int size = this.remaining() >> 3;
-        int off = offset + position();
-        return (bigEndian
-                ? (DoubleBuffer)(new ByteBufferAsDoubleBuffer$RW$B(this,
-                                                                   -1,
-                                                                   0,
-                                                                   size,
-                                                                   size,
-                                                                   off))
-                : (DoubleBuffer)(new ByteBufferAsDoubleBuffer$RW$L(this,
-                                                                   -1,
-                                                                   0,
-                                                                   size,
-                                                                   size,
-                                                                   off)));
-    }
-
-
-#end[byte]
-
-
-#if[char]
-
-    String toString(int start, int end) {               // package-private
-        try {
-            return new String(hb, start + offset, end - start);
-        } catch (StringIndexOutOfBoundsException x) {
-            throw new IndexOutOfBoundsException();
-        }
-    }
-
-
-    // --- Methods to support CharSequence ---
-
-    public CharBuffer subSequence(int start, int end) {
-        if ((start < 0)
-            || (end > length())
-            || (start > end))
-            throw new IndexOutOfBoundsException();
-        int pos = position();
-        return new HeapCharBuffer$RW$(hb,
-                                      -1,
-                                      pos + start,
-                                      pos + end,
-                                      capacity(),
-                                      offset);
-    }
-
-#end[char]
-
-
-#if[!byte]
-
-    public ByteOrder order() {
-        return ByteOrder.nativeOrder();
-    }
-
-#end[!byte]
-
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/nio/Heap-X-Buffer.java.template	Wed Jul 05 17:02:50 2017 +0200
@@ -0,0 +1,595 @@
+/*
+ * Copyright 2000-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.
+ */
+
+#warn This file is preprocessed before being compiled
+
+package java.nio;
+
+
+/**
+#if[rw]
+ * A read/write Heap$Type$Buffer.
+#else[rw]
+ * A read-only Heap$Type$Buffer.  This class extends the corresponding
+ * read/write class, overriding the mutation methods to throw a {@link
+ * ReadOnlyBufferException} and overriding the view-buffer methods to return an
+ * instance of this class rather than of the superclass.
+#end[rw]
+ */
+
+class Heap$Type$Buffer$RW$
+    extends {#if[ro]?Heap}$Type$Buffer
+{
+
+    // For speed these fields are actually declared in X-Buffer;
+    // these declarations are here as documentation
+    /*
+#if[rw]
+    protected final $type$[] hb;
+    protected final int offset;
+#end[rw]
+    */
+
+    Heap$Type$Buffer$RW$(int cap, int lim) {            // package-private
+#if[rw]
+        super(-1, 0, lim, cap, new $type$[cap], 0);
+        /*
+        hb = new $type$[cap];
+        offset = 0;
+        */
+#else[rw]
+        super(cap, lim);
+        this.isReadOnly = true;
+#end[rw]
+    }
+
+    Heap$Type$Buffer$RW$($type$[] buf, int off, int len) { // package-private
+#if[rw]
+        super(-1, off, off + len, buf.length, buf, 0);
+        /*
+        hb = buf;
+        offset = 0;
+        */
+#else[rw]
+        super(buf, off, len);
+        this.isReadOnly = true;
+#end[rw]
+    }
+
+    protected Heap$Type$Buffer$RW$($type$[] buf,
+                                   int mark, int pos, int lim, int cap,
+                                   int off)
+    {
+#if[rw]
+        super(mark, pos, lim, cap, buf, off);
+        /*
+        hb = buf;
+        offset = off;
+        */
+#else[rw]
+        super(buf, mark, pos, lim, cap, off);
+        this.isReadOnly = true;
+#end[rw]
+    }
+
+    public $Type$Buffer slice() {
+        return new Heap$Type$Buffer$RW$(hb,
+                                        -1,
+                                        0,
+                                        this.remaining(),
+                                        this.remaining(),
+                                        this.position() + offset);
+    }
+
+    public $Type$Buffer duplicate() {
+        return new Heap$Type$Buffer$RW$(hb,
+                                        this.markValue(),
+                                        this.position(),
+                                        this.limit(),
+                                        this.capacity(),
+                                        offset);
+    }
+
+    public $Type$Buffer asReadOnlyBuffer() {
+#if[rw]
+        return new Heap$Type$BufferR(hb,
+                                     this.markValue(),
+                                     this.position(),
+                                     this.limit(),
+                                     this.capacity(),
+                                     offset);
+#else[rw]
+        return duplicate();
+#end[rw]
+    }
+
+#if[rw]
+
+    protected int ix(int i) {
+        return i + offset;
+    }
+
+    public $type$ get() {
+        return hb[ix(nextGetIndex())];
+    }
+
+    public $type$ get(int i) {
+        return hb[ix(checkIndex(i))];
+    }
+
+    public $Type$Buffer get($type$[] dst, int offset, int length) {
+        checkBounds(offset, length, dst.length);
+        if (length > remaining())
+            throw new BufferUnderflowException();
+        System.arraycopy(hb, ix(position()), dst, offset, length);
+        position(position() + length);
+        return this;
+    }
+
+    public boolean isDirect() {
+        return false;
+    }
+
+#end[rw]
+
+    public boolean isReadOnly() {
+        return {#if[rw]?false:true};
+    }
+
+    public $Type$Buffer put($type$ x) {
+#if[rw]
+        hb[ix(nextPutIndex())] = x;
+        return this;
+#else[rw]
+        throw new ReadOnlyBufferException();
+#end[rw]
+    }
+
+    public $Type$Buffer put(int i, $type$ x) {
+#if[rw]
+        hb[ix(checkIndex(i))] = x;
+        return this;
+#else[rw]
+        throw new ReadOnlyBufferException();
+#end[rw]
+    }
+
+    public $Type$Buffer put($type$[] src, int offset, int length) {
+#if[rw]
+        checkBounds(offset, length, src.length);
+        if (length > remaining())
+            throw new BufferOverflowException();
+        System.arraycopy(src, offset, hb, ix(position()), length);
+        position(position() + length);
+        return this;
+#else[rw]
+        throw new ReadOnlyBufferException();
+#end[rw]
+    }
+
+    public $Type$Buffer put($Type$Buffer src) {
+#if[rw]
+        if (src instanceof Heap$Type$Buffer) {
+            if (src == this)
+                throw new IllegalArgumentException();
+            Heap$Type$Buffer sb = (Heap$Type$Buffer)src;
+            int n = sb.remaining();
+            if (n > remaining())
+                throw new BufferOverflowException();
+            System.arraycopy(sb.hb, sb.ix(sb.position()),
+                             hb, ix(position()), n);
+            sb.position(sb.position() + n);
+            position(position() + n);
+        } else if (src.isDirect()) {
+            int n = src.remaining();
+            if (n > remaining())
+                throw new BufferOverflowException();
+            src.get(hb, ix(position()), n);
+            position(position() + n);
+        } else {
+            super.put(src);
+        }
+        return this;
+#else[rw]
+        throw new ReadOnlyBufferException();
+#end[rw]
+    }
+
+    public $Type$Buffer compact() {
+#if[rw]
+        System.arraycopy(hb, ix(position()), hb, ix(0), remaining());
+        position(remaining());
+        limit(capacity());
+        discardMark();
+        return this;
+#else[rw]
+        throw new ReadOnlyBufferException();
+#end[rw]
+    }
+
+
+
+#if[byte]
+
+    byte _get(int i) {                          // package-private
+        return hb[i];
+    }
+
+    void _put(int i, byte b) {                  // package-private
+#if[rw]
+        hb[i] = b;
+#else[rw]
+        throw new ReadOnlyBufferException();
+#end[rw]
+    }
+
+    // char
+
+#if[rw]
+
+    public char getChar() {
+        return Bits.getChar(this, ix(nextGetIndex(2)), bigEndian);
+    }
+
+    public char getChar(int i) {
+        return Bits.getChar(this, ix(checkIndex(i, 2)), bigEndian);
+    }
+
+#end[rw]
+
+    public $Type$Buffer putChar(char x) {
+#if[rw]
+        Bits.putChar(this, ix(nextPutIndex(2)), x, bigEndian);
+        return this;
+#else[rw]
+        throw new ReadOnlyBufferException();
+#end[rw]
+    }
+
+    public $Type$Buffer putChar(int i, char x) {
+#if[rw]
+        Bits.putChar(this, ix(checkIndex(i, 2)), x, bigEndian);
+        return this;
+#else[rw]
+        throw new ReadOnlyBufferException();
+#end[rw]
+    }
+
+    public CharBuffer asCharBuffer() {
+        int size = this.remaining() >> 1;
+        int off = offset + position();
+        return (bigEndian
+                ? (CharBuffer)(new ByteBufferAsCharBuffer$RW$B(this,
+                                                               -1,
+                                                               0,
+                                                               size,
+                                                               size,
+                                                               off))
+                : (CharBuffer)(new ByteBufferAsCharBuffer$RW$L(this,
+                                                               -1,
+                                                               0,
+                                                               size,
+                                                               size,
+                                                               off)));
+    }
+
+
+    // short
+
+#if[rw]
+
+    public short getShort() {
+        return Bits.getShort(this, ix(nextGetIndex(2)), bigEndian);
+    }
+
+    public short getShort(int i) {
+        return Bits.getShort(this, ix(checkIndex(i, 2)), bigEndian);
+    }
+
+#end[rw]
+
+    public $Type$Buffer putShort(short x) {
+#if[rw]
+        Bits.putShort(this, ix(nextPutIndex(2)), x, bigEndian);
+        return this;
+#else[rw]
+        throw new ReadOnlyBufferException();
+#end[rw]
+    }
+
+    public $Type$Buffer putShort(int i, short x) {
+#if[rw]
+        Bits.putShort(this, ix(checkIndex(i, 2)), x, bigEndian);
+        return this;
+#else[rw]
+        throw new ReadOnlyBufferException();
+#end[rw]
+    }
+
+    public ShortBuffer asShortBuffer() {
+        int size = this.remaining() >> 1;
+        int off = offset + position();
+        return (bigEndian
+                ? (ShortBuffer)(new ByteBufferAsShortBuffer$RW$B(this,
+                                                                 -1,
+                                                                 0,
+                                                                 size,
+                                                                 size,
+                                                                 off))
+                : (ShortBuffer)(new ByteBufferAsShortBuffer$RW$L(this,
+                                                                 -1,
+                                                                 0,
+                                                                 size,
+                                                                 size,
+                                                                 off)));
+    }
+
+
+    // int
+
+#if[rw]
+
+    public int getInt() {
+        return Bits.getInt(this, ix(nextGetIndex(4)), bigEndian);
+    }
+
+    public int getInt(int i) {
+        return Bits.getInt(this, ix(checkIndex(i, 4)), bigEndian);
+    }
+
+#end[rw]
+
+    public $Type$Buffer putInt(int x) {
+#if[rw]
+        Bits.putInt(this, ix(nextPutIndex(4)), x, bigEndian);
+        return this;
+#else[rw]
+        throw new ReadOnlyBufferException();
+#end[rw]
+    }
+
+    public $Type$Buffer putInt(int i, int x) {
+#if[rw]
+        Bits.putInt(this, ix(checkIndex(i, 4)), x, bigEndian);
+        return this;
+#else[rw]
+        throw new ReadOnlyBufferException();
+#end[rw]
+    }
+
+    public IntBuffer asIntBuffer() {
+        int size = this.remaining() >> 2;
+        int off = offset + position();
+        return (bigEndian
+                ? (IntBuffer)(new ByteBufferAsIntBuffer$RW$B(this,
+                                                             -1,
+                                                             0,
+                                                             size,
+                                                             size,
+                                                             off))
+                : (IntBuffer)(new ByteBufferAsIntBuffer$RW$L(this,
+                                                             -1,
+                                                             0,
+                                                             size,
+                                                             size,
+                                                             off)));
+    }
+
+
+    // long
+
+#if[rw]
+
+    public long getLong() {
+        return Bits.getLong(this, ix(nextGetIndex(8)), bigEndian);
+    }
+
+    public long getLong(int i) {
+        return Bits.getLong(this, ix(checkIndex(i, 8)), bigEndian);
+    }
+
+#end[rw]
+
+    public $Type$Buffer putLong(long x) {
+#if[rw]
+        Bits.putLong(this, ix(nextPutIndex(8)), x, bigEndian);
+        return this;
+#else[rw]
+        throw new ReadOnlyBufferException();
+#end[rw]
+    }
+
+    public $Type$Buffer putLong(int i, long x) {
+#if[rw]
+        Bits.putLong(this, ix(checkIndex(i, 8)), x, bigEndian);
+        return this;
+#else[rw]
+        throw new ReadOnlyBufferException();
+#end[rw]
+    }
+
+    public LongBuffer asLongBuffer() {
+        int size = this.remaining() >> 3;
+        int off = offset + position();
+        return (bigEndian
+                ? (LongBuffer)(new ByteBufferAsLongBuffer$RW$B(this,
+                                                               -1,
+                                                               0,
+                                                               size,
+                                                               size,
+                                                               off))
+                : (LongBuffer)(new ByteBufferAsLongBuffer$RW$L(this,
+                                                               -1,
+                                                               0,
+                                                               size,
+                                                               size,
+                                                               off)));
+    }
+
+
+    // float
+
+#if[rw]
+
+    public float getFloat() {
+        return Bits.getFloat(this, ix(nextGetIndex(4)), bigEndian);
+    }
+
+    public float getFloat(int i) {
+        return Bits.getFloat(this, ix(checkIndex(i, 4)), bigEndian);
+    }
+
+#end[rw]
+
+    public $Type$Buffer putFloat(float x) {
+#if[rw]
+        Bits.putFloat(this, ix(nextPutIndex(4)), x, bigEndian);
+        return this;
+#else[rw]
+        throw new ReadOnlyBufferException();
+#end[rw]
+    }
+
+    public $Type$Buffer putFloat(int i, float x) {
+#if[rw]
+        Bits.putFloat(this, ix(checkIndex(i, 4)), x, bigEndian);
+        return this;
+#else[rw]
+        throw new ReadOnlyBufferException();
+#end[rw]
+    }
+
+    public FloatBuffer asFloatBuffer() {
+        int size = this.remaining() >> 2;
+        int off = offset + position();
+        return (bigEndian
+                ? (FloatBuffer)(new ByteBufferAsFloatBuffer$RW$B(this,
+                                                                 -1,
+                                                                 0,
+                                                                 size,
+                                                                 size,
+                                                                 off))
+                : (FloatBuffer)(new ByteBufferAsFloatBuffer$RW$L(this,
+                                                                 -1,
+                                                                 0,
+                                                                 size,
+                                                                 size,
+                                                                 off)));
+    }
+
+
+    // double
+
+#if[rw]
+
+    public double getDouble() {
+        return Bits.getDouble(this, ix(nextGetIndex(8)), bigEndian);
+    }
+
+    public double getDouble(int i) {
+        return Bits.getDouble(this, ix(checkIndex(i, 8)), bigEndian);
+    }
+
+#end[rw]
+
+    public $Type$Buffer putDouble(double x) {
+#if[rw]
+        Bits.putDouble(this, ix(nextPutIndex(8)), x, bigEndian);
+        return this;
+#else[rw]
+        throw new ReadOnlyBufferException();
+#end[rw]
+    }
+
+    public $Type$Buffer putDouble(int i, double x) {
+#if[rw]
+        Bits.putDouble(this, ix(checkIndex(i, 8)), x, bigEndian);
+        return this;
+#else[rw]
+        throw new ReadOnlyBufferException();
+#end[rw]
+    }
+
+    public DoubleBuffer asDoubleBuffer() {
+        int size = this.remaining() >> 3;
+        int off = offset + position();
+        return (bigEndian
+                ? (DoubleBuffer)(new ByteBufferAsDoubleBuffer$RW$B(this,
+                                                                   -1,
+                                                                   0,
+                                                                   size,
+                                                                   size,
+                                                                   off))
+                : (DoubleBuffer)(new ByteBufferAsDoubleBuffer$RW$L(this,
+                                                                   -1,
+                                                                   0,
+                                                                   size,
+                                                                   size,
+                                                                   off)));
+    }
+
+
+#end[byte]
+
+
+#if[char]
+
+    String toString(int start, int end) {               // package-private
+        try {
+            return new String(hb, start + offset, end - start);
+        } catch (StringIndexOutOfBoundsException x) {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+
+
+    // --- Methods to support CharSequence ---
+
+    public CharBuffer subSequence(int start, int end) {
+        if ((start < 0)
+            || (end > length())
+            || (start > end))
+            throw new IndexOutOfBoundsException();
+        int pos = position();
+        return new HeapCharBuffer$RW$(hb,
+                                      -1,
+                                      pos + start,
+                                      pos + end,
+                                      capacity(),
+                                      offset);
+    }
+
+#end[char]
+
+
+#if[!byte]
+
+    public ByteOrder order() {
+        return ByteOrder.nativeOrder();
+    }
+
+#end[!byte]
+
+}
--- a/jdk/src/share/classes/java/nio/X-Buffer-bin.java	Sun Nov 08 14:49:40 2009 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,132 +0,0 @@
-/*
- * Copyright 2000-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.  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.
- */
-
-#warn This file is preprocessed before being compiled
-
-class XXX {
-
-#begin
-
-    /**
-     * Relative <i>get</i> method for reading $a$ $type$ value.
-     *
-     * <p> Reads the next $nbytes$ bytes at this buffer's current position,
-     * composing them into $a$ $type$ value according to the current byte order,
-     * and then increments the position by $nbytes$.  </p>
-     *
-     * @return  The $type$ value at the buffer's current position
-     *
-     * @throws  BufferUnderflowException
-     *          If there are fewer than $nbytes$ bytes
-     *          remaining in this buffer
-     */
-    public abstract $type$ get$Type$();
-
-    /**
-     * Relative <i>put</i> method for writing $a$ $type$
-     * value&nbsp;&nbsp;<i>(optional operation)</i>.
-     *
-     * <p> Writes $nbytes$ bytes containing the given $type$ value, in the
-     * current byte order, into this buffer at the current position, and then
-     * increments the position by $nbytes$.  </p>
-     *
-     * @param  value
-     *         The $type$ value to be written
-     *
-     * @return  This buffer
-     *
-     * @throws  BufferOverflowException
-     *          If there are fewer than $nbytes$ bytes
-     *          remaining in this buffer
-     *
-     * @throws  ReadOnlyBufferException
-     *          If this buffer is read-only
-     */
-    public abstract ByteBuffer put$Type$($type$ value);
-
-    /**
-     * Absolute <i>get</i> method for reading $a$ $type$ value.
-     *
-     * <p> Reads $nbytes$ bytes at the given index, composing them into a
-     * $type$ value according to the current byte order.  </p>
-     *
-     * @param  index
-     *         The index from which the bytes will be read
-     *
-     * @return  The $type$ value at the given index
-     *
-     * @throws  IndexOutOfBoundsException
-     *          If <tt>index</tt> is negative
-     *          or not smaller than the buffer's limit,
-     *          minus $nbytesButOne$
-     */
-    public abstract $type$ get$Type$(int index);
-
-    /**
-     * Absolute <i>put</i> method for writing $a$ $type$
-     * value&nbsp;&nbsp;<i>(optional operation)</i>.
-     *
-     * <p> Writes $nbytes$ bytes containing the given $type$ value, in the
-     * current byte order, into this buffer at the given index.  </p>
-     *
-     * @param  index
-     *         The index at which the bytes will be written
-     *
-     * @param  value
-     *         The $type$ value to be written
-     *
-     * @return  This buffer
-     *
-     * @throws  IndexOutOfBoundsException
-     *          If <tt>index</tt> is negative
-     *          or not smaller than the buffer's limit,
-     *          minus $nbytesButOne$
-     *
-     * @throws  ReadOnlyBufferException
-     *          If this buffer is read-only
-     */
-    public abstract ByteBuffer put$Type$(int index, $type$ value);
-
-    /**
-     * Creates a view of this byte buffer as $a$ $type$ buffer.
-     *
-     * <p> The content of the new buffer will start at this buffer's current
-     * position.  Changes to this buffer's content will be visible in the new
-     * buffer, and vice versa; the two buffers' position, limit, and mark
-     * values will be independent.
-     *
-     * <p> The new buffer's position will be zero, its capacity and its limit
-     * will be the number of bytes remaining in this buffer divided by
-     * $nbytes$, and its mark will be undefined.  The new buffer will be direct
-     * if, and only if, this buffer is direct, and it will be read-only if, and
-     * only if, this buffer is read-only.  </p>
-     *
-     * @return  A new $type$ buffer
-     */
-    public abstract $Type$Buffer as$Type$Buffer();
-
-#end
-
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/nio/X-Buffer-bin.java.template	Wed Jul 05 17:02:50 2017 +0200
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2000-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.  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.
+ */
+
+#warn This file is preprocessed before being compiled
+
+class XXX {
+
+#begin
+
+    /**
+     * Relative <i>get</i> method for reading $a$ $type$ value.
+     *
+     * <p> Reads the next $nbytes$ bytes at this buffer's current position,
+     * composing them into $a$ $type$ value according to the current byte order,
+     * and then increments the position by $nbytes$.  </p>
+     *
+     * @return  The $type$ value at the buffer's current position
+     *
+     * @throws  BufferUnderflowException
+     *          If there are fewer than $nbytes$ bytes
+     *          remaining in this buffer
+     */
+    public abstract $type$ get$Type$();
+
+    /**
+     * Relative <i>put</i> method for writing $a$ $type$
+     * value&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> Writes $nbytes$ bytes containing the given $type$ value, in the
+     * current byte order, into this buffer at the current position, and then
+     * increments the position by $nbytes$.  </p>
+     *
+     * @param  value
+     *         The $type$ value to be written
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If there are fewer than $nbytes$ bytes
+     *          remaining in this buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public abstract ByteBuffer put$Type$($type$ value);
+
+    /**
+     * Absolute <i>get</i> method for reading $a$ $type$ value.
+     *
+     * <p> Reads $nbytes$ bytes at the given index, composing them into a
+     * $type$ value according to the current byte order.  </p>
+     *
+     * @param  index
+     *         The index from which the bytes will be read
+     *
+     * @return  The $type$ value at the given index
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If <tt>index</tt> is negative
+     *          or not smaller than the buffer's limit,
+     *          minus $nbytesButOne$
+     */
+    public abstract $type$ get$Type$(int index);
+
+    /**
+     * Absolute <i>put</i> method for writing $a$ $type$
+     * value&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> Writes $nbytes$ bytes containing the given $type$ value, in the
+     * current byte order, into this buffer at the given index.  </p>
+     *
+     * @param  index
+     *         The index at which the bytes will be written
+     *
+     * @param  value
+     *         The $type$ value to be written
+     *
+     * @return  This buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If <tt>index</tt> is negative
+     *          or not smaller than the buffer's limit,
+     *          minus $nbytesButOne$
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public abstract ByteBuffer put$Type$(int index, $type$ value);
+
+    /**
+     * Creates a view of this byte buffer as $a$ $type$ buffer.
+     *
+     * <p> The content of the new buffer will start at this buffer's current
+     * position.  Changes to this buffer's content will be visible in the new
+     * buffer, and vice versa; the two buffers' position, limit, and mark
+     * values will be independent.
+     *
+     * <p> The new buffer's position will be zero, its capacity and its limit
+     * will be the number of bytes remaining in this buffer divided by
+     * $nbytes$, and its mark will be undefined.  The new buffer will be direct
+     * if, and only if, this buffer is direct, and it will be read-only if, and
+     * only if, this buffer is read-only.  </p>
+     *
+     * @return  A new $type$ buffer
+     */
+    public abstract $Type$Buffer as$Type$Buffer();
+
+#end
+
+}
--- a/jdk/src/share/classes/java/nio/X-Buffer.java	Sun Nov 08 14:49:40 2009 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1428 +0,0 @@
-/*
- * Copyright 2000-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.
- */
-
-#warn This file is preprocessed before being compiled
-
-package java.nio;
-
-#if[char]
-import java.io.IOException;
-#end[char]
-
-/**
- * $A$ $fulltype$ buffer.
- *
- * <p> This class defines {#if[byte]?six:four} categories of operations upon
- * $fulltype$ buffers:
- *
- * <ul>
- *
- *   <li><p> Absolute and relative {@link #get() </code><i>get</i><code>} and
- *   {@link #put($type$) </code><i>put</i><code>} methods that read and write
- *   single $fulltype$s; </p></li>
- *
- *   <li><p> Relative {@link #get($type$[]) </code><i>bulk get</i><code>}
- *   methods that transfer contiguous sequences of $fulltype$s from this buffer
- *   into an array; {#if[!byte]?and}</p></li>
- *
- *   <li><p> Relative {@link #put($type$[]) </code><i>bulk put</i><code>}
- *   methods that transfer contiguous sequences of $fulltype$s from $a$
- *   $fulltype$ array{#if[char]?,&#32;a&#32;string,} or some other $fulltype$
- *   buffer into this buffer;{#if[!byte]?&#32;and} </p></li>
- *
-#if[byte]
- *
- *   <li><p> Absolute and relative {@link #getChar() </code><i>get</i><code>}
- *   and {@link #putChar(char) </code><i>put</i><code>} methods that read and
- *   write values of other primitive types, translating them to and from
- *   sequences of bytes in a particular byte order; </p></li>
- *
- *   <li><p> Methods for creating <i><a href="#views">view buffers</a></i>,
- *   which allow a byte buffer to be viewed as a buffer containing values of
- *   some other primitive type; and </p></li>
- *
-#end[byte]
- *
- *   <li><p> Methods for {@link #compact </code>compacting<code>}, {@link
- *   #duplicate </code>duplicating<code>}, and {@link #slice
- *   </code>slicing<code>} $a$ $fulltype$ buffer.  </p></li>
- *
- * </ul>
- *
- * <p> $Fulltype$ buffers can be created either by {@link #allocate
- * </code><i>allocation</i><code>}, which allocates space for the buffer's
- *
-#if[byte]
- *
- * content, or by {@link #wrap($type$[]) </code><i>wrapping</i><code>} an
- * existing $fulltype$ array {#if[char]?or&#32;string} into a buffer.
- *
-#else[byte]
- *
- * content, by {@link #wrap($type$[]) </code><i>wrapping</i><code>} an existing
- * $fulltype$ array {#if[char]?or&#32;string} into a buffer, or by creating a
- * <a href="ByteBuffer.html#views"><i>view</i></a> of an existing byte buffer.
- *
-#end[byte]
- *
-#if[byte]
- *
- * <a name="direct">
- * <h4> Direct <i>vs.</i> non-direct buffers </h4>
- *
- * <p> A byte buffer is either <i>direct</i> or <i>non-direct</i>.  Given a
- * direct byte buffer, the Java virtual machine will make a best effort to
- * perform native I/O operations directly upon it.  That is, it will attempt to
- * avoid copying the buffer's content to (or from) an intermediate buffer
- * before (or after) each invocation of one of the underlying operating
- * system's native I/O operations.
- *
- * <p> A direct byte buffer may be created by invoking the {@link
- * #allocateDirect(int) allocateDirect} factory method of this class.  The
- * buffers returned by this method typically have somewhat higher allocation
- * and deallocation costs than non-direct buffers.  The contents of direct
- * buffers may reside outside of the normal garbage-collected heap, and so
- * their impact upon the memory footprint of an application might not be
- * obvious.  It is therefore recommended that direct buffers be allocated
- * primarily for large, long-lived buffers that are subject to the underlying
- * system's native I/O operations.  In general it is best to allocate direct
- * buffers only when they yield a measureable gain in program performance.
- *
- * <p> A direct byte buffer may also be created by {@link
- * java.nio.channels.FileChannel#map </code>mapping<code>} a region of a file
- * directly into memory.  An implementation of the Java platform may optionally
- * support the creation of direct byte buffers from native code via JNI.  If an
- * instance of one of these kinds of buffers refers to an inaccessible region
- * of memory then an attempt to access that region will not change the buffer's
- * content and will cause an unspecified exception to be thrown either at the
- * time of the access or at some later time.
- *
- * <p> Whether a byte buffer is direct or non-direct may be determined by
- * invoking its {@link #isDirect isDirect} method.  This method is provided so
- * that explicit buffer management can be done in performance-critical code.
- *
- *
- * <a name="bin">
- * <h4> Access to binary data </h4>
- *
- * <p> This class defines methods for reading and writing values of all other
- * primitive types, except <tt>boolean</tt>.  Primitive values are translated
- * to (or from) sequences of bytes according to the buffer's current byte
- * order, which may be retrieved and modified via the {@link #order order}
- * methods.  Specific byte orders are represented by instances of the {@link
- * ByteOrder} class.  The initial order of a byte buffer is always {@link
- * ByteOrder#BIG_ENDIAN BIG_ENDIAN}.
- *
- * <p> For access to heterogeneous binary data, that is, sequences of values of
- * different types, this class defines a family of absolute and relative
- * <i>get</i> and <i>put</i> methods for each type.  For 32-bit floating-point
- * values, for example, this class defines:
- *
- * <blockquote><pre>
- * float  {@link #getFloat()}
- * float  {@link #getFloat(int) getFloat(int index)}
- *  void  {@link #putFloat(float) putFloat(float f)}
- *  void  {@link #putFloat(int,float) putFloat(int index, float f)}</pre></blockquote>
- *
- * <p> Corresponding methods are defined for the types <tt>char</tt>,
- * <tt>short</tt>, <tt>int</tt>, <tt>long</tt>, and <tt>double</tt>.  The index
- * parameters of the absolute <i>get</i> and <i>put</i> methods are in terms of
- * bytes rather than of the type being read or written.
- *
- * <a name="views">
- *
- * <p> For access to homogeneous binary data, that is, sequences of values of
- * the same type, this class defines methods that can create <i>views</i> of a
- * given byte buffer.  A <i>view buffer</i> is simply another buffer whose
- * content is backed by the byte buffer.  Changes to the byte buffer's content
- * will be visible in the view buffer, and vice versa; the two buffers'
- * position, limit, and mark values are independent.  The {@link
- * #asFloatBuffer() asFloatBuffer} method, for example, creates an instance of
- * the {@link FloatBuffer} class that is backed by the byte buffer upon which
- * the method is invoked.  Corresponding view-creation methods are defined for
- * the types <tt>char</tt>, <tt>short</tt>, <tt>int</tt>, <tt>long</tt>, and
- * <tt>double</tt>.
- *
- * <p> View buffers have three important advantages over the families of
- * type-specific <i>get</i> and <i>put</i> methods described above:
- *
- * <ul>
- *
- *   <li><p> A view buffer is indexed not in terms of bytes but rather in terms
- *   of the type-specific size of its values;  </p></li>
- *
- *   <li><p> A view buffer provides relative bulk <i>get</i> and <i>put</i>
- *   methods that can transfer contiguous sequences of values between a buffer
- *   and an array or some other buffer of the same type; and  </p></li>
- *
- *   <li><p> A view buffer is potentially much more efficient because it will
- *   be direct if, and only if, its backing byte buffer is direct.  </p></li>
- *
- * </ul>
- *
- * <p> The byte order of a view buffer is fixed to be that of its byte buffer
- * at the time that the view is created.  </p>
- *
-#end[byte]
-*
-#if[!byte]
- *
- * <p> Like a byte buffer, $a$ $fulltype$ buffer is either <a
- * href="ByteBuffer.html#direct"><i>direct</i> or <i>non-direct</i></a>.  A
- * $fulltype$ buffer created via the <tt>wrap</tt> methods of this class will
- * be non-direct.  $A$ $fulltype$ buffer created as a view of a byte buffer will
- * be direct if, and only if, the byte buffer itself is direct.  Whether or not
- * $a$ $fulltype$ buffer is direct may be determined by invoking the {@link
- * #isDirect isDirect} method.  </p>
- *
-#end[!byte]
-*
-#if[char]
- *
- * <p> This class implements the {@link CharSequence} interface so that
- * character buffers may be used wherever character sequences are accepted, for
- * example in the regular-expression package <tt>{@link java.util.regex}</tt>.
- * </p>
- *
-#end[char]
- *
-#if[byte]
- * <h4> Invocation chaining </h4>
-#end[byte]
- *
- * <p> Methods in this class that do not otherwise have a value to return are
- * specified to return the buffer upon which they are invoked.  This allows
- * method invocations to be chained.
- *
-#if[byte]
- *
- * The sequence of statements
- *
- * <blockquote><pre>
- * bb.putInt(0xCAFEBABE);
- * bb.putShort(3);
- * bb.putShort(45);</pre></blockquote>
- *
- * can, for example, be replaced by the single statement
- *
- * <blockquote><pre>
- * bb.putInt(0xCAFEBABE).putShort(3).putShort(45);</pre></blockquote>
- *
-#end[byte]
-#if[char]
- *
- * The sequence of statements
- *
- * <blockquote><pre>
- * cb.put("text/");
- * cb.put(subtype);
- * cb.put("; charset=");
- * cb.put(enc);</pre></blockquote>
- *
- * can, for example, be replaced by the single statement
- *
- * <blockquote><pre>
- * cb.put("text/").put(subtype).put("; charset=").put(enc);</pre></blockquote>
- *
-#end[char]
- *
- *
- * @author Mark Reinhold
- * @author JSR-51 Expert Group
- * @since 1.4
- */
-
-public abstract class $Type$Buffer
-    extends Buffer
-    implements Comparable<$Type$Buffer>{#if[char]?, Appendable, CharSequence, Readable}
-{
-
-    // These fields are declared here rather than in Heap-X-Buffer in order to
-    // reduce the number of virtual method invocations needed to access these
-    // values, which is especially costly when coding small buffers.
-    //
-    final $type$[] hb;                  // Non-null only for heap buffers
-    final int offset;
-    boolean isReadOnly;                 // Valid only for heap buffers
-
-    // Creates a new buffer with the given mark, position, limit, capacity,
-    // backing array, and array offset
-    //
-    $Type$Buffer(int mark, int pos, int lim, int cap,   // package-private
-                 $type$[] hb, int offset)
-    {
-        super(mark, pos, lim, cap);
-        this.hb = hb;
-        this.offset = offset;
-    }
-
-    // Creates a new buffer with the given mark, position, limit, and capacity
-    //
-    $Type$Buffer(int mark, int pos, int lim, int cap) { // package-private
-        this(mark, pos, lim, cap, null, 0);
-    }
-
-#if[byte]
-
-    /**
-     * Allocates a new direct $fulltype$ buffer.
-     *
-     * <p> The new buffer's position will be zero, its limit will be its
-     * capacity, its mark will be undefined, and each of its elements will be
-     * initialized to zero.  Whether or not it has a
-     * {@link #hasArray </code>backing array<code>} is unspecified.
-     *
-     * @param  capacity
-     *         The new buffer's capacity, in $fulltype$s
-     *
-     * @return  The new $fulltype$ buffer
-     *
-     * @throws  IllegalArgumentException
-     *          If the <tt>capacity</tt> is a negative integer
-     */
-    public static $Type$Buffer allocateDirect(int capacity) {
-        return new Direct$Type$Buffer(capacity);
-    }
-
-#end[byte]
-
-    /**
-     * Allocates a new $fulltype$ buffer.
-     *
-     * <p> The new buffer's position will be zero, its limit will be its
-     * capacity, its mark will be undefined, and each of its elements will be
-     * initialized to zero.  It will have a {@link #array
-     * </code>backing array<code>}, and its {@link #arrayOffset </code>array
-     * offset<code>} will be zero.
-     *
-     * @param  capacity
-     *         The new buffer's capacity, in $fulltype$s
-     *
-     * @return  The new $fulltype$ buffer
-     *
-     * @throws  IllegalArgumentException
-     *          If the <tt>capacity</tt> is a negative integer
-     */
-    public static $Type$Buffer allocate(int capacity) {
-        if (capacity < 0)
-            throw new IllegalArgumentException();
-        return new Heap$Type$Buffer(capacity, capacity);
-    }
-
-    /**
-     * Wraps $a$ $fulltype$ array into a buffer.
-     *
-     * <p> The new buffer will be backed by the given $fulltype$ array;
-     * that is, modifications to the buffer will cause the array to be modified
-     * and vice versa.  The new buffer's capacity will be
-     * <tt>array.length</tt>, its position will be <tt>offset</tt>, its limit
-     * will be <tt>offset + length</tt>, and its mark will be undefined.  Its
-     * {@link #array </code>backing array<code>} will be the given array, and
-     * its {@link #arrayOffset </code>array offset<code>} will be zero.  </p>
-     *
-     * @param  array
-     *         The array that will back the new buffer
-     *
-     * @param  offset
-     *         The offset of the subarray to be used; must be non-negative and
-     *         no larger than <tt>array.length</tt>.  The new buffer's position
-     *         will be set to this value.
-     *
-     * @param  length
-     *         The length of the subarray to be used;
-     *         must be non-negative and no larger than
-     *         <tt>array.length - offset</tt>.
-     *         The new buffer's limit will be set to <tt>offset + length</tt>.
-     *
-     * @return  The new $fulltype$ buffer
-     *
-     * @throws  IndexOutOfBoundsException
-     *          If the preconditions on the <tt>offset</tt> and <tt>length</tt>
-     *          parameters do not hold
-     */
-    public static $Type$Buffer wrap($type$[] array,
-                                    int offset, int length)
-    {
-        try {
-            return new Heap$Type$Buffer(array, offset, length);
-        } catch (IllegalArgumentException x) {
-            throw new IndexOutOfBoundsException();
-        }
-    }
-
-    /**
-     * Wraps $a$ $fulltype$ array into a buffer.
-     *
-     * <p> The new buffer will be backed by the given $fulltype$ array;
-     * that is, modifications to the buffer will cause the array to be modified
-     * and vice versa.  The new buffer's capacity and limit will be
-     * <tt>array.length</tt>, its position will be zero, and its mark will be
-     * undefined.  Its {@link #array </code>backing array<code>} will be the
-     * given array, and its {@link #arrayOffset </code>array offset<code>} will
-     * be zero.  </p>
-     *
-     * @param  array
-     *         The array that will back this buffer
-     *
-     * @return  The new $fulltype$ buffer
-     */
-    public static $Type$Buffer wrap($type$[] array) {
-        return wrap(array, 0, array.length);
-    }
-
-#if[char]
-
-    /**
-     * Attempts to read characters into the specified character buffer.
-     * The buffer is used as a repository of characters as-is: the only
-     * changes made are the results of a put operation. No flipping or
-     * rewinding of the buffer is performed.
-     *
-     * @param target the buffer to read characters into
-     * @return The number of characters added to the buffer, or
-     *         -1 if this source of characters is at its end
-     * @throws IOException if an I/O error occurs
-     * @throws NullPointerException if target is null
-     * @throws ReadOnlyBufferException if target is a read only buffer
-     * @since 1.5
-     */
-    public int read(CharBuffer target) throws IOException {
-        // Determine the number of bytes n that can be transferred
-        int targetRemaining = target.remaining();
-        int remaining = remaining();
-        if (remaining == 0)
-            return -1;
-        int n = Math.min(remaining, targetRemaining);
-        int limit = limit();
-        // Set source limit to prevent target overflow
-        if (targetRemaining < remaining)
-            limit(position() + n);
-        try {
-            if (n > 0)
-                target.put(this);
-        } finally {
-            limit(limit); // restore real limit
-        }
-        return n;
-    }
-
-    /**
-     * Wraps a character sequence into a buffer.
-     *
-     * <p> The content of the new, read-only buffer will be the content of the
-     * given character sequence.  The buffer's capacity will be
-     * <tt>csq.length()</tt>, its position will be <tt>start</tt>, its limit
-     * will be <tt>end</tt>, and its mark will be undefined.  </p>
-     *
-     * @param  csq
-     *         The character sequence from which the new character buffer is to
-     *         be created
-     *
-     * @param  start
-     *         The index of the first character to be used;
-     *         must be non-negative and no larger than <tt>csq.length()</tt>.
-     *         The new buffer's position will be set to this value.
-     *
-     * @param  end
-     *         The index of the character following the last character to be
-     *         used; must be no smaller than <tt>start</tt> and no larger
-     *         than <tt>csq.length()</tt>.
-     *         The new buffer's limit will be set to this value.
-     *
-     * @return  The new character buffer
-     *
-     * @throws  IndexOutOfBoundsException
-     *          If the preconditions on the <tt>start</tt> and <tt>end</tt>
-     *          parameters do not hold
-     */
-    public static CharBuffer wrap(CharSequence csq, int start, int end) {
-        try {
-            return new StringCharBuffer(csq, start, end);
-        } catch (IllegalArgumentException x) {
-            throw new IndexOutOfBoundsException();
-        }
-    }
-
-    /**
-     * Wraps a character sequence into a buffer.
-     *
-     * <p> The content of the new, read-only buffer will be the content of the
-     * given character sequence.  The new buffer's capacity and limit will be
-     * <tt>csq.length()</tt>, its position will be zero, and its mark will be
-     * undefined.  </p>
-     *
-     * @param  csq
-     *         The character sequence from which the new character buffer is to
-     *         be created
-     *
-     * @return  The new character buffer
-     */
-    public static CharBuffer wrap(CharSequence csq) {
-        return wrap(csq, 0, csq.length());
-    }
-
-#end[char]
-
-    /**
-     * Creates a new $fulltype$ buffer whose content is a shared subsequence of
-     * this buffer's content.
-     *
-     * <p> The content of the new buffer will start at this buffer's current
-     * position.  Changes to this buffer's content will be visible in the new
-     * buffer, and vice versa; the two buffers' position, limit, and mark
-     * values will be independent.
-     *
-     * <p> The new buffer's position will be zero, its capacity and its limit
-     * will be the number of $fulltype$s remaining in this buffer, and its mark
-     * will be undefined.  The new buffer will be direct if, and only if, this
-     * buffer is direct, and it will be read-only if, and only if, this buffer
-     * is read-only.  </p>
-     *
-     * @return  The new $fulltype$ buffer
-     */
-    public abstract $Type$Buffer slice();
-
-    /**
-     * Creates a new $fulltype$ buffer that shares this buffer's content.
-     *
-     * <p> The content of the new buffer will be that of this buffer.  Changes
-     * to this buffer's content will be visible in the new buffer, and vice
-     * versa; the two buffers' position, limit, and mark values will be
-     * independent.
-     *
-     * <p> The new buffer's capacity, limit, position, and mark values will be
-     * identical to those of this buffer.  The new buffer will be direct if,
-     * and only if, this buffer is direct, and it will be read-only if, and
-     * only if, this buffer is read-only.  </p>
-     *
-     * @return  The new $fulltype$ buffer
-     */
-    public abstract $Type$Buffer duplicate();
-
-    /**
-     * Creates a new, read-only $fulltype$ buffer that shares this buffer's
-     * content.
-     *
-     * <p> The content of the new buffer will be that of this buffer.  Changes
-     * to this buffer's content will be visible in the new buffer; the new
-     * buffer itself, however, will be read-only and will not allow the shared
-     * content to be modified.  The two buffers' position, limit, and mark
-     * values will be independent.
-     *
-     * <p> The new buffer's capacity, limit, position, and mark values will be
-     * identical to those of this buffer.
-     *
-     * <p> If this buffer is itself read-only then this method behaves in
-     * exactly the same way as the {@link #duplicate duplicate} method.  </p>
-     *
-     * @return  The new, read-only $fulltype$ buffer
-     */
-    public abstract $Type$Buffer asReadOnlyBuffer();
-
-
-    // -- Singleton get/put methods --
-
-    /**
-     * Relative <i>get</i> method.  Reads the $fulltype$ at this buffer's
-     * current position, and then increments the position. </p>
-     *
-     * @return  The $fulltype$ at the buffer's current position
-     *
-     * @throws  BufferUnderflowException
-     *          If the buffer's current position is not smaller than its limit
-     */
-    public abstract $type$ get();
-
-    /**
-     * Relative <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
-     *
-     * <p> Writes the given $fulltype$ into this buffer at the current
-     * position, and then increments the position. </p>
-     *
-     * @param  $x$
-     *         The $fulltype$ to be written
-     *
-     * @return  This buffer
-     *
-     * @throws  BufferOverflowException
-     *          If this buffer's current position is not smaller than its limit
-     *
-     * @throws  ReadOnlyBufferException
-     *          If this buffer is read-only
-     */
-    public abstract $Type$Buffer put($type$ $x$);
-
-    /**
-     * Absolute <i>get</i> method.  Reads the $fulltype$ at the given
-     * index. </p>
-     *
-     * @param  index
-     *         The index from which the $fulltype$ will be read
-     *
-     * @return  The $fulltype$ at the given index
-     *
-     * @throws  IndexOutOfBoundsException
-     *          If <tt>index</tt> is negative
-     *          or not smaller than the buffer's limit
-     */
-    public abstract $type$ get(int index);
-
-    /**
-     * Absolute <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
-     *
-     * <p> Writes the given $fulltype$ into this buffer at the given
-     * index. </p>
-     *
-     * @param  index
-     *         The index at which the $fulltype$ will be written
-     *
-     * @param  $x$
-     *         The $fulltype$ value to be written
-     *
-     * @return  This buffer
-     *
-     * @throws  IndexOutOfBoundsException
-     *          If <tt>index</tt> is negative
-     *          or not smaller than the buffer's limit
-     *
-     * @throws  ReadOnlyBufferException
-     *          If this buffer is read-only
-     */
-    public abstract $Type$Buffer put(int index, $type$ $x$);
-
-
-    // -- Bulk get operations --
-
-    /**
-     * Relative bulk <i>get</i> method.
-     *
-     * <p> This method transfers $fulltype$s from this buffer into the given
-     * destination array.  If there are fewer $fulltype$s remaining in the
-     * buffer than are required to satisfy the request, that is, if
-     * <tt>length</tt>&nbsp;<tt>&gt;</tt>&nbsp;<tt>remaining()</tt>, then no
-     * $fulltype$s are transferred and a {@link BufferUnderflowException} is
-     * thrown.
-     *
-     * <p> Otherwise, this method copies <tt>length</tt> $fulltype$s from this
-     * buffer into the given array, starting at the current position of this
-     * buffer and at the given offset in the array.  The position of this
-     * buffer is then incremented by <tt>length</tt>.
-     *
-     * <p> In other words, an invocation of this method of the form
-     * <tt>src.get(dst,&nbsp;off,&nbsp;len)</tt> has exactly the same effect as
-     * the loop
-     *
-     * <pre>
-     *     for (int i = off; i < off + len; i++)
-     *         dst[i] = src.get(); </pre>
-     *
-     * except that it first checks that there are sufficient $fulltype$s in
-     * this buffer and it is potentially much more efficient. </p>
-     *
-     * @param  dst
-     *         The array into which $fulltype$s are to be written
-     *
-     * @param  offset
-     *         The offset within the array of the first $fulltype$ to be
-     *         written; must be non-negative and no larger than
-     *         <tt>dst.length</tt>
-     *
-     * @param  length
-     *         The maximum number of $fulltype$s to be written to the given
-     *         array; must be non-negative and no larger than
-     *         <tt>dst.length - offset</tt>
-     *
-     * @return  This buffer
-     *
-     * @throws  BufferUnderflowException
-     *          If there are fewer than <tt>length</tt> $fulltype$s
-     *          remaining in this buffer
-     *
-     * @throws  IndexOutOfBoundsException
-     *          If the preconditions on the <tt>offset</tt> and <tt>length</tt>
-     *          parameters do not hold
-     */
-    public $Type$Buffer get($type$[] dst, int offset, int length) {
-        checkBounds(offset, length, dst.length);
-        if (length > remaining())
-            throw new BufferUnderflowException();
-        int end = offset + length;
-        for (int i = offset; i < end; i++)
-            dst[i] = get();
-        return this;
-    }
-
-    /**
-     * Relative bulk <i>get</i> method.
-     *
-     * <p> This method transfers $fulltype$s from this buffer into the given
-     * destination array.  An invocation of this method of the form
-     * <tt>src.get(a)</tt> behaves in exactly the same way as the invocation
-     *
-     * <pre>
-     *     src.get(a, 0, a.length) </pre>
-     *
-     * @return  This buffer
-     *
-     * @throws  BufferUnderflowException
-     *          If there are fewer than <tt>length</tt> $fulltype$s
-     *          remaining in this buffer
-     */
-    public $Type$Buffer get($type$[] dst) {
-        return get(dst, 0, dst.length);
-    }
-
-
-    // -- Bulk put operations --
-
-    /**
-     * Relative bulk <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
-     *
-     * <p> This method transfers the $fulltype$s remaining in the given source
-     * buffer into this buffer.  If there are more $fulltype$s remaining in the
-     * source buffer than in this buffer, that is, if
-     * <tt>src.remaining()</tt>&nbsp;<tt>&gt;</tt>&nbsp;<tt>remaining()</tt>,
-     * then no $fulltype$s are transferred and a {@link
-     * BufferOverflowException} is thrown.
-     *
-     * <p> Otherwise, this method copies
-     * <i>n</i>&nbsp;=&nbsp;<tt>src.remaining()</tt> $fulltype$s from the given
-     * buffer into this buffer, starting at each buffer's current position.
-     * The positions of both buffers are then incremented by <i>n</i>.
-     *
-     * <p> In other words, an invocation of this method of the form
-     * <tt>dst.put(src)</tt> has exactly the same effect as the loop
-     *
-     * <pre>
-     *     while (src.hasRemaining())
-     *         dst.put(src.get()); </pre>
-     *
-     * except that it first checks that there is sufficient space in this
-     * buffer and it is potentially much more efficient. </p>
-     *
-     * @param  src
-     *         The source buffer from which $fulltype$s are to be read;
-     *         must not be this buffer
-     *
-     * @return  This buffer
-     *
-     * @throws  BufferOverflowException
-     *          If there is insufficient space in this buffer
-     *          for the remaining $fulltype$s in the source buffer
-     *
-     * @throws  IllegalArgumentException
-     *          If the source buffer is this buffer
-     *
-     * @throws  ReadOnlyBufferException
-     *          If this buffer is read-only
-     */
-    public $Type$Buffer put($Type$Buffer src) {
-        if (src == this)
-            throw new IllegalArgumentException();
-        int n = src.remaining();
-        if (n > remaining())
-            throw new BufferOverflowException();
-        for (int i = 0; i < n; i++)
-            put(src.get());
-        return this;
-    }
-
-    /**
-     * Relative bulk <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
-     *
-     * <p> This method transfers $fulltype$s into this buffer from the given
-     * source array.  If there are more $fulltype$s to be copied from the array
-     * than remain in this buffer, that is, if
-     * <tt>length</tt>&nbsp;<tt>&gt;</tt>&nbsp;<tt>remaining()</tt>, then no
-     * $fulltype$s are transferred and a {@link BufferOverflowException} is
-     * thrown.
-     *
-     * <p> Otherwise, this method copies <tt>length</tt> $fulltype$s from the
-     * given array into this buffer, starting at the given offset in the array
-     * and at the current position of this buffer.  The position of this buffer
-     * is then incremented by <tt>length</tt>.
-     *
-     * <p> In other words, an invocation of this method of the form
-     * <tt>dst.put(src,&nbsp;off,&nbsp;len)</tt> has exactly the same effect as
-     * the loop
-     *
-     * <pre>
-     *     for (int i = off; i < off + len; i++)
-     *         dst.put(a[i]); </pre>
-     *
-     * except that it first checks that there is sufficient space in this
-     * buffer and it is potentially much more efficient. </p>
-     *
-     * @param  src
-     *         The array from which $fulltype$s are to be read
-     *
-     * @param  offset
-     *         The offset within the array of the first $fulltype$ to be read;
-     *         must be non-negative and no larger than <tt>array.length</tt>
-     *
-     * @param  length
-     *         The number of $fulltype$s to be read from the given array;
-     *         must be non-negative and no larger than
-     *         <tt>array.length - offset</tt>
-     *
-     * @return  This buffer
-     *
-     * @throws  BufferOverflowException
-     *          If there is insufficient space in this buffer
-     *
-     * @throws  IndexOutOfBoundsException
-     *          If the preconditions on the <tt>offset</tt> and <tt>length</tt>
-     *          parameters do not hold
-     *
-     * @throws  ReadOnlyBufferException
-     *          If this buffer is read-only
-     */
-    public $Type$Buffer put($type$[] src, int offset, int length) {
-        checkBounds(offset, length, src.length);
-        if (length > remaining())
-            throw new BufferOverflowException();
-        int end = offset + length;
-        for (int i = offset; i < end; i++)
-            this.put(src[i]);
-        return this;
-    }
-
-    /**
-     * Relative bulk <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
-     *
-     * <p> This method transfers the entire content of the given source
-     * $fulltype$ array into this buffer.  An invocation of this method of the
-     * form <tt>dst.put(a)</tt> behaves in exactly the same way as the
-     * invocation
-     *
-     * <pre>
-     *     dst.put(a, 0, a.length) </pre>
-     *
-     * @return  This buffer
-     *
-     * @throws  BufferOverflowException
-     *          If there is insufficient space in this buffer
-     *
-     * @throws  ReadOnlyBufferException
-     *          If this buffer is read-only
-     */
-    public final $Type$Buffer put($type$[] src) {
-        return put(src, 0, src.length);
-    }
-
-#if[char]
-
-    /**
-     * Relative bulk <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
-     *
-     * <p> This method transfers $fulltype$s from the given string into this
-     * buffer.  If there are more $fulltype$s to be copied from the string than
-     * remain in this buffer, that is, if
-     * <tt>end&nbsp;-&nbsp;start</tt>&nbsp;<tt>&gt;</tt>&nbsp;<tt>remaining()</tt>,
-     * then no $fulltype$s are transferred and a {@link
-     * BufferOverflowException} is thrown.
-     *
-     * <p> Otherwise, this method copies
-     * <i>n</i>&nbsp;=&nbsp;<tt>end</tt>&nbsp;-&nbsp;<tt>start</tt> $fulltype$s
-     * from the given string into this buffer, starting at the given
-     * <tt>start</tt> index and at the current position of this buffer.  The
-     * position of this buffer is then incremented by <i>n</i>.
-     *
-     * <p> In other words, an invocation of this method of the form
-     * <tt>dst.put(src,&nbsp;start,&nbsp;end)</tt> has exactly the same effect
-     * as the loop
-     *
-     * <pre>
-     *     for (int i = start; i < end; i++)
-     *         dst.put(src.charAt(i)); </pre>
-     *
-     * except that it first checks that there is sufficient space in this
-     * buffer and it is potentially much more efficient. </p>
-     *
-     * @param  src
-     *         The string from which $fulltype$s are to be read
-     *
-     * @param  start
-     *         The offset within the string of the first $fulltype$ to be read;
-     *         must be non-negative and no larger than
-     *         <tt>string.length()</tt>
-     *
-     * @param  end
-     *         The offset within the string of the last $fulltype$ to be read,
-     *         plus one; must be non-negative and no larger than
-     *         <tt>string.length()</tt>
-     *
-     * @return  This buffer
-     *
-     * @throws  BufferOverflowException
-     *          If there is insufficient space in this buffer
-     *
-     * @throws  IndexOutOfBoundsException
-     *          If the preconditions on the <tt>start</tt> and <tt>end</tt>
-     *          parameters do not hold
-     *
-     * @throws  ReadOnlyBufferException
-     *          If this buffer is read-only
-     */
-    public $Type$Buffer put(String src, int start, int end) {
-        checkBounds(start, end - start, src.length());
-        for (int i = start; i < end; i++)
-            this.put(src.charAt(i));
-        return this;
-    }
-
-    /**
-     * Relative bulk <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
-     *
-     * <p> This method transfers the entire content of the given source string
-     * into this buffer.  An invocation of this method of the form
-     * <tt>dst.put(s)</tt> behaves in exactly the same way as the invocation
-     *
-     * <pre>
-     *     dst.put(s, 0, s.length()) </pre>
-     *
-     * @return  This buffer
-     *
-     * @throws  BufferOverflowException
-     *          If there is insufficient space in this buffer
-     *
-     * @throws  ReadOnlyBufferException
-     *          If this buffer is read-only
-     */
-    public final $Type$Buffer put(String src) {
-        return put(src, 0, src.length());
-    }
-
-#end[char]
-
-
-    // -- Other stuff --
-
-    /**
-     * Tells whether or not this buffer is backed by an accessible $fulltype$
-     * array.
-     *
-     * <p> If this method returns <tt>true</tt> then the {@link #array() array}
-     * and {@link #arrayOffset() arrayOffset} methods may safely be invoked.
-     * </p>
-     *
-     * @return  <tt>true</tt> if, and only if, this buffer
-     *          is backed by an array and is not read-only
-     */
-    public final boolean hasArray() {
-        return (hb != null) && !isReadOnly;
-    }
-
-    /**
-     * Returns the $fulltype$ array that backs this
-     * buffer&nbsp;&nbsp;<i>(optional operation)</i>.
-     *
-     * <p> Modifications to this buffer's content will cause the returned
-     * array's content to be modified, and vice versa.
-     *
-     * <p> Invoke the {@link #hasArray hasArray} method before invoking this
-     * method in order to ensure that this buffer has an accessible backing
-     * array.  </p>
-     *
-     * @return  The array that backs this buffer
-     *
-     * @throws  ReadOnlyBufferException
-     *          If this buffer is backed by an array but is read-only
-     *
-     * @throws  UnsupportedOperationException
-     *          If this buffer is not backed by an accessible array
-     */
-    public final $type$[] array() {
-        if (hb == null)
-            throw new UnsupportedOperationException();
-        if (isReadOnly)
-            throw new ReadOnlyBufferException();
-        return hb;
-    }
-
-    /**
-     * Returns the offset within this buffer's backing array of the first
-     * element of the buffer&nbsp;&nbsp;<i>(optional operation)</i>.
-     *
-     * <p> If this buffer is backed by an array then buffer position <i>p</i>
-     * corresponds to array index <i>p</i>&nbsp;+&nbsp;<tt>arrayOffset()</tt>.
-     *
-     * <p> Invoke the {@link #hasArray hasArray} method before invoking this
-     * method in order to ensure that this buffer has an accessible backing
-     * array.  </p>
-     *
-     * @return  The offset within this buffer's array
-     *          of the first element of the buffer
-     *
-     * @throws  ReadOnlyBufferException
-     *          If this buffer is backed by an array but is read-only
-     *
-     * @throws  UnsupportedOperationException
-     *          If this buffer is not backed by an accessible array
-     */
-    public final int arrayOffset() {
-        if (hb == null)
-            throw new UnsupportedOperationException();
-        if (isReadOnly)
-            throw new ReadOnlyBufferException();
-        return offset;
-    }
-
-    /**
-     * Compacts this buffer&nbsp;&nbsp;<i>(optional operation)</i>.
-     *
-     * <p> The $fulltype$s between the buffer's current position and its limit,
-     * if any, are copied to the beginning of the buffer.  That is, the
-     * $fulltype$ at index <i>p</i>&nbsp;=&nbsp;<tt>position()</tt> is copied
-     * to index zero, the $fulltype$ at index <i>p</i>&nbsp;+&nbsp;1 is copied
-     * to index one, and so forth until the $fulltype$ at index
-     * <tt>limit()</tt>&nbsp;-&nbsp;1 is copied to index
-     * <i>n</i>&nbsp;=&nbsp;<tt>limit()</tt>&nbsp;-&nbsp;<tt>1</tt>&nbsp;-&nbsp;<i>p</i>.
-     * The buffer's position is then set to <i>n+1</i> and its limit is set to
-     * its capacity.  The mark, if defined, is discarded.
-     *
-     * <p> The buffer's position is set to the number of $fulltype$s copied,
-     * rather than to zero, so that an invocation of this method can be
-     * followed immediately by an invocation of another relative <i>put</i>
-     * method. </p>
-     *
-#if[byte]
-     *
-     * <p> Invoke this method after writing data from a buffer in case the
-     * write was incomplete.  The following loop, for example, copies bytes
-     * from one channel to another via the buffer <tt>buf</tt>:
-     *
-     * <blockquote><pre>
-     * buf.clear();          // Prepare buffer for use
-     * while (in.read(buf) >= 0 || buf.position != 0) {
-     *     buf.flip();
-     *     out.write(buf);
-     *     buf.compact();    // In case of partial write
-     * }</pre></blockquote>
-     *
-#end[byte]
-     *
-     * @return  This buffer
-     *
-     * @throws  ReadOnlyBufferException
-     *          If this buffer is read-only
-     */
-    public abstract $Type$Buffer compact();
-
-    /**
-     * Tells whether or not this $fulltype$ buffer is direct. </p>
-     *
-     * @return  <tt>true</tt> if, and only if, this buffer is direct
-     */
-    public abstract boolean isDirect();
-
-#if[!char]
-
-    /**
-     * Returns a string summarizing the state of this buffer.  </p>
-     *
-     * @return  A summary string
-     */
-    public String toString() {
-        StringBuffer sb = new StringBuffer();
-        sb.append(getClass().getName());
-        sb.append("[pos=");
-        sb.append(position());
-        sb.append(" lim=");
-        sb.append(limit());
-        sb.append(" cap=");
-        sb.append(capacity());
-        sb.append("]");
-        return sb.toString();
-    }
-
-#end[!char]
-
-
-    // ## Should really use unchecked accessors here for speed
-
-    /**
-     * Returns the current hash code of this buffer.
-     *
-     * <p> The hash code of a $type$ buffer depends only upon its remaining
-     * elements; that is, upon the elements from <tt>position()</tt> up to, and
-     * including, the element at <tt>limit()</tt>&nbsp;-&nbsp;<tt>1</tt>.
-     *
-     * <p> Because buffer hash codes are content-dependent, it is inadvisable
-     * to use buffers as keys in hash maps or similar data structures unless it
-     * is known that their contents will not change.  </p>
-     *
-     * @return  The current hash code of this buffer
-     */
-    public int hashCode() {
-        int h = 1;
-        int p = position();
-        for (int i = limit() - 1; i >= p; i--)
-            h = 31 * h + (int)get(i);
-        return h;
-    }
-
-    /**
-     * Tells whether or not this buffer is equal to another object.
-     *
-     * <p> Two $type$ buffers are equal if, and only if,
-     *
-     * <p><ol>
-     *
-     *   <li><p> They have the same element type,  </p></li>
-     *
-     *   <li><p> They have the same number of remaining elements, and
-     *   </p></li>
-     *
-     *   <li><p> The two sequences of remaining elements, considered
-     *   independently of their starting positions, are pointwise equal.
-     *   </p></li>
-     *
-     * </ol>
-     *
-     * <p> A $type$ buffer is not equal to any other type of object.  </p>
-     *
-     * @param  ob  The object to which this buffer is to be compared
-     *
-     * @return  <tt>true</tt> if, and only if, this buffer is equal to the
-     *           given object
-     */
-    public boolean equals(Object ob) {
-        if (this == ob)
-            return true;
-        if (!(ob instanceof $Type$Buffer))
-            return false;
-        $Type$Buffer that = ($Type$Buffer)ob;
-        if (this.remaining() != that.remaining())
-            return false;
-        int p = this.position();
-        for (int i = this.limit() - 1, j = that.limit() - 1; i >= p; i--, j--) {
-            $type$ v1 = this.get(i);
-            $type$ v2 = that.get(j);
-            if (v1 != v2) {
-                if ((v1 != v1) && (v2 != v2))   // For float and double
-                    continue;
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Compares this buffer to another.
-     *
-     * <p> Two $type$ buffers are compared by comparing their sequences of
-     * remaining elements lexicographically, without regard to the starting
-     * position of each sequence within its corresponding buffer.
-     *
-     * <p> A $type$ buffer is not comparable to any other type of object.
-     *
-     * @return  A negative integer, zero, or a positive integer as this buffer
-     *          is less than, equal to, or greater than the given buffer
-     */
-    public int compareTo($Type$Buffer that) {
-        int n = this.position() + Math.min(this.remaining(), that.remaining());
-        for (int i = this.position(), j = that.position(); i < n; i++, j++) {
-            $type$ v1 = this.get(i);
-            $type$ v2 = that.get(j);
-            if (v1 == v2)
-                continue;
-            if ((v1 != v1) && (v2 != v2))       // For float and double
-                continue;
-            if (v1 < v2)
-                return -1;
-            return +1;
-        }
-        return this.remaining() - that.remaining();
-    }
-
-
-
-    // -- Other char stuff --
-
-#if[char]
-
-    /**
-     * Returns a string containing the characters in this buffer.
-     *
-     * <p> The first character of the resulting string will be the character at
-     * this buffer's position, while the last character will be the character
-     * at index <tt>limit()</tt>&nbsp;-&nbsp;1.  Invoking this method does not
-     * change the buffer's position. </p>
-     *
-     * @return  The specified string
-     */
-    public String toString() {
-        return toString(position(), limit());
-    }
-
-    abstract String toString(int start, int end);       // package-private
-
-
-    // --- Methods to support CharSequence ---
-
-    /**
-     * Returns the length of this character buffer.
-     *
-     * <p> When viewed as a character sequence, the length of a character
-     * buffer is simply the number of characters between the position
-     * (inclusive) and the limit (exclusive); that is, it is equivalent to
-     * <tt>remaining()</tt>. </p>
-     *
-     * @return  The length of this character buffer
-     */
-    public final int length() {
-        return remaining();
-    }
-
-    /**
-     * Reads the character at the given index relative to the current
-     * position. </p>
-     *
-     * @param  index
-     *         The index of the character to be read, relative to the position;
-     *         must be non-negative and smaller than <tt>remaining()</tt>
-     *
-     * @return  The character at index
-     *          <tt>position()&nbsp;+&nbsp;index</tt>
-     *
-     * @throws  IndexOutOfBoundsException
-     *          If the preconditions on <tt>index</tt> do not hold
-     */
-    public final char charAt(int index) {
-        return get(position() + checkIndex(index, 1));
-    }
-
-    /**
-     * Creates a new character buffer that represents the specified subsequence
-     * of this buffer, relative to the current position.
-     *
-     * <p> The new buffer will share this buffer's content; that is, if the
-     * content of this buffer is mutable then modifications to one buffer will
-     * cause the other to be modified.  The new buffer's capacity will be that
-     * of this buffer, its position will be
-     * <tt>position()</tt>&nbsp;+&nbsp;<tt>start</tt>, and its limit will be
-     * <tt>position()</tt>&nbsp;+&nbsp;<tt>end</tt>.  The new buffer will be
-     * direct if, and only if, this buffer is direct, and it will be read-only
-     * if, and only if, this buffer is read-only.  </p>
-     *
-     * @param  start
-     *         The index, relative to the current position, of the first
-     *         character in the subsequence; must be non-negative and no larger
-     *         than <tt>remaining()</tt>
-     *
-     * @param  end
-     *         The index, relative to the current position, of the character
-     *         following the last character in the subsequence; must be no
-     *         smaller than <tt>start</tt> and no larger than
-     *         <tt>remaining()</tt>
-     *
-     * @return  The new character buffer
-     *
-     * @throws  IndexOutOfBoundsException
-     *          If the preconditions on <tt>start</tt> and <tt>end</tt>
-     *          do not hold
-     */
-    public abstract CharBuffer subSequence(int start, int end);
-
-
-    // --- Methods to support Appendable ---
-
-    /**
-     * Appends the specified character sequence  to this
-     * buffer&nbsp;&nbsp;<i>(optional operation)</i>.
-     *
-     * <p> An invocation of this method of the form <tt>dst.append(csq)</tt>
-     * behaves in exactly the same way as the invocation
-     *
-     * <pre>
-     *     dst.put(csq.toString()) </pre>
-     *
-     * <p> Depending on the specification of <tt>toString</tt> for the
-     * character sequence <tt>csq</tt>, the entire sequence may not be
-     * appended.  For instance, invoking the {@link $Type$Buffer#toString()
-     * toString} method of a character buffer will return a subsequence whose
-     * content depends upon the buffer's position and limit.
-     *
-     * @param  csq
-     *         The character sequence to append.  If <tt>csq</tt> is
-     *         <tt>null</tt>, then the four characters <tt>"null"</tt> are
-     *         appended to this character buffer.
-     *
-     * @return  This buffer
-     *
-     * @throws  BufferOverflowException
-     *          If there is insufficient space in this buffer
-     *
-     * @throws  ReadOnlyBufferException
-     *          If this buffer is read-only
-     *
-     * @since  1.5
-     */
-    public $Type$Buffer append(CharSequence csq) {
-        if (csq == null)
-            return put("null");
-        else
-            return put(csq.toString());
-    }
-
-    /**
-     * Appends a subsequence of the  specified character sequence  to this
-     * buffer&nbsp;&nbsp;<i>(optional operation)</i>.
-     *
-     * <p> An invocation of this method of the form <tt>dst.append(csq, start,
-     * end)</tt> when <tt>csq</tt> is not <tt>null</tt>, behaves in exactly the
-     * same way as the invocation
-     *
-     * <pre>
-     *     dst.put(csq.subSequence(start, end).toString()) </pre>
-     *
-     * @param  csq
-     *         The character sequence from which a subsequence will be
-     *         appended.  If <tt>csq</tt> is <tt>null</tt>, then characters
-     *         will be appended as if <tt>csq</tt> contained the four
-     *         characters <tt>"null"</tt>.
-     *
-     * @return  This buffer
-     *
-     * @throws  BufferOverflowException
-     *          If there is insufficient space in this buffer
-     *
-     * @throws  IndexOutOfBoundsException
-     *          If <tt>start</tt> or <tt>end</tt> are negative, <tt>start</tt>
-     *          is greater than <tt>end</tt>, or <tt>end</tt> is greater than
-     *          <tt>csq.length()</tt>
-     *
-     * @throws  ReadOnlyBufferException
-     *          If this buffer is read-only
-     *
-     * @since  1.5
-     */
-    public $Type$Buffer append(CharSequence csq, int start, int end) {
-        CharSequence cs = (csq == null ? "null" : csq);
-        return put(cs.subSequence(start, end).toString());
-    }
-
-    /**
-     * Appends the specified $fulltype$  to this
-     * buffer&nbsp;&nbsp;<i>(optional operation)</i>.
-     *
-     * <p> An invocation of this method of the form <tt>dst.append($x$)</tt>
-     * behaves in exactly the same way as the invocation
-     *
-     * <pre>
-     *     dst.put($x$) </pre>
-     *
-     * @param  $x$
-     *         The 16-bit $fulltype$ to append
-     *
-     * @return  This buffer
-     *
-     * @throws  BufferOverflowException
-     *          If there is insufficient space in this buffer
-     *
-     * @throws  ReadOnlyBufferException
-     *          If this buffer is read-only
-     *
-     * @since  1.5
-     */
-    public $Type$Buffer append($type$ $x$) {
-        return put($x$);
-    }
-
-#end[char]
-
-
-    // -- Other byte stuff: Access to binary data --
-
-#if[!byte]
-
-    /**
-     * Retrieves this buffer's byte order.
-     *
-     * <p> The byte order of $a$ $fulltype$ buffer created by allocation or by
-     * wrapping an existing <tt>$type$</tt> array is the {@link
-     * ByteOrder#nativeOrder </code>native order<code>} of the underlying
-     * hardware.  The byte order of $a$ $fulltype$ buffer created as a <a
-     * href="ByteBuffer.html#views">view</a> of a byte buffer is that of the
-     * byte buffer at the moment that the view is created.  </p>
-     *
-     * @return  This buffer's byte order
-     */
-    public abstract ByteOrder order();
-
-#end[!byte]
-
-#if[byte]
-
-    boolean bigEndian                                   // package-private
-        = true;
-    boolean nativeByteOrder                             // package-private
-        = (Bits.byteOrder() == ByteOrder.BIG_ENDIAN);
-
-    /**
-     * Retrieves this buffer's byte order.
-     *
-     * <p> The byte order is used when reading or writing multibyte values, and
-     * when creating buffers that are views of this byte buffer.  The order of
-     * a newly-created byte buffer is always {@link ByteOrder#BIG_ENDIAN
-     * BIG_ENDIAN}.  </p>
-     *
-     * @return  This buffer's byte order
-     */
-    public final ByteOrder order() {
-        return bigEndian ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
-    }
-
-    /**
-     * Modifies this buffer's byte order.  </p>
-     *
-     * @param  bo
-     *         The new byte order,
-     *         either {@link ByteOrder#BIG_ENDIAN BIG_ENDIAN}
-     *         or {@link ByteOrder#LITTLE_ENDIAN LITTLE_ENDIAN}
-     *
-     * @return  This buffer
-     */
-    public final $Type$Buffer order(ByteOrder bo) {
-        bigEndian = (bo == ByteOrder.BIG_ENDIAN);
-        nativeByteOrder =
-            (bigEndian == (Bits.byteOrder() == ByteOrder.BIG_ENDIAN));
-        return this;
-    }
-
-    // Unchecked accessors, for use by ByteBufferAs-X-Buffer classes
-    //
-    abstract byte _get(int i);                          // package-private
-    abstract void _put(int i, byte b);                  // package-private
-
-    // #BIN
-    //
-    // Binary-data access methods  for short, char, int, long, float,
-    // and double will be inserted here
-
-#end[byte]
-
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/nio/X-Buffer.java.template	Wed Jul 05 17:02:50 2017 +0200
@@ -0,0 +1,1428 @@
+/*
+ * Copyright 2000-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.
+ */
+
+#warn This file is preprocessed before being compiled
+
+package java.nio;
+
+#if[char]
+import java.io.IOException;
+#end[char]
+
+/**
+ * $A$ $fulltype$ buffer.
+ *
+ * <p> This class defines {#if[byte]?six:four} categories of operations upon
+ * $fulltype$ buffers:
+ *
+ * <ul>
+ *
+ *   <li><p> Absolute and relative {@link #get() </code><i>get</i><code>} and
+ *   {@link #put($type$) </code><i>put</i><code>} methods that read and write
+ *   single $fulltype$s; </p></li>
+ *
+ *   <li><p> Relative {@link #get($type$[]) </code><i>bulk get</i><code>}
+ *   methods that transfer contiguous sequences of $fulltype$s from this buffer
+ *   into an array; {#if[!byte]?and}</p></li>
+ *
+ *   <li><p> Relative {@link #put($type$[]) </code><i>bulk put</i><code>}
+ *   methods that transfer contiguous sequences of $fulltype$s from $a$
+ *   $fulltype$ array{#if[char]?,&#32;a&#32;string,} or some other $fulltype$
+ *   buffer into this buffer;{#if[!byte]?&#32;and} </p></li>
+ *
+#if[byte]
+ *
+ *   <li><p> Absolute and relative {@link #getChar() </code><i>get</i><code>}
+ *   and {@link #putChar(char) </code><i>put</i><code>} methods that read and
+ *   write values of other primitive types, translating them to and from
+ *   sequences of bytes in a particular byte order; </p></li>
+ *
+ *   <li><p> Methods for creating <i><a href="#views">view buffers</a></i>,
+ *   which allow a byte buffer to be viewed as a buffer containing values of
+ *   some other primitive type; and </p></li>
+ *
+#end[byte]
+ *
+ *   <li><p> Methods for {@link #compact </code>compacting<code>}, {@link
+ *   #duplicate </code>duplicating<code>}, and {@link #slice
+ *   </code>slicing<code>} $a$ $fulltype$ buffer.  </p></li>
+ *
+ * </ul>
+ *
+ * <p> $Fulltype$ buffers can be created either by {@link #allocate
+ * </code><i>allocation</i><code>}, which allocates space for the buffer's
+ *
+#if[byte]
+ *
+ * content, or by {@link #wrap($type$[]) </code><i>wrapping</i><code>} an
+ * existing $fulltype$ array {#if[char]?or&#32;string} into a buffer.
+ *
+#else[byte]
+ *
+ * content, by {@link #wrap($type$[]) </code><i>wrapping</i><code>} an existing
+ * $fulltype$ array {#if[char]?or&#32;string} into a buffer, or by creating a
+ * <a href="ByteBuffer.html#views"><i>view</i></a> of an existing byte buffer.
+ *
+#end[byte]
+ *
+#if[byte]
+ *
+ * <a name="direct">
+ * <h4> Direct <i>vs.</i> non-direct buffers </h4>
+ *
+ * <p> A byte buffer is either <i>direct</i> or <i>non-direct</i>.  Given a
+ * direct byte buffer, the Java virtual machine will make a best effort to
+ * perform native I/O operations directly upon it.  That is, it will attempt to
+ * avoid copying the buffer's content to (or from) an intermediate buffer
+ * before (or after) each invocation of one of the underlying operating
+ * system's native I/O operations.
+ *
+ * <p> A direct byte buffer may be created by invoking the {@link
+ * #allocateDirect(int) allocateDirect} factory method of this class.  The
+ * buffers returned by this method typically have somewhat higher allocation
+ * and deallocation costs than non-direct buffers.  The contents of direct
+ * buffers may reside outside of the normal garbage-collected heap, and so
+ * their impact upon the memory footprint of an application might not be
+ * obvious.  It is therefore recommended that direct buffers be allocated
+ * primarily for large, long-lived buffers that are subject to the underlying
+ * system's native I/O operations.  In general it is best to allocate direct
+ * buffers only when they yield a measureable gain in program performance.
+ *
+ * <p> A direct byte buffer may also be created by {@link
+ * java.nio.channels.FileChannel#map </code>mapping<code>} a region of a file
+ * directly into memory.  An implementation of the Java platform may optionally
+ * support the creation of direct byte buffers from native code via JNI.  If an
+ * instance of one of these kinds of buffers refers to an inaccessible region
+ * of memory then an attempt to access that region will not change the buffer's
+ * content and will cause an unspecified exception to be thrown either at the
+ * time of the access or at some later time.
+ *
+ * <p> Whether a byte buffer is direct or non-direct may be determined by
+ * invoking its {@link #isDirect isDirect} method.  This method is provided so
+ * that explicit buffer management can be done in performance-critical code.
+ *
+ *
+ * <a name="bin">
+ * <h4> Access to binary data </h4>
+ *
+ * <p> This class defines methods for reading and writing values of all other
+ * primitive types, except <tt>boolean</tt>.  Primitive values are translated
+ * to (or from) sequences of bytes according to the buffer's current byte
+ * order, which may be retrieved and modified via the {@link #order order}
+ * methods.  Specific byte orders are represented by instances of the {@link
+ * ByteOrder} class.  The initial order of a byte buffer is always {@link
+ * ByteOrder#BIG_ENDIAN BIG_ENDIAN}.
+ *
+ * <p> For access to heterogeneous binary data, that is, sequences of values of
+ * different types, this class defines a family of absolute and relative
+ * <i>get</i> and <i>put</i> methods for each type.  For 32-bit floating-point
+ * values, for example, this class defines:
+ *
+ * <blockquote><pre>
+ * float  {@link #getFloat()}
+ * float  {@link #getFloat(int) getFloat(int index)}
+ *  void  {@link #putFloat(float) putFloat(float f)}
+ *  void  {@link #putFloat(int,float) putFloat(int index, float f)}</pre></blockquote>
+ *
+ * <p> Corresponding methods are defined for the types <tt>char</tt>,
+ * <tt>short</tt>, <tt>int</tt>, <tt>long</tt>, and <tt>double</tt>.  The index
+ * parameters of the absolute <i>get</i> and <i>put</i> methods are in terms of
+ * bytes rather than of the type being read or written.
+ *
+ * <a name="views">
+ *
+ * <p> For access to homogeneous binary data, that is, sequences of values of
+ * the same type, this class defines methods that can create <i>views</i> of a
+ * given byte buffer.  A <i>view buffer</i> is simply another buffer whose
+ * content is backed by the byte buffer.  Changes to the byte buffer's content
+ * will be visible in the view buffer, and vice versa; the two buffers'
+ * position, limit, and mark values are independent.  The {@link
+ * #asFloatBuffer() asFloatBuffer} method, for example, creates an instance of
+ * the {@link FloatBuffer} class that is backed by the byte buffer upon which
+ * the method is invoked.  Corresponding view-creation methods are defined for
+ * the types <tt>char</tt>, <tt>short</tt>, <tt>int</tt>, <tt>long</tt>, and
+ * <tt>double</tt>.
+ *
+ * <p> View buffers have three important advantages over the families of
+ * type-specific <i>get</i> and <i>put</i> methods described above:
+ *
+ * <ul>
+ *
+ *   <li><p> A view buffer is indexed not in terms of bytes but rather in terms
+ *   of the type-specific size of its values;  </p></li>
+ *
+ *   <li><p> A view buffer provides relative bulk <i>get</i> and <i>put</i>
+ *   methods that can transfer contiguous sequences of values between a buffer
+ *   and an array or some other buffer of the same type; and  </p></li>
+ *
+ *   <li><p> A view buffer is potentially much more efficient because it will
+ *   be direct if, and only if, its backing byte buffer is direct.  </p></li>
+ *
+ * </ul>
+ *
+ * <p> The byte order of a view buffer is fixed to be that of its byte buffer
+ * at the time that the view is created.  </p>
+ *
+#end[byte]
+*
+#if[!byte]
+ *
+ * <p> Like a byte buffer, $a$ $fulltype$ buffer is either <a
+ * href="ByteBuffer.html#direct"><i>direct</i> or <i>non-direct</i></a>.  A
+ * $fulltype$ buffer created via the <tt>wrap</tt> methods of this class will
+ * be non-direct.  $A$ $fulltype$ buffer created as a view of a byte buffer will
+ * be direct if, and only if, the byte buffer itself is direct.  Whether or not
+ * $a$ $fulltype$ buffer is direct may be determined by invoking the {@link
+ * #isDirect isDirect} method.  </p>
+ *
+#end[!byte]
+*
+#if[char]
+ *
+ * <p> This class implements the {@link CharSequence} interface so that
+ * character buffers may be used wherever character sequences are accepted, for
+ * example in the regular-expression package <tt>{@link java.util.regex}</tt>.
+ * </p>
+ *
+#end[char]
+ *
+#if[byte]
+ * <h4> Invocation chaining </h4>
+#end[byte]
+ *
+ * <p> Methods in this class that do not otherwise have a value to return are
+ * specified to return the buffer upon which they are invoked.  This allows
+ * method invocations to be chained.
+ *
+#if[byte]
+ *
+ * The sequence of statements
+ *
+ * <blockquote><pre>
+ * bb.putInt(0xCAFEBABE);
+ * bb.putShort(3);
+ * bb.putShort(45);</pre></blockquote>
+ *
+ * can, for example, be replaced by the single statement
+ *
+ * <blockquote><pre>
+ * bb.putInt(0xCAFEBABE).putShort(3).putShort(45);</pre></blockquote>
+ *
+#end[byte]
+#if[char]
+ *
+ * The sequence of statements
+ *
+ * <blockquote><pre>
+ * cb.put("text/");
+ * cb.put(subtype);
+ * cb.put("; charset=");
+ * cb.put(enc);</pre></blockquote>
+ *
+ * can, for example, be replaced by the single statement
+ *
+ * <blockquote><pre>
+ * cb.put("text/").put(subtype).put("; charset=").put(enc);</pre></blockquote>
+ *
+#end[char]
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public abstract class $Type$Buffer
+    extends Buffer
+    implements Comparable<$Type$Buffer>{#if[char]?, Appendable, CharSequence, Readable}
+{
+
+    // These fields are declared here rather than in Heap-X-Buffer in order to
+    // reduce the number of virtual method invocations needed to access these
+    // values, which is especially costly when coding small buffers.
+    //
+    final $type$[] hb;                  // Non-null only for heap buffers
+    final int offset;
+    boolean isReadOnly;                 // Valid only for heap buffers
+
+    // Creates a new buffer with the given mark, position, limit, capacity,
+    // backing array, and array offset
+    //
+    $Type$Buffer(int mark, int pos, int lim, int cap,   // package-private
+                 $type$[] hb, int offset)
+    {
+        super(mark, pos, lim, cap);
+        this.hb = hb;
+        this.offset = offset;
+    }
+
+    // Creates a new buffer with the given mark, position, limit, and capacity
+    //
+    $Type$Buffer(int mark, int pos, int lim, int cap) { // package-private
+        this(mark, pos, lim, cap, null, 0);
+    }
+
+#if[byte]
+
+    /**
+     * Allocates a new direct $fulltype$ buffer.
+     *
+     * <p> The new buffer's position will be zero, its limit will be its
+     * capacity, its mark will be undefined, and each of its elements will be
+     * initialized to zero.  Whether or not it has a
+     * {@link #hasArray </code>backing array<code>} is unspecified.
+     *
+     * @param  capacity
+     *         The new buffer's capacity, in $fulltype$s
+     *
+     * @return  The new $fulltype$ buffer
+     *
+     * @throws  IllegalArgumentException
+     *          If the <tt>capacity</tt> is a negative integer
+     */
+    public static $Type$Buffer allocateDirect(int capacity) {
+        return new Direct$Type$Buffer(capacity);
+    }
+
+#end[byte]
+
+    /**
+     * Allocates a new $fulltype$ buffer.
+     *
+     * <p> The new buffer's position will be zero, its limit will be its
+     * capacity, its mark will be undefined, and each of its elements will be
+     * initialized to zero.  It will have a {@link #array
+     * </code>backing array<code>}, and its {@link #arrayOffset </code>array
+     * offset<code>} will be zero.
+     *
+     * @param  capacity
+     *         The new buffer's capacity, in $fulltype$s
+     *
+     * @return  The new $fulltype$ buffer
+     *
+     * @throws  IllegalArgumentException
+     *          If the <tt>capacity</tt> is a negative integer
+     */
+    public static $Type$Buffer allocate(int capacity) {
+        if (capacity < 0)
+            throw new IllegalArgumentException();
+        return new Heap$Type$Buffer(capacity, capacity);
+    }
+
+    /**
+     * Wraps $a$ $fulltype$ array into a buffer.
+     *
+     * <p> The new buffer will be backed by the given $fulltype$ array;
+     * that is, modifications to the buffer will cause the array to be modified
+     * and vice versa.  The new buffer's capacity will be
+     * <tt>array.length</tt>, its position will be <tt>offset</tt>, its limit
+     * will be <tt>offset + length</tt>, and its mark will be undefined.  Its
+     * {@link #array </code>backing array<code>} will be the given array, and
+     * its {@link #arrayOffset </code>array offset<code>} will be zero.  </p>
+     *
+     * @param  array
+     *         The array that will back the new buffer
+     *
+     * @param  offset
+     *         The offset of the subarray to be used; must be non-negative and
+     *         no larger than <tt>array.length</tt>.  The new buffer's position
+     *         will be set to this value.
+     *
+     * @param  length
+     *         The length of the subarray to be used;
+     *         must be non-negative and no larger than
+     *         <tt>array.length - offset</tt>.
+     *         The new buffer's limit will be set to <tt>offset + length</tt>.
+     *
+     * @return  The new $fulltype$ buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+     *          parameters do not hold
+     */
+    public static $Type$Buffer wrap($type$[] array,
+                                    int offset, int length)
+    {
+        try {
+            return new Heap$Type$Buffer(array, offset, length);
+        } catch (IllegalArgumentException x) {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+
+    /**
+     * Wraps $a$ $fulltype$ array into a buffer.
+     *
+     * <p> The new buffer will be backed by the given $fulltype$ array;
+     * that is, modifications to the buffer will cause the array to be modified
+     * and vice versa.  The new buffer's capacity and limit will be
+     * <tt>array.length</tt>, its position will be zero, and its mark will be
+     * undefined.  Its {@link #array </code>backing array<code>} will be the
+     * given array, and its {@link #arrayOffset </code>array offset<code>} will
+     * be zero.  </p>
+     *
+     * @param  array
+     *         The array that will back this buffer
+     *
+     * @return  The new $fulltype$ buffer
+     */
+    public static $Type$Buffer wrap($type$[] array) {
+        return wrap(array, 0, array.length);
+    }
+
+#if[char]
+
+    /**
+     * Attempts to read characters into the specified character buffer.
+     * The buffer is used as a repository of characters as-is: the only
+     * changes made are the results of a put operation. No flipping or
+     * rewinding of the buffer is performed.
+     *
+     * @param target the buffer to read characters into
+     * @return The number of characters added to the buffer, or
+     *         -1 if this source of characters is at its end
+     * @throws IOException if an I/O error occurs
+     * @throws NullPointerException if target is null
+     * @throws ReadOnlyBufferException if target is a read only buffer
+     * @since 1.5
+     */
+    public int read(CharBuffer target) throws IOException {
+        // Determine the number of bytes n that can be transferred
+        int targetRemaining = target.remaining();
+        int remaining = remaining();
+        if (remaining == 0)
+            return -1;
+        int n = Math.min(remaining, targetRemaining);
+        int limit = limit();
+        // Set source limit to prevent target overflow
+        if (targetRemaining < remaining)
+            limit(position() + n);
+        try {
+            if (n > 0)
+                target.put(this);
+        } finally {
+            limit(limit); // restore real limit
+        }
+        return n;
+    }
+
+    /**
+     * Wraps a character sequence into a buffer.
+     *
+     * <p> The content of the new, read-only buffer will be the content of the
+     * given character sequence.  The buffer's capacity will be
+     * <tt>csq.length()</tt>, its position will be <tt>start</tt>, its limit
+     * will be <tt>end</tt>, and its mark will be undefined.  </p>
+     *
+     * @param  csq
+     *         The character sequence from which the new character buffer is to
+     *         be created
+     *
+     * @param  start
+     *         The index of the first character to be used;
+     *         must be non-negative and no larger than <tt>csq.length()</tt>.
+     *         The new buffer's position will be set to this value.
+     *
+     * @param  end
+     *         The index of the character following the last character to be
+     *         used; must be no smaller than <tt>start</tt> and no larger
+     *         than <tt>csq.length()</tt>.
+     *         The new buffer's limit will be set to this value.
+     *
+     * @return  The new character buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If the preconditions on the <tt>start</tt> and <tt>end</tt>
+     *          parameters do not hold
+     */
+    public static CharBuffer wrap(CharSequence csq, int start, int end) {
+        try {
+            return new StringCharBuffer(csq, start, end);
+        } catch (IllegalArgumentException x) {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+
+    /**
+     * Wraps a character sequence into a buffer.
+     *
+     * <p> The content of the new, read-only buffer will be the content of the
+     * given character sequence.  The new buffer's capacity and limit will be
+     * <tt>csq.length()</tt>, its position will be zero, and its mark will be
+     * undefined.  </p>
+     *
+     * @param  csq
+     *         The character sequence from which the new character buffer is to
+     *         be created
+     *
+     * @return  The new character buffer
+     */
+    public static CharBuffer wrap(CharSequence csq) {
+        return wrap(csq, 0, csq.length());
+    }
+
+#end[char]
+
+    /**
+     * Creates a new $fulltype$ buffer whose content is a shared subsequence of
+     * this buffer's content.
+     *
+     * <p> The content of the new buffer will start at this buffer's current
+     * position.  Changes to this buffer's content will be visible in the new
+     * buffer, and vice versa; the two buffers' position, limit, and mark
+     * values will be independent.
+     *
+     * <p> The new buffer's position will be zero, its capacity and its limit
+     * will be the number of $fulltype$s remaining in this buffer, and its mark
+     * will be undefined.  The new buffer will be direct if, and only if, this
+     * buffer is direct, and it will be read-only if, and only if, this buffer
+     * is read-only.  </p>
+     *
+     * @return  The new $fulltype$ buffer
+     */
+    public abstract $Type$Buffer slice();
+
+    /**
+     * Creates a new $fulltype$ buffer that shares this buffer's content.
+     *
+     * <p> The content of the new buffer will be that of this buffer.  Changes
+     * to this buffer's content will be visible in the new buffer, and vice
+     * versa; the two buffers' position, limit, and mark values will be
+     * independent.
+     *
+     * <p> The new buffer's capacity, limit, position, and mark values will be
+     * identical to those of this buffer.  The new buffer will be direct if,
+     * and only if, this buffer is direct, and it will be read-only if, and
+     * only if, this buffer is read-only.  </p>
+     *
+     * @return  The new $fulltype$ buffer
+     */
+    public abstract $Type$Buffer duplicate();
+
+    /**
+     * Creates a new, read-only $fulltype$ buffer that shares this buffer's
+     * content.
+     *
+     * <p> The content of the new buffer will be that of this buffer.  Changes
+     * to this buffer's content will be visible in the new buffer; the new
+     * buffer itself, however, will be read-only and will not allow the shared
+     * content to be modified.  The two buffers' position, limit, and mark
+     * values will be independent.
+     *
+     * <p> The new buffer's capacity, limit, position, and mark values will be
+     * identical to those of this buffer.
+     *
+     * <p> If this buffer is itself read-only then this method behaves in
+     * exactly the same way as the {@link #duplicate duplicate} method.  </p>
+     *
+     * @return  The new, read-only $fulltype$ buffer
+     */
+    public abstract $Type$Buffer asReadOnlyBuffer();
+
+
+    // -- Singleton get/put methods --
+
+    /**
+     * Relative <i>get</i> method.  Reads the $fulltype$ at this buffer's
+     * current position, and then increments the position. </p>
+     *
+     * @return  The $fulltype$ at the buffer's current position
+     *
+     * @throws  BufferUnderflowException
+     *          If the buffer's current position is not smaller than its limit
+     */
+    public abstract $type$ get();
+
+    /**
+     * Relative <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> Writes the given $fulltype$ into this buffer at the current
+     * position, and then increments the position. </p>
+     *
+     * @param  $x$
+     *         The $fulltype$ to be written
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If this buffer's current position is not smaller than its limit
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public abstract $Type$Buffer put($type$ $x$);
+
+    /**
+     * Absolute <i>get</i> method.  Reads the $fulltype$ at the given
+     * index. </p>
+     *
+     * @param  index
+     *         The index from which the $fulltype$ will be read
+     *
+     * @return  The $fulltype$ at the given index
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If <tt>index</tt> is negative
+     *          or not smaller than the buffer's limit
+     */
+    public abstract $type$ get(int index);
+
+    /**
+     * Absolute <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> Writes the given $fulltype$ into this buffer at the given
+     * index. </p>
+     *
+     * @param  index
+     *         The index at which the $fulltype$ will be written
+     *
+     * @param  $x$
+     *         The $fulltype$ value to be written
+     *
+     * @return  This buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If <tt>index</tt> is negative
+     *          or not smaller than the buffer's limit
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public abstract $Type$Buffer put(int index, $type$ $x$);
+
+
+    // -- Bulk get operations --
+
+    /**
+     * Relative bulk <i>get</i> method.
+     *
+     * <p> This method transfers $fulltype$s from this buffer into the given
+     * destination array.  If there are fewer $fulltype$s remaining in the
+     * buffer than are required to satisfy the request, that is, if
+     * <tt>length</tt>&nbsp;<tt>&gt;</tt>&nbsp;<tt>remaining()</tt>, then no
+     * $fulltype$s are transferred and a {@link BufferUnderflowException} is
+     * thrown.
+     *
+     * <p> Otherwise, this method copies <tt>length</tt> $fulltype$s from this
+     * buffer into the given array, starting at the current position of this
+     * buffer and at the given offset in the array.  The position of this
+     * buffer is then incremented by <tt>length</tt>.
+     *
+     * <p> In other words, an invocation of this method of the form
+     * <tt>src.get(dst,&nbsp;off,&nbsp;len)</tt> has exactly the same effect as
+     * the loop
+     *
+     * <pre>
+     *     for (int i = off; i < off + len; i++)
+     *         dst[i] = src.get(); </pre>
+     *
+     * except that it first checks that there are sufficient $fulltype$s in
+     * this buffer and it is potentially much more efficient. </p>
+     *
+     * @param  dst
+     *         The array into which $fulltype$s are to be written
+     *
+     * @param  offset
+     *         The offset within the array of the first $fulltype$ to be
+     *         written; must be non-negative and no larger than
+     *         <tt>dst.length</tt>
+     *
+     * @param  length
+     *         The maximum number of $fulltype$s to be written to the given
+     *         array; must be non-negative and no larger than
+     *         <tt>dst.length - offset</tt>
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferUnderflowException
+     *          If there are fewer than <tt>length</tt> $fulltype$s
+     *          remaining in this buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+     *          parameters do not hold
+     */
+    public $Type$Buffer get($type$[] dst, int offset, int length) {
+        checkBounds(offset, length, dst.length);
+        if (length > remaining())
+            throw new BufferUnderflowException();
+        int end = offset + length;
+        for (int i = offset; i < end; i++)
+            dst[i] = get();
+        return this;
+    }
+
+    /**
+     * Relative bulk <i>get</i> method.
+     *
+     * <p> This method transfers $fulltype$s from this buffer into the given
+     * destination array.  An invocation of this method of the form
+     * <tt>src.get(a)</tt> behaves in exactly the same way as the invocation
+     *
+     * <pre>
+     *     src.get(a, 0, a.length) </pre>
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferUnderflowException
+     *          If there are fewer than <tt>length</tt> $fulltype$s
+     *          remaining in this buffer
+     */
+    public $Type$Buffer get($type$[] dst) {
+        return get(dst, 0, dst.length);
+    }
+
+
+    // -- Bulk put operations --
+
+    /**
+     * Relative bulk <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> This method transfers the $fulltype$s remaining in the given source
+     * buffer into this buffer.  If there are more $fulltype$s remaining in the
+     * source buffer than in this buffer, that is, if
+     * <tt>src.remaining()</tt>&nbsp;<tt>&gt;</tt>&nbsp;<tt>remaining()</tt>,
+     * then no $fulltype$s are transferred and a {@link
+     * BufferOverflowException} is thrown.
+     *
+     * <p> Otherwise, this method copies
+     * <i>n</i>&nbsp;=&nbsp;<tt>src.remaining()</tt> $fulltype$s from the given
+     * buffer into this buffer, starting at each buffer's current position.
+     * The positions of both buffers are then incremented by <i>n</i>.
+     *
+     * <p> In other words, an invocation of this method of the form
+     * <tt>dst.put(src)</tt> has exactly the same effect as the loop
+     *
+     * <pre>
+     *     while (src.hasRemaining())
+     *         dst.put(src.get()); </pre>
+     *
+     * except that it first checks that there is sufficient space in this
+     * buffer and it is potentially much more efficient. </p>
+     *
+     * @param  src
+     *         The source buffer from which $fulltype$s are to be read;
+     *         must not be this buffer
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If there is insufficient space in this buffer
+     *          for the remaining $fulltype$s in the source buffer
+     *
+     * @throws  IllegalArgumentException
+     *          If the source buffer is this buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public $Type$Buffer put($Type$Buffer src) {
+        if (src == this)
+            throw new IllegalArgumentException();
+        int n = src.remaining();
+        if (n > remaining())
+            throw new BufferOverflowException();
+        for (int i = 0; i < n; i++)
+            put(src.get());
+        return this;
+    }
+
+    /**
+     * Relative bulk <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> This method transfers $fulltype$s into this buffer from the given
+     * source array.  If there are more $fulltype$s to be copied from the array
+     * than remain in this buffer, that is, if
+     * <tt>length</tt>&nbsp;<tt>&gt;</tt>&nbsp;<tt>remaining()</tt>, then no
+     * $fulltype$s are transferred and a {@link BufferOverflowException} is
+     * thrown.
+     *
+     * <p> Otherwise, this method copies <tt>length</tt> $fulltype$s from the
+     * given array into this buffer, starting at the given offset in the array
+     * and at the current position of this buffer.  The position of this buffer
+     * is then incremented by <tt>length</tt>.
+     *
+     * <p> In other words, an invocation of this method of the form
+     * <tt>dst.put(src,&nbsp;off,&nbsp;len)</tt> has exactly the same effect as
+     * the loop
+     *
+     * <pre>
+     *     for (int i = off; i < off + len; i++)
+     *         dst.put(a[i]); </pre>
+     *
+     * except that it first checks that there is sufficient space in this
+     * buffer and it is potentially much more efficient. </p>
+     *
+     * @param  src
+     *         The array from which $fulltype$s are to be read
+     *
+     * @param  offset
+     *         The offset within the array of the first $fulltype$ to be read;
+     *         must be non-negative and no larger than <tt>array.length</tt>
+     *
+     * @param  length
+     *         The number of $fulltype$s to be read from the given array;
+     *         must be non-negative and no larger than
+     *         <tt>array.length - offset</tt>
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If there is insufficient space in this buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+     *          parameters do not hold
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public $Type$Buffer put($type$[] src, int offset, int length) {
+        checkBounds(offset, length, src.length);
+        if (length > remaining())
+            throw new BufferOverflowException();
+        int end = offset + length;
+        for (int i = offset; i < end; i++)
+            this.put(src[i]);
+        return this;
+    }
+
+    /**
+     * Relative bulk <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> This method transfers the entire content of the given source
+     * $fulltype$ array into this buffer.  An invocation of this method of the
+     * form <tt>dst.put(a)</tt> behaves in exactly the same way as the
+     * invocation
+     *
+     * <pre>
+     *     dst.put(a, 0, a.length) </pre>
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If there is insufficient space in this buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public final $Type$Buffer put($type$[] src) {
+        return put(src, 0, src.length);
+    }
+
+#if[char]
+
+    /**
+     * Relative bulk <i