OpenJDK / jdk / hs
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<MonitorValue> */ + /** Returns a List<ObjectValue> */ 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 <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 <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 <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 <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]?, a string,} or some other $fulltype$ - * buffer into this buffer;{#if[!byte]? 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 string} into a buffer. - * -#else[byte] - * - * content, by {@link #wrap($type$[]) </code><i>wrapping</i><code>} an existing - * $fulltype$ array {#if[char]?or 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 <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 <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> <tt>></tt> <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, off, 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 <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> <tt>></tt> <tt>remaining()</tt>, - * then no $fulltype$s are transferred and a {@link - * BufferOverflowException} is thrown. - * - * <p> Otherwise, this method copies - * <i>n</i> = <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 <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> <tt>></tt> <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, off, 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 <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 <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 - start</tt> <tt>></tt> <tt>remaining()</tt>, - * then no $fulltype$s are transferred and a {@link - * BufferOverflowException} is thrown. - * - * <p> Otherwise, this method copies - * <i>n</i> = <tt>end</tt> - <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, start, 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 <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 <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 <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> + <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 <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> = <tt>position()</tt> is copied - * to index zero, the $fulltype$ at index <i>p</i> + 1 is copied - * to index one, and so forth until the $fulltype$ at index - * <tt>limit()</tt> - 1 is copied to index - * <i>n</i> = <tt>limit()</tt> - <tt>1</tt> - <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> - <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> - 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() + 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> + <tt>start</tt>, and its limit will be - * <tt>position()</tt> + <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 <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 <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 <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]?, a string,} or some other $fulltype$ + * buffer into this buffer;{#if[!byte]? 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 string} into a buffer. + * +#else[byte] + * + * content, by {@link #wrap($type$[]) </code><i>wrapping</i><code>} an existing + * $fulltype$ array {#if[char]?or 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 <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 <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> <tt>></tt> <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, off, 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 <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> <tt>></tt> <tt>remaining()</tt>, + * then no $fulltype$s are transferred and a {@link + * BufferOverflowException} is thrown. + * + * <p> Otherwise, this method copies + * <i>n</i> = <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 <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> <tt>></tt> <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, off, 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 <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> metho