# HG changeset patch # User duke # Date 1499285760 -7200 # Node ID 552748e3d506c1f194da0049b53e1caa1a3c78c0 # Parent 8ced0dd94a6e44aa482b3214a430c61865c46d48# Parent ce8892c57791f4db6dfb66f7271d0e46dd08881f Merge diff -r 8ced0dd94a6e -r 552748e3d506 .hgtags-top-repo --- a/.hgtags-top-repo Thu Sep 22 16:41:14 2016 +0000 +++ b/.hgtags-top-repo Wed Jul 05 22:16:00 2017 +0200 @@ -379,3 +379,4 @@ 065724348690eda41fc69112278d8da6dcde548c jdk-9+134 82b94cb5f342319d2cda77f9fa59703ad7fde576 jdk-9+135 3ec350f5f32af249b59620d7e37b54bdcd77b233 jdk-9+136 +d7f519b004254b19e384131d9f0d0e40e31a0fd3 jdk-9+137 diff -r 8ced0dd94a6e -r 552748e3d506 Makefile --- a/Makefile Thu Sep 22 16:41:14 2016 +0000 +++ b/Makefile Wed Jul 05 22:16:00 2017 +0200 @@ -28,8 +28,8 @@ ### It also performs some sanity checks on make. ### -# The shell code below will be executed on /usr/ccs/bin/make on Solaris, but not in GNU Make. -# /usr/ccs/bin/make lacks basically every other flow control mechanism. +# The shell code below will be executed on /usr/bin/make on Solaris, but not in GNU Make. +# /usr/bin/make lacks basically every other flow control mechanism. .TEST_FOR_NON_GNUMAKE:sh=echo You are not using GNU Make/gmake, this is a requirement. Check your path. 1>&2 && exit 1 # The .FEATURES variable is likely to be unique for GNU Make. diff -r 8ced0dd94a6e -r 552748e3d506 README-builds.html --- a/README-builds.html Thu Sep 22 16:41:14 2016 +0000 +++ b/README-builds.html Wed Jul 05 22:16:00 2017 +0200 @@ -626,8 +626,7 @@
The Common UNIX Printing System (CUPS) Headers are required for building the
OpenJDK on Solaris and Linux. The Solaris header files can be obtained by
- installing the package SFWcups from the Solaris Software Companion
- CD/DVD, these often will be installed into the directory /opt/sfw/cups
.
The CUPS header files can always be downloaded from www.cups.org.
@@ -1111,8 +1110,7 @@PATH
./usr/bin/make
on Solaris. If your Solaris system
has the software from the Solaris Developer Companion CD installed, you
-should try and use gmake
which will be located in either the /usr/bin
,
-/opt/sfw/bin
or /usr/sfw/bin
directory./usr/bin/gmake
or /usr/gnu/bin/make
.
*{@code * // a0: BMH - * // a1: inits, a2: steps, a3: preds, a4: finis - * // a5: box, a6: unbox - * // a7 (and following): arguments - * loop=Lambda(a0:L,a1:L,a2:L,a3:L,a4:L,a5:L,a6:L,a7:L)=>{ - * t8:L=MethodHandle.invokeBasic(a5:L,a7:L); // box the arguments into an Object[] - * t9:L=MethodHandleImpl.loop(bt:L,a1:L,a2:L,a3:L,a4:L,t8:L); // call the loop executor (with supplied types in bt) - * t10:L=MethodHandle.invokeBasic(a6:L,t9:L);t10:L} // unbox the result; return the result + * // a1: LoopClauses (containing an array of arrays: inits, steps, preds, finis) + * // a2: box, a3: unbox + * // a4 (and following): arguments + * loop=Lambda(a0:L,a1:L,a2:L,a3:L,a4:L)=>{ + * t5:L=MethodHandle.invokeBasic(a2:L,a4:L); // box the arguments into an Object[] + * t6:L=MethodHandleImpl.loop(bt:L,a1:L,t5:L); // call the loop executor (with supplied types in bt) + * t7:L=MethodHandle.invokeBasic(a3:L,t6:L);t7:L} // unbox the result; return the result * }
* It is compiled into bytecode equivalent to the code seen in {@link MethodHandleImpl#loop(BasicType[], - * MethodHandle[], MethodHandle[], MethodHandle[], MethodHandle[], Object...)}, with the difference that no arrays + * MethodHandleImpl.LoopClauses, Object...)}, with the difference that no arrays * will be used for local state storage. Instead, the local state will be mapped to actual stack slots. *
* Bytecode generation applies an unrolling scheme to enable better bytecode generation regarding local state type * handling. The generated bytecode will have the following form ({@code void} types are ignored for convenience). * Assume there are {@code C} clauses in the loop. *
*{@code - * INIT: (INIT_SEQ for clause 1) - * ... - * (INIT_SEQ for clause C) - * LOOP: (LOOP_SEQ for clause 1) - * ... - * (LOOP_SEQ for clause C) - * GOTO LOOP - * DONE: ... + * PREINIT: ALOAD_1 + * CHECKCAST LoopClauses + * GETFIELD LoopClauses.clauses + * ASTORE clauseDataIndex // place the clauses 2-dimensional array on the stack + * INIT: (INIT_SEQ for clause 1) + * ... + * (INIT_SEQ for clause C) + * LOOP: (LOOP_SEQ for clause 1) + * ... + * (LOOP_SEQ for clause C) + * GOTO LOOP + * DONE: ... * }
* The {@code INIT_SEQ_x} sequence for clause {@code x} (with {@code x} ranging from {@code 0} to {@code C-1}) has * the following shape. Assume slot {@code vx} is used to hold the state for clause {@code x}. *
{@code - * INIT_SEQ_x: ALOAD inits - * CHECKCAST MethodHandle[] + * INIT_SEQ_x: ALOAD clauseDataIndex + * ICONST_0 + * AALOAD // load the inits array * ICONST x * AALOAD // load the init handle for clause x * load args @@ -1361,24 +1369,27 @@ * The {@code LOOP_SEQ_x} sequence for clause {@code x} (with {@code x} ranging from {@code 0} to {@code C-1}) has * the following shape. Again, assume slot {@code vx} is used to hold the state for clause {@code x}. *{@code - * LOOP_SEQ_x: ALOAD steps - * CHECKCAST MethodHandle[] + * LOOP_SEQ_x: ALOAD clauseDataIndex + * ICONST_1 + * AALOAD // load the steps array * ICONST x * AALOAD // load the step handle for clause x * load locals * load args * INVOKEVIRTUAL MethodHandle.invokeBasic * store vx - * ALOAD preds - * CHECKCAST MethodHandle[] + * ALOAD clauseDataIndex + * ICONST_2 + * AALOAD // load the preds array * ICONST x * AALOAD // load the pred handle for clause x * load locals * load args * INVOKEVIRTUAL MethodHandle.invokeBasic * IFNE LOOP_SEQ_x+1 // predicate returned false -> jump to next clause - * ALOAD finis - * CHECKCAST MethodHandle[] + * ALOAD clauseDataIndex + * ICONST_3 + * AALOAD // load the finis array * ICONST x * AALOAD // load the fini handle for clause x * load locals @@ -1397,8 +1408,12 @@ BasicType[] loopClauseTypes = (BasicType[]) invoker.arguments[0]; Class>[] loopLocalStateTypes = Stream.of(loopClauseTypes). filter(bt -> bt != BasicType.V_TYPE).map(BasicType::basicTypeClass).toArray(Class>[]::new); + Class>[] localTypes = new Class>[loopLocalStateTypes.length + 1]; + localTypes[0] = MethodHandleImpl.LoopClauses.class; + System.arraycopy(loopLocalStateTypes, 0, localTypes, 1, loopLocalStateTypes.length); - final int firstLoopStateIndex = extendLocalsMap(loopLocalStateTypes); + final int clauseDataIndex = extendLocalsMap(localTypes); + final int firstLoopStateIndex = clauseDataIndex + 1; Class> returnType = result.function.resolvedHandle().type().returnType(); MethodType loopType = args.function.resolvedHandle().type() @@ -1420,10 +1435,16 @@ Label lDone = new Label(); Label lNext; + // PREINIT: + emitPushArgument(MethodHandleImpl.LoopClauses.class, invoker.arguments[1]); + mv.visitFieldInsn(Opcodes.GETFIELD, LOOP_CLAUSES, "clauses", MHARY2); + emitAstoreInsn(clauseDataIndex); + // INIT: for (int c = 0, state = 0; c < nClauses; ++c) { MethodType cInitType = loopType.changeReturnType(loopClauseTypes[c].basicTypeClass()); - emitLoopHandleInvoke(invoker, inits, c, args, false, cInitType, loopLocalStateTypes, firstLoopStateIndex); + emitLoopHandleInvoke(invoker, inits, c, args, false, cInitType, loopLocalStateTypes, clauseDataIndex, + firstLoopStateIndex); if (cInitType.returnType() != void.class) { emitStoreInsn(BasicType.basicType(cInitType.returnType()), firstLoopStateIndex + state); ++state; @@ -1440,18 +1461,21 @@ boolean isVoid = stepType.returnType() == void.class; // invoke loop step - emitLoopHandleInvoke(invoker, steps, c, args, true, stepType, loopLocalStateTypes, firstLoopStateIndex); + emitLoopHandleInvoke(invoker, steps, c, args, true, stepType, loopLocalStateTypes, clauseDataIndex, + firstLoopStateIndex); if (!isVoid) { emitStoreInsn(BasicType.basicType(stepType.returnType()), firstLoopStateIndex + state); ++state; } // invoke loop predicate - emitLoopHandleInvoke(invoker, preds, c, args, true, predType, loopLocalStateTypes, firstLoopStateIndex); + emitLoopHandleInvoke(invoker, preds, c, args, true, predType, loopLocalStateTypes, clauseDataIndex, + firstLoopStateIndex); mv.visitJumpInsn(Opcodes.IFNE, lNext); // invoke fini - emitLoopHandleInvoke(invoker, finis, c, args, true, finiType, loopLocalStateTypes, firstLoopStateIndex); + emitLoopHandleInvoke(invoker, finis, c, args, true, finiType, loopLocalStateTypes, clauseDataIndex, + firstLoopStateIndex); mv.visitJumpInsn(Opcodes.GOTO, lDone); // this is the beginning of the next loop clause @@ -1483,9 +1507,10 @@ } private void emitLoopHandleInvoke(Name holder, int handles, int clause, Name args, boolean pushLocalState, - MethodType type, Class>[] loopLocalStateTypes, int firstLoopStateSlot) { + MethodType type, Class>[] loopLocalStateTypes, int clauseDataSlot, + int firstLoopStateSlot) { // load handle for clause - emitPushArgument(holder, handles); + emitPushClauseArray(clauseDataSlot, handles); emitIconstInsn(clause); mv.visitInsn(Opcodes.AALOAD); // load loop state (preceding the other arguments) @@ -1499,6 +1524,12 @@ mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, MH, "invokeBasic", type.toMethodDescriptorString(), false); } + private void emitPushClauseArray(int clauseDataSlot, int which) { + emitAloadInsn(clauseDataSlot); + emitIconstInsn(which - 1); + mv.visitInsn(Opcodes.AALOAD); + } + private void emitZero(BasicType type) { switch (type) { case I_TYPE: mv.visitInsn(Opcodes.ICONST_0); break; diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java --- a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java Wed Jul 05 22:16:00 2017 +0200 @@ -41,7 +41,6 @@ import static java.lang.invoke.LambdaForm.BasicType.*; import static java.lang.invoke.MethodHandleNatives.Constants.REF_invokeStatic; import static java.lang.invoke.MethodHandleStatics.*; -import java.util.Objects; /** * The symbolic, non-executable form of a method handle's invocation semantics. @@ -732,9 +731,9 @@ boolean isLoop(int pos) { // loop idiom: // t_{n}:L=MethodHandle.invokeBasic(...) - // t_{n+1}:L=MethodHandleImpl.loop(types, *, *, *, *, t_{n}) + // t_{n+1}:L=MethodHandleImpl.loop(types, *, t_{n}) // t_{n+2}:?=MethodHandle.invokeBasic(*, t_{n+1}) - return isMatchingIdiom(pos, "loop", 5); + return isMatchingIdiom(pos, "loop", 2); } /* diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java Wed Jul 05 22:16:00 2017 +0200 @@ -1689,8 +1689,7 @@ NF_tryFinally = new NamedFunction(MethodHandleImpl.class .getDeclaredMethod("tryFinally", MethodHandle.class, MethodHandle.class, Object[].class)); NF_loop = new NamedFunction(MethodHandleImpl.class - .getDeclaredMethod("loop", BasicType[].class, MethodHandle[].class, MethodHandle[].class, - MethodHandle[].class, MethodHandle[].class, Object[].class)); + .getDeclaredMethod("loop", BasicType[].class, LoopClauses.class, Object[].class)); NF_throwException = new NamedFunction(MethodHandleImpl.class .getDeclaredMethod("throwException", Throwable.class)); NF_profileBoolean = new NamedFunction(MethodHandleImpl.class @@ -1794,12 +1793,13 @@ MethodHandle collectArgs = varargsArray(type.parameterCount()).asType(varargsType); MethodHandle unboxResult = unboxResultHandle(tloop); - BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_LLLLLL(); + LoopClauses clauseData = + new LoopClauses(new MethodHandle[][]{toArray(init), toArray(step), toArray(pred), toArray(fini)}); + BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_LLL(); BoundMethodHandle mh; try { - mh = (BoundMethodHandle) data.constructor().invokeBasic(type, form, (Object) toArray(init), - (Object) toArray(step), (Object) toArray(pred), (Object) toArray(fini), (Object) collectArgs, - (Object) unboxResult); + mh = (BoundMethodHandle) data.constructor().invokeBasic(type, form, (Object) clauseData, + (Object) collectArgs, (Object) unboxResult); } catch (Throwable ex) { throw uncaughtException(ex); } @@ -1818,23 +1818,20 @@ * {@code t12}): **{@code * loop=Lambda(a0:L,a1:L)=>{ - * t2:L=BoundMethodHandle$Species_L6.argL0(a0:L); // array of init method handles - * t3:L=BoundMethodHandle$Species_L6.argL1(a0:L); // array of step method handles - * t4:L=BoundMethodHandle$Species_L6.argL2(a0:L); // array of pred method handles - * t5:L=BoundMethodHandle$Species_L6.argL3(a0:L); // array of fini method handles - * t6:L=BoundMethodHandle$Species_L6.argL4(a0:L); // helper handle to box the arguments into an Object[] - * t7:L=BoundMethodHandle$Species_L6.argL5(a0:L); // helper handle to unbox the result - * t8:L=MethodHandle.invokeBasic(t6:L,a1:L); // box the arguments into an Object[] - * t9:L=MethodHandleImpl.loop(null,t2:L,t3:L,t4:L,t5:L,t6:L); // call the loop executor - * t10:L=MethodHandle.invokeBasic(t7:L,t9:L);t10:L} // unbox the result; return the result + * t2:L=BoundMethodHandle$Species_L3.argL0(a0:L); // LoopClauses holding init, step, pred, fini handles + * t3:L=BoundMethodHandle$Species_L3.argL1(a0:L); // helper handle to box the arguments into an Object[] + * t4:L=BoundMethodHandle$Species_L3.argL2(a0:L); // helper handle to unbox the result + * t5:L=MethodHandle.invokeBasic(t3:L,a1:L); // box the arguments into an Object[] + * t6:L=MethodHandleImpl.loop(null,t2:L,t3:L); // call the loop executor + * t7:L=MethodHandle.invokeBasic(t4:L,t6:L);t7:L} // unbox the result; return the result * }- * {@code argL0} through {@code argL3} are the arrays of init, step, pred, and fini method handles. - * {@code argL4} and {@code argL5} are auxiliary method handles: {@code argL2} boxes arguments and wraps them into - * {@code Object[]} ({@code ValueConversions.array()}), and {@code argL3} unboxes the result if necessary + * {@code argL0} is a LoopClauses instance holding, in a 2-dimensional array, the init, step, pred, and fini method + * handles. {@code argL1} and {@code argL2} are auxiliary method handles: {@code argL1} boxes arguments and wraps + * them into {@code Object[]} ({@code ValueConversions.array()}), and {@code argL2} unboxes the result if necessary * ({@code ValueConversions.unbox()}). *
- * Having {@code t6} and {@code t7} passed in via a BMH and not hardcoded in the lambda form allows to share lambda + * Having {@code t3} and {@code t4} passed in via a BMH and not hardcoded in the lambda form allows to share lambda * forms among loop combinators with the same basic type. *
* The above template is instantiated by using the {@link LambdaFormEditor} to replace the {@code null} argument to @@ -1845,15 +1842,12 @@ private static LambdaForm makeLoopForm(MethodType basicType, BasicType[] localVarTypes) { MethodType lambdaType = basicType.invokerType(); - final int THIS_MH = 0; // the BMH_LLLLLL + final int THIS_MH = 0; // the BMH_LLL final int ARG_BASE = 1; // start of incoming arguments final int ARG_LIMIT = ARG_BASE + basicType.parameterCount(); int nameCursor = ARG_LIMIT; - final int GET_INITS = nameCursor++; - final int GET_STEPS = nameCursor++; - final int GET_PREDS = nameCursor++; - final int GET_FINIS = nameCursor++; + final int GET_CLAUSE_DATA = nameCursor++; final int GET_COLLECT_ARGS = nameCursor++; final int GET_UNBOX_RESULT = nameCursor++; final int BOXED_ARGS = nameCursor++; @@ -1864,14 +1858,11 @@ if (lform == null) { Name[] names = arguments(nameCursor - ARG_LIMIT, lambdaType); - BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_LLLLLL(); + BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_LLL(); names[THIS_MH] = names[THIS_MH].withConstraint(data); - names[GET_INITS] = new Name(data.getterFunction(0), names[THIS_MH]); - names[GET_STEPS] = new Name(data.getterFunction(1), names[THIS_MH]); - names[GET_PREDS] = new Name(data.getterFunction(2), names[THIS_MH]); - names[GET_FINIS] = new Name(data.getterFunction(3), names[THIS_MH]); - names[GET_COLLECT_ARGS] = new Name(data.getterFunction(4), names[THIS_MH]); - names[GET_UNBOX_RESULT] = new Name(data.getterFunction(5), names[THIS_MH]); + names[GET_CLAUSE_DATA] = new Name(data.getterFunction(0), names[THIS_MH]); + names[GET_COLLECT_ARGS] = new Name(data.getterFunction(1), names[THIS_MH]); + names[GET_UNBOX_RESULT] = new Name(data.getterFunction(2), names[THIS_MH]); // t_{i}:L=MethodHandle.invokeBasic(collectArgs:L,a1:L,...); MethodType collectArgsType = basicType.changeReturnType(Object.class); @@ -1881,10 +1872,10 @@ System.arraycopy(names, ARG_BASE, args, 1, ARG_LIMIT - ARG_BASE); names[BOXED_ARGS] = new Name(makeIntrinsic(invokeBasic, Intrinsic.LOOP), args); - // t_{i+1}:L=MethodHandleImpl.loop(localTypes:L,inits:L,steps:L,preds:L,finis:L,t_{i}:L); + // t_{i+1}:L=MethodHandleImpl.loop(localTypes:L,clauses:L,t_{i}:L); Object[] lArgs = new Object[]{null, // placeholder for BasicType[] localTypes - will be added by LambdaFormEditor - names[GET_INITS], names[GET_STEPS], names[GET_PREDS], names[GET_FINIS], names[BOXED_ARGS]}; + names[GET_CLAUSE_DATA], names[BOXED_ARGS]}; names[LOOP] = new Name(NF_loop, lArgs); // t_{i+2}:I=MethodHandle.invokeBasic(unbox:L,t_{i+1}:L); @@ -1900,22 +1891,52 @@ return lform.editor().noteLoopLocalTypesForm(BOXED_ARGS, localVarTypes); } + static class LoopClauses { + @Stable final MethodHandle[][] clauses; + LoopClauses(MethodHandle[][] clauses) { + assert clauses.length == 4; + this.clauses = clauses; + } + @Override + public String toString() { + StringBuffer sb = new StringBuffer("LoopClauses -- "); + for (int i = 0; i < 4; ++i) { + if (i > 0) { + sb.append(" "); + } + sb.append('<').append(i).append(">: "); + MethodHandle[] hs = clauses[i]; + for (int j = 0; j < hs.length; ++j) { + if (j > 0) { + sb.append(" "); + } + sb.append('*').append(j).append(": ").append(hs[j]).append('\n'); + } + } + sb.append(" --\n"); + return sb.toString(); + } + } /** * Intrinsified during LambdaForm compilation * (see {@link InvokerBytecodeGenerator#emitLoop(int)}). */ @LambdaForm.Hidden - static Object loop(BasicType[] localTypes, MethodHandle[] init, MethodHandle[] step, MethodHandle[] pred, - MethodHandle[] fini, Object... av) throws Throwable { + static Object loop(BasicType[] localTypes, LoopClauses clauseData, Object... av) throws Throwable { + final MethodHandle[] init = clauseData.clauses[0]; + final MethodHandle[] step = clauseData.clauses[1]; + final MethodHandle[] pred = clauseData.clauses[2]; + final MethodHandle[] fini = clauseData.clauses[3]; int varSize = (int) Stream.of(init).filter(h -> h.type().returnType() != void.class).count(); int nArgs = init[0].type().parameterCount(); Object[] varsAndArgs = new Object[varSize + nArgs]; for (int i = 0, v = 0; i < init.length; ++i) { - if (init[i].type().returnType() == void.class) { - init[i].asFixedArity().invokeWithArguments(av); + MethodHandle ih = init[i]; + if (ih.type().returnType() == void.class) { + ih.invokeWithArguments(av); } else { - varsAndArgs[v++] = init[i].asFixedArity().invokeWithArguments(av); + varsAndArgs[v++] = ih.invokeWithArguments(av); } } System.arraycopy(av, 0, varsAndArgs, varSize, nArgs); @@ -1926,12 +1947,12 @@ MethodHandle s = step[i]; MethodHandle f = fini[i]; if (s.type().returnType() == void.class) { - s.asFixedArity().invokeWithArguments(varsAndArgs); + s.invokeWithArguments(varsAndArgs); } else { - varsAndArgs[v++] = s.asFixedArity().invokeWithArguments(varsAndArgs); + varsAndArgs[v++] = s.invokeWithArguments(varsAndArgs); } - if (!(boolean) p.asFixedArity().invokeWithArguments(varsAndArgs)) { - return f.asFixedArity().invokeWithArguments(varsAndArgs); + if (!(boolean) p.invokeWithArguments(varsAndArgs)) { + return f.invokeWithArguments(varsAndArgs); } } } @@ -2122,14 +2143,13 @@ Throwable t = null; Object r = null; try { - // Use asFixedArity() to avoid unnecessary boxing of last argument for VarargsCollector case. - r = target.asFixedArity().invokeWithArguments(av); + r = target.invokeWithArguments(av); } catch (Throwable thrown) { t = thrown; throw t; } finally { Object[] args = target.type().returnType() == void.class ? prepend(av, t) : prepend(av, t, r); - r = cleanup.asFixedArity().invokeWithArguments(args); + r = cleanup.invokeWithArguments(args); } return r; } diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Wed Jul 05 22:16:00 2017 +0200 @@ -4368,10 +4368,11 @@ } // Step 4: fill in missing parameter types. - List
finit = fillParameterTypes(init, commonSuffix); - List fstep = fillParameterTypes(step, commonParameterSequence); - List fpred = fillParameterTypes(pred, commonParameterSequence); - List ffini = fillParameterTypes(fini, commonParameterSequence); + // Also convert all handles to fixed-arity handles. + List finit = fixArities(fillParameterTypes(init, commonSuffix)); + List fstep = fixArities(fillParameterTypes(step, commonParameterSequence)); + List fpred = fixArities(fillParameterTypes(pred, commonParameterSequence)); + List ffini = fixArities(fillParameterTypes(fini, commonParameterSequence)); assert finit.stream().map(MethodHandle::type).map(MethodType::parameterList). allMatch(pl -> pl.equals(commonSuffix)); @@ -4389,6 +4390,10 @@ }).collect(Collectors.toList()); } + private static List fixArities(List hs) { + return hs.stream().map(MethodHandle::asFixedArity).collect(Collectors.toList()); + } + /** * Constructs a {@code while} loop from an initializer, a body, and a predicate. This is a convenience wrapper for * the {@linkplain #loop(MethodHandle[][]) generic loop combinator}. @@ -4887,7 +4892,8 @@ // target parameter list. cleanup = dropArgumentsToMatch(cleanup, (rtype == void.class ? 1 : 2), targetParamTypes, 0); - return MethodHandleImpl.makeTryFinally(target, cleanup, rtype, targetParamTypes); + // Use asFixedArity() to avoid unnecessary boxing of last argument for VarargsCollector case. + return MethodHandleImpl.makeTryFinally(target.asFixedArity(), cleanup.asFixedArity(), rtype, targetParamTypes); } /** diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/java/lang/module/ModuleInfo.java --- a/jdk/src/java.base/share/classes/java/lang/module/ModuleInfo.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/module/ModuleInfo.java Wed Jul 05 22:16:00 2017 +0200 @@ -664,7 +664,7 @@ try { bb.get(b, off, len); } catch (BufferUnderflowException e) { - throw new EOFException(); + throw new EOFException(e.getMessage()); } } @@ -681,7 +681,7 @@ int ch = bb.get(); return (ch != 0); } catch (BufferUnderflowException e) { - throw new EOFException(); + throw new EOFException(e.getMessage()); } } @@ -690,7 +690,7 @@ try { return bb.get(); } catch (BufferUnderflowException e) { - throw new EOFException(); + throw new EOFException(e.getMessage()); } } @@ -699,7 +699,7 @@ try { return ((int) bb.get()) & 0xff; } catch (BufferUnderflowException e) { - throw new EOFException(); + throw new EOFException(e.getMessage()); } } @@ -708,7 +708,7 @@ try { return bb.getShort(); } catch (BufferUnderflowException e) { - throw new EOFException(); + throw new EOFException(e.getMessage()); } } @@ -717,7 +717,7 @@ try { return ((int) bb.getShort()) & 0xffff; } catch (BufferUnderflowException e) { - throw new EOFException(); + throw new EOFException(e.getMessage()); } } @@ -726,7 +726,7 @@ try { return bb.getChar(); } catch (BufferUnderflowException e) { - throw new EOFException(); + throw new EOFException(e.getMessage()); } } @@ -735,7 +735,7 @@ try { return bb.getInt(); } catch (BufferUnderflowException e) { - throw new EOFException(); + throw new EOFException(e.getMessage()); } } @@ -744,7 +744,7 @@ try { return bb.getLong(); } catch (BufferUnderflowException e) { - throw new EOFException(); + throw new EOFException(e.getMessage()); } } @@ -753,7 +753,7 @@ try { return bb.getFloat(); } catch (BufferUnderflowException e) { - throw new EOFException(); + throw new EOFException(e.getMessage()); } } @@ -762,7 +762,7 @@ try { return bb.getDouble(); } catch (BufferUnderflowException e) { - throw new EOFException(); + throw new EOFException(e.getMessage()); } } diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/java/lang/reflect/Proxy.java --- a/jdk/src/java.base/share/classes/java/lang/reflect/Proxy.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/reflect/Proxy.java Wed Jul 05 22:16:00 2017 +0200 @@ -597,10 +597,10 @@ private final Module module; ProxyBuilder(ClassLoader loader, List > interfaces) { if (!VM.isModuleSystemInited()) { - throw new InternalError("Proxy is not supported until module system is fully initialzed"); + throw new InternalError("Proxy is not supported until module system is fully initialized"); } if (interfaces.size() > 65535) { - throw new IllegalArgumentException("interface limit exceeded"); + throw new IllegalArgumentException("interface limit exceeded: " + interfaces.size()); } Set > refTypes = referencedTypes(loader, interfaces); diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/java/util/concurrent/CompletableFuture.java --- a/jdk/src/java.base/share/classes/java/util/concurrent/CompletableFuture.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/util/concurrent/CompletableFuture.java Wed Jul 05 22:16:00 2017 +0200 @@ -2559,6 +2559,13 @@ * exceptionally with a CompletionException with this exception as * cause. * + * Unless overridden by a subclass, a new non-minimal + * CompletableFuture with all methods available can be obtained from + * a minimal CompletionStage via {@link #toCompletableFuture()}. + * For example, completion of a minimal stage can be awaited by + * + *
{@code minimalStage.toCompletableFuture().join(); }+ * * @return the new CompletionStage * @since 9 */ @@ -2853,6 +2860,16 @@ @Override public CompletableFuturecompleteOnTimeout (T value, long timeout, TimeUnit unit) { throw new UnsupportedOperationException(); } + @Override public CompletableFuture toCompletableFuture() { + Object r; + if ((r = result) != null) + return new CompletableFuture (encodeRelay(r)); + else { + CompletableFuture d = new CompletableFuture<>(); + unipush(new UniRelay (d, this)); + return d; + } + } } // VarHandle mechanics diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java --- a/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java Wed Jul 05 22:16:00 2017 +0200 @@ -1191,7 +1191,7 @@ * Default idle timeout value (in milliseconds) for the thread * triggering quiescence to park waiting for new work */ - private static final long DEFAULT_KEEPALIVE = 60000L; + private static final long DEFAULT_KEEPALIVE = 60_000L; /** * Undershoot tolerance for idle timeouts @@ -2303,7 +2303,6 @@ throw new NullPointerException(); long ms = Math.max(unit.toMillis(keepAliveTime), TIMEOUT_SLOP); - String prefix = "ForkJoinPool-" + nextPoolId() + "-worker-"; int corep = Math.min(Math.max(corePoolSize, parallelism), MAX_CAP); long c = ((((long)(-corep) << TC_SHIFT) & TC_MASK) | (((long)(-parallelism) << RC_SHIFT) & RC_MASK)); @@ -2315,8 +2314,8 @@ n |= n >>> 1; n |= n >>> 2; n |= n >>> 4; n |= n >>> 8; n |= n >>> 16; n = (n + 1) << 1; // power of two, including space for submission queues + this.workerNamePrefix = "ForkJoinPool-" + nextPoolId() + "-worker-"; this.workQueues = new WorkQueue[n]; - this.workerNamePrefix = prefix; this.factory = factory; this.ueh = handler; this.saturate = saturate; @@ -2327,11 +2326,19 @@ checkPermission(); } + private Object newInstanceFromSystemProperty(String property) + throws ReflectiveOperationException { + String className = System.getProperty(property); + return (className == null) + ? null + : ClassLoader.getSystemClassLoader().loadClass(className) + .getConstructor().newInstance(); + } + /** * Constructor for common pool using parameters possibly * overridden by system properties */ - @SuppressWarnings("deprecation") // Class.newInstance private ForkJoinPool(byte forCommonPoolOnly) { int parallelism = -1; ForkJoinWorkerThreadFactory fac = null; @@ -2339,18 +2346,12 @@ try { // ignore exceptions in accessing/parsing properties String pp = System.getProperty ("java.util.concurrent.ForkJoinPool.common.parallelism"); - String fp = System.getProperty - ("java.util.concurrent.ForkJoinPool.common.threadFactory"); - String hp = System.getProperty - ("java.util.concurrent.ForkJoinPool.common.exceptionHandler"); if (pp != null) parallelism = Integer.parseInt(pp); - if (fp != null) - fac = ((ForkJoinWorkerThreadFactory)ClassLoader. - getSystemClassLoader().loadClass(fp).newInstance()); - if (hp != null) - handler = ((UncaughtExceptionHandler)ClassLoader. - getSystemClassLoader().loadClass(hp).newInstance()); + fac = (ForkJoinWorkerThreadFactory) newInstanceFromSystemProperty( + "java.util.concurrent.ForkJoinPool.common.threadFactory"); + handler = (UncaughtExceptionHandler) newInstanceFromSystemProperty( + "java.util.concurrent.ForkJoinPool.common.exceptionHandler"); } catch (Exception ignore) { } @@ -2373,8 +2374,8 @@ n |= n >>> 1; n |= n >>> 2; n |= n >>> 4; n |= n >>> 8; n |= n >>> 16; n = (n + 1) << 1; + this.workerNamePrefix = "ForkJoinPool.commonPool-worker-"; this.workQueues = new WorkQueue[n]; - this.workerNamePrefix = "ForkJoinPool.commonPool-worker-"; this.factory = fac; this.ueh = handler; this.saturate = null; diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAccumulator.java --- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAccumulator.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAccumulator.java Wed Jul 05 22:16:00 2017 +0200 @@ -35,6 +35,9 @@ package java.util.concurrent.atomic; +import static java.lang.Double.doubleToRawLongBits; +import static java.lang.Double.longBitsToDouble; + import java.io.Serializable; import java.util.function.DoubleBinaryOperator; @@ -91,7 +94,7 @@ public DoubleAccumulator(DoubleBinaryOperator accumulatorFunction, double identity) { this.function = accumulatorFunction; - base = this.identity = Double.doubleToRawLongBits(identity); + base = this.identity = doubleToRawLongBits(identity); } /** @@ -101,18 +104,19 @@ */ public void accumulate(double x) { Cell[] as; long b, v, r; int m; Cell a; - if ((as = cells) != null || - (r = Double.doubleToRawLongBits - (function.applyAsDouble - (Double.longBitsToDouble(b = base), x))) != b && !casBase(b, r)) { + if ((as = cells) != null + || ((r = doubleToRawLongBits + (function.applyAsDouble(longBitsToDouble(b = base), x))) != b + && !casBase(b, r))) { boolean uncontended = true; - if (as == null || (m = as.length - 1) < 0 || - (a = as[getProbe() & m]) == null || - !(uncontended = - (r = Double.doubleToRawLongBits - (function.applyAsDouble - (Double.longBitsToDouble(v = a.value), x))) == v || - a.cas(v, r))) + if (as == null + || (m = as.length - 1) < 0 + || (a = as[getProbe() & m]) == null + || !(uncontended = + ((r = doubleToRawLongBits + (function.applyAsDouble + (longBitsToDouble(v = a.value), x))) == v) + || a.cas(v, r))) doubleAccumulate(x, function, uncontended); } } @@ -128,12 +132,12 @@ */ public double get() { Cell[] as = cells; - double result = Double.longBitsToDouble(base); + double result = longBitsToDouble(base); if (as != null) { for (Cell a : as) if (a != null) result = function.applyAsDouble - (result, Double.longBitsToDouble(a.value)); + (result, longBitsToDouble(a.value)); } return result; } @@ -168,12 +172,12 @@ */ public double getThenReset() { Cell[] as = cells; - double result = Double.longBitsToDouble(base); + double result = longBitsToDouble(base); base = identity; if (as != null) { for (Cell a : as) { if (a != null) { - double v = Double.longBitsToDouble(a.value); + double v = longBitsToDouble(a.value); a.reset(identity); result = function.applyAsDouble(result, v); } @@ -267,9 +271,9 @@ * held by this proxy */ private Object readResolve() { - double d = Double.longBitsToDouble(identity); + double d = longBitsToDouble(identity); DoubleAccumulator a = new DoubleAccumulator(function, d); - a.base = Double.doubleToRawLongBits(value); + a.base = doubleToRawLongBits(value); return a; } } diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/java/util/concurrent/atomic/LongAccumulator.java --- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/LongAccumulator.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/LongAccumulator.java Wed Jul 05 22:16:00 2017 +0200 @@ -103,14 +103,16 @@ */ public void accumulate(long x) { Cell[] as; long b, v, r; int m; Cell a; - if ((as = cells) != null || - (r = function.applyAsLong(b = base, x)) != b && !casBase(b, r)) { + if ((as = cells) != null + || ((r = function.applyAsLong(b = base, x)) != b + && !casBase(b, r))) { boolean uncontended = true; - if (as == null || (m = as.length - 1) < 0 || - (a = as[getProbe() & m]) == null || - !(uncontended = - (r = function.applyAsLong(v = a.value, x)) == v || - a.cas(v, r))) + if (as == null + || (m = as.length - 1) < 0 + || (a = as[getProbe() & m]) == null + || !(uncontended = + (r = function.applyAsLong(v = a.value, x)) == v + || a.cas(v, r))) longAccumulate(x, function, uncontended); } } diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/jdk/internal/jimage/BasicImageReader.java --- a/jdk/src/java.base/share/classes/jdk/internal/jimage/BasicImageReader.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/jimage/BasicImageReader.java Wed Jul 05 22:16:00 2017 +0200 @@ -186,7 +186,9 @@ if (result.getMajorVersion() != ImageHeader.MAJOR_VERSION || result.getMinorVersion() != ImageHeader.MINOR_VERSION) { - throw new IOException("The image file \"" + name + "\" is not the correct version"); + throw new IOException("The image file \"" + name + "\" is not " + + "the correct version. Major: " + result.getMajorVersion() + + ". Minor: " + result.getMinorVersion()); } return result; @@ -318,11 +320,11 @@ private ByteBuffer readBuffer(long offset, long size) { if (offset < 0 || Integer.MAX_VALUE <= offset) { - throw new IndexOutOfBoundsException("offset"); + throw new IndexOutOfBoundsException("Bad offset: " + offset); } if (size < 0 || Integer.MAX_VALUE <= size) { - throw new IndexOutOfBoundsException("size"); + throw new IndexOutOfBoundsException("Bad size: " + size); } if (MAP_ALL) { @@ -382,11 +384,13 @@ long uncompressedSize = loc.getUncompressedSize(); if (compressedSize < 0 || Integer.MAX_VALUE < compressedSize) { - throw new IndexOutOfBoundsException("Compressed size"); + throw new IndexOutOfBoundsException( + "Bad compressed size: " + compressedSize); } if (uncompressedSize < 0 || Integer.MAX_VALUE < uncompressedSize) { - throw new IndexOutOfBoundsException("Uncompressed size"); + throw new IndexOutOfBoundsException( + "Bad uncompressed size: " + uncompressedSize); } if (compressedSize == 0) { diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/jdk/internal/jimage/ImageHeader.java --- a/jdk/src/java.base/share/classes/jdk/internal/jimage/ImageHeader.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/jimage/ImageHeader.java Wed Jul 05 22:16:00 2017 +0200 @@ -79,7 +79,8 @@ Objects.requireNonNull(buffer); if (buffer.capacity() != HEADER_SLOTS) { - throw new InternalError("jimage header not the correct size"); + throw new InternalError( + "jimage header not the correct size: " + buffer.capacity()); } int magic = buffer.get(0); diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/jdk/internal/jimage/ImageLocation.java --- a/jdk/src/java.base/share/classes/jdk/internal/jimage/ImageLocation.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/jimage/ImageLocation.java Wed Jul 05 22:16:00 2017 +0200 @@ -81,7 +81,8 @@ } if (kind < ATTRIBUTE_END || ATTRIBUTE_COUNT <= kind) { - throw new InternalError("Invalid jimage attribute kind"); + throw new InternalError( + "Invalid jimage attribute kind: " + kind); } int length = attributeLength(data); @@ -91,7 +92,7 @@ value <<= 8; if (!bytes.hasRemaining()) { - throw new InternalError("\"Missing jimage attribute datad"); + throw new InternalError("Missing jimage attribute data"); } value |= bytes.get() & 0xFF; @@ -134,7 +135,8 @@ long getAttribute(int kind) { if (kind < ATTRIBUTE_END || ATTRIBUTE_COUNT <= kind) { - throw new InternalError("Invalid jimage attribute kind"); + throw new InternalError( + "Invalid jimage attribute kind: " + kind); } return attributes[kind]; @@ -142,7 +144,8 @@ String getAttributeString(int kind) { if (kind < ATTRIBUTE_END || ATTRIBUTE_COUNT <= kind) { - throw new InternalError("Invalid jimage attribute kind"); + throw new InternalError( + "Invalid jimage attribute kind: " + kind); } return getStrings().get((int)attributes[kind]); diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/jdk/internal/jimage/ImageStream.java --- a/jdk/src/java.base/share/classes/jdk/internal/jimage/ImageStream.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/jimage/ImageStream.java Wed Jul 05 22:16:00 2017 +0200 @@ -82,7 +82,7 @@ public void ensure(int needs) { if (needs < 0) { - throw new IndexOutOfBoundsException("needs"); + throw new IndexOutOfBoundsException("Bad value: " + needs); } if (needs > buffer.remaining()) { @@ -106,7 +106,7 @@ public void skip(int n) { if (n < 0) { - throw new IndexOutOfBoundsException("n"); + throw new IndexOutOfBoundsException("skip value = " + n); } buffer.position(buffer.position() + n); diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/jdk/internal/jimage/ImageStringsReader.java --- a/jdk/src/java.base/share/classes/jdk/internal/jimage/ImageStringsReader.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/jimage/ImageStringsReader.java Wed Jul 05 22:16:00 2017 +0200 @@ -151,7 +151,7 @@ try { charsFromMUTF8(chars, bytes, offset, count); } catch (UTFDataFormatException ex) { - throw new InternalError("Attempt to convert non modified UTF-8 byte sequence"); + throw new InternalError("Attempt to convert non modified UTF-8 byte sequence", ex); } return new String(chars); @@ -199,7 +199,8 @@ ch = buffer.get(); if ((ch & 0xC0) != 0x80) { - throw new InternalError("Bad continuation in modified UTF-8 byte sequence"); + throw new InternalError("Bad continuation in " + + "modified UTF-8 byte sequence: " + ch); } uch = ((uch & ~mask) << 6) | (ch & 0x3F); @@ -208,7 +209,8 @@ } if ((uch & 0xFFFF) != uch) { - throw new InternalError("UTF-32 char in modified UTF-8 byte sequence"); + throw new InternalError("UTF-32 char in modified UTF-8 " + + "byte sequence: " + uch); } chars[j++] = (char)uch; diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystem.java --- a/jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystem.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystem.java Wed Jul 05 22:16:00 2017 +0200 @@ -183,7 +183,7 @@ public PathMatcher getPathMatcher(String syntaxAndInput) { int pos = syntaxAndInput.indexOf(':'); if (pos <= 0 || pos == syntaxAndInput.length()) { - throw new IllegalArgumentException(); + throw new IllegalArgumentException("pos is " + pos); } String syntax = syntaxAndInput.substring(0, pos); String input = syntaxAndInput.substring(pos + 1); @@ -285,7 +285,8 @@ for (OpenOption option : options) { Objects.requireNonNull(option); if (!(option instanceof StandardOpenOption)) { - throw new IllegalArgumentException(); + throw new IllegalArgumentException( + "option class: " + option.getClass()); } } if (options.contains(StandardOpenOption.WRITE) || diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtPath.java --- a/jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtPath.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtPath.java Wed Jul 05 22:16:00 2017 +0200 @@ -122,7 +122,8 @@ public final JrtPath getName(int index) { initOffsets(); if (index < 0 || index >= offsets.length) { - throw new IllegalArgumentException(); + throw new IllegalArgumentException("index: " + + index + ", offsets length: " + offsets.length); } int begin = offsets[index]; int end; @@ -139,7 +140,9 @@ initOffsets(); if (beginIndex < 0 || endIndex > offsets.length || beginIndex >= endIndex) { - throw new IllegalArgumentException(); + throw new IllegalArgumentException( + "beginIndex: " + beginIndex + ", endIndex: " + endIndex + + ", offsets length: " + offsets.length); } // starting/ending offsets int begin = offsets[beginIndex]; @@ -211,7 +214,8 @@ return o; } if (jrtfs != o.jrtfs || isAbsolute() != o.isAbsolute()) { - throw new IllegalArgumentException(); + throw new IllegalArgumentException( + "Incorrect filesystem or path: " + other); } final String tp = this.path; final String op = o.path; @@ -366,7 +370,8 @@ private JrtPath checkPath(Path path) { Objects.requireNonNull(path); if (!(path instanceof JrtPath)) - throw new ProviderMismatchException(); + throw new ProviderMismatchException("path class: " + + path.getClass()); return (JrtPath) path; } @@ -459,7 +464,7 @@ } if (c == '\u0000') { throw new InvalidPathException(path, - "Path: nul character not allowed"); + "Path: NUL character not allowed"); } to.append(c); prevC = c; diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/jdk/internal/misc/Unsafe.java --- a/jdk/src/java.base/share/classes/jdk/internal/misc/Unsafe.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/misc/Unsafe.java Wed Jul 05 22:16:00 2017 +0200 @@ -1603,11 +1603,50 @@ return weakCompareAndSwapShort(o, offset, c2s(expected), c2s(x)); } + /** + * The JVM converts integral values to boolean values using two + * different conventions, byte testing against zero and truncation + * to least-significant bit. + * + * The JNI documents specify that, at least for returning + * values from native methods, a Java boolean value is converted + * to the value-set 0..1 by first truncating to a byte (0..255 or + * maybe -128..127) and then testing against zero. Thus, Java + * booleans in non-Java data structures are by convention + * represented as 8-bit containers containing either zero (for + * false) or any non-zero value (for true). + * + *
Java booleans in the heap are also stored in bytes, but are + * strongly normalized to the value-set 0..1 (i.e., they are + * truncated to the least-significant bit). + * + *
The main reason for having different conventions for + * conversion is performance: Truncation to the least-significant + * bit can be usually implemented with fewer (machine) + * instructions than byte testing against zero. + * + *
A number of Unsafe methods load boolean values from the heap + * as bytes. Unsafe converts those values according to the JNI + * rules (i.e, using the "testing against zero" convention). The + * method {@code byte2bool} implements that conversion. + * + * @param b the byte to be converted to boolean + * @return the result of the conversion + */ @ForceInline private boolean byte2bool(byte b) { - return b > 0; - } - + return b != 0; + } + + /** + * Convert a boolean value to a byte. The return value is strongly + * normalized to the value-set 0..1 (i.e., the value is truncated + * to the least-significant bit). See {@link #byte2bool(byte)} for + * more details on conversion conventions. + * + * @param b the boolean to be converted to byte (and then normalized) + * @return the result of the conversion + */ @ForceInline private byte bool2byte(boolean b) { return b ? (byte)1 : (byte)0; diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/jdk/internal/misc/VM.java --- a/jdk/src/java.base/share/classes/jdk/internal/misc/VM.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/misc/VM.java Wed Jul 05 22:16:00 2017 +0200 @@ -50,7 +50,7 @@ public static void initLevel(int value) { synchronized (lock) { if (value <= initLevel || value > SYSTEM_BOOTED) - throw new InternalError(); + throw new InternalError("Bad level: " + value); initLevel = value; lock.notifyAll(); } diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java --- a/jdk/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java Wed Jul 05 22:16:00 2017 +0200 @@ -153,27 +153,24 @@ boolean addAllDefaultModules = false; boolean addAllSystemModules = false; boolean addAllApplicationModules = false; - String propValue = getAndRemoveProperty("jdk.module.addmods"); - if (propValue != null) { - for (String mod: propValue.split(",")) { - switch (mod) { - case ALL_DEFAULT: - addAllDefaultModules = true; - break; - case ALL_SYSTEM: - addAllSystemModules = true; - break; - case ALL_MODULE_PATH: - addAllApplicationModules = true; - break; - default : - roots.add(mod); - } + for (String mod: getExtraAddModules()) { + switch (mod) { + case ALL_DEFAULT: + addAllDefaultModules = true; + break; + case ALL_SYSTEM: + addAllSystemModules = true; + break; + case ALL_MODULE_PATH: + addAllApplicationModules = true; + break; + default : + roots.add(mod); } } // --limit-modules - propValue = getAndRemoveProperty("jdk.module.limitmods"); + String propValue = getAndRemoveProperty("jdk.module.limitmods"); if (propValue != null) { Set
mods = new HashSet<>(); for (String mod: propValue.split(",")) { @@ -392,6 +389,32 @@ } } + /** + * Returns the set of module names specified via --add-modules options + * on the command line + */ + private static Set getExtraAddModules() { + String prefix = "jdk.module.addmods."; + int index = 0; + + // the system property is removed after decoding + String value = getAndRemoveProperty(prefix + index); + if (value == null) { + return Collections.emptySet(); + } + + Set modules = new HashSet<>(); + while (value != null) { + for (String s : value.split(",")) { + if (s.length() > 0) modules.add(s); + } + + index++; + value = getAndRemoveProperty(prefix + index); + } + + return modules; + } /** * Process the --add-reads options to add any additional read edges that @@ -514,7 +537,7 @@ // value is (, )* if (map.containsKey(key)) - fail(key + " specified more than once"); + fail(key + " specified more than once"); Set values = new HashSet<>(); map.put(key, values); diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/module-info.java --- a/jdk/src/java.base/share/classes/module-info.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/module-info.java Wed Jul 05 22:16:00 2017 +0200 @@ -166,6 +166,7 @@ jdk.charsets, jdk.compiler, jdk.jartool, + jdk.jdeps, jdk.jlink, jdk.net, jdk.scripting.nashorn, @@ -189,7 +190,8 @@ jdk.unsupported, jdk.vm.ci; exports jdk.internal.util.jar to - jdk.jartool; + jdk.jartool, + jdk.jdeps; exports jdk.internal.vm to java.management, jdk.jvmstat; diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java --- a/jdk/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java Wed Jul 05 22:16:00 2017 +0200 @@ -328,8 +328,6 @@ public SocketAddress receive(ByteBuffer dst) throws IOException { if (dst.isReadOnly()) throw new IllegalArgumentException("Read-only buffer"); - if (dst == null) - throw new NullPointerException(); synchronized (readLock) { ensureOpen(); // Socket was not bound before attempting receive @@ -716,8 +714,6 @@ @Override public DatagramChannel connect(SocketAddress sa) throws IOException { - int localPort = 0; - synchronized(readLock) { synchronized(writeLock) { synchronized (stateLock) { diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java --- a/jdk/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java Wed Jul 05 22:16:00 2017 +0200 @@ -616,8 +616,6 @@ } public boolean connect(SocketAddress sa) throws IOException { - int localPort = 0; - synchronized (readLock) { synchronized (writeLock) { ensureOpenAndUnconnected(); diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/sun/security/provider/SeedGenerator.java --- a/jdk/src/java.base/share/classes/sun/security/provider/SeedGenerator.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/security/provider/SeedGenerator.java Wed Jul 05 22:16:00 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -344,7 +344,8 @@ try { BogusThread bt = new BogusThread(); Thread t = new Thread - (seedGroup, bt, "SeedGenerator Thread", 0, false); + (seedGroup, bt, "SeedGenerator Thread", 0, + false); t.start(); } catch (Exception e) { throw new InternalError("internal error: " + @@ -357,7 +358,8 @@ long startTime = System.nanoTime(); while (System.nanoTime() - startTime < 250000000) { synchronized(this){}; - latch++; + // Mask the sign bit and keep latch non-negative + latch = (latch + 1) & 0x1FFFFFFF; } // Translate the value using the permutation, and xor @@ -431,7 +433,7 @@ // data and using it to mix the trivial permutation. // It should be evenly distributed. The specific values // are not crucial to the security of this class. - private static byte[] rndTab = { + private static final byte[] rndTab = { 56, 30, -107, -6, -86, 25, -83, 75, -12, -64, 5, -128, 78, 21, 16, 32, 70, -81, 37, -51, -43, -46, -108, 87, 29, 17, -55, 22, -11, -111, diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/native/include/jvm.h --- a/jdk/src/java.base/share/native/include/jvm.h Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/native/include/jvm.h Wed Jul 05 22:16:00 2017 +0200 @@ -179,6 +179,7 @@ */ enum { JVM_STACKWALK_FILL_CLASS_REFS_ONLY = 0x2, + JVM_STACKWALK_GET_CALLER_CLASS = 0x04, JVM_STACKWALK_SHOW_HIDDEN_FRAMES = 0x20, JVM_STACKWALK_FILL_LIVE_STACK_FRAMES = 0x100 }; diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/unix/native/libjava/ProcessImpl_md.c --- a/jdk/src/java.base/unix/native/libjava/ProcessImpl_md.c Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/unix/native/libjava/ProcessImpl_md.c Wed Jul 05 22:16:00 2017 +0200 @@ -152,8 +152,8 @@ #ifdef __solaris__ /* These really are the Solaris defaults! */ return (geteuid() == 0 || getuid() == 0) ? - "/usr/xpg4/bin:/usr/ccs/bin:/usr/bin:/opt/SUNWspro/bin:/usr/sbin" : - "/usr/xpg4/bin:/usr/ccs/bin:/usr/bin:/opt/SUNWspro/bin:"; + "/usr/xpg4/bin:/usr/bin:/opt/SUNWspro/bin:/usr/sbin" : + "/usr/xpg4/bin:/usr/bin:/opt/SUNWspro/bin:"; #else return ":/bin:/usr/bin"; /* glibc */ #endif diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/unix/native/libjli/java_md.h --- a/jdk/src/java.base/unix/native/libjli/java_md.h Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/unix/native/libjli/java_md.h Wed Jul 05 22:16:00 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,12 +35,12 @@ #include "manifest_info.h" #include "jli_util.h" -#define PATH_SEPARATOR ':' -#define FILESEP "/" -#define FILE_SEPARATOR '/' +#define PATH_SEPARATOR ':' +#define FILESEP "/" +#define FILE_SEPARATOR '/' #define IS_FILE_SEPARATOR(c) ((c) == '/') #ifndef MAXNAMELEN -#define MAXNAMELEN PATH_MAX +#define MAXNAMELEN PATH_MAX #endif #ifdef _LP64 @@ -59,10 +59,13 @@ static jboolean GetJREPath(char *path, jint pathsize, const char * arch, jboolean speculative); +#if defined(_AIX) +#include "java_md_aix.h" +#endif + #ifdef MACOSX #include "java_md_macosx.h" #else /* !MACOSX */ #include "java_md_solinux.h" #endif /* MACOSX */ - #endif /* JAVA_MD_H */ diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/windows/native/libnet/Inet4AddressImpl.c --- a/jdk/src/java.base/windows/native/libnet/Inet4AddressImpl.c Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/windows/native/libnet/Inet4AddressImpl.c Wed Jul 05 22:16:00 2017 +0200 @@ -33,6 +33,7 @@ #include #include #include +#include #include "java_net_InetAddress.h" #include "java_net_Inet4AddressImpl.h" @@ -442,7 +443,15 @@ DWORD ReplySize = 0; jboolean ret = JNI_FALSE; - ReplySize = sizeof(ICMP_ECHO_REPLY) + sizeof(SendData); + // https://msdn.microsoft.com/en-us/library/windows/desktop/aa366051%28v=vs.85%29.aspx + ReplySize = sizeof(ICMP_ECHO_REPLY) // The buffer should be large enough + // to hold at least one ICMP_ECHO_REPLY + // structure + + sizeof(SendData) // plus RequestSize bytes of data. + + 8; // This buffer should also be large enough + // to also hold 8 more bytes of data + // (the size of an ICMP error message) + ReplyBuffer = (VOID*) malloc(ReplySize); if (ReplyBuffer == NULL) { IcmpCloseHandle(hIcmpFile); @@ -478,10 +487,47 @@ (timeout < 1000) ? 1000 : timeout); // DWORD Timeout } - if (dwRetVal != 0) { + if (dwRetVal == 0) { // if the call failed + TCHAR *buf; + DWORD err = WSAGetLastError(); + switch (err) { + case ERROR_NO_NETWORK: + case ERROR_NETWORK_UNREACHABLE: + case ERROR_HOST_UNREACHABLE: + case ERROR_PROTOCOL_UNREACHABLE: + case ERROR_PORT_UNREACHABLE: + case ERROR_REQUEST_ABORTED: + case ERROR_INCORRECT_ADDRESS: + case ERROR_HOST_DOWN: + case ERROR_INVALID_COMPUTERNAME: + case ERROR_INVALID_NETNAME: + case WSAEHOSTUNREACH: /* Host Unreachable */ + case WSAENETUNREACH: /* Network Unreachable */ + case WSAENETDOWN: /* Network is down */ + case WSAEPFNOSUPPORT: /* Protocol Family unsupported */ + case IP_REQ_TIMED_OUT: + break; + default: + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR)&buf, 0, NULL); + NET_ThrowNew(env, err, buf); + LocalFree(buf); + break; + } + } else { PICMP_ECHO_REPLY pEchoReply = (PICMP_ECHO_REPLY)ReplyBuffer; - if ((int)pEchoReply->RoundTripTime <= timeout) + + // This is to take into account the undocumented minimum + // timeout mentioned in the IcmpSendEcho call above. + // We perform an extra check to make sure that our + // roundtrip time was less than our desired timeout + // for cases where that timeout is < 1000ms. + if (pEchoReply->Status == IP_SUCCESS + && (int)pEchoReply->RoundTripTime <= timeout) + { ret = JNI_TRUE; + } } free(ReplyBuffer); diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.desktop/share/classes/com/sun/beans/finder/ConstructorFinder.java --- a/jdk/src/java.desktop/share/classes/com/sun/beans/finder/ConstructorFinder.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.desktop/share/classes/com/sun/beans/finder/ConstructorFinder.java Wed Jul 05 22:16:00 2017 +0200 @@ -67,19 +67,22 @@ */ public static Constructor> findConstructor(Class> type, Class>...args) throws NoSuchMethodException { if (type.isPrimitive()) { - throw new NoSuchMethodException("Primitive wrapper does not contain constructors"); + throw new NoSuchMethodException("Primitive wrapper does not contain constructors: " + + type.getName()); } if (type.isInterface()) { - throw new NoSuchMethodException("Interface does not contain constructors"); + throw new NoSuchMethodException("Interface does not contain constructors: " + + type.getName()); } if (!FinderUtils.isExported(type)) { - throw new NoSuchMethodException("Class is not accessible"); + throw new NoSuchMethodException("Class is not accessible: " + type.getName()); } if (Modifier.isAbstract(type.getModifiers())) { - throw new NoSuchMethodException("Abstract class cannot be instantiated"); + throw new NoSuchMethodException("Abstract class cannot be instantiated: " + + type.getName()); } if (!Modifier.isPublic(type.getModifiers()) || !isPackageAccessible(type)) { - throw new NoSuchMethodException("Class is not accessible"); + throw new NoSuchMethodException("Class is not accessible: " + type.getName()); } PrimitiveWrapperMap.replacePrimitivesWithWrappers(args); Signature signature = new Signature(type, args); diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.desktop/share/classes/javax/imageio/ImageReader.java --- a/jdk/src/java.desktop/share/classes/javax/imageio/ImageReader.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.desktop/share/classes/javax/imageio/ImageReader.java Wed Jul 05 22:16:00 2017 +0200 @@ -2461,16 +2461,16 @@ try { bundle = ResourceBundle.getBundle(baseName, locale, this.getClass().getModule()); } catch (MissingResourceException mre) { - throw new IllegalArgumentException("Bundle not found!"); + throw new IllegalArgumentException("Bundle not found!", mre); } String warning = null; try { warning = bundle.getString(keyword); } catch (ClassCastException cce) { - throw new IllegalArgumentException("Resource is not a String!"); + throw new IllegalArgumentException("Resource is not a String!", cce); } catch (MissingResourceException mre) { - throw new IllegalArgumentException("Resource is missing!"); + throw new IllegalArgumentException("Resource is missing!", mre); } listener.warningOccurred(this, warning); diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.desktop/share/classes/javax/imageio/ImageWriter.java --- a/jdk/src/java.desktop/share/classes/javax/imageio/ImageWriter.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.desktop/share/classes/javax/imageio/ImageWriter.java Wed Jul 05 22:16:00 2017 +0200 @@ -1963,16 +1963,16 @@ try { bundle = ResourceBundle.getBundle(baseName, locale, this.getClass().getModule()); } catch (MissingResourceException mre) { - throw new IllegalArgumentException("Bundle not found!"); + throw new IllegalArgumentException("Bundle not found!", mre); } String warning = null; try { warning = bundle.getString(keyword); } catch (ClassCastException cce) { - throw new IllegalArgumentException("Resource is not a String!"); + throw new IllegalArgumentException("Resource is not a String!", cce); } catch (MissingResourceException mre) { - throw new IllegalArgumentException("Resource is missing!"); + throw new IllegalArgumentException("Resource is missing!", mre); } listener.warningOccurred(this, imageIndex, warning); diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c --- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c Wed Jul 05 22:16:00 2017 +0200 @@ -442,7 +442,7 @@ #ifndef __linux__ /* SOLARIS */ if (xrenderLibHandle == NULL) { - xrenderLibHandle = dlopen("/usr/sfw/lib/libXrender.so.1", + xrenderLibHandle = dlopen("/usr/lib/libXrender.so.1", RTLD_LAZY | RTLD_GLOBAL); } #endif diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.desktop/unix/native/libjawt/jawt.c --- a/jdk/src/java.desktop/unix/native/libjawt/jawt.c Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.desktop/unix/native/libjawt/jawt.c Wed Jul 05 22:16:00 2017 +0200 @@ -39,6 +39,10 @@ */ JNIEXPORT jboolean JNICALL JAWT_GetAWT(JNIEnv* env, JAWT* awt) { +#if defined(HEADLESS) + /* there are no AWT libs available at all */ + return JNI_FALSE; +#else if (awt == NULL) { return JNI_FALSE; } @@ -64,4 +68,5 @@ } return JNI_TRUE; +#endif } diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11TlsKeyMaterialGenerator.java --- a/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11TlsKeyMaterialGenerator.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11TlsKeyMaterialGenerator.java Wed Jul 05 22:16:00 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -68,8 +68,8 @@ // master secret as a P11Key private P11Key p11Key; - // version, e.g. 0x0301 - private int version; + // whether SSLv3 is supported + private final boolean supportSSLv3; P11TlsKeyMaterialGenerator(Token token, String algorithm, long mechanism) throws PKCS11Exception { @@ -77,6 +77,11 @@ this.token = token; this.algorithm = algorithm; this.mechanism = mechanism; + + // Given the current lookup order specified in SunPKCS11.java, + // if CKM_SSL3_KEY_AND_MAC_DERIVE is not used to construct this object, + // it means that this mech is disabled or unsupported. + this.supportSSLv3 = (mechanism == CKM_SSL3_KEY_AND_MAC_DERIVE); } protected void engineInit(SecureRandom random) { @@ -89,20 +94,26 @@ if (params instanceof TlsKeyMaterialParameterSpec == false) { throw new InvalidAlgorithmParameterException(MSG); } - this.spec = (TlsKeyMaterialParameterSpec)params; + + TlsKeyMaterialParameterSpec spec = (TlsKeyMaterialParameterSpec)params; + int version = (spec.getMajorVersion() << 8) | spec.getMinorVersion(); + + if ((version == 0x0300 && !supportSSLv3) || (version < 0x0300) || + (version > 0x0302)) { + throw new InvalidAlgorithmParameterException + ("Only" + (supportSSLv3? " SSL 3.0,": "") + + " TLS 1.0, and TLS 1.1 are supported (0x" + + Integer.toHexString(version) + ")"); + } try { p11Key = P11SecretKeyFactory.convertKey (token, spec.getMasterSecret(), "TlsMasterSecret"); } catch (InvalidKeyException e) { throw new InvalidAlgorithmParameterException("init() failed", e); } - version = (spec.getMajorVersion() << 8) | spec.getMinorVersion(); - if ((version < 0x0300) && (version > 0x0302)) { - throw new InvalidAlgorithmParameterException - ("Only SSL 3.0, TLS 1.0, and TLS 1.1 are supported"); - } - // we assume the token supports both the CKM_SSL3_* and the CKM_TLS_* - // mechanisms + this.spec = spec; + this.mechanism = (version == 0x0300)? + CKM_SSL3_KEY_AND_MAC_DERIVE : CKM_TLS_KEY_AND_MAC_DERIVE; } protected void engineInit(int keysize, SecureRandom random) { @@ -115,8 +126,6 @@ throw new IllegalStateException ("TlsKeyMaterialGenerator must be initialized"); } - mechanism = (version == 0x0300) ? CKM_SSL3_KEY_AND_MAC_DERIVE - : CKM_TLS_KEY_AND_MAC_DERIVE; int macBits = spec.getMacKeyLength() << 3; int ivBits = spec.getIvLength() << 3; diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11TlsMasterSecretGenerator.java --- a/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11TlsMasterSecretGenerator.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11TlsMasterSecretGenerator.java Wed Jul 05 22:16:00 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -61,7 +61,10 @@ private TlsMasterSecretParameterSpec spec; private P11Key p11Key; - int version; + CK_VERSION ckVersion; + + // whether SSLv3 is supported + private final boolean supportSSLv3; P11TlsMasterSecretGenerator(Token token, String algorithm, long mechanism) throws PKCS11Exception { @@ -69,6 +72,11 @@ this.token = token; this.algorithm = algorithm; this.mechanism = mechanism; + + // Given the current lookup order specified in SunPKCS11.java, if + // CKM_SSL3_MASTER_KEY_DERIVE is not used to construct this object, + // it means that this mech is disabled or unsupported. + supportSSLv3 = (mechanism == CKM_SSL3_MASTER_KEY_DERIVE); } protected void engineInit(SecureRandom random) { @@ -81,7 +89,17 @@ if (params instanceof TlsMasterSecretParameterSpec == false) { throw new InvalidAlgorithmParameterException(MSG); } - this.spec = (TlsMasterSecretParameterSpec)params; + + TlsMasterSecretParameterSpec spec = (TlsMasterSecretParameterSpec)params; + int version = (spec.getMajorVersion() << 8) | spec.getMinorVersion(); + if ((version == 0x0300 && !supportSSLv3) || (version < 0x0300) || + (version > 0x0302)) { + throw new InvalidAlgorithmParameterException + ("Only" + (supportSSLv3? " SSL 3.0,": "") + + " TLS 1.0, and TLS 1.1 are supported (0x" + + Integer.toHexString(version) + ")"); + } + SecretKey key = spec.getPremasterSecret(); // algorithm should be either TlsRsaPremasterSecret or TlsPremasterSecret, // but we omit the check @@ -90,25 +108,7 @@ } catch (InvalidKeyException e) { throw new InvalidAlgorithmParameterException("init() failed", e); } - version = (spec.getMajorVersion() << 8) | spec.getMinorVersion(); - if ((version < 0x0300) || (version > 0x0302)) { - throw new InvalidAlgorithmParameterException - ("Only SSL 3.0, TLS 1.0, and TLS 1.1 supported"); - } - // We assume the token supports the required mechanism. If it does not, - // generateKey() will fail and the failover should take care of us. - } - - protected void engineInit(int keysize, SecureRandom random) { - throw new InvalidParameterException(MSG); - } - - protected SecretKey engineGenerateKey() { - if (spec == null) { - throw new IllegalStateException - ("TlsMasterSecretGenerator must be initialized"); - } - CK_VERSION ckVersion; + this.spec = spec; if (p11Key.getAlgorithm().equals("TlsRsaPremasterSecret")) { mechanism = (version == 0x0300) ? CKM_SSL3_MASTER_KEY_DERIVE : CKM_TLS_MASTER_KEY_DERIVE; @@ -124,6 +124,17 @@ : CKM_TLS_MASTER_KEY_DERIVE_DH; ckVersion = null; } + } + + protected void engineInit(int keysize, SecureRandom random) { + throw new InvalidParameterException(MSG); + } + + protected SecretKey engineGenerateKey() { + if (spec == null) { + throw new IllegalStateException + ("TlsMasterSecretGenerator must be initialized"); + } byte[] clientRandom = spec.getClientRandom(); byte[] serverRandom = spec.getServerRandom(); CK_SSL3_RANDOM_DATA random = @@ -139,13 +150,12 @@ long keyID = token.p11.C_DeriveKey(session.id(), new CK_MECHANISM(mechanism, params), p11Key.keyID, attributes); int major, minor; - ckVersion = params.pVersion; - if (ckVersion == null) { + if (params.pVersion == null) { major = -1; minor = -1; } else { - major = ckVersion.major; - minor = ckVersion.minor; + major = params.pVersion.major; + minor = params.pVersion.minor; } SecretKey key = P11Key.masterSecretKey(session, keyID, "TlsMasterSecret", 48 << 3, attributes, major, minor); @@ -156,5 +166,4 @@ token.releaseSession(session); } } - } diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11TlsRsaPremasterSecretGenerator.java --- a/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11TlsRsaPremasterSecretGenerator.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11TlsRsaPremasterSecretGenerator.java Wed Jul 05 22:16:00 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -60,12 +60,20 @@ @SuppressWarnings("deprecation") private TlsRsaPremasterSecretParameterSpec spec; + // whether SSLv3 is supported + private final boolean supportSSLv3; + P11TlsRsaPremasterSecretGenerator(Token token, String algorithm, long mechanism) throws PKCS11Exception { super(); this.token = token; this.algorithm = algorithm; this.mechanism = mechanism; + + // Given the current lookup order specified in SunPKCS11.java, + // if CKM_SSL3_PRE_MASTER_KEY_GEN is not used to construct this object, + // it means that this mech is disabled or unsupported. + this.supportSSLv3 = (mechanism == CKM_SSL3_PRE_MASTER_KEY_GEN); } protected void engineInit(SecureRandom random) { @@ -78,7 +86,20 @@ if (!(params instanceof TlsRsaPremasterSecretParameterSpec)) { throw new InvalidAlgorithmParameterException(MSG); } - this.spec = (TlsRsaPremasterSecretParameterSpec)params; + + TlsRsaPremasterSecretParameterSpec spec = + (TlsRsaPremasterSecretParameterSpec) params; + + int version = (spec.getMajorVersion() << 8) | spec.getMinorVersion(); + + if ((version == 0x0300 && !supportSSLv3) || (version < 0x0300) || + (version > 0x0302)) { + throw new InvalidAlgorithmParameterException + ("Only" + (supportSSLv3? " SSL 3.0,": "") + + " TLS 1.0, and TLS 1.1 are supported (0x" + + Integer.toHexString(version) + ")"); + } + this.spec = spec; } protected void engineInit(int keysize, SecureRandom random) { diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/Secmod.java --- a/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/Secmod.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/Secmod.java Wed Jul 05 22:16:00 2017 +0200 @@ -45,7 +45,7 @@ * * Secmod secmod = Secmod.getInstance(); * if (secmod.isInitialized() == false) { - * secmod.initialize("/home/myself/.mozilla", "/usr/sfw/lib/mozilla"); + * secmod.initialize("/home/myself/.mozilla"); * } * * Provider p = secmod.getModule(ModuleType.KEYSTORE).getProvider(); diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/com/sun/net/httpserver/Test5.java --- a/jdk/test/com/sun/net/httpserver/Test5.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/com/sun/net/httpserver/Test5.java Wed Jul 05 22:16:00 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -145,6 +145,7 @@ socket.close(); s = new String (b,0,count, "ISO8859_1"); if (!compare (s, result)) { + System.err.println(" Expected [" + result + "]\n actual [" + s + "]"); throw new RuntimeException ("wrong string result"); } } diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/io/PrintStream/FormatLocale.java --- a/jdk/test/java/io/PrintStream/FormatLocale.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/java/io/PrintStream/FormatLocale.java Wed Jul 05 22:16:00 2017 +0200 @@ -21,10 +21,11 @@ * questions. */ -/** +/* * @test * @bug 8146156 * @summary test whether conversion follows Locale.Category.FORMAT locale. + * @modules jdk.localedata * @run main/othervm FormatLocale */ diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/lang/StackWalker/CallerSensitiveMethod/Main.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/lang/StackWalker/CallerSensitiveMethod/Main.java Wed Jul 05 22:16:00 2017 +0200 @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8157464 + * @summary Basic test for StackWalker.getCallerClass() + * @library src + * @build java.base/java.util.CSM csm/* + * @run main/othervm csm/jdk.test.CallerSensitiveTest + * @run main/othervm csm/jdk.test.CallerSensitiveTest sm + */ +public class Main { +} + diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/lang/StackWalker/CallerSensitiveMethod/csm/jdk/test/CallerSensitiveTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/lang/StackWalker/CallerSensitiveMethod/csm/jdk/test/CallerSensitiveTest.java Wed Jul 05 22:16:00 2017 +0200 @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.test; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodHandles.Lookup; +import java.lang.invoke.MethodType; +import java.lang.reflect.Method; +import java.security.Permission; +import java.security.PermissionCollection; +import java.security.Permissions; +import java.security.Policy; +import java.security.ProtectionDomain; +import java.util.CSM.Result; +import java.util.function.Supplier; + +/** + * This test invokes StackWalker::getCallerClass via static reference, + * reflection, MethodHandle, lambda. Also verify that + * StackWalker::getCallerClass can't be called from @CallerSensitive method. + */ +public class CallerSensitiveTest { + private static final String NON_CSM_CALLER_METHOD = "getCallerClass"; + private static final String CSM_CALLER_METHOD = "caller"; + + public static void main(String... args) throws Throwable { + boolean sm = false; + if (args.length > 0 && args[0].equals("sm")) { + sm = true; + PermissionCollection perms = new Permissions(); + perms.add(new StackFramePermission("retainClassReference")); + Policy.setPolicy(new Policy() { + @Override + public boolean implies(ProtectionDomain domain, Permission p) { + return perms.implies(p); + } + }); + System.setSecurityManager(new SecurityManager()); + } + + System.err.format("Test %s security manager.%n", + sm ? "with" : "without"); + + CallerSensitiveTest cstest = new CallerSensitiveTest(); + // test static call to java.util.CSM::caller and CSM::getCallerClass + cstest.staticMethodCall(); + // test java.lang.reflect.Method call + cstest.reflectMethodCall(); + // test java.lang.invoke.MethodHandle + cstest.invokeMethodHandle(Lookup1.lookup); + cstest.invokeMethodHandle(Lookup2.lookup); + // test method ref + cstest.lambda(); + + LambdaTest.lambda(); + + if (failed > 0) { + throw new RuntimeException(failed + " test cases failed."); + } + } + + void staticMethodCall() { + java.util.CSM.caller(); + + Result result = java.util.CSM.getCallerClass(); + checkNonCSMCaller(CallerSensitiveTest.class, result); + } + + void reflectMethodCall() throws Throwable { + Method method1 = java.util.CSM.class.getMethod(CSM_CALLER_METHOD); + method1.invoke(null); + + Method method2 = java.util.CSM.class.getMethod(NON_CSM_CALLER_METHOD); + Result result = (Result) method2.invoke(null); + checkNonCSMCaller(CallerSensitiveTest.class, result); + } + + void invokeMethodHandle(Lookup lookup) throws Throwable { + MethodHandle mh1 = lookup.findStatic(java.util.CSM.class, CSM_CALLER_METHOD, + MethodType.methodType(Class.class)); + Class> c = (Class>)mh1.invokeExact(); + + MethodHandle mh2 = lookup.findStatic(java.util.CSM.class, NON_CSM_CALLER_METHOD, + MethodType.methodType(Result.class)); + Result result = (Result)mh2.invokeExact(); + checkNonCSMCaller(CallerSensitiveTest.class, result); + } + + void lambda() { + Result result = LambdaTest.getCallerClass.get(); + checkNonCSMCaller(CallerSensitiveTest.class, result); + + LambdaTest.caller.get(); + } + + static int failed = 0; + + static void checkNonCSMCaller(Class> expected, Result result) { + if (result.callers.size() != 1) { + throw new RuntimeException("Expected result.callers contain one element"); + } + if (expected != result.callers.get(0)) { + System.err.format("ERROR: Expected %s but got %s%n", expected, + result.callers); + result.frames.stream() + .forEach(f -> System.err.println(" " + f)); + failed++; + } + } + + static class Lookup1 { + static Lookup lookup = MethodHandles.lookup(); + } + + static class Lookup2 { + static Lookup lookup = MethodHandles.lookup(); + } + + static class LambdaTest { + static Supplier> caller = java.util.CSM::caller; + static Supplier getCallerClass = java.util.CSM::getCallerClass; + + static void caller() { + caller.get(); + } + static Result getCallerClass() { + return getCallerClass.get(); + } + + static void lambda() { + Result result = LambdaTest.getCallerClass(); + checkNonCSMCaller(LambdaTest.class, result); + + LambdaTest.caller(); + } + } +} diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/lang/StackWalker/CallerSensitiveMethod/csm/module-info.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/lang/StackWalker/CallerSensitiveMethod/csm/module-info.java Wed Jul 05 22:16:00 2017 +0200 @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +module csm { + exports jdk.test; +} diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/lang/StackWalker/CallerSensitiveMethod/src/java.base/java/util/CSM.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/lang/StackWalker/CallerSensitiveMethod/src/java.base/java/util/CSM.java Wed Jul 05 22:16:00 2017 +0200 @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.util; + +import static java.lang.StackWalker.Option.*; +import java.lang.StackWalker.StackFrame; +import java.util.stream.Collectors; + +import jdk.internal.reflect.CallerSensitive; +import jdk.internal.reflect.Reflection; + +public class CSM { + private static StackWalker walker = + StackWalker.getInstance(EnumSet.of(RETAIN_CLASS_REFERENCE, + SHOW_HIDDEN_FRAMES, + SHOW_REFLECT_FRAMES)); + + public static class Result { + public final List > callers; + public final List frames; + Result(List > callers, + List frames) { + this.callers = callers; + this.frames = frames; + } + } + + /** + * Returns the caller of this caller-sensitive method returned by + * by Reflection::getCallerClass. + * + * StackWalker::getCallerClass is expected to throw UOE + */ + @CallerSensitive + public static Class> caller() { + Class> c1 = Reflection.getCallerClass(); + + try { + Class> c2 = walker.getCallerClass(); + throw new RuntimeException("Exception not thrown by StackWalker::getCallerClass"); + } catch (UnsupportedOperationException e) {} + return c1; + } + + /** + * Returns the caller of this non-caller-sensitive method. + */ + public static Result getCallerClass() { + Class> caller = walker.getCallerClass(); + return new Result(List.of(caller), dump()); + } + + static List dump() { + return walker.walk(s -> s.collect(Collectors.toList())); + } +} diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/lang/instrument/SimpleAgent.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/lang/instrument/SimpleAgent.java Wed Jul 05 22:16:00 2017 +0200 @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.lang.instrument.Instrumentation; + +class SimpleAgent { + + public static void premain(String args, Instrumentation inst) { + System.out.println("in premain"); + } + +} diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/lang/instrument/TestAgentWithLimitMods.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/lang/instrument/TestAgentWithLimitMods.java Wed Jul 05 22:16:00 2017 +0200 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * + * @test + * @summary Tests that the -javaagent option adds the java.instrument into + * the module graph + * @modules java.instrument + * @run shell MakeJAR3.sh SimpleAgent + * @run main/othervm -javaagent:SimpleAgent.jar -limitmods java.base TestAgentWithLimitMods + * + */ +public class TestAgentWithLimitMods { + + public static void main(String[] args) { + System.out.println("Test passed"); + } + +} diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/lang/invoke/MethodHandlesTest.java --- a/jdk/test/java/lang/invoke/MethodHandlesTest.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/java/lang/invoke/MethodHandlesTest.java Wed Jul 05 22:16:00 2017 +0200 @@ -632,6 +632,7 @@ } public void testFindVirtualClone0() throws Throwable { + if (CAN_SKIP_WORKING) return; // test some ad hoc system methods testFindVirtual(false, PUBLIC, Object.class, Object.class, "clone"); @@ -2798,11 +2799,17 @@ toClauseMajor(postClauses, inits, steps, usePreds, finis); MethodHandle pre = MethodHandles.loop(preClauses); MethodHandle post = MethodHandles.loop(postClauses); + if (verbosity >= 6) { + System.out.println("pre-handle: " + pre); + } Object[] preResults = (Object[]) pre.invokeWithArguments(args); if (verbosity >= 4) { System.out.println("pre-checked: expected " + Arrays.asList(preCheckedResults[i]) + ", actual " + Arrays.asList(preResults)); } + if (verbosity >= 6) { + System.out.println("post-handle: " + post); + } Object[] postResults = (Object[]) post.invokeWithArguments(args); if (verbosity >= 4) { System.out.println("post-checked: expected " + Arrays.asList(postCheckedResults[i]) + ", actual " + diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/net/MulticastSocket/TimeToLive.java --- a/jdk/test/java/net/MulticastSocket/TimeToLive.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/java/net/MulticastSocket/TimeToLive.java Wed Jul 05 22:16:00 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 1999, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,26 +37,27 @@ static int[] bad_ttls = { -1, 256 }; public static void main(String[] args) throws Exception { - MulticastSocket socket = new MulticastSocket(6789); - int ttl = socket.getTimeToLive(); - System.out.println("default ttl: " + ttl); - for (int i = 0; i < new_ttls.length; i++) { - socket.setTimeToLive(new_ttls[i]); - if (!(new_ttls[i] == socket.getTimeToLive())) { - throw new RuntimeException("test failure, set/get differ: " + - new_ttls[i] + " / " + - socket.getTimeToLive()); + try (MulticastSocket socket = new MulticastSocket()) { + int ttl = socket.getTimeToLive(); + System.out.println("default ttl: " + ttl); + for (int i = 0; i < new_ttls.length; i++) { + socket.setTimeToLive(new_ttls[i]); + if (!(new_ttls[i] == socket.getTimeToLive())) { + throw new RuntimeException("test failure, set/get differ: " + + new_ttls[i] + " / " + + socket.getTimeToLive()); + } } - } - for (int j = 0; j < bad_ttls.length; j++) { - boolean exception = false; - try { - socket.setTimeToLive(bad_ttls[j]); - } catch (IllegalArgumentException e) { - exception = true; - } - if (!exception) { - throw new RuntimeException("bad argument accepted: " + bad_ttls[j]); + for (int j = 0; j < bad_ttls.length; j++) { + boolean exception = false; + try { + socket.setTimeToLive(bad_ttls[j]); + } catch (IllegalArgumentException e) { + exception = true; + } + if (!exception) { + throw new RuntimeException("bad argument accepted: " + bad_ttls[j]); + } } } } diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/net/ServerSocket/ThreadStop.java --- a/jdk/test/java/net/ServerSocket/ThreadStop.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/java/net/ServerSocket/ThreadStop.java Wed Jul 05 22:16:00 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -68,23 +68,23 @@ thr.start(); // give server time to block in ServerSocket.accept() - Thread.currentThread().sleep(2000); + Thread.sleep(2000); // "stop" the thread thr.stop(); // give thread time to stop - Thread.currentThread().sleep(2000); + Thread.sleep(2000); // it's platform specific if Thread.stop interrupts the // thread - on Linux/Windows most likely that thread is // still in accept() so we connect to server which causes // it to unblock and do JNI-stuff with a pending exception - try { - Socket s = new Socket("localhost", svr.localPort()); - } catch (IOException ioe) { } - + try (Socket s = new Socket("localhost", svr.localPort())) { + } catch (IOException ioe) { + } + thr.join(); } } diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/net/Socket/InheritHandle.java --- a/jdk/test/java/net/Socket/InheritHandle.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/java/net/Socket/InheritHandle.java Wed Jul 05 22:16:00 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,7 @@ @author Chris Hegarty */ +import java.net.BindException; import java.net.ServerSocket; import java.io.File; import java.io.IOException; @@ -74,6 +75,11 @@ } catch (IOException ioe) { System.out.println("Cannot create process"); ioe.printStackTrace(); + try { + ss.close(); + } catch (IOException e) { + e.printStackTrace(); + } return; } @@ -85,9 +91,18 @@ System.out.println("Now close the socket and try to create another" + " one listening on the same port"); ss.close(); - ss = new ServerSocket(port); - System.out.println("Second ServerSocket created successfully"); - ss.close(); + int retries = 0; + while (retries < 5) { + try (ServerSocket s = new ServerSocket(port);) { + System.out.println("Second ServerSocket created successfully"); + break; + } catch (BindException e) { + System.out.println("BindException \"" + e.getMessage() + "\", retrying..."); + Thread.sleep(100L); + retries ++; + continue; + } + } } catch (InterruptedException ie) { } catch (IOException ioe) { diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/net/URLClassLoader/definePackage/SplitPackage.java --- a/jdk/test/java/net/URLClassLoader/definePackage/SplitPackage.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/java/net/URLClassLoader/definePackage/SplitPackage.java Wed Jul 05 22:16:00 2017 +0200 @@ -27,6 +27,7 @@ * @summary Test two URLClassLoader define Package object of the same name * @library /lib/testlibrary * @build CompilerUtils + * @modules jdk.compiler * @run testng SplitPackage */ diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/net/URLPermission/nstest/LookupTest.java --- a/jdk/test/java/net/URLPermission/nstest/LookupTest.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/java/net/URLPermission/nstest/LookupTest.java Wed Jul 05 22:16:00 2017 +0200 @@ -37,6 +37,7 @@ String url, boolean throwsSecException, boolean throwsIOException) { try { + ProxySelector.setDefault(null); URL u = new URL(url); System.err.println ("Connecting to " + u); URLConnection urlc = u.openConnection(); @@ -71,7 +72,7 @@ System.out.print(port); } else if (cmd.equals("-runtest")) { port = Integer.parseInt(args[1]); - String hostsFileName = System.getProperty("test.src", ".") + "/LookupTestHosts"; + String hostsFileName = System.getProperty("user.dir", ".") + "/LookupTestHosts"; System.setProperty("jdk.net.hosts.file", hostsFileName); addMappingToHostsFile("allowedAndFound.com", "127.0.0.1", hostsFileName, false); addMappingToHostsFile("notAllowedButFound.com", "99.99.99.99", hostsFileName, true); diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/net/URLPermission/nstest/LookupTestHosts --- a/jdk/test/java/net/URLPermission/nstest/LookupTestHosts Thu Sep 22 16:41:14 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ -127.0.0.1 allowedAndFound.com -99.99.99.99 notAllowedButFound.com diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/net/URLPermission/nstest/lookup.sh --- a/jdk/test/java/net/URLPermission/nstest/lookup.sh Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/java/net/URLPermission/nstest/lookup.sh Wed Jul 05 22:16:00 2017 +0200 @@ -48,6 +48,7 @@ grant { permission java.net.URLPermission "http://allowedAndFound.com:${port}/-", "*:*"; permission java.net.URLPermission "http://allowedButNotfound.com:${port}/-", "*:*"; + permission java.net.NetPermission "setProxySelector"; permission java.io.FilePermission "< >", "read,write,delete"; permission java.util.PropertyPermission "java.io.tmpdir", "read"; diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/net/httpclient/HeadersTest1.java --- a/jdk/test/java/net/httpclient/HeadersTest1.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/java/net/httpclient/HeadersTest1.java Wed Jul 05 22:16:00 2017 +0200 @@ -23,9 +23,11 @@ * questions. */ -/** +/* * @test * @bug 8153142 + * @modules java.httpclient + * jdk.httpserver * @run main/othervm HeadersTest1 * @summary HeadersTest1 */ @@ -39,9 +41,11 @@ import java.io.InputStream; import java.io.OutputStream; import java.net.InetSocketAddress; -import java.net.PasswordAuthentication; import java.net.URI; -import java.net.http.*; +import java.net.http.HttpClient; +import java.net.http.HttpHeaders; +import java.net.http.HttpResponse; +import java.net.http.HttpRequest; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.List; diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/net/httpclient/ProxyAuthTest.java --- a/jdk/test/java/net/httpclient/ProxyAuthTest.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/java/net/httpclient/ProxyAuthTest.java Wed Jul 05 22:16:00 2017 +0200 @@ -26,6 +26,7 @@ * @test * @bug 8163561 * @modules java.base/sun.net.www + * java.httpclient * @summary Verify that Proxy-Authenticate header is correctly handled * * @run main/othervm ProxyAuthTest diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/net/httpclient/whitebox/Driver.java --- a/jdk/test/java/net/httpclient/whitebox/Driver.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/java/net/httpclient/whitebox/Driver.java Wed Jul 05 22:16:00 2017 +0200 @@ -24,5 +24,6 @@ /* * @test * @bug 8151299 + * @modules java.httpclient * @run testng java.httpclient/java.net.http.SelectorTest */ diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/util/Collections/EmptyNavigableMap.java --- a/jdk/test/java/util/Collections/EmptyNavigableMap.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/java/util/Collections/EmptyNavigableMap.java Wed Jul 05 22:16:00 2017 +0200 @@ -33,7 +33,6 @@ import java.util.Collections; import java.util.Comparator; import java.util.Iterator; -import java.util.NoSuchElementException; import java.util.NavigableMap; import java.util.SortedMap; import java.util.TreeMap; @@ -41,10 +40,8 @@ import org.testng.annotations.DataProvider; import static org.testng.Assert.fail; -import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertSame; public class EmptyNavigableMap { diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/util/Collections/EmptyNavigableSet.java --- a/jdk/test/java/util/Collections/EmptyNavigableSet.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/java/util/Collections/EmptyNavigableSet.java Wed Jul 05 22:16:00 2017 +0200 @@ -41,10 +41,9 @@ import org.testng.annotations.DataProvider; import static org.testng.Assert.fail; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertTrue; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertSame; +import static org.testng.Assert.assertTrue; public class EmptyNavigableSet { diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/util/Deque/ChorusLine.java --- a/jdk/test/java/util/Deque/ChorusLine.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/java/util/Deque/ChorusLine.java Wed Jul 05 22:16:00 2017 +0200 @@ -28,8 +28,14 @@ * @author Martin Buchholz */ -import java.util.*; -import java.util.concurrent.*; +import java.util.ArrayDeque; +import java.util.Collection; +import java.util.Deque; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.NoSuchElementException; +import java.util.concurrent.ConcurrentLinkedDeque; +import java.util.concurrent.LinkedBlockingDeque; public class ChorusLine { private interface Tweaker { diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/util/PriorityQueue/ForgetMeNot.java --- a/jdk/test/java/util/PriorityQueue/ForgetMeNot.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/java/util/PriorityQueue/ForgetMeNot.java Wed Jul 05 22:16:00 2017 +0200 @@ -28,7 +28,11 @@ * @author Martin Buchholz */ -import java.util.*; +import java.util.Arrays; +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.util.PriorityQueue; +import java.util.Queue; public class ForgetMeNot { private static void checkQ(PriorityQueue q, Integer...elts) { diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/util/PriorityQueue/PriorityQueueSort.java --- a/jdk/test/java/util/PriorityQueue/PriorityQueueSort.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/java/util/PriorityQueue/PriorityQueueSort.java Wed Jul 05 22:16:00 2017 +0200 @@ -37,7 +37,13 @@ * @summary Checks that a priority queue returns elements in sorted order across various operations */ -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; +import java.util.Queue; +import java.util.PriorityQueue; public class PriorityQueueSort { diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/util/PriorityQueue/RemoveContains.java --- a/jdk/test/java/util/PriorityQueue/RemoveContains.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/java/util/PriorityQueue/RemoveContains.java Wed Jul 05 22:16:00 2017 +0200 @@ -28,8 +28,17 @@ * @author Martin Buchholz */ -import java.util.*; -import java.util.concurrent.*; +import java.util.ArrayDeque; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; +import java.util.PriorityQueue; +import java.util.Queue; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.PriorityBlockingQueue; +import java.util.concurrent.LinkedTransferQueue; public class RemoveContains { static volatile int passed = 0, failed = 0; diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/util/concurrent/Executors/AutoShutdown.java --- a/jdk/test/java/util/concurrent/Executors/AutoShutdown.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/java/util/concurrent/Executors/AutoShutdown.java Wed Jul 05 22:16:00 2017 +0200 @@ -31,8 +31,6 @@ */ import static java.util.concurrent.Executors.defaultThreadFactory; -import static java.util.concurrent.Executors.newFixedThreadPool; -import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor; import static java.util.concurrent.Executors.newSingleThreadExecutor; import static java.util.concurrent.TimeUnit.MILLISECONDS; diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/util/concurrent/ThreadPoolExecutor/CoreThreadTimeOut.java --- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/CoreThreadTimeOut.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/CoreThreadTimeOut.java Wed Jul 05 22:16:00 2017 +0200 @@ -83,15 +83,18 @@ tpe.allowCoreThreadTimeOut(true); check(tpe.allowsCoreThreadTimeOut()); equal(countExecutorThreads(), 0); - long t0 = System.nanoTime(); - for (int i = 0; i < threadCount; i++) - tpe.submit(new Runnable() { public void run() {}}); - int count = countExecutorThreads(); - if (millisElapsedSince(t0) < timeoutMillis) - equal(count, threadCount); + long startTime = System.nanoTime(); + for (int i = 0; i < threadCount; i++) { + tpe.submit(() -> {}); + int count = countExecutorThreads(); + if (millisElapsedSince(startTime) < timeoutMillis) + equal(count, i + 1); + } while (countExecutorThreads() > 0 && - millisElapsedSince(t0) < 10 * 1000); + millisElapsedSince(startTime) < LONG_DELAY_MS) + Thread.yield(); equal(countExecutorThreads(), 0); + check(millisElapsedSince(startTime) >= timeoutMillis); tpe.shutdown(); check(tpe.allowsCoreThreadTimeOut()); check(tpe.awaitTermination(LONG_DELAY_MS, MILLISECONDS)); diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/util/concurrent/tck/AtomicIntegerArrayTest.java --- a/jdk/test/java/util/concurrent/tck/AtomicIntegerArrayTest.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/java/util/concurrent/tck/AtomicIntegerArrayTest.java Wed Jul 05 22:16:00 2017 +0200 @@ -303,7 +303,7 @@ class Counter extends CheckedRunnable { final AtomicIntegerArray aa; - volatile int counts; + int decs; Counter(AtomicIntegerArray a) { aa = a; } public void realRun() { for (;;) { @@ -314,7 +314,7 @@ if (v != 0) { done = false; if (aa.compareAndSet(i, v, v - 1)) - ++counts; + decs++; } } if (done) @@ -334,13 +334,11 @@ aa.set(i, countdown); Counter c1 = new Counter(aa); Counter c2 = new Counter(aa); - Thread t1 = new Thread(c1); - Thread t2 = new Thread(c2); - t1.start(); - t2.start(); + Thread t1 = newStartedThread(c1); + Thread t2 = newStartedThread(c2); t1.join(); t2.join(); - assertEquals(c1.counts+c2.counts, SIZE * countdown); + assertEquals(c1.decs + c2.decs, SIZE * countdown); } /** diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/util/concurrent/tck/AtomicLongArrayTest.java --- a/jdk/test/java/util/concurrent/tck/AtomicLongArrayTest.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/java/util/concurrent/tck/AtomicLongArrayTest.java Wed Jul 05 22:16:00 2017 +0200 @@ -302,7 +302,7 @@ class Counter extends CheckedRunnable { final AtomicLongArray aa; - volatile long counts; + int decs; Counter(AtomicLongArray a) { aa = a; } public void realRun() { for (;;) { @@ -313,7 +313,7 @@ if (v != 0) { done = false; if (aa.compareAndSet(i, v, v - 1)) - ++counts; + decs++; } } if (done) @@ -333,13 +333,11 @@ aa.set(i, countdown); Counter c1 = new Counter(aa); Counter c2 = new Counter(aa); - Thread t1 = new Thread(c1); - Thread t2 = new Thread(c2); - t1.start(); - t2.start(); + Thread t1 = newStartedThread(c1); + Thread t2 = newStartedThread(c2); t1.join(); t2.join(); - assertEquals(c1.counts+c2.counts, SIZE * countdown); + assertEquals(c1.decs + c2.decs, SIZE * countdown); } /** diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/util/concurrent/tck/CompletableFutureTest.java --- a/jdk/test/java/util/concurrent/tck/CompletableFutureTest.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/java/util/concurrent/tck/CompletableFutureTest.java Wed Jul 05 22:16:00 2017 +0200 @@ -388,7 +388,7 @@ checkCompletedNormally(f, "test"); } - abstract class CheckedAction { + abstract static class CheckedAction { int invocationCount = 0; final ExecutionMode m; CheckedAction(ExecutionMode m) { this.m = m; } @@ -400,7 +400,7 @@ void assertInvoked() { assertEquals(1, invocationCount); } } - abstract class CheckedIntegerAction extends CheckedAction { + abstract static class CheckedIntegerAction extends CheckedAction { Integer value; CheckedIntegerAction(ExecutionMode m) { super(m); } void assertValue(Integer expected) { @@ -409,7 +409,7 @@ } } - class IntegerSupplier extends CheckedAction + static class IntegerSupplier extends CheckedAction implements Supplier { final Integer value; @@ -428,7 +428,7 @@ return (x == null) ? null : x + 1; } - class NoopConsumer extends CheckedIntegerAction + static class NoopConsumer extends CheckedIntegerAction implements Consumer { NoopConsumer(ExecutionMode m) { super(m); } @@ -438,7 +438,7 @@ } } - class IncFunction extends CheckedIntegerAction + static class IncFunction extends CheckedIntegerAction implements Function { IncFunction(ExecutionMode m) { super(m); } @@ -456,7 +456,7 @@ - ((y == null) ? 99 : y.intValue()); } - class SubtractAction extends CheckedIntegerAction + static class SubtractAction extends CheckedIntegerAction implements BiConsumer { SubtractAction(ExecutionMode m) { super(m); } @@ -466,7 +466,7 @@ } } - class SubtractFunction extends CheckedIntegerAction + static class SubtractFunction extends CheckedIntegerAction implements BiFunction { SubtractFunction(ExecutionMode m) { super(m); } @@ -476,14 +476,14 @@ } } - class Noop extends CheckedAction implements Runnable { + static class Noop extends CheckedAction implements Runnable { Noop(ExecutionMode m) { super(m); } public void run() { invoked(); } } - class FailingSupplier extends CheckedAction + static class FailingSupplier extends CheckedAction implements Supplier { final CFException ex; @@ -494,7 +494,7 @@ } } - class FailingConsumer extends CheckedIntegerAction + static class FailingConsumer extends CheckedIntegerAction implements Consumer { final CFException ex; @@ -506,7 +506,7 @@ } } - class FailingBiConsumer extends CheckedIntegerAction + static class FailingBiConsumer extends CheckedIntegerAction implements BiConsumer { final CFException ex; @@ -518,7 +518,7 @@ } } - class FailingFunction extends CheckedIntegerAction + static class FailingFunction extends CheckedIntegerAction implements Function { final CFException ex; @@ -530,7 +530,7 @@ } } - class FailingBiFunction extends CheckedIntegerAction + static class FailingBiFunction extends CheckedIntegerAction implements BiFunction { final CFException ex; @@ -542,7 +542,7 @@ } } - class FailingRunnable extends CheckedAction implements Runnable { + static class FailingRunnable extends CheckedAction implements Runnable { final CFException ex; FailingRunnable(ExecutionMode m) { super(m); ex = new CFException(); } public void run() { @@ -551,7 +551,7 @@ } } - class CompletableFutureInc extends CheckedIntegerAction + static class CompletableFutureInc extends CheckedIntegerAction implements Function > { CompletableFutureInc(ExecutionMode m) { super(m); } @@ -564,7 +564,7 @@ } } - class FailingCompletableFutureFunction extends CheckedIntegerAction + static class FailingCompletableFutureFunction extends CheckedIntegerAction implements Function > { final CFException ex; @@ -3604,29 +3604,53 @@ * copy returns a CompletableFuture that is completed normally, * with the same value, when source is. */ - public void testCopy() { + public void testCopy_normalCompletion() { + for (boolean createIncomplete : new boolean[] { true, false }) + for (Integer v1 : new Integer[] { 1, null }) + { CompletableFuture f = new CompletableFuture<>(); + if (!createIncomplete) assertTrue(f.complete(v1)); CompletableFuture g = f.copy(); - checkIncomplete(f); - checkIncomplete(g); - f.complete(1); - checkCompletedNormally(f, 1); - checkCompletedNormally(g, 1); - } + if (createIncomplete) { + checkIncomplete(f); + checkIncomplete(g); + assertTrue(f.complete(v1)); + } + checkCompletedNormally(f, v1); + checkCompletedNormally(g, v1); + }} /** * copy returns a CompletableFuture that is completed exceptionally * when source is. */ - public void testCopy2() { + public void testCopy_exceptionalCompletion() { + for (boolean createIncomplete : new boolean[] { true, false }) + { + CFException ex = new CFException(); CompletableFuture f = new CompletableFuture<>(); + if (!createIncomplete) f.completeExceptionally(ex); CompletableFuture g = f.copy(); - checkIncomplete(f); - checkIncomplete(g); - CFException ex = new CFException(); - f.completeExceptionally(ex); + if (createIncomplete) { + checkIncomplete(f); + checkIncomplete(g); + f.completeExceptionally(ex); + } checkCompletedExceptionally(f, ex); checkCompletedWithWrappedException(g, ex); + }} + + /** + * Completion of a copy does not complete its source. + */ + public void testCopy_oneWayPropagation() { + CompletableFuture f = new CompletableFuture<>(); + assertTrue(f.copy().complete(1)); + assertTrue(f.copy().complete(null)); + assertTrue(f.copy().cancel(true)); + assertTrue(f.copy().cancel(false)); + assertTrue(f.copy().completeExceptionally(new CFException())); + checkIncomplete(f); } /** @@ -3991,7 +4015,10 @@ .collect(Collectors.toList()); List > stages = new ArrayList<>(); - stages.add(new CompletableFuture ().minimalCompletionStage()); + CompletionStage min = + new CompletableFuture ().minimalCompletionStage(); + stages.add(min); + stages.add(min.thenApply(x -> x)); stages.add(CompletableFuture.completedStage(1)); stages.add(CompletableFuture.failedStage(new CFException())); @@ -4027,6 +4054,131 @@ throw new Error("Methods did not throw UOE: " + bugs); } + /** + * minimalStage.toCompletableFuture() returns a CompletableFuture that + * is completed normally, with the same value, when source is. + */ + public void testMinimalCompletionStage_toCompletableFuture_normalCompletion() { + for (boolean createIncomplete : new boolean[] { true, false }) + for (Integer v1 : new Integer[] { 1, null }) + { + CompletableFuture f = new CompletableFuture<>(); + CompletionStage minimal = f.minimalCompletionStage(); + if (!createIncomplete) assertTrue(f.complete(v1)); + CompletableFuture g = minimal.toCompletableFuture(); + if (createIncomplete) { + checkIncomplete(f); + checkIncomplete(g); + assertTrue(f.complete(v1)); + } + checkCompletedNormally(f, v1); + checkCompletedNormally(g, v1); + }} + + /** + * minimalStage.toCompletableFuture() returns a CompletableFuture that + * is completed exceptionally when source is. + */ + public void testMinimalCompletionStage_toCompletableFuture_exceptionalCompletion() { + for (boolean createIncomplete : new boolean[] { true, false }) + { + CFException ex = new CFException(); + CompletableFuture f = new CompletableFuture<>(); + CompletionStage minimal = f.minimalCompletionStage(); + if (!createIncomplete) f.completeExceptionally(ex); + CompletableFuture g = minimal.toCompletableFuture(); + if (createIncomplete) { + checkIncomplete(f); + checkIncomplete(g); + f.completeExceptionally(ex); + } + checkCompletedExceptionally(f, ex); + checkCompletedWithWrappedException(g, ex); + }} + + /** + * minimalStage.toCompletableFuture() gives mutable CompletableFuture + */ + public void testMinimalCompletionStage_toCompletableFuture_mutable() { + for (Integer v1 : new Integer[] { 1, null }) + { + CompletableFuture f = new CompletableFuture<>(); + CompletionStage minimal = f.minimalCompletionStage(); + CompletableFuture g = minimal.toCompletableFuture(); + assertTrue(g.complete(v1)); + checkCompletedNormally(g, v1); + checkIncomplete(f); + checkIncomplete(minimal.toCompletableFuture()); + }} + + /** + * minimalStage.toCompletableFuture().join() awaits completion + */ + public void testMinimalCompletionStage_toCompletableFuture_join() throws Exception { + for (boolean createIncomplete : new boolean[] { true, false }) + for (Integer v1 : new Integer[] { 1, null }) + { + CompletableFuture f = new CompletableFuture<>(); + if (!createIncomplete) assertTrue(f.complete(v1)); + CompletionStage minimal = f.minimalCompletionStage(); + if (createIncomplete) assertTrue(f.complete(v1)); + assertEquals(v1, minimal.toCompletableFuture().join()); + assertEquals(v1, minimal.toCompletableFuture().get()); + checkCompletedNormally(minimal.toCompletableFuture(), v1); + }} + + /** + * Completion of a toCompletableFuture copy of a minimal stage + * does not complete its source. + */ + public void testMinimalCompletionStage_toCompletableFuture_oneWayPropagation() { + CompletableFuture f = new CompletableFuture<>(); + CompletionStage g = f.minimalCompletionStage(); + assertTrue(g.toCompletableFuture().complete(1)); + assertTrue(g.toCompletableFuture().complete(null)); + assertTrue(g.toCompletableFuture().cancel(true)); + assertTrue(g.toCompletableFuture().cancel(false)); + assertTrue(g.toCompletableFuture().completeExceptionally(new CFException())); + checkIncomplete(g.toCompletableFuture()); + f.complete(1); + checkCompletedNormally(g.toCompletableFuture(), 1); + } + + /** Demo utility method for external reliable toCompletableFuture */ + static CompletableFuture toCompletableFuture(CompletionStage stage) { + CompletableFuture f = new CompletableFuture<>(); + stage.handle((T t, Throwable ex) -> { + if (ex != null) f.completeExceptionally(ex); + else f.complete(t); + return null; + }); + return f; + } + + /** Demo utility method to join a CompletionStage */ + static T join(CompletionStage stage) { + return toCompletableFuture(stage).join(); + } + + /** + * Joining a minimal stage "by hand" works + */ + public void testMinimalCompletionStage_join_by_hand() { + for (boolean createIncomplete : new boolean[] { true, false }) + for (Integer v1 : new Integer[] { 1, null }) + { + CompletableFuture f = new CompletableFuture<>(); + CompletionStage minimal = f.minimalCompletionStage(); + CompletableFuture g = new CompletableFuture<>(); + if (!createIncomplete) assertTrue(f.complete(v1)); + minimal.thenAccept((x) -> g.complete(x)); + if (createIncomplete) assertTrue(f.complete(v1)); + g.join(); + checkCompletedNormally(g, v1); + checkCompletedNormally(f, v1); + assertEquals(v1, join(minimal)); + }} + static class Monad { static class ZeroException extends RuntimeException { public ZeroException() { super("monadic zero"); } @@ -4317,6 +4469,22 @@ assertTrue(neverCompleted.thenRun(() -> {}).cancel(true)); } + /** + * Checks for garbage retention when MinimalStage.toCompletableFuture() + * is invoked many times. + * 8161600: Garbage retention when source CompletableFutures are never completed + * + * As of 2016-07, fails with OOME: + * ant -Dvmoptions=-Xmx8m -Djsr166.expensiveTests=true -Djsr166.tckTestClass=CompletableFutureTest -Djsr166.methodFilter=testToCompletableFutureGarbageRetention tck + */ + public void testToCompletableFutureGarbageRetention() throws Throwable { + final int n = expensiveTests ? 900_000 : 10; + CompletableFuture neverCompleted = new CompletableFuture<>(); + CompletionStage minimal = neverCompleted.minimalCompletionStage(); + for (int i = 0; i < n; i++) + assertTrue(minimal.toCompletableFuture().cancel(true)); + } + // static U join(CompletionStage stage) { // CompletableFuture f = new CompletableFuture<>(); // stage.whenComplete((v, ex) -> { diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/util/concurrent/tck/ConcurrentSkipListMapTest.java --- a/jdk/test/java/util/concurrent/tck/ConcurrentSkipListMapTest.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/java/util/concurrent/tck/ConcurrentSkipListMapTest.java Wed Jul 05 22:16:00 2017 +0200 @@ -1024,7 +1024,7 @@ static NavigableMap newMap(Class cl) throws Exception { NavigableMap result = - (NavigableMap ) cl.newInstance(); + (NavigableMap ) cl.getConstructor().newInstance(); assertEquals(0, result.size()); assertFalse(result.keySet().iterator().hasNext()); return result; diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/util/concurrent/tck/ConcurrentSkipListSetTest.java --- a/jdk/test/java/util/concurrent/tck/ConcurrentSkipListSetTest.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/java/util/concurrent/tck/ConcurrentSkipListSetTest.java Wed Jul 05 22:16:00 2017 +0200 @@ -725,7 +725,8 @@ } static NavigableSet newSet(Class cl) throws Exception { - NavigableSet result = (NavigableSet ) cl.newInstance(); + NavigableSet result = + (NavigableSet ) cl.getConstructor().newInstance(); assertEquals(0, result.size()); assertFalse(result.iterator().hasNext()); return result; diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/util/concurrent/tck/CyclicBarrierTest.java --- a/jdk/test/java/util/concurrent/tck/CyclicBarrierTest.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/java/util/concurrent/tck/CyclicBarrierTest.java Wed Jul 05 22:16:00 2017 +0200 @@ -40,6 +40,7 @@ import java.util.concurrent.CyclicBarrier; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; import junit.framework.Test; import junit.framework.TestSuite; @@ -52,11 +53,6 @@ return new TestSuite(CyclicBarrierTest.class); } - private volatile int countAction; - private class MyAction implements Runnable { - public void run() { ++countAction; } - } - /** * Spin-waits till the number of waiters == numberOfWaiters. */ @@ -114,14 +110,16 @@ * The supplied barrier action is run at barrier */ public void testBarrierAction() throws Exception { - countAction = 0; - CyclicBarrier b = new CyclicBarrier(1, new MyAction()); + final AtomicInteger count = new AtomicInteger(0); + final Runnable incCount = new Runnable() { public void run() { + count.getAndIncrement(); }}; + CyclicBarrier b = new CyclicBarrier(1, incCount); assertEquals(1, b.getParties()); assertEquals(0, b.getNumberWaiting()); b.await(); b.await(); assertEquals(0, b.getNumberWaiting()); - assertEquals(2, countAction); + assertEquals(2, count.get()); } /** diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/util/concurrent/tck/DelayQueueTest.java --- a/jdk/test/java/util/concurrent/tck/DelayQueueTest.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/java/util/concurrent/tck/DelayQueueTest.java Wed Jul 05 22:16:00 2017 +0200 @@ -121,10 +121,8 @@ } public boolean equals(Object other) { - return equals((NanoDelay)other); - } - public boolean equals(NanoDelay other) { - return other.trigger == trigger; + return (other instanceof NanoDelay) && + this.trigger == ((NanoDelay)other).trigger; } // suppress [overrides] javac warning diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/util/concurrent/tck/ForkJoinPoolTest.java --- a/jdk/test/java/util/concurrent/tck/ForkJoinPoolTest.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/java/util/concurrent/tck/ForkJoinPoolTest.java Wed Jul 05 22:16:00 2017 +0200 @@ -51,6 +51,7 @@ import java.util.concurrent.RecursiveTask; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.ReentrantLock; import junit.framework.AssertionFailedError; @@ -84,13 +85,6 @@ // Some classes to test extension and factory methods - static class MyHandler implements Thread.UncaughtExceptionHandler { - volatile int catches = 0; - public void uncaughtException(Thread t, Throwable e) { - ++catches; - } - } - static class MyError extends Error {} // to test handlers @@ -101,9 +95,9 @@ static class FailingThreadFactory implements ForkJoinPool.ForkJoinWorkerThreadFactory { - volatile int calls = 0; + final AtomicInteger calls = new AtomicInteger(0); public ForkJoinWorkerThread newThread(ForkJoinPool p) { - if (++calls > 1) return null; + if (calls.incrementAndGet() > 1) return null; return new FailingFJWSubclass(p); } } diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/util/concurrent/tck/JSR166TestCase.java --- a/jdk/test/java/util/concurrent/tck/JSR166TestCase.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/java/util/concurrent/tck/JSR166TestCase.java Wed Jul 05 22:16:00 2017 +0200 @@ -1032,14 +1032,17 @@ ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); System.err.println("------ stacktrace dump start ------"); for (ThreadInfo info : threadMXBean.dumpAllThreads(true, true)) { - String name = info.getThreadName(); + final String name = info.getThreadName(); + String lockName; if ("Signal Dispatcher".equals(name)) continue; if ("Reference Handler".equals(name) - && info.getLockName().startsWith("java.lang.ref.Reference$Lock")) + && (lockName = info.getLockName()) != null + && lockName.startsWith("java.lang.ref.Reference$Lock")) continue; if ("Finalizer".equals(name) - && info.getLockName().startsWith("java.lang.ref.ReferenceQueue$Lock")) + && (lockName = info.getLockName()) != null + && lockName.startsWith("java.lang.ref.ReferenceQueue$Lock")) continue; if ("checkForWedgedTest".equals(name)) continue; @@ -1783,7 +1786,7 @@ * A CyclicBarrier that uses timed await and fails with * AssertionFailedErrors instead of throwing checked exceptions. */ - public class CheckedBarrier extends CyclicBarrier { + public static class CheckedBarrier extends CyclicBarrier { public CheckedBarrier(int parties) { super(parties); } public int await() { diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/util/concurrent/tck/ScheduledExecutorTest.java --- a/jdk/test/java/util/concurrent/tck/ScheduledExecutorTest.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/java/util/concurrent/tck/ScheduledExecutorTest.java Wed Jul 05 22:16:00 2017 +0200 @@ -537,15 +537,14 @@ * isShutdown is false before shutdown, true after */ public void testIsShutdown() { - final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1); - try { - assertFalse(p.isShutdown()); + assertFalse(p.isShutdown()); + try (PoolCleaner cleaner = cleaner(p)) { + try { + p.shutdown(); + assertTrue(p.isShutdown()); + } catch (SecurityException ok) {} } - finally { - try { p.shutdown(); } catch (SecurityException ok) { return; } - } - assertTrue(p.isShutdown()); } /** diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/util/concurrent/tck/TreeMapTest.java --- a/jdk/test/java/util/concurrent/tck/TreeMapTest.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/java/util/concurrent/tck/TreeMapTest.java Wed Jul 05 22:16:00 2017 +0200 @@ -829,7 +829,7 @@ static NavigableMap newMap(Class cl) throws Exception { NavigableMap result - = (NavigableMap ) cl.newInstance(); + = (NavigableMap ) cl.getConstructor().newInstance(); assertEquals(0, result.size()); assertFalse(result.keySet().iterator().hasNext()); return result; diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/util/concurrent/tck/TreeSetTest.java --- a/jdk/test/java/util/concurrent/tck/TreeSetTest.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/java/util/concurrent/tck/TreeSetTest.java Wed Jul 05 22:16:00 2017 +0200 @@ -722,7 +722,8 @@ } static NavigableSet newSet(Class cl) throws Exception { - NavigableSet result = (NavigableSet ) cl.newInstance(); + NavigableSet result = + (NavigableSet ) cl.getConstructor().newInstance(); assertEquals(0, result.size()); assertFalse(result.iterator().hasNext()); return result; diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/jdk/internal/misc/Unsafe/TestBadHostClass.java --- a/jdk/test/jdk/internal/misc/Unsafe/TestBadHostClass.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/jdk/internal/misc/Unsafe/TestBadHostClass.java Wed Jul 05 22:16:00 2017 +0200 @@ -25,7 +25,6 @@ * @test * @bug 8058575 * @summary Test that bad host classes cause exceptions to get thrown. - * @library /test/lib * @modules java.base/jdk.internal.misc * java.base/jdk.internal.org.objectweb.asm * @run main TestBadHostClass @@ -35,7 +34,6 @@ import java.lang.*; import java.lang.reflect.Field; import jdk.internal.misc.Unsafe; -import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.org.objectweb.asm.ClassWriter; import static jdk.internal.org.objectweb.asm.Opcodes.*; diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/jprt.config --- a/jdk/test/jprt.config Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/jprt.config Wed Jul 05 22:16:00 2017 +0200 @@ -82,15 +82,12 @@ fi # Add basic solaris system paths - path4sdk=/usr/ccs/bin:/usr/ccs/lib:/usr/bin:/bin:/usr/sfw/bin + path4sdk=/usr/bin:/usr/gnu/bin # Find GNU make - make=/usr/sfw/bin/gmake + make=/usr/bin/gmake if [ ! -f ${make} ] ; then - make=/opt/sfw/bin/gmake - if [ ! -f ${make} ] ; then - make=${slashjava}/devtools/${solaris_arch}/bin/gnumake - fi + make=${slashjava}/devtools/${solaris_arch}/bin/gnumake fi fileMustExist "${make}" make diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/start-Xvfb.sh --- a/jdk/test/start-Xvfb.sh Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/start-Xvfb.sh Wed Jul 05 22:16:00 2017 +0200 @@ -59,9 +59,6 @@ /usr/bin/nohup /usr/bin/X11/Xvfb -fbdir ${currentDir} -pixdepths 8 16 24 32 ${DISPLAY} > ${currentDir}/nohup.$$ 2>&1 & fi WM="/usr/bin/X11/fvwm2" -if [ ! -x ${WM} ] ; then - WM="/opt/sfw/bin/fvwm2" -fi # # Wait for Xvfb to initialize: sleep 5 diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/sun/nio/cs/TestUnmappable.java --- a/jdk/test/sun/nio/cs/TestUnmappable.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/sun/nio/cs/TestUnmappable.java Wed Jul 05 22:16:00 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,11 +28,11 @@ * @bug 8008386 * @summary (cs) Unmappable leading should be decoded to replacement. * Tests for Shift_JIS and MS932 decoding + * @modules jdk.charsets * @run main TestUnmappable */ -import java.nio.*; -import java.nio.charset.*; +import java.nio.charset.Charset; public class TestUnmappable { public static void main(String args[]) throws Exception { diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/sun/security/pkcs11/tls/TestKeyMaterial.java --- a/jdk/test/sun/security/pkcs11/tls/TestKeyMaterial.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/sun/security/pkcs11/tls/TestKeyMaterial.java Wed Jul 05 22:16:00 2017 +0200 @@ -23,7 +23,7 @@ /* * @test - * @bug 6316539 + * @bug 6316539 8136355 * @summary Known-answer-test for TlsKeyMaterial generator * @author Andreas Sterbenz * @library .. @@ -37,6 +37,7 @@ import java.nio.file.Files; import java.nio.file.Paths; import java.security.Provider; +import java.security.InvalidAlgorithmParameterException; import java.util.Arrays; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; @@ -139,21 +140,28 @@ keyLength, expandedKeyLength, ivLength, macLength, null, -1, -1); - kg.init(spec); - TlsKeyMaterialSpec result = - (TlsKeyMaterialSpec)kg.generateKey(); - match(lineNumber, clientCipherBytes, - result.getClientCipherKey(), cipherAlgorithm); - match(lineNumber, serverCipherBytes, - result.getServerCipherKey(), cipherAlgorithm); - match(lineNumber, clientIv, result.getClientIv(), ""); - match(lineNumber, serverIv, result.getServerIv(), ""); - match(lineNumber, clientMacBytes, result.getClientMacKey(), ""); - match(lineNumber, serverMacBytes, result.getServerMacKey(), ""); - - } else { + try { + kg.init(spec); + TlsKeyMaterialSpec result = + (TlsKeyMaterialSpec)kg.generateKey(); + match(lineNumber, clientCipherBytes, + result.getClientCipherKey(), cipherAlgorithm); + match(lineNumber, serverCipherBytes, + result.getServerCipherKey(), cipherAlgorithm); + match(lineNumber, clientIv, result.getClientIv(), ""); + match(lineNumber, serverIv, result.getServerIv(), ""); + match(lineNumber, clientMacBytes, result.getClientMacKey(), ""); + match(lineNumber, serverMacBytes, result.getServerMacKey(), ""); + } catch (InvalidAlgorithmParameterException iape) { + // SSLv3 support is removed in S12 + if (major == 3 && minor == 0) { + System.out.println("Skip testing SSLv3"); + continue; + } + } + } else { throw new Exception("Unknown line: " + line); - } + } } if (n == 0) { throw new Exception("no tests"); diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/sun/security/pkcs11/tls/TestMasterSecret.java --- a/jdk/test/sun/security/pkcs11/tls/TestMasterSecret.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/sun/security/pkcs11/tls/TestMasterSecret.java Wed Jul 05 22:16:00 2017 +0200 @@ -23,7 +23,7 @@ /* * @test - * @bug 6316539 + * @bug 6316539 8136355 * @summary Known-answer-test for TlsMasterSecret generator * @author Andreas Sterbenz * @library .. @@ -38,6 +38,7 @@ import java.nio.file.Files; import java.nio.file.Paths; import java.security.Provider; +import java.security.InvalidAlgorithmParameterException; import java.util.Arrays; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; @@ -116,15 +117,24 @@ new TlsMasterSecretParameterSpec(premasterKey, protoMajor, protoMinor, clientRandom, serverRandom, null, -1, -1); - kg.init(spec); - TlsMasterSecret key = (TlsMasterSecret)kg.generateKey(); - byte[] enc = key.getEncoded(); - if (Arrays.equals(master, enc) == false) { - throw new Exception("mismatch line: " + lineNumber); - } - if ((preMajor != key.getMajorVersion()) || - (preMinor != key.getMinorVersion())) { - throw new Exception("version mismatch line: " + lineNumber); + + try { + kg.init(spec); + TlsMasterSecret key = (TlsMasterSecret)kg.generateKey(); + byte[] enc = key.getEncoded(); + if (Arrays.equals(master, enc) == false) { + throw new Exception("mismatch line: " + lineNumber); + } + if ((preMajor != key.getMajorVersion()) || + (preMinor != key.getMinorVersion())) { + throw new Exception("version mismatch line: " + lineNumber); + } + } catch (InvalidAlgorithmParameterException iape) { + // SSLv3 support is removed in S12 + if (preMajor == 3 && preMinor == 0) { + System.out.println("Skip testing SSLv3"); + continue; + } } } else { throw new Exception("Unknown line: " + line); diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/sun/security/pkcs11/tls/TestPremaster.java --- a/jdk/test/sun/security/pkcs11/tls/TestPremaster.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/sun/security/pkcs11/tls/TestPremaster.java Wed Jul 05 22:16:00 2017 +0200 @@ -23,7 +23,7 @@ /* * @test - * @bug 6316539 + * @bug 6316539 8136355 * @summary Basic tests for TlsRsaPremasterSecret generator * @author Andreas Sterbenz * @library .. @@ -34,6 +34,7 @@ */ import java.security.Provider; +import java.security.InvalidAlgorithmParameterException; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec; @@ -61,7 +62,7 @@ System.out.println("OK: " + e); } - int[] protocolVersions = {0x0300, 0x0301, 0x0302, 0x0400}; + int[] protocolVersions = {0x0300, 0x0301, 0x0302}; for (int clientVersion : protocolVersions) { for (int serverVersion : protocolVersions) { test(kg, clientVersion, serverVersion); @@ -81,8 +82,18 @@ "Testing RSA pre-master secret key generation between " + "client (0x%04X) and server(0x%04X)%n", clientVersion, serverVersion); - kg.init(new TlsRsaPremasterSecretParameterSpec( + try { + kg.init(new TlsRsaPremasterSecretParameterSpec( clientVersion, serverVersion)); + } catch (InvalidAlgorithmParameterException iape) { + // S12 removed support for SSL v3.0 + if (clientVersion == 0x300 || serverVersion == 0x300) { + System.out.println("Skip testing SSLv3 due to no support"); + return; + } + // unexpected, pass it up + throw iape; + } SecretKey key = kg.generateKey(); byte[] encoded = key.getEncoded(); if (encoded != null) { // raw key material may be not extractable diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/sun/security/smartcardio/README.txt --- a/jdk/test/sun/security/smartcardio/README.txt Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/sun/security/smartcardio/README.txt Wed Jul 05 22:16:00 2017 +0200 @@ -1,17 +1,17 @@ Rough hints for setting up MUSCLE on Solaris: -Make sure you have libusb, usually in /usr/sfw: +Make sure you have libusb, usually in /usr/lib: -ls -l /usr/sfw/lib/libusb.so -lrwxrwxrwx 1 root other 11 Jan 12 16:02 /usr/sfw/lib/libusb.so -> libusb.so.1 +ls -l /usr/lib/libusb.so +lrwxrwxrwx 1 root other 11 Jan 12 16:02 /usr/lib/libusb.so -> libusb.so.1 Get PCSC and CCID. -rwx------ 1 user staff 529540 Jun 16 18:24 ccid-1.0.1.tar.gz -rwx------ 1 user staff 842654 Jun 16 18:24 pcsc-lite-1.3.1.tar.gz Unpack pcsc -Run ./configure --enable-libusb=/usr/sfw (??) +Run ./configure --enable-libusb (??) gnumake Make /usr/local writeable for user gnumake install diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/sun/security/smartcardio/TestChannel.java --- a/jdk/test/sun/security/smartcardio/TestChannel.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/sun/security/smartcardio/TestChannel.java Wed Jul 05 22:16:00 2017 +0200 @@ -21,11 +21,12 @@ * questions. */ -/** +/* * @test * @bug 6239117 * @summary test logical channels work * @author Andreas Sterbenz + * @modules java.smartcardio/javax.smartcardio * @run main/manual TestChannel */ diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/sun/security/smartcardio/TestConnect.java --- a/jdk/test/sun/security/smartcardio/TestConnect.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/sun/security/smartcardio/TestConnect.java Wed Jul 05 22:16:00 2017 +0200 @@ -21,11 +21,12 @@ * questions. */ -/** +/* * @test * @bug 6293769 6294527 6309280 * @summary test connect() works * @author Andreas Sterbenz + * @modules java.smartcardio/javax.smartcardio * @run main/manual TestConnect */ diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/sun/security/smartcardio/TestConnectAgain.java --- a/jdk/test/sun/security/smartcardio/TestConnectAgain.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/sun/security/smartcardio/TestConnectAgain.java Wed Jul 05 22:16:00 2017 +0200 @@ -21,11 +21,12 @@ * questions. */ -/** +/* * @test * @bug 6239117 * @summary test connect works correctly if called multiple times/card removed * @author Andreas Sterbenz + * @modules java.smartcardio/javax.smartcardio * @run main/manual TestConnectAgain */ diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/sun/security/smartcardio/TestControl.java --- a/jdk/test/sun/security/smartcardio/TestControl.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/sun/security/smartcardio/TestControl.java Wed Jul 05 22:16:00 2017 +0200 @@ -21,11 +21,12 @@ * questions. */ -/** +/* * @test * @bug 6239117 6470320 * @summary test if transmitControlCommand() works * @author Andreas Sterbenz + * @modules java.smartcardio/javax.smartcardio * @run main/manual TestControl */ diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/sun/security/smartcardio/TestDefault.java --- a/jdk/test/sun/security/smartcardio/TestDefault.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/sun/security/smartcardio/TestDefault.java Wed Jul 05 22:16:00 2017 +0200 @@ -21,11 +21,12 @@ * questions. */ -/** +/* * @test * @bug 6327047 * @summary verify that TerminalFactory.getDefault() works * @author Andreas Sterbenz + * @modules java.smartcardio/javax.smartcardio * @run main/manual TestDefault */ diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/sun/security/smartcardio/TestDirect.java --- a/jdk/test/sun/security/smartcardio/TestDirect.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/sun/security/smartcardio/TestDirect.java Wed Jul 05 22:16:00 2017 +0200 @@ -21,10 +21,11 @@ * questions. */ -/** +/* * @test * @bug 8046343 * @summary Make sure that direct protocol is available + * @modules java.smartcardio/javax.smartcardio * @run main/manual TestDirect */ diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/sun/security/smartcardio/TestExclusive.java --- a/jdk/test/sun/security/smartcardio/TestExclusive.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/sun/security/smartcardio/TestExclusive.java Wed Jul 05 22:16:00 2017 +0200 @@ -21,11 +21,12 @@ * questions. */ -/** +/* * @test * @bug 6239117 * @summary verify that beginExclusive()/endExclusive() works * @author Andreas Sterbenz + * @modules java.smartcardio/javax.smartcardio * @run main/manual TestExclusive */ diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/sun/security/smartcardio/TestMultiplePresent.java --- a/jdk/test/sun/security/smartcardio/TestMultiplePresent.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/sun/security/smartcardio/TestMultiplePresent.java Wed Jul 05 22:16:00 2017 +0200 @@ -21,11 +21,12 @@ * questions. */ -/** +/* * @test * @bug 6239117 6445367 * @summary test that CardTerminals.waitForCard() works * @author Andreas Sterbenz + * @modules java.smartcardio/javax.smartcardio * @run main/manual TestMultiplePresent */ diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/sun/security/smartcardio/TestPresent.java --- a/jdk/test/sun/security/smartcardio/TestPresent.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/sun/security/smartcardio/TestPresent.java Wed Jul 05 22:16:00 2017 +0200 @@ -21,11 +21,12 @@ * questions. */ -/** +/* * @test * @bug 6293769 6294527 * @summary test that the isCardPresent()/waitForX() APIs work correctly * @author Andreas Sterbenz + * @modules java.smartcardio/javax.smartcardio * @run main/manual TestPresent */ diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/sun/security/smartcardio/TestTransmit.java --- a/jdk/test/sun/security/smartcardio/TestTransmit.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/sun/security/smartcardio/TestTransmit.java Wed Jul 05 22:16:00 2017 +0200 @@ -21,11 +21,12 @@ * questions. */ -/** +/* * @test * @bug 6293769 6294527 * @summary test transmit() works * @author Andreas Sterbenz + * @modules java.smartcardio/javax.smartcardio * @run main/manual TestTransmit */ diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/sun/security/ssl/SocketCreation/SocketCreation.java --- a/jdk/test/sun/security/ssl/SocketCreation/SocketCreation.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/sun/security/ssl/SocketCreation/SocketCreation.java Wed Jul 05 22:16:00 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -139,7 +139,7 @@ (SSLServerSocketFactory) SSLServerSocketFactory.getDefault(); System.out.println("Server: Will call createServerSocket(int)"); - ServerSocket sslServerSocket = sslssf.createServerSocket(serverPort); + ServerSocket sslServerSocket = sslssf.createServerSocket(0); serverPort = sslServerSocket.getLocalPort(); System.out.println("Server: Will accept on SSL server socket..."); @@ -157,7 +157,7 @@ (SSLServerSocketFactory) SSLServerSocketFactory.getDefault(); System.out.println("Server: Will call createServerSocket(int, int)"); - ServerSocket sslServerSocket = sslssf.createServerSocket(serverPort, + ServerSocket sslServerSocket = sslssf.createServerSocket(0, 1); serverPort = sslServerSocket.getLocalPort(); @@ -177,7 +177,7 @@ System.out.println("Server: Will call createServerSocket(int, " + " int, InetAddress)"); - ServerSocket sslServerSocket = sslssf.createServerSocket(serverPort, + ServerSocket sslServerSocket = sslssf.createServerSocket(0, 1, InetAddress.getByName("localhost")); serverPort = sslServerSocket.getLocalPort(); @@ -203,14 +203,15 @@ if (sslServerSocket.isBound()) throw new Exception("Server socket is already bound!"); - System.out.println("Server: Will bind SSL server socket to port " + - serverPort + "..."); - - sslServerSocket.bind(new java.net.InetSocketAddress(serverPort)); + sslServerSocket.bind(new java.net.InetSocketAddress(0)); if (!sslServerSocket.isBound()) throw new Exception("Server socket is not bound!"); + serverPort = sslServerSocket.getLocalPort(); + System.out.println("Server: Bound SSL server socket to port " + + serverPort + "..."); + serverReady = true; System.out.println("Server: Will accept on SSL server socket..."); @@ -224,11 +225,10 @@ SSLSocketFactory sslsf = (SSLSocketFactory) SSLSocketFactory.getDefault(); - System.out.println("Server: Will create normal server socket bound" - + " to port " + serverPort + "..."); - - ServerSocket ss = new ServerSocket(serverPort); + ServerSocket ss = new ServerSocket(0); serverPort = ss.getLocalPort(); + System.out.println("Server: Created normal server socket bound" + + " to port " + serverPort + "..."); System.out.println("Server: Will accept on server socket..."); serverReady = true; Socket s = ss.accept(); diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/sun/security/tools/keytool/KeyToolTest.java --- a/jdk/test/sun/security/tools/keytool/KeyToolTest.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/sun/security/tools/keytool/KeyToolTest.java Wed Jul 05 22:16:00 2017 +0200 @@ -1761,7 +1761,7 @@ //PKCS#11 tests // 1. sccs edit cert8.db key3.db - //Runtime.getRuntime().exec("/usr/ccs/bin/sccs edit cert8.db key3.db"); + //Runtime.getRuntime().exec("/usr/bin/sccs edit cert8.db key3.db"); testOK("", p11Arg + ("-storepass test12 -genkey -alias genkey" + " -dname cn=genkey -keysize 512 -keyalg rsa")); testOK("", p11Arg + "-storepass test12 -list"); @@ -1781,7 +1781,7 @@ testOK("", p11Arg + "-storepass test12 -list"); assertTrue(out.indexOf("Your keystore contains 0 entries") != -1); //(check for empty database listing) - //Runtime.getRuntime().exec("/usr/ccs/bin/sccs unedit cert8.db key3.db"); + //Runtime.getRuntime().exec("/usr/bin/sccs unedit cert8.db key3.db"); remove("genkey.cert"); remove("genkey.certreq"); // 12. sccs unedit cert8.db key3.db diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/tools/launcher/RunpathTest.java --- a/jdk/test/tools/launcher/RunpathTest.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/tools/launcher/RunpathTest.java Wed Jul 05 22:16:00 2017 +0200 @@ -40,7 +40,7 @@ } final String findElfReader() { - String[] paths = {"/bin", "/sbin", "/usr/bin", "/usr/sbin", "/usr/ccs/bin"}; + String[] paths = {"/usr/sbin", "/usr/bin"}; final String cmd = isSolaris ? "elfdump" : "readelf"; for (String x : paths) { File p = new File(x); diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/tools/launcher/TooSmallStackSize.java --- a/jdk/test/tools/launcher/TooSmallStackSize.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/tools/launcher/TooSmallStackSize.java Wed Jul 05 22:16:00 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,11 @@ * stack size for the platform (as provided by the JVM error message when a very * small stack is used), and then verify that the JVM can be launched with that stack * size without a crash or any error messages. + * + * Note: The '-Xss ' and '-XX:ThreadStackSize= ' options + * both control Java thread stack size. This repo's version of the test + * exercises the '-Xss' option. The hotspot repo's version of the test + * exercises the '-XX:ThreadStackSize' VM option. */ public class TooSmallStackSize extends TestHelper { @@ -59,7 +64,7 @@ static String getMinStackAllowed(TestResult tr) { /* * The JVM output will contain in one of the lines: - * "The stack size specified is too small, Specify at least 100k" + * "The Java thread stack size specified is too small. Specify at least 100k" * Although the actual size will vary. We need to extract this size * string from the output and return it. */ @@ -73,6 +78,9 @@ } } + System.out.println("Expect='" + matchStr + "'"); + System.out.println("Actual:"); + printTestOutput(tr); System.out.println("FAILED: Could not get the stack size from the output"); throw new RuntimeException("test fails"); } @@ -96,11 +104,15 @@ System.out.println("PASSED: got no error message with stack size of " + stackSize); min_stack_allowed = stackSize; } else { - if (tr.contains("The stack size specified is too small")) { + String matchStr = "The Java thread stack size specified is too small"; + if (tr.contains(matchStr)) { System.out.println("PASSED: got expected error message with stack size of " + stackSize); min_stack_allowed = getMinStackAllowed(tr); } else { // Likely a crash + System.out.println("Expect='" + matchStr + "'"); + System.out.println("Actual:"); + printTestOutput(tr); System.out.println("FAILED: Did not get expected error message with stack size of " + stackSize); throw new RuntimeException("test fails"); } @@ -123,6 +135,8 @@ System.out.println("PASSED: VM launched with minimum allowed stack size of " + stackSize); } else { // Likely a crash + System.out.println("Test output:"); + printTestOutput(tr); System.out.println("FAILED: VM failed to launch with minimum allowed stack size of " + stackSize); throw new RuntimeException("test fails"); } diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/tools/launcher/modules/addmods/AddModsTest.java --- a/jdk/test/tools/launcher/modules/addmods/AddModsTest.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/tools/launcher/modules/addmods/AddModsTest.java Wed Jul 05 22:16:00 2017 +0200 @@ -31,6 +31,7 @@ * @summary Basic test for java --add-modules */ +import java.io.File; import java.nio.file.Path; import java.nio.file.Paths; @@ -224,6 +225,27 @@ /** + * Tests {@code --add-modules} be specified more than once. + */ + public void testWithMultipleAddModules() throws Exception { + + String modulepath = MODS1_DIR.toString() + File.pathSeparator + + MODS2_DIR.toString(); + int exitValue + = executeTestJava("--module-path", modulepath, + "--add-modules", LOGGER_MODULE, + "--add-modules", TEST_MODULE, + "-m", TEST_MID, + "logger.Logger") + .outputTo(System.out) + .errorTo(System.out) + .getExitValue(); + + assertTrue(exitValue == 0); + } + + + /** * Attempt to run with a bad module name specified to --add-modules */ public void testRunWithBadAddMods() throws Exception { diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/tools/pack200/Pack200Test.java --- a/jdk/test/tools/pack200/Pack200Test.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/test/tools/pack200/Pack200Test.java Wed Jul 05 22:16:00 2017 +0200 @@ -24,6 +24,7 @@ /* * @test * @bug 6521334 6712743 8007902 8151901 + * @requires (sun.arch.data.model == "64" & os.maxMemory >= 4g) * @summary test general packer/unpacker functionality * using native and java unpackers * @compile -XDignore.symbol.file Utils.java Pack200Test.java diff -r 8ced0dd94a6e -r 552748e3d506 make/MainSupport.gmk --- a/make/MainSupport.gmk Thu Sep 22 16:41:14 2016 +0000 +++ b/make/MainSupport.gmk Wed Jul 05 22:16:00 2017 +0200 @@ -31,11 +31,13 @@ _MAINSUPPORT_GMK := 1 # Run the tests specified by $1, with PRODUCT_HOME specified by $2 +# JT_JAVA is picked up by the jtreg launcher and used to run Jtreg itself. define RunTests ($(CD) $(SRC_ROOT)/test && $(MAKE) $(MAKE_ARGS) -j1 -k MAKEFLAGS= \ JT_HOME=$(JT_HOME) PRODUCT_HOME=$(strip $2) \ TEST_IMAGE_DIR=$(TEST_IMAGE_DIR) \ ALT_OUTPUTDIR=$(OUTPUT_ROOT) TEST_JOBS=$(TEST_JOBS) \ + JT_JAVA=$(BOOT_JDK) \ JOBS=$(JOBS) $1) || true endef diff -r 8ced0dd94a6e -r 552748e3d506 nashorn/.hgtags --- a/nashorn/.hgtags Thu Sep 22 16:41:14 2016 +0000 +++ b/nashorn/.hgtags Wed Jul 05 22:16:00 2017 +0200 @@ -370,3 +370,4 @@ e05400ba935753c77697af936db24657eb811022 jdk-9+134 cb00d5ef023a18a66fcb4311ed4474d4145c66e9 jdk-9+135 f11b8f5c4ccbf9c87d283815abac6c0117fba3c0 jdk-9+136 +17ed43add2f9e3528686cd786ae2ed49c8ed36e9 jdk-9+137 diff -r 8ced0dd94a6e -r 552748e3d506 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java Thu Sep 22 16:41:14 2016 +0000 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java Wed Jul 05 22:16:00 2017 +0200 @@ -2512,7 +2512,8 @@ final List elements = objectNode.getElements(); final List > tuples = new ArrayList<>(); - final List gettersSetters = new ArrayList<>(); + // List below will contain getter/setter properties and properties with computed keys (ES6) + final List specialProperties = new ArrayList<>(); final int ccp = getCurrentContinuationEntryPoint(); final List ranges = objectNode.getSplitRanges(); @@ -2522,11 +2523,14 @@ for (final PropertyNode propertyNode : elements) { final Expression value = propertyNode.getValue(); final String key = propertyNode.getKeyName(); + final boolean isComputedOrAccessor = propertyNode.isComputed() || value == null; + // Just use a pseudo-symbol. We just need something non null; use the name and zero flags. - final Symbol symbol = value == null ? null : new Symbol(key, 0); - - if (value == null) { - gettersSetters.add(propertyNode); + final Symbol symbol = isComputedOrAccessor ? null : new Symbol(key, 0); + + if (isComputedOrAccessor) { + // Properties with computed names or getter/setters need special handling. + specialProperties.add(propertyNode); } else if (propertyNode.getKey() instanceof IdentNode && key.equals(ScriptObject.PROTO_PROPERTY_NAME)) { // ES6 draft compliant __proto__ inside object literal @@ -2542,7 +2546,7 @@ //for literals, a value of null means object type, i.e. the value null or getter setter function //(I think) - final Class> valueType = (!useDualFields() || value == null || value.getType().isBoolean()) ? Object.class : value.getType().getTypeClass(); + final Class> valueType = (!useDualFields() || isComputedOrAccessor || value.getType().isBoolean()) ? Object.class : value.getType().getTypeClass(); tuples.add(new MapTuple (key, symbol, Type.typeFor(valueType), value) { @Override public Class> getValueType() { @@ -2590,26 +2594,41 @@ method.invoke(ScriptObject.SET_GLOBAL_OBJECT_PROTO); } - for (final PropertyNode propertyNode : gettersSetters) { - final FunctionNode getter = propertyNode.getGetter(); - final FunctionNode setter = propertyNode.getSetter(); - - assert getter != null || setter != null; - - method.dup().loadKey(propertyNode.getKey()); - if (getter == null) { - method.loadNull(); + for (final PropertyNode propertyNode : specialProperties) { + + method.dup(); + + if (propertyNode.isComputed()) { + assert propertyNode.getKeyName() == null; + loadExpressionAsObject(propertyNode.getKey()); + } else { + method.loadKey(propertyNode.getKey()); + } + + if (propertyNode.getValue() != null) { + loadExpressionAsObject(propertyNode.getValue()); + method.load(0); + method.invoke(ScriptObject.GENERIC_SET); } else { - getter.accept(this); - } - - if (setter == null) { - method.loadNull(); - } else { - setter.accept(this); - } - - method.invoke(ScriptObject.SET_USER_ACCESSORS); + final FunctionNode getter = propertyNode.getGetter(); + final FunctionNode setter = propertyNode.getSetter(); + + assert getter != null || setter != null; + + if (getter == null) { + method.loadNull(); + } else { + getter.accept(this); + } + + if (setter == null) { + method.loadNull(); + } else { + setter.accept(this); + } + + method.invoke(ScriptObject.SET_USER_ACCESSORS); + } } } diff -r 8ced0dd94a6e -r 552748e3d506 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/PropertyNode.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/PropertyNode.java Thu Sep 22 16:41:14 2016 +0000 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/PropertyNode.java Wed Jul 05 22:16:00 2017 +0200 @@ -86,11 +86,11 @@ } /** - * Get the name of the property key - * @return key name + * Get the name of the property key, or {@code null} if key is a computed name. + * @return key name or null */ public String getKeyName() { - return key instanceof PropertyKey ? ((PropertyKey) key).getPropertyName() : null; + return !computed && key instanceof PropertyKey ? ((PropertyKey) key).getPropertyName() : null; } @Override diff -r 8ced0dd94a6e -r 552748e3d506 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java Thu Sep 22 16:41:14 2016 +0000 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java Wed Jul 05 22:16:00 2017 +0200 @@ -1176,10 +1176,9 @@ labelStatement(); return; } - final boolean allowPropertyFunction = (reparseFlags & ScriptFunctionData.IS_PROPERTY_ACCESSOR) != 0; - final boolean isES6Method = (reparseFlags & ScriptFunctionData.IS_ES6_METHOD) != 0; - if(allowPropertyFunction) { - final String ident = (String)getValue(); + + if ((reparseFlags & ScriptFunctionData.IS_PROPERTY_ACCESSOR) != 0) { + final String ident = (String) getValue(); final long propertyToken = token; final int propertyLine = line; if (GET_NAME.equals(ident)) { @@ -1191,19 +1190,22 @@ addPropertyFunctionStatement(propertySetterFunction(propertyToken, propertyLine)); return; } - } else if (isES6Method) { - final String ident = (String)getValue(); - IdentNode identNode = createIdentNode(token, finish, ident).setIsPropertyName(); - final long propertyToken = token; - final int propertyLine = line; - next(); - // Code below will need refinement once we fully support ES6 class syntax - final int flags = CONSTRUCTOR_NAME.equals(ident) ? FunctionNode.ES6_IS_CLASS_CONSTRUCTOR : FunctionNode.ES6_IS_METHOD; - addPropertyFunctionStatement(propertyMethodFunction(identNode, propertyToken, propertyLine, false, flags, false)); - return; } } + if ((reparseFlags & ScriptFunctionData.IS_ES6_METHOD) != 0 + && (type == IDENT || type == LBRACKET || isNonStrictModeIdent())) { + final String ident = (String)getValue(); + final long propertyToken = token; + final int propertyLine = line; + final Expression propertyKey = propertyName(); + + // Code below will need refinement once we fully support ES6 class syntax + final int flags = CONSTRUCTOR_NAME.equals(ident) ? FunctionNode.ES6_IS_CLASS_CONSTRUCTOR : FunctionNode.ES6_IS_METHOD; + addPropertyFunctionStatement(propertyMethodFunction(propertyKey, propertyToken, propertyLine, false, flags, false)); + return; + } + expressionStatement(); break; } diff -r 8ced0dd94a6e -r 552748e3d506 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptObject.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptObject.java Thu Sep 22 16:41:14 2016 +0000 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptObject.java Wed Jul 05 22:16:00 2017 +0200 @@ -186,7 +186,10 @@ /** Method handle for setting the user accessors of a ScriptObject */ //TODO fastpath this - public static final Call SET_USER_ACCESSORS = virtualCall(MethodHandles.lookup(), ScriptObject.class, "setUserAccessors", void.class, String.class, ScriptFunction.class, ScriptFunction.class); + public static final Call SET_USER_ACCESSORS = virtualCallNoLookup(ScriptObject.class, "setUserAccessors", void.class, Object.class, ScriptFunction.class, ScriptFunction.class); + + /** Method handle for generic property setter */ + public static final Call GENERIC_SET = virtualCallNoLookup(ScriptObject.class, "set", void.class, Object.class, Object.class, int.class); static final MethodHandle[] SET_SLOW = new MethodHandle[] { findOwnMH_V("set", void.class, Object.class, int.class, int.class), @@ -1063,12 +1066,13 @@ * @param getter {@link UserAccessorProperty} defined getter, or null if none * @param setter {@link UserAccessorProperty} defined setter, or null if none */ - public final void setUserAccessors(final String key, final ScriptFunction getter, final ScriptFunction setter) { - final Property oldProperty = getMap().findProperty(key); + public final void setUserAccessors(final Object key, final ScriptFunction getter, final ScriptFunction setter) { + final Object realKey = JSType.toPropertyKey(key); + final Property oldProperty = getMap().findProperty(realKey); if (oldProperty instanceof UserAccessorProperty) { modifyOwnProperty(oldProperty, oldProperty.getFlags(), getter, setter); } else { - addOwnProperty(newUserAccessors(key, oldProperty != null ? oldProperty.getFlags() : 0, getter, setter)); + addOwnProperty(newUserAccessors(realKey, oldProperty != null ? oldProperty.getFlags() : 0, getter, setter)); } } diff -r 8ced0dd94a6e -r 552748e3d506 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/Functions.properties --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/Functions.properties Thu Sep 22 16:41:14 2016 +0000 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/Functions.properties Wed Jul 05 22:16:00 2017 +0200 @@ -190,3 +190,105 @@ Number.prototype.toPrecision=returns a string representing the number to a specified precision in fixed-point or exponential notation +Date.parse=returns a number, the UTC time value corresponding to the date and time interpreted from the given string argument, returns NAN if the argument is not recognized + +Date.UTC=returns the number of milliseconds in the given date object since January 1, 1970, 00:00:00 universal time + +Date.now=returns the number of milliseconds elapsed since January 1, 1970, 00:00:00 UTC + +Date.prototype.toString=returns the string value representing the given date object + +Date.prototype.toDateString=returns the string value representing the date portion of the given date object + +Date.prototype.toTimeString=returns the string value representing the time portion of the given date object + +Date.prototype.toLocaleString=returns the string value representing the date according to language specific conventions + +Date.prototype.toLocaleDateString=returns the string value representing the date portion of the given date object according to language specific conventions + +Date.prototype.toLocaleTimeString=returns the string value representing the time portion of the given date object according to language specific conventions + +Date.prototype.valueOf=returns the number of milliseconds between January 1, 1970, 00:00:00 UTC and the given date + +Date.prototype.getTime=returns the number representing milliseconds elapsed between January 1, 1970, 00:00:00 UTC and the given date + +Date.prototype.getFullYear=returns the year of the given date according to local time + +Date.prototype.getUTCFullYear=returns the year of the given date according to universal time + +Date.prototype.getMonth=returns the month between 0 to 11 of the given date according to local time + +Date.prototype.getUTCMonth=returns the month between 0 and 11 of the given date according to universal time + +Date.prototype.getDate=returns the day of the month for the given date according to local time + +Date.prototype.getUTCDate=returns the day of the month for the given date according to universal time + +Date.prototype.getDay=returns the day of the week for the given date according to local time, 0 represents Sunday + +Date.prototype.getUTCDay=returns the day of the week for the given date according to universal time, 0 represents Sunday + +Date.prototype.getHours=returns the hour in the given date, according to local time + +Date.prototype.getUTCHours=returns the hour in the given date, according to universal time + +Date.prototype.getMinutes=returns the minutes in the given date, according to local time + +Date.prototype.getUTCMinutes=returns the minutes in the given date, according to universal time + +Date.prototype.getSeconds=returns the seconds in the given date, according to local time + +Date.prototype.getUTCSeconds=returns the seconds in the given date, according to universal time + +Date.prototype.getMilliseconds=returns the milliseconds in the given date, according to local time + +Date.prototype.getUTCMilliseconds=returns the milliseconds in the given date, according to universal time + +Date.prototype.getTimezoneOffset=returns the difference between local time and UTC time in minutes + +Date.prototype.setTime=sets the date object to the time given, which is represented by the number of milliseconds since January 1, 1970, 00:00:00 UTC + +Date.prototype.setMilliseconds=sets the milliseconds for the given date according to local time + +Date.prototype.setUTCMilliseconds=sets the milliseconds for the given date according to universal time + +Date.prototype.setSeconds=sets the seconds for the given date according to local time + +Date.prototype.setUTCSeconds=sets the seconds for the given date according to universal time + +Date.prototype.setMinutes=sets the minutes for the given date according to local time + +Date.prototype.setUTCMinutes=sets the minutes for the given date according to universal time + +Date.prototype.setHours=sets the hours for the given date according to local time + +Date.prototype.setUTCHours=sets the hours for the given date according to universal time + +Date.prototype.setDate=sets the day of the month for the given date according to local time + +Date.prototype.setUTCDate=sets the day of the month for the given date according to universal time + +Date.prototype.setMonth=sets the month for the given date according to the currently set year + +Date.prototype.setUTCMonth=sets the month for the given date according to the universal time + +Date.prototype.setFullYear=sets the full year for the given date according to local time + +Date.prototype.toUTCString=converts the given date to a string using UTC time zone + +Date.prototype.toISOString=returns the string value in ISO 8601 format for the given date according to universal time + +Date.prototype.toJSON=returns the string representation of the given date + +RegExp.prototype.exec=returns an array object containing the results of match of given string against regular expression, null if no match found + +RegExp.prototype.test=returns true if match of given string against regular expression found, else returns false + +RegExp.prototype.toString=returns string representation of regular expression + +Error.prototype.toString=returns string representation of error object + +JSON.parse=returns an object by parsing given string as JSON + +JSON.stringify=returns a JSON string corresponding to the given ECMAScript value + diff -r 8ced0dd94a6e -r 552748e3d506 nashorn/test/script/basic/es6/computed-property-duplicate.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/basic/es6/computed-property-duplicate.js Wed Jul 05 22:16:00 2017 +0200 @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8164467: ES6 computed properties are implemented wrongly + * + * @test + * @run + * @option --language=es6 + */ + +var obj = { + get ['a']() { + throw new Error('should not be called'); + }, + get ['a']() { + throw new Error('should not be called'); + }, + get ['a']() { + return 'a'; + } +}; + +Assert.assertEquals(obj.a, 'a'); diff -r 8ced0dd94a6e -r 552748e3d506 nashorn/test/script/basic/es6/computed-property-getter.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/basic/es6/computed-property-getter.js Wed Jul 05 22:16:00 2017 +0200 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8164467: ES6 computed properties are implemented wrongly + * + * @test + * @run + * @option --language=es6 + */ + +function f(x) { + return x; +} + +var d = 'd'; +var n = 3; +var s1 = Symbol(); +var s2 = Symbol(); + +var object = { + get a() { return 'a' }, + get ['b']() { return 'b' }, + get [f('c')]() { return 'c' }, + get [d]() { return d }, + get [1]() { return 1 }, + get [f(2)]() { return 2 }, + get [n]() { return 3 }, + get [s1]() { return s1 }, + get [f(s2)]() { return s2 } +}; + + +Assert.assertEquals(object.a, 'a'); +Assert.assertEquals(object.b, 'b'); +Assert.assertEquals(object.c, 'c'); +Assert.assertEquals(object.d, 'd'); +Assert.assertEquals(object[1], 1); +Assert.assertEquals(object[2], 2); +Assert.assertEquals(object[3], 3); +Assert.assertEquals(object[s1], s1); +Assert.assertEquals(object[s2], s2); + +for (var s of ['a', 'b', 'c', 'd', 1, 2, 3, s1, s2]) { + Assert.assertEquals(object[s], s); +} diff -r 8ced0dd94a6e -r 552748e3d506 nashorn/test/script/basic/es6/computed-property-method.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/basic/es6/computed-property-method.js Wed Jul 05 22:16:00 2017 +0200 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8164467: ES6 computed properties are implemented wrongly + * + * @test + * @run + * @option --language=es6 + */ + +function f(x) { + return x; +} + +var d = 'd'; +var n = 3; +var s1 = Symbol(); +var s2 = Symbol(); + +var object = { + a() { return 'a' }, + ['b']() { return 'b' }, + [f('c')]() { return 'c' }, + [d]() { return d }, + [1]() { return 1 }, + [f(2)]() { return 2 }, + [n]() { return 3 }, + [s1]() { return s1 }, + [f(s2)]() { return s2 } +}; + + +Assert.assertEquals(object.a(), 'a'); +Assert.assertEquals(object.b(), 'b'); +Assert.assertEquals(object.c(), 'c'); +Assert.assertEquals(object.d(), 'd'); +Assert.assertEquals(object[1](), 1); +Assert.assertEquals(object[2](), 2); +Assert.assertEquals(object[3](), 3); +Assert.assertEquals(object[s1](), s1); +Assert.assertEquals(object[s2](), s2); + +for (var s of ['a', 'b', 'c', 'd', 1, 2, 3, s1, s2]) { + Assert.assertEquals(object[s](), s); +} diff -r 8ced0dd94a6e -r 552748e3d506 nashorn/test/script/basic/es6/computed-property-number.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/basic/es6/computed-property-number.js Wed Jul 05 22:16:00 2017 +0200 @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8164467: ES6 computed properties are implemented wrongly + * + * @test + * @run + * @option --language=es6 + */ + +function f(x) { + return x; +} + +var object = { + [1.5]: 'a', + get [f(1e+40)]() { return 'b' }, + [0.0001]: 'c', + [-0]: 'd', + [Infinity]: 'e', + [-Infinity]: 'f', + [NaN]: 'g' + +}; + + +Assert.assertEquals(object['1.5'], 'a'); +Assert.assertEquals(object['1e+40'], 'b'); +Assert.assertEquals(object['0.0001'], 'c'); +Assert.assertEquals(object[0], 'd'); +Assert.assertEquals(object[Infinity], 'e'); +Assert.assertEquals(object[-Infinity], 'f'); +Assert.assertEquals(object[NaN], 'g'); diff -r 8ced0dd94a6e -r 552748e3d506 nashorn/test/script/basic/es6/computed-property-setter.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/basic/es6/computed-property-setter.js Wed Jul 05 22:16:00 2017 +0200 @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8164467: ES6 computed properties are implemented wrongly + * + * @test + * @run + * @option --language=es6 + */ + +var counter = 0; + +var obj = { + set ['a'](x) { + counter++; + } +}; + +obj.a = 'a'; +Assert.assertTrue(counter === 1); +obj.a = 'a'; +Assert.assertTrue(counter === 2); diff -r 8ced0dd94a6e -r 552748e3d506 nashorn/test/script/basic/es6/computed-property.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/basic/es6/computed-property.js Wed Jul 05 22:16:00 2017 +0200 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8164467: ES6 computed properties are implemented wrongly + * + * @test + * @run + * @option --language=es6 + */ + +function f(x) { + return x; +} + +var d = 'd'; +var n = 3; +var s1 = Symbol(); +var s2 = Symbol(); + +var object = { + a: 'a', + ['b']: 'b', + [f('c')]: 'c', + [d]: d, + [1]: 1, + [f(2)]: 2, + [n]: 3, + [s1]: s1, + [f(s2)]: s2 +}; + + +Assert.assertEquals(object.a, 'a'); +Assert.assertEquals(object.b, 'b'); +Assert.assertEquals(object.c, 'c'); +Assert.assertEquals(object.d, 'd'); +Assert.assertEquals(object[1], 1); +Assert.assertEquals(object[2], 2); +Assert.assertEquals(object[3], 3); +Assert.assertEquals(object[s1], s1); +Assert.assertEquals(object[s2], s2); + +for (var s of ['a', 'b', 'c', 'd', 1, 2, 3, s1, s2]) { + Assert.assertEquals(object[s], s); +} diff -r 8ced0dd94a6e -r 552748e3d506 nashorn/test/script/trusted/JDK-8006529.js --- a/nashorn/test/script/trusted/JDK-8006529.js Thu Sep 22 16:41:14 2016 +0000 +++ b/nashorn/test/script/trusted/JDK-8006529.js Wed Jul 05 22:16:00 2017 +0200 @@ -38,7 +38,7 @@ * We cannot use direct Java class (via dynalink bean linker) to Compiler * and FunctionNode because of package-access check and so reflective calls. */ - +var Reflector = Java.type("jdk.nashorn.test.models.Reflector"); var forName = java.lang.Class["forName(String)"]; var Parser = forName("jdk.nashorn.internal.parser.Parser").static var Compiler = forName("jdk.nashorn.internal.codegen.Compiler").static @@ -69,7 +69,11 @@ var lhsMethod = BinaryNode.class.getMethod("lhs") var binaryRhsMethod = BinaryNode.class.getMethod("rhs") var debugIdMethod = Debug.class.getMethod("id", java.lang.Object.class) -var compilePhases = CompilationPhases.class.getField("COMPILE_UPTO_BYTECODE").get(null); +var compilePhases = Reflector.get(CompilationPhases.class.getField("COMPILE_UPTO_BYTECODE"), null); + +function invoke(m, obj) { + return Reflector.invoke(m, obj); +} // These are method names of methods in FunctionNode class var allAssertionList = ['isVarArg', 'needsParentScope', 'needsCallee', 'hasScopeBlock', 'usesSelfSymbol', 'isSplit', 'hasEval', 'allVarsInScope', 'isStrict'] @@ -86,7 +90,7 @@ // returns functionNode.getBody().getStatements().get(0) function getFirstFunction(functionNode) { - var f = findFunction(getBodyMethod.invoke(functionNode)) + var f = findFunction(invoke(getBodyMethod, functionNode)) if (f == null) { throw new Error(); } @@ -95,7 +99,7 @@ function findFunction(node) { if(node instanceof Block) { - var stmts = getStatementsMethod.invoke(node) + var stmts = invoke(getStatementsMethod, node) for(var i = 0; i < stmts.size(); ++i) { var retval = findFunction(stmts.get(i)) if(retval != null) { @@ -103,13 +107,13 @@ } } } else if(node instanceof VarNode) { - return findFunction(getInitMethod.invoke(node)) + return findFunction(invoke(getInitMethod, node)) } else if(node instanceof UnaryNode) { - return findFunction(rhsMethod.invoke(node)) + return findFunction(invoke(rhsMethod, node)) } else if(node instanceof BinaryNode) { - return findFunction(lhsMethod.invoke(node)) || findFunction(binaryRhsMethod.invoke(node)) + return findFunction(invoke(lhsMethod, node)) || findFunction(invoke(binaryRhsMethod, node)) } else if(node instanceof ExpressionStatement) { - return findFunction(getExpressionMethod.invoke(node)) + return findFunction(invoke(getExpressionMethod, node)) } else if(node instanceof FunctionNode) { return node } @@ -131,12 +135,12 @@ var ctxt = getContextMethod.invoke(null); var env = getEnvMethod.invoke(ctxt); - var parser = ParserConstructor.newInstance(env, source, ThrowErrorManager.class.newInstance()); - var func = parseMethod.invoke(parser); + var parser = Reflector.newInstance(ParserConstructor, env, source, ThrowErrorManager.class.newInstance()); + var func = invoke(parseMethod, parser); - var compiler = CompilerConstructor.invoke(null, ctxt, source, false); + var compiler = Reflector.invoke(CompilerConstructor, null, ctxt, source, false); - return compileMethod.invoke(compiler, func, phases); + return Reflector.invoke(compileMethod, compiler, func, phases); }; var allAssertions = (function() { @@ -161,9 +165,10 @@ } for(var assertion in allAssertions) { var expectedValue = !!assertions[assertion] - var actualValue = functionNodeMethods[assertion].invoke(f) + var actualValue = invoke(functionNodeMethods[assertion], f) if(actualValue !== expectedValue) { - throw "Expected " + assertion + " === " + expectedValue + ", got " + actualValue + " for " + f + ":" + debugIdMethod.invoke(null, f); + throw "Expected " + assertion + " === " + expectedValue + ", got " + actualValue + " for " + f + ":" + + invoke(debugIdMethod, null, f); } } } diff -r 8ced0dd94a6e -r 552748e3d506 nashorn/test/script/trusted/event_queue.js --- a/nashorn/test/script/trusted/event_queue.js Thu Sep 22 16:41:14 2016 +0000 +++ b/nashorn/test/script/trusted/event_queue.js Wed Jul 05 22:16:00 2017 +0200 @@ -36,6 +36,7 @@ print(Debug); print(); +var Reflector = Java.type("jdk.nashorn.test.models.Reflector"); var forName = java.lang.Class["forName(String)"]; var RuntimeEvent = forName("jdk.nashorn.internal.runtime.events.RuntimeEvent").static; var getValue = RuntimeEvent.class.getMethod("getValue"); @@ -84,19 +85,19 @@ var e = events[i]; print("event #" + i); print("\tevent class=" + e.getClass()); - print("\tvalueClass in event=" + getValueClass.invoke(e)); - var v = getValue.invoke(e); + print("\tvalueClass in event=" + Reflector.invoke(getValueClass, e)); + var v = Reflector.invoke(getValue, e); print("\tclass of value=" + v.getClass()); - print("\treturn type=" + getReturnType.invoke(v)); + print("\treturn type=" + Reflector.invoke(getReturnType, v)); lastInLoop = events[i]; } print(); print("in loop last class = " + lastInLoop.getClass()); -print("in loop last value class = " + getValueClass.invoke(lastInLoop)); -var rexInLoop = getValue.invoke(lastInLoop); +print("in loop last value class = " + Reflector.invoke(getValueClass, lastInLoop)); +var rexInLoop = Reflector.invoke(getValue, lastInLoop); print("in loop rex class = " + rexInLoop.getClass()); -print("in loop rex return type = " + getReturnType.invoke(rexInLoop)); +print("in loop rex return type = " + Reflector.invoke(getReturnType, rexInLoop)); //try last runtime events var last = Debug.getLastRuntimeEvent(); @@ -106,10 +107,10 @@ print(); print("last class = " + last.getClass()); -print("last value class = " + getValueClass.invoke(last)); -var rex = getValue.invoke(last); +print("last value class = " + Reflector.invoke(getValueClass, last)); +var rex = Reflector.invoke(getValue, last); print("rex class = " + rex.getClass()); -print("rex return type = " + getReturnType.invoke(rex)); +print("rex return type = " + Reflector.invoke(getReturnType, rex)); //try the capacity setter print(); diff -r 8ced0dd94a6e -r 552748e3d506 nashorn/test/script/trusted/optimistic_recompilation.js --- a/nashorn/test/script/trusted/optimistic_recompilation.js Thu Sep 22 16:41:14 2016 +0000 +++ b/nashorn/test/script/trusted/optimistic_recompilation.js Wed Jul 05 22:16:00 2017 +0200 @@ -32,6 +32,7 @@ * @run */ +var Reflector = Java.type("jdk.nashorn.test.models.Reflector"); var forName = java.lang.Class["forName(String)"]; var RuntimeEvent = forName("jdk.nashorn.internal.runtime.events.RuntimeEvent").static; var getValue = RuntimeEvent.class.getMethod("getValue"); @@ -42,6 +43,10 @@ var setReturnTypeAndValue = []; var expectedValues = []; +function invoke(m, obj) { + return Reflector.invoke(m, obj); +} + function checkExpectedRecompilation(f, expectedValues, testCase) { Debug.clearRuntimeEvents(); print(f()); @@ -51,12 +56,12 @@ if (events.length == expectedValues.length) { for (var i in events) { var e = events[i]; - var returnValue = getReturnValue.invoke(e); + var returnValue = invoke(getReturnValue, e); if (typeof returnValue != 'undefined') { - setReturnTypeAndValue[i] = [getReturnType.invoke(getValue.invoke(e)), returnValue]; + setReturnTypeAndValue[i] = [invoke(getReturnType, invoke(getValue, e)), returnValue]; } else { returnValue = "undefined"; - setReturnTypeAndValue[i] = [getReturnType.invoke(getValue.invoke(e)), returnValue]; + setReturnTypeAndValue[i] = [invoke(getReturnType, invoke(getValue, e)), returnValue]; } if (!setReturnTypeAndValue[i].toString().equals(expectedValues[i].toString())) { fail("The return values are not as expected. Expected value: " + expectedValues[i] + " and got: " + setReturnTypeAndValue[i] + " in test case: " + f); diff -r 8ced0dd94a6e -r 552748e3d506 nashorn/test/src/jdk/nashorn/test/models/Reflector.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/src/jdk/nashorn/test/models/Reflector.java Wed Jul 05 22:16:00 2017 +0200 @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.test.models; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Module; +import jdk.nashorn.internal.runtime.Context; + +/** + * Few tests reflectively invoke or read fields of Nashorn classes + * and objects - but of packages that are not exported to any module! + * But, those packages are qualified exported to test [java] code + * such as this class. So, test scripts can invoke the methods of this + * class instead. + */ +public final class Reflector { + private Reflector() {} + private static final Module NASHORN_MOD = Context.class.getModule(); + + public static Object invoke(Method m, Object self, Object...args) { + if (m.getDeclaringClass().getModule() != NASHORN_MOD) { + throw new RuntimeException(m + " is not from Nashorn module"); + } + + try { + return m.invoke(self, args); + } catch (final Exception e) { + if (e instanceof RuntimeException) { + throw (RuntimeException)e; + } else { + throw new RuntimeException(e); + } + } + } + + public static Object newInstance(Constructor c, Object...args) { + if (c.getDeclaringClass().getModule() != NASHORN_MOD) { + throw new RuntimeException(c + " is not from Nashorn module"); + } + + try { + return c.newInstance(args); + } catch (final Exception e) { + if (e instanceof RuntimeException) { + throw (RuntimeException)e; + } else { + throw new RuntimeException(e); + } + } + } + + public static Object get(Field f, Object self) { + if (f.getDeclaringClass().getModule() != NASHORN_MOD) { + throw new RuntimeException(f + " is not from Nashorn module"); + } + + try { + return f.get(self); + } catch (final Exception e) { + if (e instanceof RuntimeException) { + throw (RuntimeException)e; + } else { + throw new RuntimeException(e); + } + } + } +} diff -r 8ced0dd94a6e -r 552748e3d506 test/failure_handler/src/share/classes/jdk/test/failurehandler/jtreg/GatherDiagnosticInfoObserver.java --- a/test/failure_handler/src/share/classes/jdk/test/failurehandler/jtreg/GatherDiagnosticInfoObserver.java Thu Sep 22 16:41:14 2016 +0000 +++ b/test/failure_handler/src/share/classes/jdk/test/failurehandler/jtreg/GatherDiagnosticInfoObserver.java Wed Jul 05 22:16:00 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,8 +26,7 @@ import com.sun.javatest.Harness; import com.sun.javatest.Parameters; import com.sun.javatest.TestResult; -import com.sun.javatest.regtest.RegressionParameters; -import com.sun.javatest.regtest.OS; +import com.sun.javatest.InterviewParameters; import jdk.test.failurehandler.*; import java.io.File; @@ -119,7 +118,7 @@ @Override public void startingTestRun(Parameters params) { // TODO find a better way to get JDKs - RegressionParameters rp = (RegressionParameters) params; + InterviewParameters rp = (InterviewParameters) params; Map,?> map = new HashMap<>(); rp.save(map); compileJdk = (String) map.get("regtest.compilejdk"); diff -r 8ced0dd94a6e -r 552748e3d506 test/failure_handler/src/share/classes/jdk/test/failurehandler/jtreg/GatherProcessInfoTimeoutHandler.java --- a/test/failure_handler/src/share/classes/jdk/test/failurehandler/jtreg/GatherProcessInfoTimeoutHandler.java Thu Sep 22 16:41:14 2016 +0000 +++ b/test/failure_handler/src/share/classes/jdk/test/failurehandler/jtreg/GatherProcessInfoTimeoutHandler.java Wed Jul 05 22:16:00 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ package jdk.test.failurehandler.jtreg; -import com.sun.javatest.regtest.OS; import com.sun.javatest.regtest.TimeoutHandler; import jdk.test.failurehandler.*; diff -r 8ced0dd94a6e -r 552748e3d506 test/failure_handler/src/share/classes/jdk/test/failurehandler/jtreg/OS.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/failure_handler/src/share/classes/jdk/test/failurehandler/jtreg/OS.java Wed Jul 05 22:16:00 2017 +0200 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.test.failurehandler.jtreg; + +// Stripped down version of jtreg internal class com.sun.javatest.regtest.config.OS +class OS { + public final String family; + + private static OS current; + + public static OS current() { + if (current == null) { + String name = System.getProperty("os.name"); + current = new OS(name); + } + return current; + } + + private OS(String name) { + if (name.startsWith("Linux")) { + family = "linux"; + } else if (name.startsWith("Mac") || name.startsWith("Darwin")) { + family = "mac"; + } else if (name.startsWith("SunOS") || name.startsWith("Solaris")) { + family = "solaris"; + } else if (name.startsWith("Windows")) { + family = "windows"; + } else { + // use first word of name + family = name.replaceFirst("^([^ ]+).*", "$1"); + } + } +} + + diff -r 8ced0dd94a6e -r 552748e3d506 test/lib/jdk/test/lib/Platform.java --- a/test/lib/jdk/test/lib/Platform.java Thu Sep 22 16:41:14 2016 +0000 +++ b/test/lib/jdk/test/lib/Platform.java Wed Jul 05 22:16:00 2017 +0200 @@ -116,6 +116,14 @@ return (jdkDebug.toLowerCase().contains("debug")); } + public static boolean isSlowDebugBuild() { + return (jdkDebug.toLowerCase().equals("slowdebug")); + } + + public static boolean isFastDebugBuild() { + return (jdkDebug.toLowerCase().equals("fastdebug")); + } + public static String getVMVersion() { return vmVersion; } diff -r 8ced0dd94a6e -r 552748e3d506 test/lib/jdk/test/lib/unsafe/UnsafeHelper.java --- a/test/lib/jdk/test/lib/unsafe/UnsafeHelper.java Thu Sep 22 16:41:14 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.test.lib.unsafe; - -import jdk.internal.misc.Unsafe; -import java.lang.reflect.Field; - - -/** - * Helper class for accessing the jdk.internal.misc.Unsafe functionality - */ -public final class UnsafeHelper { - private static Unsafe unsafe = null; - - /** - * @return Unsafe instance. - */ - public static synchronized Unsafe getUnsafe() { - if (unsafe == null) { - try { - Field f = Unsafe.class.getDeclaredField("theUnsafe"); - f.setAccessible(true); - unsafe = (Unsafe) f.get(null); - } catch (NoSuchFieldException | IllegalAccessException e) { - throw new RuntimeException("Unable to get Unsafe instance.", e); - } - } - return unsafe; - } -} -