--- a/.hgtags Wed Oct 26 15:46:13 2016 -0400
+++ b/.hgtags Wed Oct 26 20:13:29 2016 +0000
@@ -382,3 +382,5 @@
9cb87c88ed851c0575b8ead753ea238ed5b544e9 jdk-9+137
d273dfe9a126d3bffe92072547fef2cd1361b0eb jdk-9+138
65477538bec32963dc41153d89c4417eb46c45fc jdk-9+139
+0875007901f7d364a08220b052f0c81003e9c8c5 jdk-9+140
+9aadd2163b568d76f8969ad2fb404a63733da359 jdk-9+141
--- a/.hgtags-top-repo Wed Oct 26 15:46:13 2016 -0400
+++ b/.hgtags-top-repo Wed Oct 26 20:13:29 2016 +0000
@@ -382,3 +382,5 @@
d7f519b004254b19e384131d9f0d0e40e31a0fd3 jdk-9+137
67c4388142bdf58aec8fefa4475faaa8a5d7380c jdk-9+138
7dcf453eacae79ee86a6bcc75fd0b546fc99b48a jdk-9+139
+a5815c6098a241d3a1df64d22b84b3524e4a77df jdk-9+140
+f64afae7f1a5608e438585bbf0bc23785e69cba0 jdk-9+141
--- a/common/autoconf/basics.m4 Wed Oct 26 15:46:13 2016 -0400
+++ b/common/autoconf/basics.m4 Wed Oct 26 20:13:29 2016 +0000
@@ -428,9 +428,10 @@
# Call BASIC_SETUP_TOOL with AC_PATH_PROGS to locate the tool
# $1: variable to set
# $2: executable name (or list of names) to look for
+# $3: [path]
AC_DEFUN([BASIC_PATH_PROGS],
[
- BASIC_SETUP_TOOL($1, [AC_PATH_PROGS($1, $2)])
+ BASIC_SETUP_TOOL($1, [AC_PATH_PROGS($1, $2, , $3)])
])
# Call BASIC_SETUP_TOOL with AC_CHECK_TOOLS to locate the tool
@@ -444,9 +445,10 @@
# Like BASIC_PATH_PROGS but fails if no tool was found.
# $1: variable to set
# $2: executable name (or list of names) to look for
+# $3: [path]
AC_DEFUN([BASIC_REQUIRE_PROGS],
[
- BASIC_PATH_PROGS($1, $2)
+ BASIC_PATH_PROGS($1, $2, , $3)
BASIC_CHECK_NONEMPTY($1)
])
@@ -1065,7 +1067,9 @@
BASIC_PATH_PROGS(HG, hg)
BASIC_PATH_PROGS(STAT, stat)
BASIC_PATH_PROGS(TIME, time)
- BASIC_PATH_PROGS(DTRACE, dtrace)
+ # Dtrace is usually found in /usr/sbin on Solaris, but that directory may not
+ # be in the user path.
+ BASIC_PATH_PROGS(DTRACE, dtrace, $PATH:/usr/sbin)
BASIC_PATH_PROGS(PATCH, [gpatch patch])
# Check if it's GNU time
IS_GNU_TIME=`$TIME --version 2>&1 | $GREP 'GNU time'`
--- a/common/autoconf/basics_windows.m4 Wed Oct 26 15:46:13 2016 -0400
+++ b/common/autoconf/basics_windows.m4 Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
--- a/common/autoconf/boot-jdk.m4 Wed Oct 26 15:46:13 2016 -0400
+++ b/common/autoconf/boot-jdk.m4 Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
--- a/common/autoconf/bootcycle-spec.gmk.in Wed Oct 26 15:46:13 2016 -0400
+++ b/common/autoconf/bootcycle-spec.gmk.in Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
--- a/common/autoconf/build-performance.m4 Wed Oct 26 15:46:13 2016 -0400
+++ b/common/autoconf/build-performance.m4 Wed Oct 26 20:13:29 2016 +0000
@@ -168,7 +168,6 @@
[AS_HELP_STRING([--enable-ccache],
[enable using ccache to speed up recompilations @<:@disabled@:>@])])
- CCACHE=
CCACHE_STATUS=
AC_MSG_CHECKING([is ccache enabled])
if test "x$enable_ccache" = xyes; then
--- a/common/autoconf/buildjdk-spec.gmk.in Wed Oct 26 15:46:13 2016 -0400
+++ b/common/autoconf/buildjdk-spec.gmk.in Wed Oct 26 20:13:29 2016 +0000
@@ -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
@@ -156,7 +156,3 @@
JVM_VARIANT_ZERO := false
JVM_VARIANT_ZEROSHARK := false
JVM_VARIANT_CORE := false
-
-# Sneak this in via the spec.gmk file, since we don't want to mess around too much with the Hotspot make files.
-# This is needed to get the LOG setting to work properly.
-include $(SRC_ROOT)/make/common/MakeBase.gmk
--- a/common/autoconf/compare.sh.in Wed Oct 26 15:46:13 2016 -0400
+++ b/common/autoconf/compare.sh.in Wed Oct 26 20:13:29 2016 +0000
@@ -1,6 +1,6 @@
#!/bin/bash
#
-# Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 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
--- a/common/autoconf/flags.m4 Wed Oct 26 15:46:13 2016 -0400
+++ b/common/autoconf/flags.m4 Wed Oct 26 20:13:29 2016 +0000
@@ -895,7 +895,7 @@
elif test "x$OPENJDK_$1_OS" = xsolaris; then
$2JVM_CFLAGS="[$]$2JVM_CFLAGS -DSOLARIS"
$2JVM_CFLAGS="[$]$2JVM_CFLAGS -template=no%extdef -features=no%split_init \
- -D_Crun_inline_placement -library=%none -KPIC -mt -xwe -features=no%except"
+ -D_Crun_inline_placement -library=%none -KPIC -mt -features=no%except"
elif test "x$OPENJDK_$1_OS" = xmacosx; then
$2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -D_ALLBSD_SOURCE -D_DARWIN_UNLIMITED_SELECT"
$2JVM_CFLAGS="[$]$2JVM_CFLAGS -D_ALLBSD_SOURCE"
--- a/common/autoconf/generated-configure.sh Wed Oct 26 15:46:13 2016 -0400
+++ b/common/autoconf/generated-configure.sh Wed Oct 26 20:13:29 2016 +0000
@@ -3657,6 +3657,7 @@
# Call BASIC_SETUP_TOOL with AC_PATH_PROGS to locate the tool
# $1: variable to set
# $2: executable name (or list of names) to look for
+# $3: [path]
# Call BASIC_SETUP_TOOL with AC_CHECK_TOOLS to locate the tool
@@ -3667,6 +3668,7 @@
# Like BASIC_PATH_PROGS but fails if no tool was found.
# $1: variable to set
# $2: executable name (or list of names) to look for
+# $3: [path]
# Like BASIC_SETUP_TOOL but fails if no tool was found.
@@ -3733,7 +3735,7 @@
#
-# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
@@ -3792,7 +3794,7 @@
# ... then the rest
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
@@ -4403,7 +4405,7 @@
#
-# 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
@@ -4498,7 +4500,7 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
@@ -4818,7 +4820,7 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
@@ -5091,7 +5093,7 @@
#CUSTOM_AUTOCONF_INCLUDE
# Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1475218974
+DATE_WHEN_GENERATED=1477108079
###############################################################################
#
@@ -22769,6 +22771,8 @@
fi
+ # Dtrace is usually found in /usr/sbin on Solaris, but that directory may not
+ # be in the user path.
# Publish this variable in the help.
@@ -22791,7 +22795,8 @@
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
+as_dummy="$PATH:/usr/sbin"
+for as_dir in $as_dummy
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
@@ -22849,7 +22854,8 @@
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
+as_dummy="$PATH:/usr/sbin"
+for as_dir in $as_dummy
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
@@ -50071,7 +50077,7 @@
elif test "x$OPENJDK_TARGET_OS" = xsolaris; then
JVM_CFLAGS="$JVM_CFLAGS -DSOLARIS"
JVM_CFLAGS="$JVM_CFLAGS -template=no%extdef -features=no%split_init \
- -D_Crun_inline_placement -library=%none -KPIC -mt -xwe -features=no%except"
+ -D_Crun_inline_placement -library=%none -KPIC -mt -features=no%except"
elif test "x$OPENJDK_TARGET_OS" = xmacosx; then
COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D_ALLBSD_SOURCE -D_DARWIN_UNLIMITED_SELECT"
JVM_CFLAGS="$JVM_CFLAGS -D_ALLBSD_SOURCE"
@@ -50886,7 +50892,7 @@
elif test "x$OPENJDK_BUILD_OS" = xsolaris; then
OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -DSOLARIS"
OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -template=no%extdef -features=no%split_init \
- -D_Crun_inline_placement -library=%none -KPIC -mt -xwe -features=no%except"
+ -D_Crun_inline_placement -library=%none -KPIC -mt -features=no%except"
elif test "x$OPENJDK_BUILD_OS" = xmacosx; then
OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -D_ALLBSD_SOURCE -D_DARWIN_UNLIMITED_SELECT"
OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -D_ALLBSD_SOURCE"
@@ -65239,7 +65245,6 @@
fi
- CCACHE=
CCACHE_STATUS=
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking is ccache enabled" >&5
$as_echo_n "checking is ccache enabled... " >&6; }
--- a/common/autoconf/jdk-version.m4 Wed Oct 26 15:46:13 2016 -0400
+++ b/common/autoconf/jdk-version.m4 Wed Oct 26 20:13:29 2016 +0000
@@ -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
--- a/common/autoconf/lib-bundled.m4 Wed Oct 26 15:46:13 2016 -0400
+++ b/common/autoconf/lib-bundled.m4 Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
--- a/common/autoconf/source-dirs.m4 Wed Oct 26 15:46:13 2016 -0400
+++ b/common/autoconf/source-dirs.m4 Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
--- a/common/autoconf/spec.gmk.in Wed Oct 26 15:46:13 2016 -0400
+++ b/common/autoconf/spec.gmk.in Wed Oct 26 20:13:29 2016 +0000
@@ -175,7 +175,7 @@
VERSION_STRING := @VERSION_STRING@
# The short version string, without trailing zeroes and just PRE, if present.
VERSION_SHORT := @VERSION_SHORT@
-# The Java specification version. It usually equals to the major version number.
+# The Java specification version. It usually equals the major version number.
VERSION_SPECIFICATION := @VERSION_MAJOR@
# A GA version is defined by the PRE string being empty. Rather than testing for
# that, this variable defines it with true/false.
@@ -244,9 +244,6 @@
# Only build headless support or not
ENABLE_HEADLESS_ONLY := @ENABLE_HEADLESS_ONLY@
-# Legacy support
-USE_NEW_HOTSPOT_BUILD:=@USE_NEW_HOTSPOT_BUILD@
-
# JDK_OUTPUTDIR specifies where a working jvm is built.
# You can run $(JDK_OUTPUTDIR)/bin/java
# Though the layout of the contents of $(JDK_OUTPUTDIR) is not
--- a/common/autoconf/version-numbers Wed Oct 26 15:46:13 2016 -0400
+++ b/common/autoconf/version-numbers Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
--- a/common/bin/compare_exceptions.sh.incl Wed Oct 26 15:46:13 2016 -0400
+++ b/common/bin/compare_exceptions.sh.incl Wed Oct 26 20:13:29 2016 +0000
@@ -1,6 +1,6 @@
#!/bin/bash
#
-# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 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
--- a/common/bin/hgforest.sh Wed Oct 26 15:46:13 2016 -0400
+++ b/common/bin/hgforest.sh Wed Oct 26 20:13:29 2016 +0000
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 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
--- a/common/bin/jib.sh Wed Oct 26 15:46:13 2016 -0400
+++ b/common/bin/jib.sh Wed Oct 26 20:13:29 2016 +0000
@@ -1,6 +1,6 @@
#!/bin/bash
#
-# 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
--- a/common/conf/jib-profiles.js Wed Oct 26 15:46:13 2016 -0400
+++ b/common/conf/jib-profiles.js Wed Oct 26 20:13:29 2016 +0000
@@ -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
@@ -287,7 +287,8 @@
target_os: "solaris",
target_cpu: "x64",
dependencies: concat(common.dependencies, "devkit", "cups"),
- configure_args: concat(common.configure_args, "--with-zlib=system"),
+ configure_args: concat(common.configure_args, "--with-zlib=system",
+ "--enable-dtrace"),
default_make_targets: common.default_make_targets
},
@@ -295,7 +296,8 @@
target_os: "solaris",
target_cpu: "sparcv9",
dependencies: concat(common.dependencies, "devkit", "cups"),
- configure_args: concat(common.configure_args, "--with-zlib=system"),
+ configure_args: concat(common.configure_args, "--with-zlib=system",
+ "--enable-dtrace"),
default_make_targets: common.default_make_targets
},
--- a/corba/.hgtags Wed Oct 26 15:46:13 2016 -0400
+++ b/corba/.hgtags Wed Oct 26 20:13:29 2016 +0000
@@ -382,3 +382,5 @@
258cf18fa7fc59359b874f8743b7168dc48baf73 jdk-9+137
27bb44be32076861a0951bcefb07a1d92509a4b6 jdk-9+138
8c9da7fc5b07c606afd571c7012441b77dda83b2 jdk-9+139
+9f3fc931bc230f44f2a58d75f7f6360af98bb113 jdk-9+140
+b32f998da32b488ec7c4e9dbb3c750841b48e74d jdk-9+141
--- a/corba/make/gensrc/Gensrc-java.corba.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/corba/make/gensrc/Gensrc-java.corba.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -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
--- a/corba/src/java.corba/share/classes/com/sun/corba/se/impl/io/IIOPInputStream.java Wed Oct 26 15:46:13 2016 -0400
+++ b/corba/src/java.corba/share/classes/com/sun/corba/se/impl/io/IIOPInputStream.java Wed Oct 26 20:13:29 2016 +0000
@@ -31,22 +31,17 @@
package com.sun.corba.se.impl.io;
-import java.io.InputStream;
import java.io.IOException;
import java.io.StreamCorruptedException;
import java.io.ObjectInputValidation;
import java.io.NotActiveException;
import java.io.InvalidObjectException;
import java.io.InvalidClassException;
-import java.io.DataInputStream;
import java.io.OptionalDataException;
-import java.io.WriteAbortedException;
import java.io.Externalizable;
import java.io.EOFException;
import java.lang.reflect.*;
import java.util.Vector;
-import java.util.Stack;
-import java.util.Hashtable;
import java.util.Enumeration;
import sun.corba.Bridge ;
@@ -54,7 +49,6 @@
import java.security.AccessController ;
import java.security.PrivilegedAction ;
-import com.sun.corba.se.impl.io.ObjectStreamClass;
import com.sun.corba.se.impl.util.Utility;
import org.omg.CORBA.portable.ValueInputStream;
@@ -71,14 +65,12 @@
import com.sun.org.omg.CORBA.ValueDefPackage.FullValueDescription;
import com.sun.org.omg.SendingContext.CodeBase;
-import javax.rmi.PortableRemoteObject;
import javax.rmi.CORBA.Util;
import javax.rmi.CORBA.ValueHandler;
import java.security.*;
import java.util.*;
-import com.sun.corba.se.impl.orbutil.ObjectUtility ;
import com.sun.corba.se.impl.logging.OMGSystemException ;
import com.sun.corba.se.impl.logging.UtilSystemException ;
@@ -182,75 +174,6 @@
private byte streamFormatVersion;
- // Since java.io.OptionalDataException's constructors are
- // package private, but we need to throw it in some special
- // cases, we try to do it by reflection.
- private static final Constructor OPT_DATA_EXCEPTION_CTOR;
-
- private Object[] readObjectArgList = { this } ;
-
- static {
- OPT_DATA_EXCEPTION_CTOR = getOptDataExceptionCtor();
- }
-
- // Grab the OptionalDataException boolean ctor and make
- // it accessible. Note that any exceptions
- // will be wrapped in ExceptionInInitializerErrors.
- private static Constructor getOptDataExceptionCtor() {
-
- try {
-
- Constructor result =
-
- (Constructor) AccessController.doPrivileged(
- new PrivilegedExceptionAction() {
- public java.lang.Object run()
- throws NoSuchMethodException,
- SecurityException {
-
- Constructor boolCtor
- = OptionalDataException.class.getDeclaredConstructor(
- new Class[] {
- Boolean.TYPE });
-
- boolCtor.setAccessible(true);
-
- return boolCtor;
- }});
-
- if (result == null)
- // XXX I18N, logging needed.
- throw new Error("Unable to find OptionalDataException constructor");
-
- return result;
-
- } catch (Exception ex) {
- // XXX I18N, logging needed.
- throw new ExceptionInInitializerError(ex);
- }
- }
-
- // Create a new OptionalDataException with the EOF marker
- // set to true. See handleOptionalDataMarshalException.
- private OptionalDataException createOptionalDataException() {
- try {
- OptionalDataException result
- = (OptionalDataException)
- OPT_DATA_EXCEPTION_CTOR.newInstance(new Object[] {
- Boolean.TRUE });
-
- if (result == null)
- // XXX I18N, logging needed.
- throw new Error("Created null OptionalDataException");
-
- return result;
-
- } catch (Exception ex) {
- // XXX I18N, logging needed.
- throw new Error("Couldn't create OptionalDataException", ex);
- }
- }
-
// Return the stream format version currently being used
// to deserialize an object
protected byte getStreamFormatVersion() {
@@ -395,7 +318,6 @@
int offset)
/* throws OptionalDataException, ClassNotFoundException, IOException */
{
-
/* Save the current state and get ready to read an object. */
Object prevObject = currentObject;
ObjectStreamClass prevClassDesc = currentClassDesc;
@@ -947,7 +869,7 @@
if (!objectRead)
result = new EOFException("No more optional data");
else
- result = createOptionalDataException();
+ result = bridge.newOptionalDataExceptionForSerialization(true);
result.initCause(marshalException);
@@ -1230,8 +1152,7 @@
readObjectState.beginUnmarshalCustomValue(this,
calledDefaultWriteObject,
- (currentClassDesc.readObjectMethod
- != null));
+ currentClassDesc.hasReadObject());
} else {
if (currentClassDesc.hasReadObject())
setState(IN_READ_OBJECT_REMOTE_NOT_CUSTOM_MARSHALED);
@@ -1556,8 +1477,7 @@
readObjectState.beginUnmarshalCustomValue(this,
calledDefaultWriteObject,
- (currentClassDesc.readObjectMethod
- != null));
+ currentClassDesc.hasReadObject());
}
boolean usedReadObject = false;
@@ -1714,13 +1634,8 @@
throws InvalidClassException, StreamCorruptedException,
ClassNotFoundException, IOException
{
- if (osc.readObjectMethod == null) {
- return false;
- }
-
try {
- osc.readObjectMethod.invoke( obj, readObjectArgList ) ;
- return true;
+ return osc.invokeReadObject( obj, this ) ;
} catch (InvocationTargetException e) {
Throwable t = e.getTargetException();
if (t instanceof ClassNotFoundException)
@@ -1734,8 +1649,6 @@
else
// XXX I18N, logging needed.
throw new Error("internal error");
- } catch (IllegalAccessException e) {
- return false;
}
}
--- a/corba/src/java.corba/share/classes/com/sun/corba/se/impl/io/IIOPOutputStream.java Wed Oct 26 15:46:13 2016 -0400
+++ b/corba/src/java.corba/share/classes/com/sun/corba/se/impl/io/IIOPOutputStream.java Wed Oct 26 20:13:29 2016 +0000
@@ -31,33 +31,23 @@
package com.sun.corba.se.impl.io;
-import org.omg.CORBA.INTERNAL;
import org.omg.CORBA.portable.OutputStream;
import java.security.AccessController ;
import java.security.PrivilegedAction ;
import java.io.IOException;
-import java.io.DataOutputStream;
-import java.io.Serializable;
import java.io.InvalidClassException;
-import java.io.StreamCorruptedException;
import java.io.Externalizable;
-import java.io.ObjectStreamException;
import java.io.NotSerializableException;
import java.io.NotActiveException;
import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Field;
-
-import java.util.Stack;
import javax.rmi.CORBA.Util;
-import javax.rmi.CORBA.ValueHandlerMultiFormat;
import sun.corba.Bridge ;
-import com.sun.corba.se.impl.io.ObjectStreamClass;
import com.sun.corba.se.impl.util.Utility;
import com.sun.corba.se.impl.util.RepositoryId;
@@ -621,7 +611,7 @@
writeObjectState.enterWriteObject(this);
// writeObject(obj, c, this);
- osc.writeObjectMethod.invoke( obj, writeObjectArgList ) ;
+ osc.invokeWriteObject( obj, this ) ;
writeObjectState.exitWriteObject(this);
@@ -636,8 +626,6 @@
else
// XXX I18N, Logging needed.
throw new Error("invokeObjectWriter internal error",e);
- } catch (IllegalAccessException e) {
- // cannot happen
}
}
@@ -761,59 +749,52 @@
*/
private void outputClassFields(Object o, Class cl,
ObjectStreamField[] fields)
- throws IOException, InvalidClassException {
+ throws IOException {
for (int i = 0; i < fields.length; i++) {
if (fields[i].getField() == null)
- // XXX I18N, Logging needed.
throw new InvalidClassException(cl.getName(),
"Nonexistent field " + fields[i].getName());
-
- try {
- switch (fields[i].getTypeCode()) {
- case 'B':
- byte byteValue = fields[i].getField().getByte( o ) ;
- orbStream.write_octet(byteValue);
- break;
- case 'C':
- char charValue = fields[i].getField().getChar( o ) ;
- orbStream.write_wchar(charValue);
- break;
- case 'F':
- float floatValue = fields[i].getField().getFloat( o ) ;
- orbStream.write_float(floatValue);
- break;
- case 'D' :
- double doubleValue = fields[i].getField().getDouble( o ) ;
- orbStream.write_double(doubleValue);
- break;
- case 'I':
- int intValue = fields[i].getField().getInt( o ) ;
- orbStream.write_long(intValue);
- break;
- case 'J':
- long longValue = fields[i].getField().getLong( o ) ;
- orbStream.write_longlong(longValue);
- break;
- case 'S':
- short shortValue = fields[i].getField().getShort( o ) ;
- orbStream.write_short(shortValue);
- break;
- case 'Z':
- boolean booleanValue = fields[i].getField().getBoolean( o ) ;
- orbStream.write_boolean(booleanValue);
- break;
- case '[':
- case 'L':
- Object objectValue = fields[i].getField().get( o ) ;
- writeObjectField(fields[i], objectValue);
- break;
- default:
- // XXX I18N, Logging needed.
- throw new InvalidClassException(cl.getName());
- }
- } catch (IllegalAccessException exc) {
- throw wrapper.illegalFieldAccess( exc, fields[i].getName() ) ;
+ switch (fields[i].getTypeCode()) {
+ case 'B':
+ byte byteValue = bridge.getByte(o, fields[i].getFieldID()) ;
+ orbStream.write_octet(byteValue);
+ break;
+ case 'C':
+ char charValue = bridge.getChar(o, fields[i].getFieldID()) ;
+ orbStream.write_wchar(charValue);
+ break;
+ case 'F':
+ float floatValue = bridge.getFloat(o, fields[i].getFieldID()) ;
+ orbStream.write_float(floatValue);
+ break;
+ case 'D' :
+ double doubleValue = bridge.getDouble(o, fields[i].getFieldID()) ;
+ orbStream.write_double(doubleValue);
+ break;
+ case 'I':
+ int intValue = bridge.getInt(o, fields[i].getFieldID()) ;
+ orbStream.write_long(intValue);
+ break;
+ case 'J':
+ long longValue = bridge.getLong(o, fields[i].getFieldID()) ;
+ orbStream.write_longlong(longValue);
+ break;
+ case 'S':
+ short shortValue = bridge.getShort(o, fields[i].getFieldID()) ;
+ orbStream.write_short(shortValue);
+ break;
+ case 'Z':
+ boolean booleanValue = bridge.getBoolean(o, fields[i].getFieldID()) ;
+ orbStream.write_boolean(booleanValue);
+ break;
+ case '[':
+ case 'L':
+ Object objectValue = bridge.getObject(o, fields[i].getFieldID()) ;
+ writeObjectField(fields[i], objectValue);
+ break;
+ default:
+ throw new InvalidClassException(cl.getName());
}
}
}
--- a/corba/src/java.corba/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java Wed Oct 26 15:46:13 2016 -0400
+++ b/corba/src/java.corba/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java Wed Oct 26 20:13:29 2016 +0000
@@ -31,16 +31,16 @@
package com.sun.corba.se.impl.io;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.lang.invoke.MethodHandle;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.DigestOutputStream;
import java.security.AccessController;
-import java.security.PrivilegedExceptionAction;
-import java.security.PrivilegedActionException;
import java.security.PrivilegedAction;
import java.lang.reflect.Modifier;
-import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
@@ -80,9 +80,6 @@
public static final long kDefaultUID = -1;
- private static Object noArgsList[] = {};
- private static Class<?> noTypesList[] = {};
-
/** true if represents enum type */
private boolean isEnum;
@@ -311,12 +308,37 @@
return null;
}
+ public final boolean invokeWriteObject(Object obj, ObjectOutputStream ois) throws InvocationTargetException {
+ if (!hasWriteObject()) {
+ return false;
+ }
+ try {
+ writeObjectMethod.invoke(obj, ois);
+ } catch (Throwable t) {
+ throw new InvocationTargetException(t, "writeObject");
+ }
+ return true;
+ }
+
+ public final boolean invokeReadObject(Object obj, ObjectInputStream ois) throws InvocationTargetException {
+ if (hasReadObject()) {
+ try {
+ readObjectMethod.invoke(obj, ois);
+ return true;
+ } catch (Throwable t) {
+ throw new InvocationTargetException(t, "readObject");
+ }
+ } else {
+ return false;
+ }
+ }
+
public Serializable writeReplace(Serializable value) {
if (writeReplaceObjectMethod != null) {
try {
- return (Serializable) writeReplaceObjectMethod.invoke(value,noArgsList);
- } catch(Throwable t) {
- throw new RuntimeException(t);
+ return (Serializable) writeReplaceObjectMethod.invoke(value);
+ } catch (Throwable t) {
+ throw new InternalError("unexpected error", t);
}
}
else return value;
@@ -325,9 +347,9 @@
public Object readResolve(Object value) {
if (readResolveObjectMethod != null) {
try {
- return readResolveObjectMethod.invoke(value,noArgsList);
- } catch(Throwable t) {
- throw new RuntimeException(t);
+ return readResolveObjectMethod.invoke(value);
+ } catch (Throwable t) {
+ throw new InternalError("unexpected error", t);
}
}
else return value;
@@ -382,31 +404,34 @@
*/
}
- private static final class PersistentFieldsValue
+ static final class PersistentFieldsValue
extends ClassValue<ObjectStreamField[]> {
PersistentFieldsValue() { }
protected ObjectStreamField[] computeValue(Class<?> type) {
try {
+ bridge.ensureClassInitialized(type);
Field pf = type.getDeclaredField("serialPersistentFields");
int mods = pf.getModifiers();
if (Modifier.isPrivate(mods) && Modifier.isStatic(mods) &&
Modifier.isFinal(mods)) {
- pf.setAccessible(true);
+ long offset = bridge.staticFieldOffset(pf);
java.io.ObjectStreamField[] fields =
- (java.io.ObjectStreamField[])pf.get(type);
+ (java.io.ObjectStreamField[])bridge.getObject(type, offset);
return translateFields(fields);
}
- } catch (NoSuchFieldException | IllegalAccessException |
+ } catch (NoSuchFieldException |
IllegalArgumentException | ClassCastException e) {
}
return null;
}
- private static ObjectStreamField[] translateFields(
- java.io.ObjectStreamField[] fields) {
+ private static ObjectStreamField[] translateFields(java.io.ObjectStreamField[] fields) {
+ if (fields == null) {
+ return null;
+ }
ObjectStreamField[] translation =
- new ObjectStreamField[fields.length];
+ new ObjectStreamField[fields.length];
for (int i = 0; i < fields.length; i++) {
translation[i] = new ObjectStreamField(fields[i].getName(),
fields[i].getType());
@@ -450,13 +475,11 @@
* If it is declared, use the declared serialPersistentFields.
* Otherwise, extract the fields from the class itself.
*/
- fields = persistentFieldsValue.get(cl);
+ fields = persistentFieldsValue.get(cl);
if (fields == null) {
- /* Get all of the declared fields for this
- * Class. setAccessible on all fields so they
- * can be accessed later. Create a temporary
- * ObjectStreamField array to hold each
+ /* Get all of the declared fields for this Class.
+ * Create a temporary ObjectStreamField array to hold each
* non-static, non-transient field. Then copy the
* temporary array into an array of the correct
* size once the number of fields is known.
@@ -471,7 +494,6 @@
int modifiers = fld.getModifiers();
if (!Modifier.isStatic(modifiers) &&
!Modifier.isTransient(modifiers)) {
- fld.setAccessible(true) ;
tempFields[numFields++] = new ObjectStreamField(fld);
}
}
@@ -487,7 +509,6 @@
try {
Field reflField = cl.getDeclaredField(fields[j].getName());
if (fields[j].getType() == reflField.getType()) {
- reflField.setAccessible(true);
fields[j].setField(reflField);
}
} catch (NoSuchFieldException e) {
@@ -527,8 +548,8 @@
int mods = f.getModifiers();
// SerialBug 5: static final SUID should be read
if (Modifier.isStatic(mods) && Modifier.isFinal(mods) ) {
- f.setAccessible(true);
- suid = f.getLong(cl);
+ long offset = bridge.staticFieldOffset(f);
+ suid = bridge.getLong(cl, offset);
// SerialBug 2: should be computed after writeObject
// actualSuid = computeStructuralUID(cl);
} else {
@@ -540,16 +561,12 @@
suid = _computeSerialVersionUID(cl);
// SerialBug 2: should be computed after writeObject
// actualSuid = computeStructuralUID(cl);
- } catch (IllegalAccessException ex) {
- suid = _computeSerialVersionUID(cl);
}
}
- writeReplaceObjectMethod = ObjectStreamClass.getInheritableMethod(cl,
- "writeReplace", noTypesList, Object.class);
+ writeReplaceObjectMethod = bridge.writeReplaceForSerialization(cl);
- readResolveObjectMethod = ObjectStreamClass.getInheritableMethod(cl,
- "readResolve", noTypesList, Object.class);
+ readResolveObjectMethod = bridge.readResolveForSerialization(cl);
if (externalizable)
cons = getExternalizableConstructor(cl) ;
@@ -557,14 +574,8 @@
cons = getSerializableConstructor(cl) ;
if (serializable && !forProxyClass) {
- /* Look for the writeObject method
- * Set the accessible flag on it here. ObjectOutputStream
- * will call it as necessary.
- */
- writeObjectMethod = getPrivateMethod( cl, "writeObject",
- new Class<?>[] { java.io.ObjectOutputStream.class }, Void.TYPE ) ;
- readObjectMethod = getPrivateMethod( cl, "readObject",
- new Class<?>[] { java.io.ObjectInputStream.class }, Void.TYPE ) ;
+ writeObjectMethod = bridge.writeObjectForSerialization(cl) ;
+ readObjectMethod = bridge.readObjectForSerialization(cl);
}
return null;
}
@@ -585,27 +596,6 @@
}
}
- /**
- * Returns non-static private method with given signature defined by given
- * class, or null if none found. Access checks are disabled on the
- * returned method (if any).
- */
- private static Method getPrivateMethod(Class<?> cl, String name,
- Class<?>[] argTypes,
- Class<?> returnType)
- {
- try {
- Method meth = cl.getDeclaredMethod(name, argTypes);
- meth.setAccessible(true);
- int mods = meth.getModifiers();
- return ((meth.getReturnType() == returnType) &&
- ((mods & Modifier.STATIC) == 0) &&
- ((mods & Modifier.PRIVATE) != 0)) ? meth : null;
- } catch (NoSuchMethodException ex) {
- return null;
- }
- }
-
// Specific to RMI-IIOP
/**
* Java to IDL ptc-02-01-12 1.5.1
@@ -849,6 +839,22 @@
}
/**
+ * Returns true if represented class is serializable or externalizable and
+ * defines a conformant writeReplace method. Otherwise, returns false.
+ */
+ boolean hasWriteReplaceMethod() {
+ return (writeReplaceObjectMethod != null);
+ }
+
+ /**
+ * Returns true if represented class is serializable or externalizable and
+ * defines a conformant readResolve method. Otherwise, returns false.
+ */
+ boolean hasReadResolveMethod() {
+ return (readResolveObjectMethod != null);
+ }
+
+ /**
* Returns when or not this class should be custom
* marshaled (use chunking). This should happen if
* it is Externalizable OR if it or
@@ -904,7 +910,7 @@
{
if (cons != null) {
try {
- return cons.newInstance(new Object[0]);
+ return cons.newInstance();
} catch (IllegalAccessException ex) {
// should not occur, as access checks have been suppressed
InternalError ie = new InternalError();
@@ -912,7 +918,7 @@
throw ie ;
}
} else {
- throw new UnsupportedOperationException();
+ throw new UnsupportedOperationException("no constructor for " + ofClass);
}
}
@@ -921,15 +927,8 @@
* Access checks are disabled on the returned constructor (if any), since
* the defining class may still be non-public.
*/
- private static Constructor getExternalizableConstructor(Class<?> cl) {
- try {
- Constructor cons = cl.getDeclaredConstructor(new Class<?>[0]);
- cons.setAccessible(true);
- return ((cons.getModifiers() & Modifier.PUBLIC) != 0) ?
- cons : null;
- } catch (NoSuchMethodException ex) {
- return null;
- }
+ private static Constructor<?> getExternalizableConstructor(Class<?> cl) {
+ return bridge.newConstructorForExternalization(cl);
}
/**
@@ -937,28 +936,8 @@
* superclass, or null if none found. Access checks are disabled on the
* returned constructor (if any).
*/
- private static Constructor getSerializableConstructor(Class<?> cl) {
- Class<?> initCl = cl;
- while (Serializable.class.isAssignableFrom(initCl)) {
- if ((initCl = initCl.getSuperclass()) == null) {
- return null;
- }
- }
- try {
- Constructor cons = initCl.getDeclaredConstructor(new Class<?>[0]);
- int mods = cons.getModifiers();
- if ((mods & Modifier.PRIVATE) != 0 ||
- ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0 &&
- !packageEquals(cl, initCl)))
- {
- return null;
- }
- cons = bridge.newConstructorForSerialization(cl, cons);
- cons.setAccessible(true);
- return cons;
- } catch (NoSuchMethodException ex) {
- return null;
- }
+ private static Constructor<?> getSerializableConstructor(Class<?> cl) {
+ return bridge.newConstructorForSerialization(cl);
}
/*
@@ -1522,11 +1501,11 @@
* @since JDK 1.2
*/
private boolean hasExternalizableBlockData;
- Method writeObjectMethod;
- Method readObjectMethod;
- private transient Method writeReplaceObjectMethod;
- private transient Method readResolveObjectMethod;
- private Constructor cons ;
+ private transient MethodHandle writeObjectMethod;
+ private transient MethodHandle readObjectMethod;
+ private transient MethodHandle writeReplaceObjectMethod;
+ private transient MethodHandle readResolveObjectMethod;
+ private transient Constructor<?> cons;
/**
* Beginning in Java to IDL ptc/02-01-12, RMI-IIOP has a
@@ -1543,44 +1522,12 @@
*/
private ObjectStreamClass localClassDesc;
- /* Find out if the class has a static class initializer <clinit> */
- private static Method hasStaticInitializerMethod = null;
/**
* Returns true if the given class defines a static initializer method,
* false otherwise.
*/
private static boolean hasStaticInitializer(Class<?> cl) {
- if (hasStaticInitializerMethod == null) {
- Class<?> classWithThisMethod = null;
-
- try {
- if (classWithThisMethod == null)
- classWithThisMethod = java.io.ObjectStreamClass.class;
-
- hasStaticInitializerMethod =
- classWithThisMethod.getDeclaredMethod("hasStaticInitializer",
- new Class<?>[] { Class.class });
- } catch (NoSuchMethodException ex) {
- }
-
- if (hasStaticInitializerMethod == null) {
- // XXX I18N, logging needed
- throw new InternalError("Can't find hasStaticInitializer method on "
- + classWithThisMethod.getName());
- }
- hasStaticInitializerMethod.setAccessible(true);
- }
-
- try {
- Boolean retval = (Boolean)
- hasStaticInitializerMethod.invoke(null, new Object[] { cl });
- return retval.booleanValue();
- } catch (Exception ex) {
- // XXX I18N, logging needed
- InternalError ie = new InternalError( "Error invoking hasStaticInitializer" ) ;
- ie.initCause( ex ) ;
- throw ie ;
- }
+ return bridge.hasStaticInitializerForSerialization(cl);
}
@@ -1754,7 +1701,6 @@
if ((meth == null) || (meth.getReturnType() != returnType)) {
return null;
}
- meth.setAccessible(true);
int mods = meth.getModifiers();
if ((mods & (Modifier.STATIC | Modifier.ABSTRACT)) != 0) {
return null;
--- a/corba/src/java.corba/share/classes/module-info.java Wed Oct 26 15:46:13 2016 -0400
+++ b/corba/src/java.corba/share/classes/module-info.java Wed Oct 26 20:13:29 2016 +0000
@@ -32,6 +32,7 @@
requires java.logging;
requires java.naming;
requires java.transaction;
+ requires jdk.unsupported;
exports javax.activity;
exports javax.rmi;
--- a/corba/src/java.corba/share/classes/sun/corba/Bridge.java Wed Oct 26 15:46:13 2016 -0400
+++ b/corba/src/java.corba/share/classes/sun/corba/Bridge.java Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 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
@@ -25,25 +25,24 @@
package sun.corba ;
+import java.io.OptionalDataException;
+import java.lang.invoke.MethodHandle;
import java.lang.reflect.Field ;
-import java.lang.reflect.Method ;
import java.lang.reflect.Constructor ;
-import java.lang.reflect.InvocationTargetException ;
-
-import java.io.ObjectInputStream ;
import java.security.AccessController;
import java.security.Permission;
import java.security.PrivilegedAction;
-import jdk.internal.misc.Unsafe ;
-import jdk.internal.reflect.ReflectionFactory;
+import sun.misc.Unsafe;
+import sun.reflect.ReflectionFactory;
/** This class provides the methods for fundamental JVM operations
* needed in the ORB that are not part of the public Java API. This includes:
* <ul>
* <li>throwException, which can throw undeclared checked exceptions.
- * This is needed to handle throwing arbitrary exceptions across a standardized OMG interface that (incorrectly) does not specify appropriate exceptions.</li>
+ * This is needed to handle throwing arbitrary exceptions across a standardized
+ * OMG interface that (incorrectly) does not specify appropriate exceptions.</li>
* <li>putXXX/getXXX methods that allow unchecked access to fields of objects.
* This is used for setting uninitialzed non-static final fields (which is
* impossible with reflection) and for speed.</li>
@@ -71,88 +70,28 @@
*/
public final class Bridge
{
- private static final Class[] NO_ARGS = new Class[] {};
private static final Permission getBridgePermission =
- new BridgePermission( "getBridge" ) ;
+ new BridgePermission("getBridge");
private static Bridge bridge = null ;
- // latestUserDefinedLoader() is a private static method
- // in ObjectInputStream in JDK 1.3 through 1.5.
- // We use reflection in a doPrivileged block to get a
- // Method reference and make it accessible.
- private final Method latestUserDefinedLoaderMethod ;
- private final Unsafe unsafe ;
- private final ReflectionFactory reflectionFactory ;
+ /** Access to Unsafe to read/write fields. */
+ private static final Unsafe unsafe = AccessController.doPrivileged(
+ (PrivilegedAction<Unsafe>)() -> {
+ try {
+ Field field = Unsafe.class.getDeclaredField("theUnsafe");
+ field.setAccessible(true);
+ return (Unsafe)field.get(null);
- private Method getLatestUserDefinedLoaderMethod()
- {
- return (Method) AccessController.doPrivileged(
- new PrivilegedAction()
- {
- public Object run()
- {
- Method result = null;
-
- try {
- Class io = ObjectInputStream.class;
- result = io.getDeclaredMethod(
- "latestUserDefinedLoader", NO_ARGS);
- result.setAccessible(true);
- } catch (NoSuchMethodException nsme) {
- Error err = new Error( "java.io.ObjectInputStream" +
- " latestUserDefinedLoader " + nsme );
- err.initCause(nsme) ;
- throw err ;
- }
-
- return result;
+ } catch (NoSuchFieldException |IllegalAccessException ex) {
+ throw new InternalError("Unsafe.theUnsafe field not available", ex);
}
}
- );
- }
-
- private Unsafe getUnsafe() {
- Field fld = (Field)AccessController.doPrivileged(
- new PrivilegedAction()
- {
- public Object run()
- {
- Field fld = null ;
+ ) ;
- try {
- Class unsafeClass = jdk.internal.misc.Unsafe.class ;
- fld = unsafeClass.getDeclaredField( "theUnsafe" ) ;
- fld.setAccessible( true ) ;
- return fld ;
- } catch (NoSuchFieldException exc) {
- Error err = new Error( "Could not access Unsafe" ) ;
- err.initCause( exc ) ;
- throw err ;
- }
- }
- }
- ) ;
-
- Unsafe unsafe = null;
+ private final ReflectionFactory reflectionFactory ;
- try {
- unsafe = (Unsafe)(fld.get( null )) ;
- } catch (Throwable t) {
- Error err = new Error( "Could not access Unsafe" ) ;
- err.initCause( t ) ;
- throw err ;
- }
-
- return unsafe ;
- }
-
-
- private Bridge()
- {
- latestUserDefinedLoaderMethod = getLatestUserDefinedLoaderMethod();
- unsafe = getUnsafe() ;
- reflectionFactory = (ReflectionFactory)AccessController.doPrivileged(
- new ReflectionFactory.GetReflectionFactoryAction());
+ private Bridge() {
+ reflectionFactory = ReflectionFactory.getReflectionFactory();
}
/** Fetch the Bridge singleton. This requires the following
@@ -182,23 +121,8 @@
/** Obtain the latest user defined ClassLoader from the call stack.
* This is required by the RMI-IIOP specification.
*/
- public final ClassLoader getLatestUserDefinedLoader()
- {
- try {
- // Invoke the ObjectInputStream.latestUserDefinedLoader method
- return (ClassLoader)latestUserDefinedLoaderMethod.invoke(null,
- (Object[])NO_ARGS);
- } catch (InvocationTargetException ite) {
- Error err = new Error(
- "sun.corba.Bridge.latestUserDefinedLoader: " + ite ) ;
- err.initCause( ite ) ;
- throw err ;
- } catch (IllegalAccessException iae) {
- Error err = new Error(
- "sun.corba.Bridge.latestUserDefinedLoader: " + iae ) ;
- err.initCause( iae ) ;
- throw err ;
- }
+ public final ClassLoader getLatestUserDefinedLoader() {
+ return jdk.internal.misc.VM.latestUserDefinedLoader();
}
/**
@@ -345,6 +269,23 @@
return unsafe.objectFieldOffset( f ) ;
}
+ /**
+ * Returns the offset of a static field.
+ */
+ public final long staticFieldOffset(Field f)
+ {
+ return unsafe.staticFieldOffset( f ) ;
+ }
+
+ /**
+ * Ensure that the class has been initalized.
+ * @param cl the class to ensure is initialized
+ */
+ public final void ensureClassInitialized(Class<?> cl) {
+ unsafe.ensureClassInitialized(cl);
+ }
+
+
/** Throw the exception.
* The exception may be an undeclared checked exception.
*/
@@ -353,16 +294,55 @@
unsafe.throwException( ee ) ;
}
- /** Obtain a constructor for Class cl using constructor cons which
- * may be the constructor defined in a superclass of cl. This is
- * used to create a constructor for Serializable classes that
- * constructs an instance of the Serializable class using the
+ /**
+ * Obtain a constructor for Class cl.
+ * This is used to create a constructor for Serializable classes that
+ * construct an instance of the Serializable class using the
* no args constructor of the first non-Serializable superclass
* of the Serializable class.
*/
- public final Constructor newConstructorForSerialization( Class cl,
- Constructor cons )
- {
- return reflectionFactory.newConstructorForSerialization( cl, cons ) ;
+ public final Constructor<?> newConstructorForSerialization( Class<?> cl ) {
+ return reflectionFactory.newConstructorForSerialization( cl ) ;
+ }
+
+ public final Constructor<?> newConstructorForExternalization(Class<?> cl) {
+ return reflectionFactory.newConstructorForExternalization( cl ) ;
+ }
+
+ /**
+ * Returns true if the given class defines a static initializer method,
+ * false otherwise.
+ */
+ public final boolean hasStaticInitializerForSerialization(Class<?> cl) {
+ return reflectionFactory.hasStaticInitializerForSerialization(cl);
+ }
+
+ public final MethodHandle writeObjectForSerialization(Class<?> cl) {
+ return reflectionFactory.writeObjectForSerialization(cl);
+ }
+
+ public final MethodHandle readObjectForSerialization(Class<?> cl) {
+ return reflectionFactory.readObjectForSerialization(cl);
}
+
+ public final MethodHandle readObjectNoDataForSerialization(Class<?> cl) {
+ return reflectionFactory.readObjectNoDataForSerialization(cl);
+ }
+
+ public final MethodHandle readResolveForSerialization(Class<?> cl) {
+ return reflectionFactory.readResolveForSerialization(cl);
+ }
+
+ public final MethodHandle writeReplaceForSerialization(Class<?> cl) {
+ return reflectionFactory.writeReplaceForSerialization(cl);
+ }
+
+ /**
+ * Return a new OptionalDataException instance.
+ * @return a new OptionalDataException instance
+ */
+ public final OptionalDataException newOptionalDataExceptionForSerialization(boolean bool) {
+ return reflectionFactory.newOptionalDataExceptionForSerialization(bool);
+ }
+
}
--- a/corba/src/java.corba/share/classes/sun/corba/SharedSecrets.java Wed Oct 26 15:46:13 2016 -0400
+++ b/corba/src/java.corba/share/classes/sun/corba/SharedSecrets.java Wed Oct 26 20:13:29 2016 +0000
@@ -25,13 +25,13 @@
package sun.corba;
-import com.sun.corba.se.impl.io.ValueUtility;
-import jdk.internal.misc.Unsafe;
-
import java.lang.reflect.Field;
import java.security.AccessController;
import java.security.PrivilegedAction;
+import com.sun.corba.se.impl.io.ValueUtility;
+import sun.misc.Unsafe;
+
/** A repository of "shared secrets", which are a mechanism for
calling implementation-private methods in another package without
using reflection. A package-private class implements a public
@@ -43,22 +43,22 @@
// SharedSecrets cloned in corba repo to avoid build issues
public class SharedSecrets {
- private static final Unsafe unsafe = getUnsafe();
- private static JavaCorbaAccess javaCorbaAccess;
- private static Unsafe getUnsafe() {
- PrivilegedAction<Unsafe> pa = () -> {
- Class<?> unsafeClass = jdk.internal.misc.Unsafe.class ;
- try {
- Field f = unsafeClass.getDeclaredField("theUnsafe");
- f.setAccessible(true);
- return (Unsafe) f.get(null);
- } catch (Exception e) {
- throw new Error(e);
- }
- };
- return AccessController.doPrivileged(pa);
- }
+ /** Access to Unsafe to read/write fields. */
+ private static final Unsafe unsafe = AccessController.doPrivileged(
+ (PrivilegedAction<Unsafe>)() -> {
+ try {
+ Field field = Unsafe.class.getDeclaredField("theUnsafe");
+ field.setAccessible(true);
+ return (Unsafe)field.get(null);
+
+ } catch (NoSuchFieldException |IllegalAccessException ex) {
+ throw new InternalError("Unsafe.theUnsafe field not available", ex);
+ }
+ }
+ );
+
+ private static JavaCorbaAccess javaCorbaAccess;
public static JavaCorbaAccess getJavaCorbaAccess() {
if (javaCorbaAccess == null) {
--- a/hotspot/.hgtags Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/.hgtags Wed Oct 26 20:13:29 2016 +0000
@@ -542,3 +542,5 @@
dfcbf839e299e7e2bba1da69bdb347617ea4c7e8 jdk-9+137
fc0956308c7a586267c5dd35dff74f773aa9c3eb jdk-9+138
08492e67bf3226784dab3bf9ae967382ddbc1af5 jdk-9+139
+fec31089c2ef5a12dd64f401b0bf2e00f56ee0d0 jdk-9+140
+160a00bc6ed0af1fdf8418fc65e6bddbbc0c536d jdk-9+141
--- a/hotspot/.mx.jvmci/.pydevproject Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/.mx.jvmci/.pydevproject Wed Oct 26 20:13:29 2016 +0000
@@ -1,11 +1,9 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<?eclipse-pydev version="1.0"?>
-
-<pydev_project>
+<?eclipse-pydev version="1.0"?><pydev_project>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.7</pydev_property>
<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
-<path>/mx.jvmci</path>
+<path>/.mx.jvmci</path>
</pydev_pathproperty>
<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
<path>/mx</path>
--- a/hotspot/make/lib/Lib-jdk.hotspot.agent.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/make/lib/Lib-jdk.hotspot.agent.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -61,9 +61,8 @@
else ifeq ($(OPENJDK_TARGET_OS), solaris)
SA_TOOLCHAIN := TOOLCHAIN_LINK_CXX
- COMMON_CFLAGS := -DSOLARIS_11_B159_OR_LATER
- SA_CFLAGS := $(CFLAGS_JDKLIB) $(COMMON_CFLAGS)
- SA_CXXFLAGS := $(CXXFLAGS_JDKLIB) $(COMMON_CFLAGS)
+ SA_CFLAGS := $(CFLAGS_JDKLIB)
+ SA_CXXFLAGS := $(CXXFLAGS_JDKLIB)
SA_LDFLAGS := $(subst -Wl$(COMMA)-z$(COMMA)defs,, $(LDFLAGS_JDKLIB)) \
-mt $(LDFLAGS_CXX_JDK)
SA_LIBS := -ldl -ldemangle -lthread -lc
@@ -75,7 +74,7 @@
-mstack-alignment=16 -fPIC
SA_LDFLAGS := $(LDFLAGS_JDKLIB)
SA_LIBS := -framework Foundation -framework JavaNativeFoundation \
- -framework Security -framework CoreFoundation
+ -framework JavaRuntimeSupport -framework Security -framework CoreFoundation
else ifeq ($(OPENJDK_TARGET_OS), windows)
SA_NAME := sawindbg
--- a/hotspot/src/cpu/aarch64/vm/frame_aarch64.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/cpu/aarch64/vm/frame_aarch64.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -142,6 +142,10 @@
}
sender_sp = _unextended_sp + _cb->frame_size();
+ // Is sender_sp safe?
+ if ((address)sender_sp >= thread->stack_base()) {
+ return false;
+ }
sender_unextended_sp = sender_sp;
sender_pc = (address) *(sender_sp-1);
// Note: frame::sender_sp_offset is only valid for compiled frame
@@ -200,8 +204,15 @@
}
// construct the potential sender
+
frame sender(sender_sp, sender_unextended_sp, saved_fp, sender_pc);
- return sender.is_entry_frame_valid(thread);
+
+ // Validate the JavaCallWrapper an entry frame must have
+ address jcw = (address)sender.entry_frame_call_wrapper();
+
+ bool jcw_safe = (jcw < thread->stack_base()) && (jcw > (address)sender.fp());
+
+ return jcw_safe;
}
CompiledMethod* nm = sender_blob->as_compiled_method_or_null();
--- a/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -1962,6 +1962,8 @@
// due to cache line collision.
__ serialize_memory(rthread, r2);
}
+ } else {
+ __ strw(rscratch1, Address(rthread, JavaThread::thread_state_offset()));
}
// check for safepoint operation in progress and/or pending suspend requests
--- a/hotspot/src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -454,8 +454,9 @@
__ str(zr, Address(rfp, frame::interpreter_frame_last_sp_offset * wordSize));
#if INCLUDE_JVMCI
- // Check if we need to take lock at entry of synchronized method.
- if (UseJVMCICompiler) {
+ // Check if we need to take lock at entry of synchronized method. This can
+ // only occur on method entry so emit it only for vtos with step 0.
+ if (UseJVMCICompiler && state == vtos && step == 0) {
Label L;
__ ldr(rscratch1, Address(rthread, Thread::pending_exception_offset()));
__ cbz(rscratch1, L);
@@ -464,6 +465,16 @@
// Take lock.
lock_method();
__ bind(L);
+ } else {
+#ifdef ASSERT
+ if (UseJVMCICompiler) {
+ Label L;
+ __ ldr(rscratch1, Address(rthread, Thread::pending_exception_offset()));
+ __ cbz(rscratch1, L);
+ __ stop("unexpected pending monitor in deopt entry");
+ __ bind(L);
+ }
+#endif
}
#endif
// handle exceptions
--- a/hotspot/src/cpu/ppc/vm/assembler_ppc.hpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/cpu/ppc/vm/assembler_ppc.hpp Wed Oct 26 20:13:29 2016 +0000
@@ -2102,7 +2102,9 @@
inline void mfvscr( VectorRegister d);
// Vector-Scalar (VSX) instructions.
+ inline void lxvd2x( VectorSRegister d, Register a);
inline void lxvd2x( VectorSRegister d, Register a, Register b);
+ inline void stxvd2x( VectorSRegister d, Register a);
inline void stxvd2x( VectorSRegister d, Register a, Register b);
inline void mtvrd( VectorRegister d, Register a);
inline void mfvrd( Register a, VectorRegister d);
--- a/hotspot/src/cpu/ppc/vm/assembler_ppc.inline.hpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/cpu/ppc/vm/assembler_ppc.inline.hpp Wed Oct 26 20:13:29 2016 +0000
@@ -734,8 +734,10 @@
inline void Assembler::lvsr( VectorRegister d, Register s1, Register s2) { emit_int32( LVSR_OPCODE | vrt(d) | ra0mem(s1) | rb(s2)); }
// Vector-Scalar (VSX) instructions.
-inline void Assembler::lxvd2x (VectorSRegister d, Register s1, Register s2) { emit_int32( LXVD2X_OPCODE | vsrt(d) | ra(s1) | rb(s2)); }
-inline void Assembler::stxvd2x(VectorSRegister d, Register s1, Register s2) { emit_int32( STXVD2X_OPCODE | vsrt(d) | ra(s1) | rb(s2)); }
+inline void Assembler::lxvd2x (VectorSRegister d, Register s1) { emit_int32( LXVD2X_OPCODE | vsrt(d) | ra(0) | rb(s1)); }
+inline void Assembler::lxvd2x (VectorSRegister d, Register s1, Register s2) { emit_int32( LXVD2X_OPCODE | vsrt(d) | ra0mem(s1) | rb(s2)); }
+inline void Assembler::stxvd2x(VectorSRegister d, Register s1) { emit_int32( STXVD2X_OPCODE | vsrt(d) | ra(0) | rb(s1)); }
+inline void Assembler::stxvd2x(VectorSRegister d, Register s1, Register s2) { emit_int32( STXVD2X_OPCODE | vsrt(d) | ra0mem(s1) | rb(s2)); }
inline void Assembler::mtvrd( VectorRegister d, Register a) { emit_int32( MTVSRD_OPCODE | vrt(d) | ra(a) | 1u); } // 1u: d is treated as Vector (VMX/Altivec).
inline void Assembler::mfvrd( Register a, VectorRegister d) { emit_int32( MFVSRD_OPCODE | vrt(d) | ra(a) | 1u); } // 1u: d is treated as Vector (VMX/Altivec).
--- a/hotspot/src/cpu/ppc/vm/c1_LIRAssembler_ppc.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/cpu/ppc/vm/c1_LIRAssembler_ppc.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -1894,6 +1894,22 @@
__ beq(combined_check, slow);
}
+ if (flags & LIR_OpArrayCopy::type_check) {
+ if (!(flags & LIR_OpArrayCopy::LIR_OpArrayCopy::dst_objarray)) {
+ __ load_klass(tmp, dst);
+ __ lwz(tmp2, in_bytes(Klass::layout_helper_offset()), tmp);
+ __ cmpwi(CCR0, tmp2, Klass::_lh_neutral_value);
+ __ bge(CCR0, slow);
+ }
+
+ if (!(flags & LIR_OpArrayCopy::LIR_OpArrayCopy::src_objarray)) {
+ __ load_klass(tmp, src);
+ __ lwz(tmp2, in_bytes(Klass::layout_helper_offset()), tmp);
+ __ cmpwi(CCR0, tmp2, Klass::_lh_neutral_value);
+ __ bge(CCR0, slow);
+ }
+ }
+
// Higher 32bits must be null.
__ extsw(length, length);
--- a/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -1220,8 +1220,8 @@
__ bind(l_10);
// Use loop with VSX load/store instructions to
// copy 32 elements a time.
- __ lxvd2x(tmp_vsr1, 0, R3_ARG1); // Load src
- __ stxvd2x(tmp_vsr1, 0, R4_ARG2); // Store to dst
+ __ lxvd2x(tmp_vsr1, R3_ARG1); // Load src
+ __ stxvd2x(tmp_vsr1, R4_ARG2); // Store to dst
__ lxvd2x(tmp_vsr2, tmp1, R3_ARG1); // Load src + 16
__ stxvd2x(tmp_vsr2, tmp1, R4_ARG2); // Store to dst + 16
__ addi(R3_ARG1, R3_ARG1, 32); // Update src+=32
@@ -1486,8 +1486,8 @@
__ bind(l_9);
// Use loop with VSX load/store instructions to
// copy 16 elements a time.
- __ lxvd2x(tmp_vsr1, 0, R3_ARG1); // Load from src.
- __ stxvd2x(tmp_vsr1, 0, R4_ARG2); // Store to dst.
+ __ lxvd2x(tmp_vsr1, R3_ARG1); // Load from src.
+ __ stxvd2x(tmp_vsr1, R4_ARG2); // Store to dst.
__ lxvd2x(tmp_vsr2, R3_ARG1, tmp1); // Load from src + 16.
__ stxvd2x(tmp_vsr2, R4_ARG2, tmp1); // Store to dst + 16.
__ addi(R3_ARG1, R3_ARG1, 32); // Update src+=32.
@@ -1677,8 +1677,8 @@
__ bind(l_7);
// Use loop with VSX load/store instructions to
// copy 8 elements a time.
- __ lxvd2x(tmp_vsr1, 0, R3_ARG1); // Load src
- __ stxvd2x(tmp_vsr1, 0, R4_ARG2); // Store to dst
+ __ lxvd2x(tmp_vsr1, R3_ARG1); // Load src
+ __ stxvd2x(tmp_vsr1, R4_ARG2); // Store to dst
__ lxvd2x(tmp_vsr2, tmp1, R3_ARG1); // Load src + 16
__ stxvd2x(tmp_vsr2, tmp1, R4_ARG2); // Store to dst + 16
__ addi(R3_ARG1, R3_ARG1, 32); // Update src+=32
@@ -1745,13 +1745,16 @@
// Do reverse copy. We assume the case of actual overlap is rare enough
// that we don't have to optimize it.
- Label l_1, l_2, l_3, l_4, l_5, l_6;
+ Label l_1, l_2, l_3, l_4, l_5, l_6, l_7;
Register tmp1 = R6_ARG4;
Register tmp2 = R7_ARG5;
Register tmp3 = R8_ARG6;
Register tmp4 = R0;
+ VectorSRegister tmp_vsr1 = VSR1;
+ VectorSRegister tmp_vsr2 = VSR2;
+
{ // FasterArrayCopy
__ cmpwi(CCR0, R5_ARG3, 0);
__ beq(CCR0, l_6);
@@ -1761,6 +1764,25 @@
__ add(R4_ARG2, R4_ARG2, R5_ARG3);
__ srdi(R5_ARG3, R5_ARG3, 2);
+ if (!aligned) {
+ // check if arrays have same alignment mod 8.
+ __ xorr(tmp1, R3_ARG1, R4_ARG2);
+ __ andi_(R0, tmp1, 7);
+ // Not the same alignment, but ld and std just need to be 4 byte aligned.
+ __ bne(CCR0, l_7); // to OR from is 8 byte aligned -> copy 2 at a time
+
+ // copy 1 element to align to and from on an 8 byte boundary
+ __ andi_(R0, R3_ARG1, 7);
+ __ beq(CCR0, l_7);
+
+ __ addi(R3_ARG1, R3_ARG1, -4);
+ __ addi(R4_ARG2, R4_ARG2, -4);
+ __ addi(R5_ARG3, R5_ARG3, -1);
+ __ lwzx(tmp2, R3_ARG1);
+ __ stwx(tmp2, R4_ARG2);
+ __ bind(l_7);
+ }
+
__ cmpwi(CCR0, R5_ARG3, 7);
__ ble(CCR0, l_5); // copy 1 at a time if less than 8 elements remain
@@ -1768,6 +1790,7 @@
__ andi(R5_ARG3, R5_ARG3, 7);
__ mtctr(tmp1);
+ if (!VM_Version::has_vsx()) {
__ bind(l_4);
// Use unrolled version for mass copying (copy 4 elements a time).
// Load feeding store gets zero latency on Power6, however not on Power5.
@@ -1783,6 +1806,40 @@
__ std(tmp2, 8, R4_ARG2);
__ std(tmp1, 0, R4_ARG2);
__ bdnz(l_4);
+ } else { // Processor supports VSX, so use it to mass copy.
+ // Prefetch the data into the L2 cache.
+ __ dcbt(R3_ARG1, 0);
+
+ // If supported set DSCR pre-fetch to deepest.
+ if (VM_Version::has_mfdscr()) {
+ __ load_const_optimized(tmp2, VM_Version::_dscr_val | 7);
+ __ mtdscr(tmp2);
+ }
+
+ __ li(tmp1, 16);
+
+ // Backbranch target aligned to 32-byte. Not 16-byte align as
+ // loop contains < 8 instructions that fit inside a single
+ // i-cache sector.
+ __ align(32);
+
+ __ bind(l_4);
+ // Use loop with VSX load/store instructions to
+ // copy 8 elements a time.
+ __ addi(R3_ARG1, R3_ARG1, -32); // Update src-=32
+ __ addi(R4_ARG2, R4_ARG2, -32); // Update dsc-=32
+ __ lxvd2x(tmp_vsr2, tmp1, R3_ARG1); // Load src+16
+ __ lxvd2x(tmp_vsr1, R3_ARG1); // Load src
+ __ stxvd2x(tmp_vsr2, tmp1, R4_ARG2); // Store to dst+16
+ __ stxvd2x(tmp_vsr1, R4_ARG2); // Store to dst
+ __ bdnz(l_4);
+
+ // Restore DSCR pre-fetch value.
+ if (VM_Version::has_mfdscr()) {
+ __ load_const_optimized(tmp2, VM_Version::_dscr_val);
+ __ mtdscr(tmp2);
+ }
+ }
__ cmpwi(CCR0, R5_ARG3, 0);
__ beq(CCR0, l_6);
@@ -1892,8 +1949,8 @@
__ bind(l_5);
// Use loop with VSX load/store instructions to
// copy 4 elements a time.
- __ lxvd2x(tmp_vsr1, 0, R3_ARG1); // Load src
- __ stxvd2x(tmp_vsr1, 0, R4_ARG2); // Store to dst
+ __ lxvd2x(tmp_vsr1, R3_ARG1); // Load src
+ __ stxvd2x(tmp_vsr1, R4_ARG2); // Store to dst
__ lxvd2x(tmp_vsr2, tmp1, R3_ARG1); // Load src + 16
__ stxvd2x(tmp_vsr2, tmp1, R4_ARG2); // Store to dst + 16
__ addi(R3_ARG1, R3_ARG1, 32); // Update src+=32
@@ -1962,6 +2019,9 @@
Register tmp3 = R8_ARG6;
Register tmp4 = R0;
+ VectorSRegister tmp_vsr1 = VSR1;
+ VectorSRegister tmp_vsr2 = VSR2;
+
Label l_1, l_2, l_3, l_4, l_5;
__ cmpwi(CCR0, R5_ARG3, 0);
@@ -1980,6 +2040,7 @@
__ andi(R5_ARG3, R5_ARG3, 3);
__ mtctr(tmp1);
+ if (!VM_Version::has_vsx()) {
__ bind(l_4);
// Use unrolled version for mass copying (copy 4 elements a time).
// Load feeding store gets zero latency on Power6, however not on Power5.
@@ -1995,6 +2056,40 @@
__ std(tmp2, 8, R4_ARG2);
__ std(tmp1, 0, R4_ARG2);
__ bdnz(l_4);
+ } else { // Processor supports VSX, so use it to mass copy.
+ // Prefetch the data into the L2 cache.
+ __ dcbt(R3_ARG1, 0);
+
+ // If supported set DSCR pre-fetch to deepest.
+ if (VM_Version::has_mfdscr()) {
+ __ load_const_optimized(tmp2, VM_Version::_dscr_val | 7);
+ __ mtdscr(tmp2);
+ }
+
+ __ li(tmp1, 16);
+
+ // Backbranch target aligned to 32-byte. Not 16-byte align as
+ // loop contains < 8 instructions that fit inside a single
+ // i-cache sector.
+ __ align(32);
+
+ __ bind(l_4);
+ // Use loop with VSX load/store instructions to
+ // copy 4 elements a time.
+ __ addi(R3_ARG1, R3_ARG1, -32); // Update src-=32
+ __ addi(R4_ARG2, R4_ARG2, -32); // Update dsc-=32
+ __ lxvd2x(tmp_vsr2, tmp1, R3_ARG1); // Load src+16
+ __ lxvd2x(tmp_vsr1, R3_ARG1); // Load src
+ __ stxvd2x(tmp_vsr2, tmp1, R4_ARG2); // Store to dst+16
+ __ stxvd2x(tmp_vsr1, R4_ARG2); // Store to dst
+ __ bdnz(l_4);
+
+ // Restore DSCR pre-fetch value.
+ if (VM_Version::has_mfdscr()) {
+ __ load_const_optimized(tmp2, VM_Version::_dscr_val);
+ __ mtdscr(tmp2);
+ }
+ }
__ cmpwi(CCR0, R5_ARG3, 0);
__ beq(CCR0, l_1);
--- a/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -656,7 +656,7 @@
a->vpmsumb(VR0, VR1, VR2); // code[11] -> vpmsumb
a->tcheck(0); // code[12] -> tcheck
a->mfdscr(R0); // code[13] -> mfdscr
- a->lxvd2x(VSR0, 0, R3_ARG1); // code[14] -> vsx
+ a->lxvd2x(VSR0, R3_ARG1); // code[14] -> vsx
a->blr();
// Emit function to set one cache line to zero. Emit function descriptor and get pointer to it.
--- a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -2034,6 +2034,27 @@
__ delayed()->nop();
}
+ // If the compiler was not able to prove that exact type of the source or the destination
+ // of the arraycopy is an array type, check at runtime if the source or the destination is
+ // an instance type.
+ if (flags & LIR_OpArrayCopy::type_check) {
+ if (!(flags & LIR_OpArrayCopy::LIR_OpArrayCopy::dst_objarray)) {
+ __ load_klass(dst, tmp);
+ __ lduw(tmp, in_bytes(Klass::layout_helper_offset()), tmp2);
+ __ cmp(tmp2, Klass::_lh_neutral_value);
+ __ br(Assembler::greaterEqual, false, Assembler::pn, *stub->entry());
+ __ delayed()->nop();
+ }
+
+ if (!(flags & LIR_OpArrayCopy::LIR_OpArrayCopy::src_objarray)) {
+ __ load_klass(src, tmp);
+ __ lduw(tmp, in_bytes(Klass::layout_helper_offset()), tmp2);
+ __ cmp(tmp2, Klass::_lh_neutral_value);
+ __ br(Assembler::greaterEqual, false, Assembler::pn, *stub->entry());
+ __ delayed()->nop();
+ }
+ }
+
if (flags & LIR_OpArrayCopy::src_pos_positive_check) {
// test src_pos register
__ cmp_zero_and_br(Assembler::less, src_pos, *stub->entry());
--- a/hotspot/src/cpu/sparc/vm/frame_sparc.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/cpu/sparc/vm/frame_sparc.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -279,7 +279,13 @@
}
if (sender.is_entry_frame()) {
- return sender.is_entry_frame_valid(thread);
+ // Validate the JavaCallWrapper an entry frame must have
+
+ address jcw = (address)sender.entry_frame_call_wrapper();
+
+ bool jcw_safe = (jcw <= thread->stack_base()) && (jcw > sender_fp);
+
+ return jcw_safe;
}
// If the frame size is 0 something (or less) is bad because every nmethod has a non-zero frame size
--- a/hotspot/src/cpu/sparc/vm/templateInterpreterGenerator_sparc.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/cpu/sparc/vm/templateInterpreterGenerator_sparc.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -384,8 +384,9 @@
address entry = __ pc();
__ get_constant_pool_cache(LcpoolCache); // load LcpoolCache
#if INCLUDE_JVMCI
- // Check if we need to take lock at entry of synchronized method.
- if (UseJVMCICompiler) {
+ // Check if we need to take lock at entry of synchronized method. This can
+ // only occur on method entry so emit it only for vtos with step 0.
+ if (UseJVMCICompiler && state == vtos && step == 0) {
Label L;
Address pending_monitor_enter_addr(G2_thread, JavaThread::pending_monitorenter_offset());
__ ldbool(pending_monitor_enter_addr, Gtemp); // Load if pending monitor enter
@@ -395,6 +396,17 @@
// Take lock.
lock_method();
__ bind(L);
+ } else {
+#ifdef ASSERT
+ if (UseJVMCICompiler) {
+ Label L;
+ Address pending_monitor_enter_addr(G2_thread, JavaThread::pending_monitorenter_offset());
+ __ ldbool(pending_monitor_enter_addr, Gtemp); // Load if pending monitor enter
+ __ cmp_and_br_short(Gtemp, G0, Assembler::equal, Assembler::pn, L);
+ __ stop("unexpected pending monitor in deopt entry");
+ __ bind(L);
+ }
+#endif
}
#endif
{ Label L;
--- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -457,9 +457,10 @@
unsigned int VM_Version::calc_parallel_worker_threads() {
unsigned int result;
- if (is_M_series()) {
- // for now, use same gc thread calculation for M-series as for niagara-plus
- // in future, we may want to tweak parameters for nof_parallel_worker_thread
+ if (is_M_series() || is_S_series()) {
+ // for now, use same gc thread calculation for M-series and S-series as for
+ // niagara-plus. In future, we may want to tweak parameters for
+ // nof_parallel_worker_thread
result = nof_parallel_worker_threads(5, 16, 8);
} else if (is_niagara_plus()) {
result = nof_parallel_worker_threads(5, 16, 8);
@@ -483,6 +484,9 @@
} else if (strstr(impl, "SPARC-M") != NULL) {
// M-series SPARC is based on T-series.
features |= (M_family_m | T_family_m);
+ } else if (strstr(impl, "SPARC-S") != NULL) {
+ // S-series SPARC is based on T-series.
+ features |= (S_family_m | T_family_m);
} else if (strstr(impl, "SPARC-T") != NULL) {
features |= T_family_m;
if (strstr(impl, "SPARC-T1") != NULL) {
--- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp Wed Oct 26 20:13:29 2016 +0000
@@ -49,14 +49,15 @@
cbcond_instructions = 12,
sparc64_family = 13,
M_family = 14,
- T_family = 15,
- T1_model = 16,
- sparc5_instructions = 17,
- aes_instructions = 18,
- sha1_instruction = 19,
- sha256_instruction = 20,
- sha512_instruction = 21,
- crc32c_instruction = 22
+ S_family = 15,
+ T_family = 16,
+ T1_model = 17,
+ sparc5_instructions = 18,
+ aes_instructions = 19,
+ sha1_instruction = 20,
+ sha256_instruction = 21,
+ sha512_instruction = 22,
+ crc32c_instruction = 23
};
enum Feature_Flag_Set {
@@ -78,6 +79,7 @@
cbcond_instructions_m = 1 << cbcond_instructions,
sparc64_family_m = 1 << sparc64_family,
M_family_m = 1 << M_family,
+ S_family_m = 1 << S_family,
T_family_m = 1 << T_family,
T1_model_m = 1 << T1_model,
sparc5_instructions_m = 1 << sparc5_instructions,
@@ -105,6 +107,7 @@
// Returns true if the platform is in the niagara line (T series)
static bool is_M_family(int features) { return (features & M_family_m) != 0; }
+ static bool is_S_family(int features) { return (features & S_family_m) != 0; }
static bool is_T_family(int features) { return (features & T_family_m) != 0; }
static bool is_niagara() { return is_T_family(_features); }
#ifdef ASSERT
@@ -153,6 +156,7 @@
static bool is_niagara_plus() { return is_T_family(_features) && !is_T1_model(_features); }
static bool is_M_series() { return is_M_family(_features); }
+ static bool is_S_series() { return is_S_family(_features); }
static bool is_T4() { return is_T_family(_features) && has_cbcond(); }
static bool is_T7() { return is_T_family(_features) && has_sparc5_instr(); }
--- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -2461,6 +2461,7 @@
InstructionMark im(this);
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
+ attributes.reset_is_clear_context();
simd_prefix(src, xnoreg, dst, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
emit_int8(0x7F);
emit_operand(src, dst);
@@ -2490,6 +2491,7 @@
InstructionMark im(this);
InstructionAttr attributes(AVX_256bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
+ attributes.reset_is_clear_context();
// swap src<->dst for encoding
assert(src != xnoreg, "sanity");
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
@@ -2590,6 +2592,7 @@
InstructionMark im(this);
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
+ attributes.reset_is_clear_context();
attributes.set_embedded_opmask_register_specifier(mask);
attributes.set_is_evex_instruction();
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
@@ -2623,6 +2626,7 @@
InstructionMark im(this);
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
+ attributes.reset_is_clear_context();
attributes.set_is_evex_instruction();
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
emit_int8(0x7F);
@@ -2655,6 +2659,7 @@
InstructionMark im(this);
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
+ attributes.reset_is_clear_context();
attributes.set_is_evex_instruction();
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
emit_int8(0x7F);
@@ -2794,6 +2799,7 @@
InstructionMark im(this);
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
+ attributes.reset_is_clear_context();
attributes.set_rex_vex_w_reverted();
simd_prefix(src, xnoreg, dst, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
emit_int8(0x11);
@@ -2823,6 +2829,7 @@
InstructionMark im(this);
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
+ attributes.reset_is_clear_context();
simd_prefix(src, xnoreg, dst, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
emit_int8(0x11);
emit_operand(src, dst);
@@ -3291,6 +3298,15 @@
emit_int8(imm8);
}
+void Assembler::vperm2f128(XMMRegister dst, XMMRegister nds, XMMRegister src, int imm8) {
+ assert(VM_Version::supports_avx(), "");
+ InstructionAttr attributes(AVX_256bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+ int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
+ emit_int8(0x06);
+ emit_int8(0xC0 | encode);
+ emit_int8(imm8);
+}
+
void Assembler::pause() {
emit_int8((unsigned char)0xF3);
@@ -3362,6 +3378,7 @@
InstructionMark im(this);
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
+ attributes.reset_is_clear_context();
attributes.set_embedded_opmask_register_specifier(mask);
attributes.set_is_evex_instruction();
int dst_enc = kdst->encoding();
@@ -3384,6 +3401,7 @@
assert(is_vector_masking(), "");
assert(VM_Version::supports_avx512vlbw(), "");
InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+ attributes.reset_is_clear_context();
attributes.set_embedded_opmask_register_specifier(mask);
attributes.set_is_evex_instruction();
int encode = vex_prefix_and_encode(kdst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
@@ -3423,6 +3441,7 @@
InstructionMark im(this);
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_reg_mask */ false, /* uses_vl */ false);
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
+ attributes.reset_is_clear_context();
attributes.set_embedded_opmask_register_specifier(mask);
attributes.set_is_evex_instruction();
vex_prefix(src, nds->encoding(), kdst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
@@ -3493,6 +3512,7 @@
assert(VM_Version::supports_evex(), "");
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
attributes.set_is_evex_instruction();
+ attributes.reset_is_clear_context();
int encode = vex_prefix_and_encode(kdst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
emit_int8(0x76);
emit_int8((unsigned char)(0xC0 | encode));
@@ -3503,6 +3523,7 @@
InstructionMark im(this);
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit);
+ attributes.reset_is_clear_context();
attributes.set_is_evex_instruction();
int dst_enc = kdst->encoding();
vex_prefix(src, nds->encoding(), dst_enc, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
@@ -3532,6 +3553,7 @@
void Assembler::evpcmpeqq(KRegister kdst, XMMRegister nds, XMMRegister src, int vector_len) {
assert(VM_Version::supports_evex(), "");
InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
+ attributes.reset_is_clear_context();
attributes.set_is_evex_instruction();
int encode = vex_prefix_and_encode(kdst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
emit_int8(0x29);
@@ -3543,6 +3565,7 @@
assert(VM_Version::supports_evex(), "");
InstructionMark im(this);
InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
+ attributes.reset_is_clear_context();
attributes.set_is_evex_instruction();
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
int dst_enc = kdst->encoding();
@@ -3763,6 +3786,7 @@
InstructionMark im(this);
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
attributes.set_address_attributes(/* tuple_type */ EVEX_HVM, /* input_size_in_bits */ EVEX_NObit);
+ attributes.reset_is_clear_context();
attributes.set_embedded_opmask_register_specifier(mask);
attributes.set_is_evex_instruction();
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F_38, &attributes);
@@ -6208,6 +6232,7 @@
InstructionMark im(this);
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
attributes.set_address_attributes(/* tuple_type */ EVEX_T4, /* input_size_in_bits */ EVEX_32bit);
+ attributes.reset_is_clear_context();
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
emit_int8(0x39);
emit_operand(src, dst);
@@ -6238,6 +6263,7 @@
InstructionMark im(this);
InstructionAttr attributes(AVX_512bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
attributes.set_address_attributes(/* tuple_type */ EVEX_T4, /* input_size_in_bits */ EVEX_32bit);
+ attributes.reset_is_clear_context();
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
emit_int8(0x39);
emit_operand(src, dst);
@@ -6298,6 +6324,7 @@
InstructionMark im(this);
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
attributes.set_address_attributes(/* tuple_type */ EVEX_T4, /* input_size_in_bits */ EVEX_32bit);
+ attributes.reset_is_clear_context();
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
emit_int8(0x19);
emit_operand(src, dst);
@@ -6328,6 +6355,7 @@
InstructionMark im(this);
InstructionAttr attributes(AVX_512bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
attributes.set_address_attributes(/* tuple_type */ EVEX_T4, /* input_size_in_bits */ EVEX_32bit);
+ attributes.reset_is_clear_context();
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
emit_int8(0x19);
emit_operand(src, dst);
@@ -6371,6 +6399,7 @@
InstructionMark im(this);
InstructionAttr attributes(AVX_512bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
attributes.set_address_attributes(/* tuple_type */ EVEX_T4,/* input_size_in_bits */ EVEX_64bit);
+ attributes.reset_is_clear_context();
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
emit_int8(0x1B);
emit_operand(src, dst);
@@ -7181,7 +7210,9 @@
// fourth EVEX.L'L for vector length : 0 is 128, 1 is 256, 2 is 512, currently we do not support 1024
byte4 |= ((_attributes->get_vector_len())& 0x3) << 5;
// last is EVEX.z for zero/merge actions
- byte4 |= (_attributes->is_clear_context() ? EVEX_Z : 0);
+ if (_attributes->is_no_reg_mask() == false) {
+ byte4 |= (_attributes->is_clear_context() ? EVEX_Z : 0);
+ }
emit_int8(byte4);
}
@@ -7337,7 +7368,7 @@
emit_int8((unsigned char)(0xF & cop));
}
-void Assembler::vpblendd(XMMRegister dst, XMMRegister nds, XMMRegister src1, XMMRegister src2, int vector_len) {
+void Assembler::blendvpd(XMMRegister dst, XMMRegister nds, XMMRegister src1, XMMRegister src2, int vector_len) {
assert(VM_Version::supports_avx(), "");
assert(!VM_Version::supports_evex(), "");
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
@@ -7348,6 +7379,15 @@
emit_int8((unsigned char)(0xF0 & src2_enc<<4));
}
+void Assembler::vpblendd(XMMRegister dst, XMMRegister nds, XMMRegister src, int imm8, int vector_len) {
+ assert(VM_Version::supports_avx2(), "");
+ InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+ int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
+ emit_int8((unsigned char)0x02);
+ emit_int8((unsigned char)(0xC0 | encode));
+ emit_int8((unsigned char)imm8);
+}
+
void Assembler::shlxl(Register dst, Register src1, Register src2) {
assert(VM_Version::supports_bmi2(), "");
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
--- a/hotspot/src/cpu/x86/vm/assembler_x86.hpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.hpp Wed Oct 26 20:13:29 2016 +0000
@@ -1550,6 +1550,7 @@
void vpermq(XMMRegister dst, XMMRegister src, int imm8, int vector_len);
void vpermq(XMMRegister dst, XMMRegister src, int imm8);
void vperm2i128(XMMRegister dst, XMMRegister nds, XMMRegister src, int imm8);
+ void vperm2f128(XMMRegister dst, XMMRegister nds, XMMRegister src, int imm8);
void pause();
@@ -2105,7 +2106,8 @@
// AVX support for vectorized conditional move (double). The following two instructions used only coupled.
void cmppd(XMMRegister dst, XMMRegister nds, XMMRegister src, int cop, int vector_len);
- void vpblendd(XMMRegister dst, XMMRegister nds, XMMRegister src1, XMMRegister src2, int vector_len);
+ void blendvpd(XMMRegister dst, XMMRegister nds, XMMRegister src1, XMMRegister src2, int vector_len);
+ void vpblendd(XMMRegister dst, XMMRegister nds, XMMRegister src, int imm8, int vector_len);
protected:
// Next instructions require address alignment 16 bytes SSE mode.
@@ -2139,7 +2141,7 @@
_input_size_in_bits(Assembler::EVEX_NObit),
_is_evex_instruction(false),
_evex_encoding(0),
- _is_clear_context(false),
+ _is_clear_context(true),
_is_extended_context(false),
_current_assembler(NULL),
_embedded_opmask_register_specifier(1) { // hard code k1, it will be initialized for now
@@ -2205,7 +2207,7 @@
void set_evex_encoding(int value) { _evex_encoding = value; }
// Set the Evex.Z field to be used to clear all non directed XMM/YMM/ZMM components
- void set_is_clear_context(void) { _is_clear_context = true; }
+ void reset_is_clear_context(void) { _is_clear_context = false; }
// Map back to current asembler so that we can manage object level assocation
void set_current_assembler(Assembler *current_assembler) { _current_assembler = current_assembler; }
--- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -3146,6 +3146,23 @@
__ jcc(Assembler::zero, *stub->entry());
}
+ // If the compiler was not able to prove that exact type of the source or the destination
+ // of the arraycopy is an array type, check at runtime if the source or the destination is
+ // an instance type.
+ if (flags & LIR_OpArrayCopy::type_check) {
+ if (!(flags & LIR_OpArrayCopy::dst_objarray)) {
+ __ load_klass(tmp, dst);
+ __ cmpl(Address(tmp, in_bytes(Klass::layout_helper_offset())), Klass::_lh_neutral_value);
+ __ jcc(Assembler::greaterEqual, *stub->entry());
+ }
+
+ if (!(flags & LIR_OpArrayCopy::src_objarray)) {
+ __ load_klass(tmp, src);
+ __ cmpl(Address(tmp, in_bytes(Klass::layout_helper_offset())), Klass::_lh_neutral_value);
+ __ jcc(Assembler::greaterEqual, *stub->entry());
+ }
+ }
+
// check if negative
if (flags & LIR_OpArrayCopy::src_pos_positive_check) {
__ testl(src_pos, src_pos);
--- a/hotspot/src/cpu/x86/vm/frame_x86.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/cpu/x86/vm/frame_x86.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -140,6 +140,10 @@
}
sender_sp = _unextended_sp + _cb->frame_size();
+ // Is sender_sp safe?
+ if ((address)sender_sp >= thread->stack_base()) {
+ return false;
+ }
sender_unextended_sp = sender_sp;
// On Intel the return_address is always the word on the stack
sender_pc = (address) *(sender_sp-1);
@@ -199,8 +203,15 @@
}
// construct the potential sender
+
frame sender(sender_sp, sender_unextended_sp, saved_fp, sender_pc);
- return sender.is_entry_frame_valid(thread);
+
+ // Validate the JavaCallWrapper an entry frame must have
+ address jcw = (address)sender.entry_frame_call_wrapper();
+
+ bool jcw_safe = (jcw < thread->stack_base()) && (jcw > (address)sender.fp());
+
+ return jcw_safe;
}
CompiledMethod* nm = sender_blob->as_compiled_method_or_null();
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -4309,6 +4309,15 @@
}
}
+void MacroAssembler::vpand(XMMRegister dst, XMMRegister nds, AddressLiteral src, int vector_len) {
+ if (reachable(src)) {
+ Assembler::vpand(dst, nds, as_Address(src), vector_len);
+ } else {
+ lea(rscratch1, src);
+ Assembler::vpand(dst, nds, Address(rscratch1, 0), vector_len);
+ }
+}
+
void MacroAssembler::vpbroadcastw(XMMRegister dst, XMMRegister src) {
int dst_enc = dst->encoding();
int src_enc = src->encoding();
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp Wed Oct 26 20:13:29 2016 +0000
@@ -943,6 +943,23 @@
bool multi_block, XMMRegister shuf_mask);
#endif
+#ifdef _LP64
+ private:
+ void sha512_AVX2_one_round_compute(Register old_h, Register a, Register b, Register c, Register d,
+ Register e, Register f, Register g, Register h, int iteration);
+
+ void sha512_AVX2_one_round_and_schedule(XMMRegister xmm4, XMMRegister xmm5, XMMRegister xmm6, XMMRegister xmm7,
+ Register a, Register b, Register c, Register d, Register e, Register f,
+ Register g, Register h, int iteration);
+
+ void addmq(int disp, Register r1, Register r2);
+ public:
+ void sha512_AVX2(XMMRegister msg, XMMRegister state0, XMMRegister state1, XMMRegister msgtmp0,
+ XMMRegister msgtmp1, XMMRegister msgtmp2, XMMRegister msgtmp3, XMMRegister msgtmp4,
+ Register buf, Register state, Register ofs, Register limit, Register rsp, bool multi_block,
+ XMMRegister shuf_mask);
+#endif
+
void fast_sha1(XMMRegister abcd, XMMRegister e0, XMMRegister e1, XMMRegister msg0,
XMMRegister msg1, XMMRegister msg2, XMMRegister msg3, XMMRegister shuf_mask,
Register buf, Register state, Register ofs, Register limit, Register rsp,
@@ -1177,6 +1194,10 @@
void vpaddw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
void vpaddw(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
+ void vpand(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) { Assembler::vpand(dst, nds, src, vector_len); }
+ void vpand(XMMRegister dst, XMMRegister nds, Address src, int vector_len) { Assembler::vpand(dst, nds, src, vector_len); }
+ void vpand(XMMRegister dst, XMMRegister nds, AddressLiteral src, int vector_len);
+
void vpbroadcastw(XMMRegister dst, XMMRegister src);
void vpcmpeqb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86_sha.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86_sha.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -674,6 +674,11 @@
movl(Address(r1, disp), r2);
}
+void MacroAssembler::addmq(int disp, Register r1, Register r2) {
+ addq(r2, Address(r1, disp));
+ movq(Address(r1, disp), r2);
+}
+
void MacroAssembler::sha256_AVX2(XMMRegister msg, XMMRegister state0, XMMRegister state1, XMMRegister msgtmp0,
XMMRegister msgtmp1, XMMRegister msgtmp2, XMMRegister msgtmp3, XMMRegister msgtmp4,
Register buf, Register state, Register ofs, Register limit, Register rsp,
@@ -1026,4 +1031,488 @@
bind(compute_size_end1);
}
}
+
+void MacroAssembler::sha512_AVX2_one_round_compute(Register old_h, Register a, Register b, Register c,
+ Register d, Register e, Register f, Register g, Register h,
+ int iteration)
+{
+
+ const Register& y0 = r13;
+ const Register& y1 = r14;
+ const Register& y2 = r15;
+#ifdef _WIN64
+ const Register& y3 = rcx;
+#else
+ const Register& y3 = rdi;
+#endif
+ const Register& T1 = r12;
+
+ if (iteration % 4 > 0) {
+ addq(old_h, y2); //h = k + w + h + S0 + S1 + CH = t1 + S0;
+ }
+ movq(y2, f); //y2 = f; CH
+ rorxq(y0, e, 41); //y0 = e >> 41; S1A
+ rorxq(y1, e, 18); //y1 = e >> 18; S1B
+ xorq(y2, g); //y2 = f^g; CH
+
+ xorq(y0, y1); //y0 = (e >> 41) ^ (e >> 18); S1
+ rorxq(y1, e, 14); //y1 = (e >> 14); S1
+ andq(y2, e); //y2 = (f^g)&e; CH
+
+ if (iteration % 4 > 0 ) {
+ addq(old_h, y3); //h = t1 + S0 + MAJ
+ }
+ xorq(y0, y1); //y0 = (e >> 41) ^ (e >> 18) ^ (e >> 14); S1
+ rorxq(T1, a, 34); //T1 = a >> 34; S0B
+ xorq(y2, g); //y2 = CH = ((f^g)&e) ^g; CH
+ rorxq(y1, a, 39); //y1 = a >> 39; S0A
+ movq(y3, a); //y3 = a; MAJA
+
+ xorq(y1, T1); //y1 = (a >> 39) ^ (a >> 34); S0
+ rorxq(T1, a, 28); //T1 = (a >> 28); S0
+ addq(h, Address(rsp, (8 * iteration))); //h = k + w + h; --
+ orq(y3, c); //y3 = a | c; MAJA
+
+ xorq(y1, T1); //y1 = (a >> 39) ^ (a >> 34) ^ (a >> 28); S0
+ movq(T1, a); //T1 = a; MAJB
+ andq(y3, b); //y3 = (a | c)&b; MAJA
+ andq(T1, c); //T1 = a&c; MAJB
+ addq(y2, y0); //y2 = S1 + CH; --
+
+ addq(d, h); //d = k + w + h + d; --
+ orq(y3, T1); //y3 = MAJ = (a | c)&b) | (a&c); MAJ
+ addq(h, y1); //h = k + w + h + S0; --
+
+ addq(d, y2); //d = k + w + h + d + S1 + CH = d + t1; --
+
+ if (iteration % 4 == 3) {
+ addq(h, y2); //h = k + w + h + S0 + S1 + CH = t1 + S0; --
+ addq(h, y3); //h = t1 + S0 + MAJ; --
+ }
+}
+
+void MacroAssembler::sha512_AVX2_one_round_and_schedule(
+ XMMRegister xmm4, // ymm4
+ XMMRegister xmm5, // ymm5
+ XMMRegister xmm6, // ymm6
+ XMMRegister xmm7, // ymm7
+ Register a, //rax
+ Register b, //rbx
+ Register c, //rdi
+ Register d, //rsi
+ Register e, //r8
+ Register f, //r9
+ Register g, //r10
+ Register h, //r11
+ int iteration)
+{
+
+ const Register& y0 = r13;
+ const Register& y1 = r14;
+ const Register& y2 = r15;
+#ifdef _WIN64
+ const Register& y3 = rcx;
+#else
+ const Register& y3 = rdi;
+#endif
+ const Register& T1 = r12;
+
+ if (iteration % 4 == 0) {
+ // Extract w[t - 7]
+ // xmm0 = W[-7]
+ vperm2f128(xmm0, xmm7, xmm6, 3);
+ vpalignr(xmm0, xmm0, xmm6, 8, AVX_256bit);
+
+ // Calculate w[t - 16] + w[t - 7]
+ vpaddq(xmm0, xmm0, xmm4, AVX_256bit); //xmm0 = W[-7] + W[-16]
+ // Extract w[t - 15]
+ //xmm1 = W[-15]
+ vperm2f128(xmm1, xmm5, xmm4, 3);
+ vpalignr(xmm1, xmm1, xmm4, 8, AVX_256bit);
+
+ // Calculate sigma0
+ // Calculate w[t - 15] ror 1
+ vpsrlq(xmm2, xmm1, 1, AVX_256bit);
+ vpsllq(xmm3, xmm1, (64 - 1), AVX_256bit);
+ vpor(xmm3, xmm3, xmm2, AVX_256bit); //xmm3 = W[-15] ror 1
+ // Calculate w[t - 15] shr 7
+ vpsrlq(xmm8, xmm1, 7, AVX_256bit); //xmm8 = W[-15] >> 7
+
+ } else if (iteration % 4 == 1) {
+ //Calculate w[t - 15] ror 8
+ vpsrlq(xmm2, xmm1, 8, AVX_256bit);
+ vpsllq(xmm1, xmm1, (64 - 8), AVX_256bit);
+ vpor(xmm1, xmm1, xmm2, AVX_256bit); //xmm1 = W[-15] ror 8
+
+ //XOR the three components
+ vpxor(xmm3, xmm3, xmm8, AVX_256bit); //xmm3 = W[-15] ror 1 ^ W[-15] >> 7
+ vpxor(xmm1, xmm3, xmm1, AVX_256bit); //xmm1 = s0
+
+ //Add three components, w[t - 16], w[t - 7] and sigma0
+ vpaddq(xmm0, xmm0, xmm1, AVX_256bit); //xmm0 = W[-16] + W[-7] + s0
+
+ // Move to appropriate lanes for calculating w[16] and w[17]
+ vperm2f128(xmm4, xmm0, xmm0, 0); //xmm4 = W[-16] + W[-7] + s0{ BABA }
+
+ address MASK_YMM_LO = StubRoutines::x86::pshuffle_byte_flip_mask_addr_sha512();
+ //Move to appropriate lanes for calculating w[18] and w[19]
+ vpand(xmm0, xmm0, ExternalAddress(MASK_YMM_LO + 32), AVX_256bit); //xmm0 = W[-16] + W[-7] + s0{ DC00 }
+ //Calculate w[16] and w[17] in both 128 bit lanes
+ //Calculate sigma1 for w[16] and w[17] on both 128 bit lanes
+ vperm2f128(xmm2, xmm7, xmm7, 17); //xmm2 = W[-2] {BABA}
+ vpsrlq(xmm8, xmm2, 6, AVX_256bit); //xmm8 = W[-2] >> 6 {BABA}
+
+ } else if (iteration % 4 == 2) {
+ vpsrlq(xmm3, xmm2, 19, AVX_256bit); //xmm3 = W[-2] >> 19 {BABA}
+ vpsllq(xmm1, xmm2, (64 - 19), AVX_256bit); //xmm1 = W[-2] << 19 {BABA}
+ vpor(xmm3, xmm3, xmm1, AVX_256bit); //xmm3 = W[-2] ror 19 {BABA}
+ vpxor(xmm8, xmm8, xmm3, AVX_256bit);// xmm8 = W[-2] ror 19 ^ W[-2] >> 6 {BABA}
+ vpsrlq(xmm3, xmm2, 61, AVX_256bit); //xmm3 = W[-2] >> 61 {BABA}
+ vpsllq(xmm1, xmm2, (64 - 61), AVX_256bit); //xmm1 = W[-2] << 61 {BABA}
+ vpor(xmm3, xmm3, xmm1, AVX_256bit); //xmm3 = W[-2] ror 61 {BABA}
+ vpxor(xmm8, xmm8, xmm3, AVX_256bit); //xmm8 = s1 = (W[-2] ror 19) ^ (W[-2] ror 61) ^ (W[-2] >> 6) { BABA }
+
+ //Add sigma1 to the other components to get w[16] and w[17]
+ vpaddq(xmm4, xmm4, xmm8, AVX_256bit); //xmm4 = { W[1], W[0], W[1], W[0] }
+
+ //Calculate sigma1 for w[18] and w[19] for upper 128 bit lane
+ vpsrlq(xmm8, xmm4, 6, AVX_256bit); //xmm8 = W[-2] >> 6 {DC--}
+
+ } else if (iteration % 4 == 3){
+ vpsrlq(xmm3, xmm4, 19, AVX_256bit); //xmm3 = W[-2] >> 19 {DC--}
+ vpsllq(xmm1, xmm4, (64 - 19), AVX_256bit); //xmm1 = W[-2] << 19 {DC--}
+ vpor(xmm3, xmm3, xmm1, AVX_256bit); //xmm3 = W[-2] ror 19 {DC--}
+ vpxor(xmm8, xmm8, xmm3, AVX_256bit); //xmm8 = W[-2] ror 19 ^ W[-2] >> 6 {DC--}
+ vpsrlq(xmm3, xmm4, 61, AVX_256bit); //xmm3 = W[-2] >> 61 {DC--}
+ vpsllq(xmm1, xmm4, (64 - 61), AVX_256bit); //xmm1 = W[-2] << 61 {DC--}
+ vpor(xmm3, xmm3, xmm1, AVX_256bit); //xmm3 = W[-2] ror 61 {DC--}
+ vpxor(xmm8, xmm8, xmm3, AVX_256bit); //xmm8 = s1 = (W[-2] ror 19) ^ (W[-2] ror 61) ^ (W[-2] >> 6) { DC-- }
+
+ //Add the sigma0 + w[t - 7] + w[t - 16] for w[18] and w[19] to newly calculated sigma1 to get w[18] and w[19]
+ vpaddq(xmm2, xmm0, xmm8, AVX_256bit); //xmm2 = { W[3], W[2], --, -- }
+
+ //Form w[19, w[18], w17], w[16]
+ vpblendd(xmm4, xmm4, xmm2, 0xF0, AVX_256bit); //xmm4 = { W[3], W[2], W[1], W[0] }
+ }
+
+ movq(y3, a); //y3 = a; MAJA
+ rorxq(y0, e, 41); // y0 = e >> 41; S1A
+ rorxq(y1, e, 18); //y1 = e >> 18; S1B
+ addq(h, Address(rsp, (iteration * 8))); //h = k + w + h; --
+ orq(y3, c); //y3 = a | c; MAJA
+ movq(y2, f); //y2 = f; CH
+
+ xorq(y2, g); //y2 = f^g; CH
+
+ rorxq(T1, a, 34); //T1 = a >> 34; S0B
+ xorq(y0, y1); //y0 = (e >> 41) ^ (e >> 18); S1
+
+ rorxq(y1, e, 14); //y1 = (e >> 14); S1
+
+ andq(y2, e); //y2 = (f^g) & e; CH
+ addq(d, h); //d = k + w + h + d; --
+
+ andq(y3, b); //y3 = (a | c)&b; MAJA
+ xorq(y0, y1); //y0 = (e >> 41) ^ (e >> 18) ^ (e >> 14); S1
+ rorxq(y1, a, 39); //y1 = a >> 39; S0A
+
+ xorq(y1, T1); //y1 = (a >> 39) ^ (a >> 34); S0
+ rorxq(T1, a, 28); //T1 = (a >> 28); S0
+ xorq(y2, g); //y2 = CH = ((f^g)&e) ^ g; CH
+
+ xorq(y1, T1); //y1 = (a >> 39) ^ (a >> 34) ^ (a >> 28); S0
+ movq(T1, a); //T1 = a; MAJB
+
+ andq(T1, c); //T1 = a&c; MAJB
+ addq(y2, y0); //y2 = S1 + CH; --
+
+ orq(y3, T1); //y3 = MAJ = (a | c)&b) | (a&c); MAJ
+ addq(h, y1); //h = k + w + h + S0; --
+
+ addq(d, y2); //d = k + w + h + d + S1 + CH = d + t1; --
+ addq(h, y2); //h = k + w + h + S0 + S1 + CH = t1 + S0; --
+ addq(h, y3); //h = t1 + S0 + MAJ; --
+}
+
+void MacroAssembler::sha512_AVX2(XMMRegister msg, XMMRegister state0, XMMRegister state1, XMMRegister msgtmp0,
+ XMMRegister msgtmp1, XMMRegister msgtmp2, XMMRegister msgtmp3, XMMRegister msgtmp4,
+ Register buf, Register state, Register ofs, Register limit, Register rsp,
+ bool multi_block, XMMRegister shuf_mask)
+{
+
+ Label loop0, loop1, loop2, done_hash,
+ compute_block_size, compute_size,
+ compute_block_size_end, compute_size_end;
+
+ address K512_W = StubRoutines::x86::k512_W_addr();
+ address pshuffle_byte_flip_mask_sha512 = StubRoutines::x86::pshuffle_byte_flip_mask_addr_sha512();
+ address pshuffle_byte_flip_mask_addr = 0;
+
+ const XMMRegister& XFER = xmm0; // YTMP0
+ const XMMRegister& BYTE_FLIP_MASK = xmm9; // ymm9
+#ifdef _WIN64
+ const Register& INP = rcx; //1st arg
+ const Register& CTX = rdx; //2nd arg
+ const Register& NUM_BLKS = r8; //3rd arg
+ const Register& c = rdi;
+ const Register& d = rsi;
+ const Register& e = r8;
+ const Register& y3 = rcx;
+ const Register& offset = r8;
+ const Register& input_limit = r9;
+#else
+ const Register& INP = rdi; //1st arg
+ const Register& CTX = rsi; //2nd arg
+ const Register& NUM_BLKS = rdx; //3rd arg
+ const Register& c = rcx;
+ const Register& d = r8;
+ const Register& e = rdx;
+ const Register& y3 = rdi;
+ const Register& offset = rdx;
+ const Register& input_limit = rcx;
+#endif
+
+ const Register& TBL = rbp;
+
+ const Register& a = rax;
+ const Register& b = rbx;
+
+ const Register& f = r9;
+ const Register& g = r10;
+ const Register& h = r11;
+
+ //Local variables as defined in assembly file.
+ enum
+ {
+ _XFER_SIZE = 4 * 8, // resq 4 => reserve 4 quadwords. Hence 4 * 8
+ _SRND_SIZE = 8, // resq 1
+ _INP_SIZE = 8,
+ _INP_END_SIZE = 8,
+ _RSP_SAVE_SIZE = 8, // defined as resq 1
+
+#ifdef _WIN64
+ _GPR_SAVE_SIZE = 8 * 8, // defined as resq 8
+#else
+ _GPR_SAVE_SIZE = 6 * 8 // resq 6
+#endif
+ };
+
+ enum
+ {
+ _XFER = 0,
+ _SRND = _XFER + _XFER_SIZE, // 32
+ _INP = _SRND + _SRND_SIZE, // 40
+ _INP_END = _INP + _INP_SIZE, // 48
+ _RSP = _INP_END + _INP_END_SIZE, // 56
+ _GPR = _RSP + _RSP_SAVE_SIZE, // 64
+ _STACK_SIZE = _GPR + _GPR_SAVE_SIZE // 128 for windows and 112 for linux.
+ };
+
+//Saving offset and limit as it will help with blocksize calculation for multiblock SHA512.
+#ifdef _WIN64
+ push(r8); // win64: this is ofs
+ push(r9); // win64: this is limit, we need them again at the very end.
+#else
+ push(rdx); // linux : this is ofs, need at the end for multiblock calculation
+ push(rcx); // linux: This is the limit.
+#endif
+
+ //Allocate Stack Space
+ movq(rax, rsp);
+ subq(rsp, _STACK_SIZE);
+ andq(rsp, -32);
+ movq(Address(rsp, _RSP), rax);
+
+ //Save GPRs
+ movq(Address(rsp, _GPR), rbp);
+ movq(Address(rsp, (_GPR + 8)), rbx);
+ movq(Address(rsp, (_GPR + 16)), r12);
+ movq(Address(rsp, (_GPR + 24)), r13);
+ movq(Address(rsp, (_GPR + 32)), r14);
+ movq(Address(rsp, (_GPR + 40)), r15);
+
+#ifdef _WIN64
+ movq(Address(rsp, (_GPR + 48)), rsi);
+ movq(Address(rsp, (_GPR + 56)), rdi);
+#endif
+
+ vpblendd(xmm0, xmm0, xmm1, 0xF0, AVX_128bit);
+ vpblendd(xmm0, xmm0, xmm1, 0xF0, AVX_256bit);
+
+ if (multi_block) {
+ xorq(rax, rax);
+ bind(compute_block_size);
+ cmpptr(offset, input_limit); // Assuming that offset is less than limit.
+ jccb(Assembler::aboveEqual, compute_block_size_end);
+ addq(offset, 128);
+ addq(rax, 128);
+ jmpb(compute_block_size);
+
+ bind(compute_block_size_end);
+ movq(NUM_BLKS, rax);
+
+ cmpq(NUM_BLKS, 0);
+ jcc(Assembler::equal, done_hash);
+ } else {
+ xorq(NUM_BLKS, NUM_BLKS); //If single block.
+ addq(NUM_BLKS, 128);
+ }
+
+ addq(NUM_BLKS, INP); //pointer to end of data
+ movq(Address(rsp, _INP_END), NUM_BLKS);
+
+ //load initial digest
+ movq(a, Address(CTX, 8 * 0));
+ movq(b, Address(CTX, 8 * 1));
+ movq(c, Address(CTX, 8 * 2));
+ movq(d, Address(CTX, 8 * 3));
+ movq(e, Address(CTX, 8 * 4));
+ movq(f, Address(CTX, 8 * 5));
+ movq(g, Address(CTX, 8 * 6));
+ movq(h, Address(CTX, 8 * 7));
+
+ pshuffle_byte_flip_mask_addr = pshuffle_byte_flip_mask_sha512;
+ vmovdqu(BYTE_FLIP_MASK, ExternalAddress(pshuffle_byte_flip_mask_addr + 0)); //PSHUFFLE_BYTE_FLIP_MASK wrt rip
+
+ bind(loop0);
+ lea(TBL, ExternalAddress(K512_W));
+
+ //byte swap first 16 dwords
+ vmovdqu(xmm4, Address(INP, 32 * 0));
+ vpshufb(xmm4, xmm4, BYTE_FLIP_MASK, AVX_256bit);
+ vmovdqu(xmm5, Address(INP, 32 * 1));
+ vpshufb(xmm5, xmm5, BYTE_FLIP_MASK, AVX_256bit);
+ vmovdqu(xmm6, Address(INP, 32 * 2));
+ vpshufb(xmm6, xmm6, BYTE_FLIP_MASK, AVX_256bit);
+ vmovdqu(xmm7, Address(INP, 32 * 3));
+ vpshufb(xmm7, xmm7, BYTE_FLIP_MASK, AVX_256bit);
+
+ movq(Address(rsp, _INP), INP);
+
+ movslq(Address(rsp, _SRND), 4);
+ align(16);
+
+ //Schedule 64 input dwords, by calling sha512_AVX2_one_round_and_schedule
+ bind(loop1);
+ vpaddq(xmm0, xmm4, Address(TBL, 0 * 32), AVX_256bit);
+ vmovdqu(Address(rsp, _XFER), xmm0);
+ //four rounds and schedule
+ sha512_AVX2_one_round_and_schedule(xmm4, xmm5, xmm6, xmm7, a, b, c, d, e, f, g, h, 0);
+ sha512_AVX2_one_round_and_schedule(xmm4, xmm5, xmm6, xmm7, h, a, b, c, d, e, f, g, 1);
+ sha512_AVX2_one_round_and_schedule(xmm4, xmm5, xmm6, xmm7, g, h, a, b, c, d, e, f, 2);
+ sha512_AVX2_one_round_and_schedule(xmm4, xmm5, xmm6, xmm7, f, g, h, a, b, c, d, e, 3);
+
+ vpaddq(xmm0, xmm5, Address(TBL, 1 * 32), AVX_256bit);
+ vmovdqu(Address(rsp, _XFER), xmm0);
+ //four rounds and schedule
+ sha512_AVX2_one_round_and_schedule(xmm5, xmm6, xmm7, xmm4, e, f, g, h, a, b, c, d, 0);
+ sha512_AVX2_one_round_and_schedule(xmm5, xmm6, xmm7, xmm4, d, e, f, g, h, a, b, c, 1);
+ sha512_AVX2_one_round_and_schedule(xmm5, xmm6, xmm7, xmm4, c, d, e, f, g, h, a, b, 2);
+ sha512_AVX2_one_round_and_schedule(xmm5, xmm6, xmm7, xmm4, b, c, d, e, f, g, h, a, 3);
+
+ vpaddq(xmm0, xmm6, Address(TBL, 2 * 32), AVX_256bit);
+ vmovdqu(Address(rsp, _XFER), xmm0);
+ //four rounds and schedule
+ sha512_AVX2_one_round_and_schedule(xmm6, xmm7, xmm4, xmm5, a, b, c, d, e, f, g, h, 0);
+ sha512_AVX2_one_round_and_schedule(xmm6, xmm7, xmm4, xmm5, h, a, b, c, d, e, f, g, 1);
+ sha512_AVX2_one_round_and_schedule(xmm6, xmm7, xmm4, xmm5, g, h, a, b, c, d, e, f, 2);
+ sha512_AVX2_one_round_and_schedule(xmm6, xmm7, xmm4, xmm5, f, g, h, a, b, c, d, e, 3);
+
+ vpaddq(xmm0, xmm7, Address(TBL, 3 * 32), AVX_256bit);
+ vmovdqu(Address(rsp, _XFER), xmm0);
+ addq(TBL, 4 * 32);
+ //four rounds and schedule
+ sha512_AVX2_one_round_and_schedule(xmm7, xmm4, xmm5, xmm6, e, f, g, h, a, b, c, d, 0);
+ sha512_AVX2_one_round_and_schedule(xmm7, xmm4, xmm5, xmm6, d, e, f, g, h, a, b, c, 1);
+ sha512_AVX2_one_round_and_schedule(xmm7, xmm4, xmm5, xmm6, c, d, e, f, g, h, a, b, 2);
+ sha512_AVX2_one_round_and_schedule(xmm7, xmm4, xmm5, xmm6, b, c, d, e, f, g, h, a, 3);
+
+ subq(Address(rsp, _SRND), 1);
+ jcc(Assembler::notEqual, loop1);
+
+ movslq(Address(rsp, _SRND), 2);
+
+ bind(loop2);
+ vpaddq(xmm0, xmm4, Address(TBL, 0 * 32), AVX_256bit);
+ vmovdqu(Address(rsp, _XFER), xmm0);
+ //four rounds and compute.
+ sha512_AVX2_one_round_compute(a, a, b, c, d, e, f, g, h, 0);
+ sha512_AVX2_one_round_compute(h, h, a, b, c, d, e, f, g, 1);
+ sha512_AVX2_one_round_compute(g, g, h, a, b, c, d, e, f, 2);
+ sha512_AVX2_one_round_compute(f, f, g, h, a, b, c, d, e, 3);
+
+ vpaddq(xmm0, xmm5, Address(TBL, 1 * 32), AVX_256bit);
+ vmovdqu(Address(rsp, _XFER), xmm0);
+ addq(TBL, 2 * 32);
+ // four rounds and compute.
+ sha512_AVX2_one_round_compute(e, e, f, g, h, a, b, c, d, 0);
+ sha512_AVX2_one_round_compute(d, d, e, f, g, h, a, b, c, 1);
+ sha512_AVX2_one_round_compute(c, c, d, e, f, g, h, a, b, 2);
+ sha512_AVX2_one_round_compute(b, b, c, d, e, f, g, h, a, 3);
+
+ vmovdqu(xmm4, xmm6);
+ vmovdqu(xmm5, xmm7);
+
+ subq(Address(rsp, _SRND), 1);
+ jcc(Assembler::notEqual, loop2);
+
+ addmq(8 * 0, CTX, a);
+ addmq(8 * 1, CTX, b);
+ addmq(8 * 2, CTX, c);
+ addmq(8 * 3, CTX, d);
+ addmq(8 * 4, CTX, e);
+ addmq(8 * 5, CTX, f);
+ addmq(8 * 6, CTX, g);
+ addmq(8 * 7, CTX, h);
+
+ movq(INP, Address(rsp, _INP));
+ addq(INP, 128);
+ cmpq(INP, Address(rsp, _INP_END));
+ jcc(Assembler::notEqual, loop0);
+
+ bind(done_hash);
+
+ //Restore GPRs
+ movq(rbp, Address(rsp, (_GPR + 0)));
+ movq(rbx, Address(rsp, (_GPR + 8)));
+ movq(r12, Address(rsp, (_GPR + 16)));
+ movq(r13, Address(rsp, (_GPR + 24)));
+ movq(r14, Address(rsp, (_GPR + 32)));
+ movq(r15, Address(rsp, (_GPR + 40)));
+
+#ifdef _WIN64
+ movq(rsi, Address(rsp, (_GPR + 48)));
+ movq(rdi, Address(rsp, (_GPR + 56)));
+#endif
+
+ //Restore Stack Pointer
+ movq(rsp, Address(rsp, _RSP));
+
+#ifdef _WIN64
+ pop(r9);
+ pop(r8);
+#else
+ pop(rcx);
+ pop(rdx);
+#endif
+
+ if (multi_block) {
+#ifdef _WIN64
+ const Register& limit_end = r9;
+ const Register& ofs_end = r8;
+#else
+ const Register& limit_end = rcx;
+ const Register& ofs_end = rdx;
+#endif
+ movq(rax, ofs_end);
+ bind(compute_size);
+ cmpptr(rax, limit_end);
+ jccb(Assembler::aboveEqual, compute_size_end);
+ addq(rax, 128);
+ jmpb(compute_size);
+ bind(compute_size_end);
+ }
+}
+
#endif //#ifdef _LP64
+
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -3718,6 +3718,25 @@
return start;
}
+ //Mask for byte-swapping a couple of qwords in an XMM register using (v)pshufb.
+ address generate_pshuffle_byte_flip_mask_sha512() {
+ __ align(32);
+ StubCodeMark mark(this, "StubRoutines", "pshuffle_byte_flip_mask_sha512");
+ address start = __ pc();
+ if (VM_Version::supports_avx2()) {
+ __ emit_data64(0x0001020304050607, relocInfo::none); // PSHUFFLE_BYTE_FLIP_MASK
+ __ emit_data64(0x08090a0b0c0d0e0f, relocInfo::none);
+ __ emit_data64(0x1011121314151617, relocInfo::none);
+ __ emit_data64(0x18191a1b1c1d1e1f, relocInfo::none);
+ __ emit_data64(0x0000000000000000, relocInfo::none); //MASK_YMM_LO
+ __ emit_data64(0x0000000000000000, relocInfo::none);
+ __ emit_data64(0xFFFFFFFFFFFFFFFF, relocInfo::none);
+ __ emit_data64(0xFFFFFFFFFFFFFFFF, relocInfo::none);
+ }
+
+ return start;
+ }
+
// ofs and limit are use for multi-block byte array.
// int com.sun.security.provider.DigestBase.implCompressMultiBlock(byte[] b, int ofs, int limit)
address generate_sha256_implCompress(bool multi_block, const char *name) {
@@ -3761,6 +3780,39 @@
return start;
}
+ address generate_sha512_implCompress(bool multi_block, const char *name) {
+ assert(VM_Version::supports_avx2(), "");
+ assert(VM_Version::supports_bmi2(), "");
+ __ align(CodeEntryAlignment);
+ StubCodeMark mark(this, "StubRoutines", name);
+ address start = __ pc();
+
+ Register buf = c_rarg0;
+ Register state = c_rarg1;
+ Register ofs = c_rarg2;
+ Register limit = c_rarg3;
+
+ const XMMRegister msg = xmm0;
+ const XMMRegister state0 = xmm1;
+ const XMMRegister state1 = xmm2;
+ const XMMRegister msgtmp0 = xmm3;
+ const XMMRegister msgtmp1 = xmm4;
+ const XMMRegister msgtmp2 = xmm5;
+ const XMMRegister msgtmp3 = xmm6;
+ const XMMRegister msgtmp4 = xmm7;
+
+ const XMMRegister shuf_mask = xmm8;
+
+ __ enter();
+
+ __ sha512_AVX2(msg, state0, state1, msgtmp0, msgtmp1, msgtmp2, msgtmp3, msgtmp4,
+ buf, state, ofs, limit, rsp, multi_block, shuf_mask);
+
+ __ leave();
+ __ ret(0);
+ return start;
+ }
+
// This is a version of CTR/AES crypt which does 6 blocks in a loop at a time
// to hide instruction latency
//
@@ -5081,6 +5133,12 @@
StubRoutines::_sha256_implCompress = generate_sha256_implCompress(false, "sha256_implCompress");
StubRoutines::_sha256_implCompressMB = generate_sha256_implCompress(true, "sha256_implCompressMB");
}
+ if (UseSHA512Intrinsics) {
+ StubRoutines::x86::_k512_W_addr = (address)StubRoutines::x86::_k512_W;
+ StubRoutines::x86::_pshuffle_byte_flip_mask_addr_sha512 = generate_pshuffle_byte_flip_mask_sha512();
+ StubRoutines::_sha512_implCompress = generate_sha512_implCompress(false, "sha512_implCompress");
+ StubRoutines::_sha512_implCompressMB = generate_sha512_implCompress(true, "sha512_implCompressMB");
+ }
// Generate GHASH intrinsics code
if (UseGHASHIntrinsics) {
--- a/hotspot/src/cpu/x86/vm/stubRoutines_x86.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/cpu/x86/vm/stubRoutines_x86.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -48,6 +48,8 @@
address StubRoutines::x86::_k256_adr = NULL;
#ifdef _LP64
address StubRoutines::x86::_k256_W_adr = NULL;
+address StubRoutines::x86::_k512_W_addr = NULL;
+address StubRoutines::x86::_pshuffle_byte_flip_mask_addr_sha512 = NULL;
#endif
address StubRoutines::x86::_pshuffle_byte_flip_mask_addr = NULL;
@@ -297,4 +299,49 @@
// used in MacroAssembler::sha256_AVX2
// dynamically built from _k256
ALIGNED_(64) juint StubRoutines::x86::_k256_W[2*sizeof(StubRoutines::x86::_k256)];
+
+// used in MacroAssembler::sha512_AVX2
+ALIGNED_(64) julong StubRoutines::x86::_k512_W[] =
+{
+ 0x428a2f98d728ae22LL, 0x7137449123ef65cdLL,
+ 0xb5c0fbcfec4d3b2fLL, 0xe9b5dba58189dbbcLL,
+ 0x3956c25bf348b538LL, 0x59f111f1b605d019LL,
+ 0x923f82a4af194f9bLL, 0xab1c5ed5da6d8118LL,
+ 0xd807aa98a3030242LL, 0x12835b0145706fbeLL,
+ 0x243185be4ee4b28cLL, 0x550c7dc3d5ffb4e2LL,
+ 0x72be5d74f27b896fLL, 0x80deb1fe3b1696b1LL,
+ 0x9bdc06a725c71235LL, 0xc19bf174cf692694LL,
+ 0xe49b69c19ef14ad2LL, 0xefbe4786384f25e3LL,
+ 0x0fc19dc68b8cd5b5LL, 0x240ca1cc77ac9c65LL,
+ 0x2de92c6f592b0275LL, 0x4a7484aa6ea6e483LL,
+ 0x5cb0a9dcbd41fbd4LL, 0x76f988da831153b5LL,
+ 0x983e5152ee66dfabLL, 0xa831c66d2db43210LL,
+ 0xb00327c898fb213fLL, 0xbf597fc7beef0ee4LL,
+ 0xc6e00bf33da88fc2LL, 0xd5a79147930aa725LL,
+ 0x06ca6351e003826fLL, 0x142929670a0e6e70LL,
+ 0x27b70a8546d22ffcLL, 0x2e1b21385c26c926LL,
+ 0x4d2c6dfc5ac42aedLL, 0x53380d139d95b3dfLL,
+ 0x650a73548baf63deLL, 0x766a0abb3c77b2a8LL,
+ 0x81c2c92e47edaee6LL, 0x92722c851482353bLL,
+ 0xa2bfe8a14cf10364LL, 0xa81a664bbc423001LL,
+ 0xc24b8b70d0f89791LL, 0xc76c51a30654be30LL,
+ 0xd192e819d6ef5218LL, 0xd69906245565a910LL,
+ 0xf40e35855771202aLL, 0x106aa07032bbd1b8LL,
+ 0x19a4c116b8d2d0c8LL, 0x1e376c085141ab53LL,
+ 0x2748774cdf8eeb99LL, 0x34b0bcb5e19b48a8LL,
+ 0x391c0cb3c5c95a63LL, 0x4ed8aa4ae3418acbLL,
+ 0x5b9cca4f7763e373LL, 0x682e6ff3d6b2b8a3LL,
+ 0x748f82ee5defb2fcLL, 0x78a5636f43172f60LL,
+ 0x84c87814a1f0ab72LL, 0x8cc702081a6439ecLL,
+ 0x90befffa23631e28LL, 0xa4506cebde82bde9LL,
+ 0xbef9a3f7b2c67915LL, 0xc67178f2e372532bLL,
+ 0xca273eceea26619cLL, 0xd186b8c721c0c207LL,
+ 0xeada7dd6cde0eb1eLL, 0xf57d4f7fee6ed178LL,
+ 0x06f067aa72176fbaLL, 0x0a637dc5a2c898a6LL,
+ 0x113f9804bef90daeLL, 0x1b710b35131c471bLL,
+ 0x28db77f523047d84LL, 0x32caab7b40c72493LL,
+ 0x3c9ebe0a15c9bebcLL, 0x431d67c49c100d4cLL,
+ 0x4cc5d4becb3e42b6LL, 0x597f299cfc657e2aLL,
+ 0x5fcb6fab3ad6faecLL, 0x6c44198c4a475817LL,
+};
#endif
--- a/hotspot/src/cpu/x86/vm/stubRoutines_x86.hpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/cpu/x86/vm/stubRoutines_x86.hpp Wed Oct 26 20:13:29 2016 +0000
@@ -33,7 +33,7 @@
enum platform_dependent_constants {
code_size1 = 20000 LP64_ONLY(+10000), // simply increase if too small (assembler will crash if too small)
- code_size2 = 33800 LP64_ONLY(+1200) // simply increase if too small (assembler will crash if too small)
+ code_size2 = 33800 LP64_ONLY(+10000) // simply increase if too small (assembler will crash if too small)
};
class x86 {
@@ -134,6 +134,10 @@
#ifdef _LP64
static juint _k256_W[];
static address _k256_W_adr;
+ static julong _k512_W[];
+ static address _k512_W_addr;
+ // byte flip mask for sha512
+ static address _pshuffle_byte_flip_mask_addr_sha512;
#endif
// byte flip mask for sha256
static address _pshuffle_byte_flip_mask_addr;
@@ -192,6 +196,8 @@
static address k256_addr() { return _k256_adr; }
#ifdef _LP64
static address k256_W_addr() { return _k256_W_adr; }
+ static address k512_W_addr() { return _k512_W_addr; }
+ static address pshuffle_byte_flip_mask_addr_sha512() { return _pshuffle_byte_flip_mask_addr_sha512; }
#endif
static address pshuffle_byte_flip_mask_addr() { return _pshuffle_byte_flip_mask_addr; }
static void generate_CRC32C_table(bool is_pclmulqdq_supported);
--- a/hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -254,8 +254,9 @@
const Register thread = NOT_LP64(rcx) LP64_ONLY(r15_thread);
NOT_LP64(__ get_thread(thread));
#if INCLUDE_JVMCI
- // Check if we need to take lock at entry of synchronized method.
- if (UseJVMCICompiler) {
+ // Check if we need to take lock at entry of synchronized method. This can
+ // only occur on method entry so emit it only for vtos with step 0.
+ if (UseJVMCICompiler && state == vtos && step == 0) {
Label L;
__ cmpb(Address(thread, JavaThread::pending_monitorenter_offset()), 0);
__ jcc(Assembler::zero, L);
@@ -266,6 +267,16 @@
// Take lock.
lock_method();
__ bind(L);
+ } else {
+#ifdef ASSERT
+ if (UseJVMCICompiler) {
+ Label L;
+ __ cmpb(Address(r15_thread, JavaThread::pending_monitorenter_offset()), 0);
+ __ jccb(Assembler::zero, L);
+ __ stop("unexpected pending monitor in deopt entry");
+ __ bind(L);
+ }
+#endif
}
#endif
// handle exceptions
--- a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -769,7 +769,11 @@
FLAG_SET_DEFAULT(UseSHA256Intrinsics, false);
}
- if (UseSHA512Intrinsics) {
+ if (UseSHA) {
+ if (FLAG_IS_DEFAULT(UseSHA512Intrinsics)) {
+ FLAG_SET_DEFAULT(UseSHA512Intrinsics, true);
+ }
+ } else if (UseSHA512Intrinsics) {
warning("Intrinsics for SHA-384 and SHA-512 crypto hash functions not available on this CPU.");
FLAG_SET_DEFAULT(UseSHA512Intrinsics, false);
}
--- a/hotspot/src/cpu/x86/vm/x86.ad Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/cpu/x86/vm/x86.ad Wed Oct 26 20:13:29 2016 +0000
@@ -8173,13 +8173,13 @@
match(Set dst (CMoveVD (Binary copnd cop) (Binary src1 src2)));
effect(TEMP dst, USE src1, USE src2);
format %{ "cmppd.$copnd $dst, $src1, $src2 ! vcmovevd, cond=$cop\n\t"
- "vpblendd $dst,$src1,$src2,$dst ! vcmovevd\n\t"
+ "blendvpd $dst,$src1,$src2,$dst ! vcmovevd\n\t"
%}
ins_encode %{
int vector_len = 1;
int cond = (Assembler::Condition)($copnd$$cmpcode);
__ cmppd($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, cond, vector_len);
- __ vpblendd($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, $dst$$XMMRegister, vector_len);
+ __ blendvpd($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, $dst$$XMMRegister, vector_len);
%}
ins_pipe( pipe_slow );
%}
--- a/hotspot/src/jdk.hotspot.agent/macosx/native/libsaproc/MacosxDebuggerLocal.m Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/jdk.hotspot.agent/macosx/native/libsaproc/MacosxDebuggerLocal.m Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2014, 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
@@ -25,6 +25,7 @@
#include <objc/objc-runtime.h>
#import <Foundation/Foundation.h>
#import <JavaNativeFoundation/JavaNativeFoundation.h>
+#import <JavaRuntimeSupport/JavaRuntimeSupport.h>
#include <jni.h>
--- a/hotspot/src/jdk.hotspot.agent/solaris/native/libsaproc/libproc.h Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/jdk.hotspot.agent/solaris/native/libsaproc/libproc.h Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2011, 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
@@ -420,8 +420,6 @@
/*
* Stack frame iteration interface.
*/
-#ifdef SOLARIS_11_B159_OR_LATER
-/* building on Nevada-B159 or later so define the new callback */
typedef int proc_stack_f(
void *, /* the cookie given to Pstack_iter() */
const prgregset_t, /* the frame's registers */
@@ -432,10 +430,6 @@
#define PR_SIGNAL_FRAME 1 /* called by a signal handler */
#define PR_FOUND_SIGNAL 2 /* we found the corresponding signal number */
-#else
-/* building on Nevada-B158 or earlier so define the old callback */
-typedef int proc_stack_f(void *, const prgregset_t, uint_t, const long *);
-#endif
extern int Pstack_iter(struct ps_prochandle *,
const prgregset_t, proc_stack_f *, void *);
--- a/hotspot/src/jdk.hotspot.agent/solaris/native/libsaproc/salibproc.h Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/jdk.hotspot.agent/solaris/native/libsaproc/salibproc.h Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -46,6 +46,17 @@
extern "C" {
#endif
+/* extended symbol table information */
+typedef struct {
+ const char *prs_object; /* object name */
+ const char *prs_name; /* symbol name */
+ Lmid_t prs_lmid; /* link map id */
+ uint_t prs_id; /* symbol id */
+ uint_t prs_table; /* symbol table id */
+} prsyminfo_t;
+
+typedef struct ps_prochandle ps_prochandle_t;
+
/*
* 'object_name' is the name of a load object obtained from an
* iteration over the process's address space mappings (Pmapping_iter),
@@ -53,8 +64,10 @@
* or else it is one of the special PR_OBJ_* values above.
*/
-extern int Plookup_by_addr(struct ps_prochandle *,
- uintptr_t, char *, size_t, GElf_Sym *);
+extern int Plookup_by_addr(ps_prochandle_t *, uintptr_t, char *,
+ size_t, GElf_Sym *, prsyminfo_t *);
+extern ps_prochandle_t *proc_arg_grab(const char *, int, int,
+ int *, const char **);
typedef int proc_map_f(void *, const prmap_t *, const char *);
extern int Pobject_iter(struct ps_prochandle *, proc_map_f *, void *);
@@ -88,7 +101,6 @@
#define G_ELF 13 /* Libelf error, elf_errno() is meaningful */
#define G_NOTE 14 /* Required PT_NOTE Phdr not present in core */
-extern struct ps_prochandle *proc_arg_grab(const char *, int, int, int *);
extern const pstatus_t *Pstatus(struct ps_prochandle *);
/* Flags accepted by Prelease (partial) */
@@ -101,8 +113,6 @@
/*
* Stack frame iteration interface.
*/
-#ifdef SOLARIS_11_B159_OR_LATER
-/* building on Nevada-B159 or later so define the new callback */
typedef int proc_stack_f(
void *, /* the cookie given to Pstack_iter() */
const prgregset_t, /* the frame's registers */
@@ -113,10 +123,6 @@
#define PR_SIGNAL_FRAME 1 /* called by a signal handler */
#define PR_FOUND_SIGNAL 2 /* we found the corresponding signal number */
-#else
-/* building on Nevada-B158 or earlier so define the old callback */
-typedef int proc_stack_f(void *, const prgregset_t, uint_t, const long *);
-#endif
extern int Pstack_iter(struct ps_prochandle *,
const prgregset_t, proc_stack_f *, void *);
--- a/hotspot/src/jdk.hotspot.agent/solaris/native/libsaproc/saproc.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/jdk.hotspot.agent/solaris/native/libsaproc/saproc.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2013, 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
@@ -24,9 +24,6 @@
#include "salibproc.h"
#include "sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal.h"
-#ifndef SOLARIS_11_B159_OR_LATER
-#include <sys/utsname.h>
-#endif
#include <thread_db.h>
#include <strings.h>
#include <limits.h>
@@ -45,20 +42,6 @@
// debug modes
static int _libsaproc_debug = 0;
-#ifndef SOLARIS_11_B159_OR_LATER
-static bool _Pstack_iter_debug = false;
-
-static void dprintf_2(const char* format,...) {
- if (_Pstack_iter_debug) {
- va_list alist;
-
- va_start(alist, format);
- fputs("Pstack_iter DEBUG: ", stderr);
- vfprintf(stderr, format, alist);
- va_end(alist);
- }
-}
-#endif // !SOLARIS_11_B159_OR_LATER
static void print_debug(const char* format,...) {
if (_libsaproc_debug) {
@@ -757,7 +740,8 @@
#endif
// connect to process/core
- struct ps_prochandle* ph = proc_arg_grab(cmdLine_cstr, (isProcess? PR_ARG_PIDS : PR_ARG_CORES), PGRAB_FORCE, &gcode);
+ ps_prochandle_t* ph = proc_arg_grab(cmdLine_cstr, (isProcess? PR_ARG_PIDS : PR_ARG_CORES), PGRAB_FORCE, &gcode, NULL);
+
env->ReleaseStringUTFChars(cmdLine, cmdLine_cstr);
if (! ph) {
if (gcode > 0 && gcode < sizeof(proc_arg_grab_errmsgs)/sizeof(const char*)) {
@@ -997,11 +981,6 @@
TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY, TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
}
-#ifndef SOLARIS_11_B159_OR_LATER
-// building on Nevada-B158 or earlier so more hoops to jump through
-static bool has_newer_Pstack_iter = false; // older version by default
-#endif
-
/*
* Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
* Method: fillCFrameList0
@@ -1030,23 +1009,8 @@
env->ReleaseLongArrayElements(regsArray, ptr, JNI_ABORT);
CHECK_EXCEPTION_(0);
-#ifdef SOLARIS_11_B159_OR_LATER
- // building on Nevada-B159 or later so use the new callback
Pstack_iter((struct ps_prochandle*) p_ps_prochandle, gregs,
wrapper_fill_cframe_list, &dbgo2);
-#else
- // building on Nevada-B158 or earlier so figure out which callback to use
-
- if (has_newer_Pstack_iter) {
- // Since we're building on Nevada-B158 or earlier, we have to
- // cast wrapper_fill_cframe_list to make the compiler happy.
- Pstack_iter((struct ps_prochandle*) p_ps_prochandle, gregs,
- (proc_stack_f *)wrapper_fill_cframe_list, &dbgo2);
- } else {
- Pstack_iter((struct ps_prochandle*) p_ps_prochandle, gregs,
- fill_cframe_list, &dbgo2);
- }
-#endif // SOLARIS_11_B159_OR_LATER
return dbgo2.obj;
}
@@ -1236,7 +1200,8 @@
char nameBuf[SYMBOL_BUF_SIZE + 1];
GElf_Sym sym;
int res = Plookup_by_addr((struct ps_prochandle*) p_ps_prochandle, (uintptr_t) address,
- nameBuf, sizeof(nameBuf), &sym);
+ nameBuf, sizeof(nameBuf), &sym, NULL);
+
if (res != 0) { // failed
return 0;
}
@@ -1268,102 +1233,6 @@
return res;
}
-#ifndef SOLARIS_11_B159_OR_LATER
-// Determine if the OS we're running on has the newer version
-// of libproc's Pstack_iter.
-//
-// Set env var PSTACK_ITER_DEBUG=true to debug this logic.
-// Set env var PSTACK_ITER_DEBUG_RELEASE to simulate a 'release' value.
-// Set env var PSTACK_ITER_DEBUG_VERSION to simulate a 'version' value.
-//
-// frankenputer 'uname -r -v': 5.10 Generic_141445-09
-// jurassic 'uname -r -v': 5.11 snv_164
-// lonepeak 'uname -r -v': 5.11 snv_127
-//
-static void set_has_newer_Pstack_iter(JNIEnv *env) {
- static bool done_set = false;
-
- if (done_set) {
- // already set has_newer_Pstack_iter
- return;
- }
-
- struct utsname name;
- if (uname(&name) == -1) {
- THROW_NEW_DEBUGGER_EXCEPTION("uname() failed!");
- }
- dprintf_2("release='%s' version='%s'\n", name.release, name.version);
-
- if (_Pstack_iter_debug) {
- char *override = getenv("PSTACK_ITER_DEBUG_RELEASE");
- if (override != NULL) {
- strncpy(name.release, override, SYS_NMLN - 1);
- name.release[SYS_NMLN - 2] = '\0';
- dprintf_2("overriding with release='%s'\n", name.release);
- }
- override = getenv("PSTACK_ITER_DEBUG_VERSION");
- if (override != NULL) {
- strncpy(name.version, override, SYS_NMLN - 1);
- name.version[SYS_NMLN - 2] = '\0';
- dprintf_2("overriding with version='%s'\n", name.version);
- }
- }
-
- // the major number corresponds to the old SunOS major number
- int major = atoi(name.release);
- if (major >= 6) {
- dprintf_2("release is SunOS 6 or later\n");
- has_newer_Pstack_iter = true;
- done_set = true;
- return;
- }
- if (major < 5) {
- dprintf_2("release is SunOS 4 or earlier\n");
- done_set = true;
- return;
- }
-
- // some SunOS 5.* build so now check for Solaris versions
- char *dot = strchr(name.release, '.');
- int minor = 0;
- if (dot != NULL) {
- // release is major.minor format
- *dot = NULL;
- minor = atoi(dot + 1);
- }
-
- if (minor <= 10) {
- dprintf_2("release is Solaris 10 or earlier\n");
- done_set = true;
- return;
- } else if (minor >= 12) {
- dprintf_2("release is Solaris 12 or later\n");
- has_newer_Pstack_iter = true;
- done_set = true;
- return;
- }
-
- // some Solaris 11 build so now check for internal build numbers
- if (strncmp(name.version, "snv_", 4) != 0) {
- dprintf_2("release is Solaris 11 post-GA or later\n");
- has_newer_Pstack_iter = true;
- done_set = true;
- return;
- }
-
- // version begins with "snv_" so a pre-GA build of Solaris 11
- int build = atoi(&name.version[4]);
- if (build >= 159) {
- dprintf_2("release is Nevada-B159 or later\n");
- has_newer_Pstack_iter = true;
- } else {
- dprintf_2("release is Nevada-B158 or earlier\n");
- }
-
- done_set = true;
-}
-#endif // !SOLARIS_11_B159_OR_LATER
-
/*
* Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
* Method: initIDs
@@ -1383,14 +1252,6 @@
if (libproc_handle == 0)
THROW_NEW_DEBUGGER_EXCEPTION("can't load libproc.so, if you are using Solaris 5.7 or below, copy libproc.so from 5.8!");
-#ifndef SOLARIS_11_B159_OR_LATER
- _Pstack_iter_debug = getenv("PSTACK_ITER_DEBUG") != NULL;
-
- set_has_newer_Pstack_iter(env);
- CHECK_EXCEPTION;
- dprintf_2("has_newer_Pstack_iter=%d\n", has_newer_Pstack_iter);
-#endif
-
p_ps_prochandle_ID = env->GetFieldID(clazz, "p_ps_prochandle", "J");
CHECK_EXCEPTION;
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java Wed Oct 26 20:13:29 2016 +0000
@@ -171,6 +171,9 @@
return (String) getValue();
}
+ private static final int PROPERTY_LINE_WIDTH = 80;
+ private static final int PROPERTY_HELP_INDENT = 10;
+
/**
* Prints a description of the properties used to configure shared JVMCI code.
*
@@ -178,24 +181,26 @@
*/
public static void printProperties(PrintStream out) {
out.println("[JVMCI properties]");
- int typeWidth = 0;
- int nameWidth = 0;
Option[] values = values();
for (Option option : values) {
- typeWidth = Math.max(typeWidth, option.type.getSimpleName().length());
- nameWidth = Math.max(nameWidth, option.getPropertyName().length());
- }
- for (Option option : values) {
Object value = option.getValue();
if (value instanceof String) {
value = '"' + String.valueOf(value) + '"';
}
- String assign = option.isDefault ? " =" : ":=";
- String format = "%" + (typeWidth + 1) + "s %-" + (nameWidth + 1) + "s %s %s%n";
- out.printf(format, option.type.getSimpleName(), option.getPropertyName(), assign, value);
- String helpFormat = "%" + (typeWidth + 1) + "s %s%n";
+
+ String name = option.getPropertyName();
+ String assign = option.isDefault ? "=" : ":=";
+ String typeName = option.type.getSimpleName();
+ String linePrefix = String.format("%s %s %s ", name, assign, value);
+ int typeStartPos = PROPERTY_LINE_WIDTH - typeName.length();
+ int linePad = typeStartPos - linePrefix.length();
+ if (linePad > 0) {
+ out.printf("%s%-" + linePad + "s[%s]%n", linePrefix, "", typeName);
+ } else {
+ out.printf("%s[%s]%n", linePrefix, typeName);
+ }
for (String line : option.helpLines) {
- out.printf(helpFormat, "", line);
+ out.printf("%" + PROPERTY_HELP_INDENT + "s%s%n", "", line);
}
}
}
@@ -306,6 +311,7 @@
PrintStream out = new PrintStream(getLogStream());
Option.printProperties(out);
compilerFactory.printProperties(out);
+ System.exit(0);
}
if (Option.PrintConfig.getBoolean()) {
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/Services.java Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/Services.java Wed Oct 26 20:13:29 2016 +0000
@@ -22,7 +22,8 @@
*/
package jdk.vm.ci.services;
-import java.lang.reflect.Module;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.util.Formatter;
import java.util.Iterator;
import java.util.ServiceConfigurationError;
@@ -36,11 +37,62 @@
private Services() {
}
+ private static int getJavaSpecificationVersion() {
+ String value = System.getProperty("java.specification.version");
+ if (value.startsWith("1.")) {
+ value = value.substring(2);
+ }
+ return Integer.parseInt(value);
+ }
+
+ /**
+ * The integer value corresponding to the value of the {@code java.specification.version} system
+ * property after any leading {@code "1."} has been stripped.
+ */
+ public static final int JAVA_SPECIFICATION_VERSION = getJavaSpecificationVersion();
+
+ // Use reflection so that this compiles on Java 8
+ private static final Method getModule;
+ private static final Method getPackages;
+ private static final Method addUses;
+ private static final Method isExported;
+ private static final Method addExports;
+
+ static {
+ if (JAVA_SPECIFICATION_VERSION >= 9) {
+ try {
+ getModule = Class.class.getMethod("getModule");
+ Class<?> moduleClass = getModule.getReturnType();
+ getPackages = moduleClass.getMethod("getPackages");
+ addUses = moduleClass.getMethod("addUses", Class.class);
+ isExported = moduleClass.getMethod("isExported", String.class, moduleClass);
+ addExports = moduleClass.getMethod("addExports", String.class, moduleClass);
+ } catch (NoSuchMethodException | SecurityException e) {
+ throw new InternalError(e);
+ }
+ } else {
+ getModule = null;
+ getPackages = null;
+ addUses = null;
+ isExported = null;
+ addExports = null;
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ static <T> T invoke(Method method, Object receiver, Object... args) {
+ try {
+ return (T) method.invoke(receiver, args);
+ } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+ throw new InternalError(e);
+ }
+ }
+
/**
* Performs any required security checks and dynamic reconfiguration to allow the module of a
* given class to access the classes in the JVMCI module.
*
- * Note: This API uses {@link Class} instead of {@link Module} to provide backwards
+ * Note: This API uses {@link Class} instead of {@code Module} to provide backwards
* compatibility for JVMCI clients compiled against a JDK release earlier than 9.
*
* @param requestor a class requesting access to the JVMCI module for its module
@@ -52,15 +104,19 @@
if (sm != null) {
sm.checkPermission(new JVMCIPermission());
}
- Module jvmci = Services.class.getModule();
- Module requestorModule = requestor.getModule();
- if (jvmci != requestorModule) {
- for (String pkg : jvmci.getPackages()) {
- // Export all JVMCI packages dynamically instead
- // of requiring a long list of --add-exports
- // options on the JVM command line.
- if (!jvmci.isExported(pkg, requestorModule)) {
- jvmci.addExports(pkg, requestorModule);
+ if (JAVA_SPECIFICATION_VERSION >= 9) {
+ Object jvmci = invoke(getModule, Services.class);
+ Object requestorModule = invoke(getModule, requestor);
+ if (jvmci != requestorModule) {
+ String[] packages = invoke(getPackages, jvmci);
+ for (String pkg : packages) {
+ // Export all JVMCI packages dynamically instead
+ // of requiring a long list of --add-exports
+ // options on the JVM command line.
+ boolean exported = invoke(isExported, jvmci, pkg, requestorModule);
+ if (!exported) {
+ invoke(addExports, jvmci, pkg, requestorModule);
+ }
}
}
}
@@ -77,8 +133,10 @@
if (sm != null) {
sm.checkPermission(new JVMCIPermission());
}
- Module jvmci = Services.class.getModule();
- jvmci.addUses(service);
+ if (JAVA_SPECIFICATION_VERSION >= 9) {
+ Object jvmci = invoke(getModule, Services.class);
+ invoke(addUses, jvmci, service);
+ }
// Restrict JVMCI clients to be on the class path or module path
return ServiceLoader.load(service, ClassLoader.getSystemClassLoader());
@@ -98,8 +156,10 @@
if (sm != null) {
sm.checkPermission(new JVMCIPermission());
}
- Module jvmci = Services.class.getModule();
- jvmci.addUses(service);
+ if (JAVA_SPECIFICATION_VERSION >= 9) {
+ Object jvmci = invoke(getModule, Services.class);
+ invoke(addUses, jvmci, service);
+ }
// Restrict JVMCI clients to be on the class path or module path
Iterable<S> providers = ServiceLoader.load(service, ClassLoader.getSystemClassLoader());
S singleProvider = null;
--- a/hotspot/src/share/vm/c1/c1_Compiler.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/c1/c1_Compiler.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -42,7 +42,7 @@
#include "runtime/sharedRuntime.hpp"
-Compiler::Compiler() : AbstractCompiler(c1) {
+Compiler::Compiler() : AbstractCompiler(compiler_c1) {
}
void Compiler::init_c1_runtime() {
@@ -223,6 +223,7 @@
case vmIntrinsics::_putCharStringU:
#ifdef TRACE_HAVE_INTRINSICS
case vmIntrinsics::_counterTime:
+ case vmIntrinsics::_getBufferWriter:
#if defined(_LP64) || !defined(TRACE_ID_CLASS_SHIFT)
case vmIntrinsics::_getClassId:
#endif
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -3120,6 +3120,22 @@
__ move(id, rlock_result(x));
}
+
+void LIRGenerator::do_getBufferWriter(Intrinsic* x) {
+ LabelObj* L_end = new LabelObj();
+
+ LIR_Address* jobj_addr = new LIR_Address(getThreadPointer(),
+ in_bytes(TRACE_THREAD_DATA_WRITER_OFFSET),
+ T_OBJECT);
+ LIR_Opr result = rlock_result(x);
+ __ move_wide(jobj_addr, result);
+ __ cmp(lir_cond_equal, result, LIR_OprFact::oopConst(NULL));
+ __ branch(lir_cond_equal, T_OBJECT, L_end->label());
+ __ move_wide(new LIR_Address(result, T_OBJECT), result);
+
+ __ branch_destination(L_end->label());
+}
+
#endif
@@ -3151,6 +3167,9 @@
case vmIntrinsics::_getClassId:
do_ClassIDIntrinsic(x);
break;
+ case vmIntrinsics::_getBufferWriter:
+ do_getBufferWriter(x);
+ break;
case vmIntrinsics::_counterTime:
do_RuntimeCall(CAST_FROM_FN_PTR(address, TRACE_TIME_METHOD), x);
break;
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp Wed Oct 26 20:13:29 2016 +0000
@@ -441,6 +441,7 @@
#ifdef TRACE_HAVE_INTRINSICS
void do_ClassIDIntrinsic(Intrinsic* x);
+ void do_getBufferWriter(Intrinsic* x);
#endif
void do_RuntimeCall(address routine, Intrinsic* x);
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -5775,9 +5775,22 @@
// Anonymous classes such as generated LambdaForm classes are also not included.
if (SystemDictionaryShared::is_sharing_possible(_loader_data) &&
_host_klass == NULL) {
+ oop class_loader = _loader_data->class_loader();
ResourceMark rm(THREAD);
- classlist_file->print_cr("%s", _class_name->as_C_string());
- classlist_file->flush();
+ // For the boot and platform class loaders, check if the class is not found in the
+ // java runtime image. Additional check for the boot class loader is if the class
+ // is not found in the boot loader's appended entries. This indicates that the class
+ // is not useable during run time, such as the ones found in the --patch-module entries,
+ // so it should not be included in the classlist file.
+ if (((class_loader == NULL && !ClassLoader::contains_append_entry(stream->source())) ||
+ SystemDictionary::is_platform_class_loader(class_loader)) &&
+ !ClassLoader::is_jrt(stream->source())) {
+ tty->print_cr("skip writing class %s from source %s to classlist file",
+ _class_name->as_C_string(), stream->source());
+ } else {
+ classlist_file->print_cr("%s", _class_name->as_C_string());
+ classlist_file->flush();
+ }
}
}
#endif
@@ -5856,6 +5869,11 @@
assert(cp != NULL, "invariant");
assert(_loader_data != NULL, "invariant");
+ if (_class_name == vmSymbols::java_lang_Object()) {
+ check_property(_local_interfaces == Universe::the_empty_klass_array(),
+ "java.lang.Object cannot implement an interface in class file %s",
+ CHECK);
+ }
// We check super class after class file is parsed and format is checked
if (_super_class_index > 0 && NULL ==_super_klass) {
Symbol* const super_class_name = cp->klass_name_at(_super_class_index);
--- a/hotspot/src/share/vm/classfile/classLoader.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/classfile/classLoader.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -945,11 +945,11 @@
}
// returns true if entry already on class path
-bool ClassLoader::contains_entry(ClassPathEntry *entry) {
+bool ClassLoader::contains_append_entry(const char* name) {
ClassPathEntry* e = _first_append_entry;
while (e != NULL) {
// assume zip entries have been canonicalized
- if (strcmp(entry->name(), e->name()) == 0) {
+ if (strcmp(name, e->name()) == 0) {
return true;
}
e = e->next();
@@ -991,7 +991,7 @@
// Do not reorder the bootclasspath which would break get_system_package().
// Add new entry to linked list
- if (!check_for_duplicates || !contains_entry(new_entry)) {
+ if (!check_for_duplicates || !contains_append_entry(new_entry->name())) {
ClassLoaderExt::add_class_path_entry(path, check_for_duplicates, new_entry);
}
return true;
--- a/hotspot/src/share/vm/classfile/classLoader.hpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/classfile/classLoader.hpp Wed Oct 26 20:13:29 2016 +0000
@@ -451,7 +451,7 @@
static void set_first_append_entry(ClassPathEntry* entry);
// indicates if class path already contains a entry (exact match by name)
- static bool contains_entry(ClassPathEntry* entry);
+ static bool contains_append_entry(const char* name);
// adds a class path list
static void add_to_list(ClassPathEntry* new_entry);
--- a/hotspot/src/share/vm/classfile/klassFactory.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/classfile/klassFactory.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -74,7 +74,7 @@
(SharedClassPathEntry*)FileMapInfo::shared_classpath(path_index);
ClassFileStream* stream = new ClassFileStream(ptr,
end_ptr - ptr,
- ent->_name,
+ ent == NULL ? NULL : ent->_name,
ClassFileStream::verify);
ClassFileParser parser(stream,
class_name,
--- a/hotspot/src/share/vm/classfile/stackMapTableFormat.hpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/classfile/stackMapTableFormat.hpp Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -203,6 +203,7 @@
inline bool verify(address start, address end) const;
inline void print_on(outputStream* st, int current_offset) const;
+ inline void print_truncated(outputStream* st, int current_offset) const;
// Create as_xxx and is_xxx methods for the subtypes
#define FRAME_TYPE_DECL(stackmap_frame_type, arg1, arg2) \
@@ -263,6 +264,10 @@
void print_on(outputStream* st, int current_offset = -1) const {
st->print("same_frame(@%d)", offset_delta() + current_offset);
}
+
+ void print_truncated(outputStream* st, int current_offset = -1) const {
+ print_on(st, current_offset);
+ }
};
class same_frame_extended : public stack_map_frame {
@@ -309,6 +314,10 @@
void print_on(outputStream* st, int current_offset = -1) const {
st->print("same_frame_extended(@%d)", offset_delta() + current_offset);
}
+
+ void print_truncated(outputStream* st, int current_offset = -1) const {
+ print_on(st, current_offset);
+ }
};
class same_locals_1_stack_item_frame : public stack_map_frame {
@@ -381,6 +390,11 @@
types()->print_on(st);
st->print(")");
}
+
+ void print_truncated(outputStream* st, int current_offset = -1) const {
+ st->print("same_locals_1_stack_item_frame(@%d), output truncated, Stackmap exceeds table size.",
+ offset_delta() + current_offset);
+ }
};
class same_locals_1_stack_item_extended : public stack_map_frame {
@@ -446,6 +460,11 @@
types()->print_on(st);
st->print(")");
}
+
+ void print_truncated(outputStream* st, int current_offset = -1) const {
+ st->print("same_locals_1_stack_item_extended(@%d), output truncated, Stackmap exceeds table size.",
+ offset_delta() + current_offset);
+ }
};
class chop_frame : public stack_map_frame {
@@ -511,6 +530,10 @@
void print_on(outputStream* st, int current_offset = -1) const {
st->print("chop_frame(@%d,%d)", offset_delta() + current_offset, chops());
}
+
+ void print_truncated(outputStream* st, int current_offset = -1) const {
+ print_on(st, current_offset);
+ }
};
class append_frame : public stack_map_frame {
@@ -619,6 +642,11 @@
}
st->print(")");
}
+
+ void print_truncated(outputStream* st, int current_offset = -1) const {
+ st->print("append_frame(@%d), output truncated, Stackmap exceeds table size.",
+ offset_delta() + current_offset);
+ }
};
class full_frame : public stack_map_frame {
@@ -784,6 +812,11 @@
}
st->print("})");
}
+
+ void print_truncated(outputStream* st, int current_offset = -1) const {
+ st->print("full_frame(@%d), output truncated, Stackmap exceeds table size.",
+ offset_delta() + current_offset);
+ }
};
#define VIRTUAL_DISPATCH(stack_frame_type, func_name, args) \
@@ -841,6 +874,10 @@
FOR_EACH_STACKMAP_FRAME_TYPE(VOID_VIRTUAL_DISPATCH, print_on, (st, offs));
}
+void stack_map_frame::print_truncated(outputStream* st, int offs = -1) const {
+ FOR_EACH_STACKMAP_FRAME_TYPE(VOID_VIRTUAL_DISPATCH, print_truncated, (st, offs));
+}
+
#undef VIRTUAL_DISPATCH
#undef VOID_VIRTUAL_DISPATCH
--- a/hotspot/src/share/vm/classfile/stringTable.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/classfile/stringTable.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -437,17 +437,15 @@
st->print("%d: ", length);
} else {
ResourceMark rm(THREAD);
- int utf8_length;
+ int utf8_length = length;
char* utf8_string;
if (!is_latin1) {
jchar* chars = value->char_at_addr(0);
- utf8_length = UNICODE::utf8_length(chars, length);
- utf8_string = UNICODE::as_utf8(chars, length);
+ utf8_string = UNICODE::as_utf8(chars, utf8_length);
} else {
jbyte* bytes = value->byte_at_addr(0);
- utf8_length = UNICODE::utf8_length(bytes, length);
- utf8_string = UNICODE::as_utf8(bytes, length);
+ utf8_string = UNICODE::as_utf8(bytes, utf8_length);
}
st->print("%d: ", utf8_length);
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -1234,7 +1234,7 @@
SharedClassPathEntry* ent =
(SharedClassPathEntry*)FileMapInfo::shared_classpath(path_index);
if (!Universe::is_module_initialized()) {
- assert(ent->is_jrt(),
+ assert(ent != NULL && ent->is_jrt(),
"Loading non-bootstrap classes before the module system is initialized");
assert(class_loader.is_null(), "sanity");
return true;
@@ -1257,6 +1257,7 @@
}
if (class_loader.is_null()) {
+ assert(ent != NULL, "Shared class for NULL classloader must have valid SharedClassPathEntry");
// The NULL classloader can load archived class originated from the
// "modules" jimage and the -Xbootclasspath/a. For class from the
// "modules" jimage, the PackageEntry/ModuleEntry must be defined
--- a/hotspot/src/share/vm/classfile/verifier.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/classfile/verifier.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -541,8 +541,19 @@
stack_map_frame* sm_frame = sm_table->entries();
streamIndentor si2(ss);
int current_offset = -1;
+ // Subtract two from StackMapAttribute length because the length includes
+ // two bytes for number of table entries.
+ size_t sm_table_space = method->stackmap_data()->length() - 2;
for (u2 i = 0; i < sm_table->number_of_entries(); ++i) {
ss->indent();
+ size_t sm_frame_size = sm_frame->size();
+ // If the size of the next stackmap exceeds the length of the entire
+ // stackmap table then print a truncated message and return.
+ if (sm_frame_size > sm_table_space) {
+ sm_frame->print_truncated(ss, current_offset);
+ return;
+ }
+ sm_table_space -= sm_frame_size;
sm_frame->print_on(ss, current_offset);
ss->cr();
current_offset += sm_frame->offset_delta();
--- a/hotspot/src/share/vm/code/codeBlob.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/code/codeBlob.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -45,6 +45,10 @@
#include "c1/c1_Runtime1.hpp"
#endif
+const char* CodeBlob::compiler_name() const {
+ return compilertype2name(_type);
+}
+
unsigned int CodeBlob::align_code_offset(int offset) {
// align the size to CodeEntryAlignment
return
@@ -65,7 +69,7 @@
return size;
}
-CodeBlob::CodeBlob(const char* name, const CodeBlobLayout& layout, int frame_complete_offset, int frame_size, ImmutableOopMapSet* oop_maps, bool caller_must_gc_arguments) :
+CodeBlob::CodeBlob(const char* name, CompilerType type, const CodeBlobLayout& layout, int frame_complete_offset, int frame_size, ImmutableOopMapSet* oop_maps, bool caller_must_gc_arguments) :
_name(name),
_size(layout.size()),
_header_size(layout.header_size()),
@@ -80,7 +84,8 @@
_data_end(layout.data_end()),
_relocation_begin(layout.relocation_begin()),
_relocation_end(layout.relocation_end()),
- _content_begin(layout.content_begin())
+ _content_begin(layout.content_begin()),
+ _type(type)
{
assert(layout.size() == round_to(layout.size(), oopSize), "unaligned size");
assert(layout.header_size() == round_to(layout.header_size(), oopSize), "unaligned size");
@@ -92,7 +97,7 @@
#endif // COMPILER1
}
-CodeBlob::CodeBlob(const char* name, const CodeBlobLayout& layout, CodeBuffer* cb, int frame_complete_offset, int frame_size, OopMapSet* oop_maps, bool caller_must_gc_arguments) :
+CodeBlob::CodeBlob(const char* name, CompilerType type, const CodeBlobLayout& layout, CodeBuffer* cb, int frame_complete_offset, int frame_size, OopMapSet* oop_maps, bool caller_must_gc_arguments) :
_name(name),
_size(layout.size()),
_header_size(layout.header_size()),
@@ -106,7 +111,8 @@
_data_end(layout.data_end()),
_relocation_begin(layout.relocation_begin()),
_relocation_end(layout.relocation_end()),
- _content_begin(layout.content_begin())
+ _content_begin(layout.content_begin()),
+ _type(type)
{
assert(_size == round_to(_size, oopSize), "unaligned size");
assert(_header_size == round_to(_header_size, oopSize), "unaligned size");
@@ -123,7 +129,7 @@
// Creates a simple CodeBlob. Sets up the size of the different regions.
RuntimeBlob::RuntimeBlob(const char* name, int header_size, int size, int frame_complete, int locs_size)
- : CodeBlob(name, CodeBlobLayout((address) this, size, header_size, locs_size, size), frame_complete, 0, NULL, false /* caller_must_gc_arguments */)
+ : CodeBlob(name, compiler_none, CodeBlobLayout((address) this, size, header_size, locs_size, size), frame_complete, 0, NULL, false /* caller_must_gc_arguments */)
{
assert(locs_size == round_to(locs_size, oopSize), "unaligned size");
assert(!UseRelocIndex, "no space allocated for reloc index yet");
@@ -148,7 +154,7 @@
int frame_size,
OopMapSet* oop_maps,
bool caller_must_gc_arguments
-) : CodeBlob(name, CodeBlobLayout((address) this, size, header_size, cb), cb, frame_complete, frame_size, oop_maps, caller_must_gc_arguments) {
+) : CodeBlob(name, compiler_none, CodeBlobLayout((address) this, size, header_size, cb), cb, frame_complete, frame_size, oop_maps, caller_must_gc_arguments) {
cb->copy_code_and_locs_to(this);
}
--- a/hotspot/src/share/vm/code/codeBlob.hpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/code/codeBlob.hpp Wed Oct 26 20:13:29 2016 +0000
@@ -26,6 +26,7 @@
#define SHARE_VM_CODE_CODEBLOB_HPP
#include "asm/codeBuffer.hpp"
+#include "compiler/compilerDefinitions.hpp"
#include "compiler/oopMap.hpp"
#include "runtime/frame.hpp"
#include "runtime/handles.hpp"
@@ -71,7 +72,8 @@
friend class CodeCacheDumper;
protected:
- const char* _name;
+
+ const CompilerType _type; // CompilerType
int _size; // total size of CodeBlob in bytes
int _header_size; // size of header (depends on subclass)
int _frame_complete_offset; // instruction offsets in [0.._frame_complete_offset) have
@@ -92,9 +94,10 @@
ImmutableOopMapSet* _oop_maps; // OopMap for this CodeBlob
bool _caller_must_gc_arguments;
CodeStrings _strings;
+ const char* _name;
- CodeBlob(const char* name, const CodeBlobLayout& layout, int frame_complete_offset, int frame_size, ImmutableOopMapSet* oop_maps, bool caller_must_gc_arguments);
- CodeBlob(const char* name, const CodeBlobLayout& layout, CodeBuffer* cb, int frame_complete_offset, int frame_size, OopMapSet* oop_maps, bool caller_must_gc_arguments);
+ CodeBlob(const char* name, CompilerType type, const CodeBlobLayout& layout, int frame_complete_offset, int frame_size, ImmutableOopMapSet* oop_maps, bool caller_must_gc_arguments);
+ CodeBlob(const char* name, CompilerType type, const CodeBlobLayout& layout, CodeBuffer* cb, int frame_complete_offset, int frame_size, OopMapSet* oop_maps, bool caller_must_gc_arguments);
public:
// Returns the space needed for CodeBlob
static unsigned int allocation_size(CodeBuffer* cb, int header_size);
@@ -115,9 +118,11 @@
virtual bool is_method_handles_adapter_blob() const { return false; }
virtual bool is_compiled() const { return false; }
- virtual bool is_compiled_by_c2() const { return false; }
- virtual bool is_compiled_by_c1() const { return false; }
- virtual bool is_compiled_by_jvmci() const { return false; }
+ inline bool is_compiled_by_c1() const { return _type == compiler_c1; };
+ inline bool is_compiled_by_c2() const { return _type == compiler_c2; };
+ inline bool is_compiled_by_jvmci() const { return _type == compiler_jvmci; };
+ inline bool is_compiled_by_shark() const { return _type == compiler_shark; };
+ const char* compiler_name() const;
// Casting
nmethod* as_nmethod_or_null() { return is_nmethod() ? (nmethod*) this : NULL; }
--- a/hotspot/src/share/vm/code/compiledMethod.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/code/compiledMethod.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -31,14 +31,14 @@
#include "memory/resourceArea.hpp"
#include "runtime/mutexLocker.hpp"
-CompiledMethod::CompiledMethod(Method* method, const char* name, const CodeBlobLayout& layout, int frame_complete_offset, int frame_size, ImmutableOopMapSet* oop_maps, bool caller_must_gc_arguments)
- : CodeBlob(name, layout, frame_complete_offset, frame_size, oop_maps, caller_must_gc_arguments),
+CompiledMethod::CompiledMethod(Method* method, const char* name, CompilerType type, const CodeBlobLayout& layout, int frame_complete_offset, int frame_size, ImmutableOopMapSet* oop_maps, bool caller_must_gc_arguments)
+ : CodeBlob(name, type, layout, frame_complete_offset, frame_size, oop_maps, caller_must_gc_arguments),
_method(method), _mark_for_deoptimization_status(not_marked) {
init_defaults();
}
-CompiledMethod::CompiledMethod(Method* method, const char* name, int size, int header_size, CodeBuffer* cb, int frame_complete_offset, int frame_size, OopMapSet* oop_maps, bool caller_must_gc_arguments)
- : CodeBlob(name, CodeBlobLayout((address) this, size, header_size, cb), cb, frame_complete_offset, frame_size, oop_maps, caller_must_gc_arguments),
+CompiledMethod::CompiledMethod(Method* method, const char* name, CompilerType type, int size, int header_size, CodeBuffer* cb, int frame_complete_offset, int frame_size, OopMapSet* oop_maps, bool caller_must_gc_arguments)
+ : CodeBlob(name, type, CodeBlobLayout((address) this, size, header_size, cb), cb, frame_complete_offset, frame_size, oop_maps, caller_must_gc_arguments),
_method(method), _mark_for_deoptimization_status(not_marked) {
init_defaults();
}
--- a/hotspot/src/share/vm/code/compiledMethod.hpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/code/compiledMethod.hpp Wed Oct 26 20:13:29 2016 +0000
@@ -164,8 +164,8 @@
virtual void flush() = 0;
protected:
- CompiledMethod(Method* method, const char* name, const CodeBlobLayout& layout, int frame_complete_offset, int frame_size, ImmutableOopMapSet* oop_maps, bool caller_must_gc_arguments);
- CompiledMethod(Method* method, const char* name, int size, int header_size, CodeBuffer* cb, int frame_complete_offset, int frame_size, OopMapSet* oop_maps, bool caller_must_gc_arguments);
+ CompiledMethod(Method* method, const char* name, CompilerType type, const CodeBlobLayout& layout, int frame_complete_offset, int frame_size, ImmutableOopMapSet* oop_maps, bool caller_must_gc_arguments);
+ CompiledMethod(Method* method, const char* name, CompilerType type, int size, int header_size, CodeBuffer* cb, int frame_complete_offset, int frame_size, OopMapSet* oop_maps, bool caller_must_gc_arguments);
public:
virtual bool is_compiled() const { return true; }
@@ -191,12 +191,10 @@
// will be transformed to zombie immediately
};
- virtual AbstractCompiler* compiler() const = 0;
virtual bool is_in_use() const = 0;
virtual int comp_level() const = 0;
virtual int compile_id() const = 0;
-
virtual address verified_entry_point() const = 0;
virtual void log_identity(xmlStream* log) const = 0;
virtual void log_state_change() const = 0;
--- a/hotspot/src/share/vm/code/dependencyContext.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/code/dependencyContext.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -272,79 +272,3 @@
int nmethodBucket::decrement() {
return Atomic::add(-1, (volatile int *)&_count);
}
-
-/////////////// Unit tests ///////////////
-
-#ifndef PRODUCT
-
-class TestDependencyContext {
- public:
- nmethod* _nmethods[3];
-
- intptr_t _dependency_context;
-
- DependencyContext dependencies() {
- DependencyContext depContext(&_dependency_context);
- return depContext;
- }
-
- TestDependencyContext() : _dependency_context(DependencyContext::EMPTY) {
- CodeCache_lock->lock_without_safepoint_check();
-
- _nmethods[0] = reinterpret_cast<nmethod*>(0x8 * 0);
- _nmethods[1] = reinterpret_cast<nmethod*>(0x8 * 1);
- _nmethods[2] = reinterpret_cast<nmethod*>(0x8 * 2);
-
- dependencies().add_dependent_nmethod(_nmethods[2]);
- dependencies().add_dependent_nmethod(_nmethods[1]);
- dependencies().add_dependent_nmethod(_nmethods[0]);
- }
-
- ~TestDependencyContext() {
- dependencies().wipe();
- CodeCache_lock->unlock();
- }
-
- static void testRemoveDependentNmethod(int id, bool delete_immediately) {
- TestDependencyContext c;
- DependencyContext depContext = c.dependencies();
- assert(!has_stale_entries(depContext), "check");
-
- nmethod* nm = c._nmethods[id];
- depContext.remove_dependent_nmethod(nm, delete_immediately);
-
- if (!delete_immediately) {
- assert(has_stale_entries(depContext), "check");
- assert(depContext.is_dependent_nmethod(nm), "check");
- depContext.expunge_stale_entries();
- }
-
- assert(!has_stale_entries(depContext), "check");
- assert(!depContext.is_dependent_nmethod(nm), "check");
- }
-
- static void testRemoveDependentNmethod() {
- testRemoveDependentNmethod(0, false);
- testRemoveDependentNmethod(1, false);
- testRemoveDependentNmethod(2, false);
-
- testRemoveDependentNmethod(0, true);
- testRemoveDependentNmethod(1, true);
- testRemoveDependentNmethod(2, true);
- }
-
- static void test() {
- testRemoveDependentNmethod();
- }
-
- static bool has_stale_entries(DependencyContext ctx) {
- assert(ctx.has_stale_entries() == ctx.find_stale_entries(), "check");
- return ctx.has_stale_entries();
- }
-};
-
-void TestDependencyContext_test() {
- TestDependencyContext::test();
-}
-
-#endif // PRODUCT
--- a/hotspot/src/share/vm/code/dependencyContext.hpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/code/dependencyContext.hpp Wed Oct 26 20:13:29 2016 +0000
@@ -29,6 +29,7 @@
#include "oops/oop.hpp"
#include "runtime/handles.hpp"
#include "runtime/perfData.hpp"
+#include "runtime/safepoint.hpp"
class nmethod;
class DepChange;
--- a/hotspot/src/share/vm/code/nmethod.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/code/nmethod.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -82,32 +82,6 @@
#endif
-bool nmethod::is_compiled_by_c1() const {
- if (compiler() == NULL) {
- return false;
- }
- return compiler()->is_c1();
-}
-bool nmethod::is_compiled_by_jvmci() const {
- if (compiler() == NULL || method() == NULL) return false; // can happen during debug printing
- if (is_native_method()) return false;
- return compiler()->is_jvmci();
-}
-bool nmethod::is_compiled_by_c2() const {
- if (compiler() == NULL) {
- return false;
- }
- return compiler()->is_c2();
-}
-bool nmethod::is_compiled_by_shark() const {
- if (compiler() == NULL) {
- return false;
- }
- return compiler()->is_shark();
-}
-
-
-
//---------------------------------------------------------------------------------
// NMethod statistics
// They are printed under various flags, including:
@@ -440,7 +414,6 @@
_scavenge_root_link = NULL;
}
_scavenge_root_state = 0;
- _compiler = NULL;
#if INCLUDE_RTM_OPT
_rtm_state = NoRTM;
#endif
@@ -468,7 +441,7 @@
CodeOffsets offsets;
offsets.set_value(CodeOffsets::Verified_Entry, vep_offset);
offsets.set_value(CodeOffsets::Frame_Complete, frame_complete);
- nm = new (native_nmethod_size, CompLevel_none) nmethod(method(), native_nmethod_size,
+ nm = new (native_nmethod_size, CompLevel_none) nmethod(method(), compiler_none, native_nmethod_size,
compile_id, &offsets,
code_buffer, frame_size,
basic_lock_owner_sp_offset,
@@ -518,7 +491,7 @@
+ round_to(debug_info->data_size() , oopSize);
nm = new (nmethod_size, comp_level)
- nmethod(method(), nmethod_size, compile_id, entry_bci, offsets,
+ nmethod(method(), compiler->type(), nmethod_size, compile_id, entry_bci, offsets,
orig_pc_offset, debug_info, dependencies, code_buffer, frame_size,
oop_maps,
handler_table,
@@ -569,6 +542,7 @@
// For native wrappers
nmethod::nmethod(
Method* method,
+ CompilerType type,
int nmethod_size,
int compile_id,
CodeOffsets* offsets,
@@ -577,7 +551,7 @@
ByteSize basic_lock_owner_sp_offset,
ByteSize basic_lock_sp_offset,
OopMapSet* oop_maps )
- : CompiledMethod(method, "native nmethod", nmethod_size, sizeof(nmethod), code_buffer, offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps, false),
+ : CompiledMethod(method, "native nmethod", type, nmethod_size, sizeof(nmethod), code_buffer, offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps, false),
_native_receiver_sp_offset(basic_lock_owner_sp_offset),
_native_basic_lock_sp_offset(basic_lock_sp_offset)
{
@@ -666,6 +640,7 @@
nmethod::nmethod(
Method* method,
+ CompilerType type,
int nmethod_size,
int compile_id,
int entry_bci,
@@ -685,7 +660,7 @@
Handle speculation_log
#endif
)
- : CompiledMethod(method, "nmethod", nmethod_size, sizeof(nmethod), code_buffer, offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps, false),
+ : CompiledMethod(method, "nmethod", type, nmethod_size, sizeof(nmethod), code_buffer, offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps, false),
_native_receiver_sp_offset(in_ByteSize(-1)),
_native_basic_lock_sp_offset(in_ByteSize(-1))
{
@@ -701,7 +676,6 @@
_entry_bci = entry_bci;
_compile_id = compile_id;
_comp_level = comp_level;
- _compiler = compiler;
_orig_pc_offset = orig_pc_offset;
_hotness_counter = NMethodSweeper::hotness_counter_reset_val();
@@ -803,9 +777,7 @@
log->print(" compile_id='%d'", compile_id());
const char* nm_kind = compile_kind();
if (nm_kind != NULL) log->print(" compile_kind='%s'", nm_kind);
- if (compiler() != NULL) {
- log->print(" compiler='%s'", compiler()->name());
- }
+ log->print(" compiler='%s'", compiler_name());
if (TieredCompilation) {
log->print(" level='%d'", comp_level());
}
--- a/hotspot/src/share/vm/code/nmethod.hpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/code/nmethod.hpp Wed Oct 26 20:13:29 2016 +0000
@@ -74,8 +74,6 @@
static nmethod* volatile _oops_do_mark_nmethods;
nmethod* volatile _oops_do_mark_link;
- AbstractCompiler* _compiler; // The compiler which compiled this nmethod
-
// offsets for entry points
address _entry_point; // entry point with class check
address _verified_entry_point; // entry point without class check
@@ -166,6 +164,7 @@
// For native wrappers
nmethod(Method* method,
+ CompilerType type,
int nmethod_size,
int compile_id,
CodeOffsets* offsets,
@@ -177,6 +176,7 @@
// Creation support
nmethod(Method* method,
+ CompilerType type,
int nmethod_size,
int compile_id,
int entry_bci,
@@ -251,18 +251,10 @@
ByteSize basic_lock_sp_offset,
OopMapSet* oop_maps);
- // accessors
- AbstractCompiler* compiler() const { return _compiler; }
-
// type info
bool is_nmethod() const { return true; }
bool is_osr_method() const { return _entry_bci != InvocationEntryBci; }
- bool is_compiled_by_c1() const;
- bool is_compiled_by_jvmci() const;
- bool is_compiled_by_c2() const;
- bool is_compiled_by_shark() const;
-
// boundaries for different parts
address consts_begin () const { return header_begin() + _consts_offset ; }
address consts_end () const { return code_begin() ; }
--- a/hotspot/src/share/vm/code/relocInfo.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/code/relocInfo.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -743,7 +743,9 @@
}
Method* virtual_call_Relocation::method_value() {
- Metadata* m = code()->metadata_at(_method_index);
+ CompiledMethod* cm = code();
+ if (cm == NULL) return (Method*)NULL;
+ Metadata* m = cm->metadata_at(_method_index);
assert(m != NULL || _method_index == 0, "should be non-null for non-zero index");
assert(m == NULL || m->is_method(), "not a method");
return (Method*)m;
@@ -769,7 +771,9 @@
}
Method* opt_virtual_call_Relocation::method_value() {
- Metadata* m = code()->metadata_at(_method_index);
+ CompiledMethod* cm = code();
+ if (cm == NULL) return (Method*)NULL;
+ Metadata* m = cm->metadata_at(_method_index);
assert(m != NULL || _method_index == 0, "should be non-null for non-zero index");
assert(m == NULL || m->is_method(), "not a method");
return (Method*)m;
@@ -800,7 +804,9 @@
}
Method* static_call_Relocation::method_value() {
- Metadata* m = code()->metadata_at(_method_index);
+ CompiledMethod* cm = code();
+ if (cm == NULL) return (Method*)NULL;
+ Metadata* m = cm->metadata_at(_method_index);
assert(m != NULL || _method_index == 0, "should be non-null for non-zero index");
assert(m == NULL || m->is_method(), "not a method");
return (Method*)m;
@@ -970,7 +976,9 @@
// work even during GC or other inconvenient times.
if (WizardMode && oop_value != NULL) {
tty->print("oop_value=" INTPTR_FORMAT ": ", p2i(oop_value));
- oop_value->print_value_on(tty);
+ if (oop_value->is_oop()) {
+ oop_value->print_value_on(tty);
+ }
}
break;
}
--- a/hotspot/src/share/vm/compiler/abstractCompiler.hpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/compiler/abstractCompiler.hpp Wed Oct 26 20:13:29 2016 +0000
@@ -26,6 +26,7 @@
#define SHARE_VM_COMPILER_ABSTRACTCOMPILER_HPP
#include "ci/compilerInterface.hpp"
+#include "compiler/compilerDefinitions.hpp"
#include "compiler/compilerDirectives.hpp"
typedef void (*initializer)(void);
@@ -82,24 +83,15 @@
// This thread will initialize the compiler runtime.
bool should_perform_init();
- // The (closed set) of concrete compiler classes.
- enum Type {
- none,
- c1,
- c2,
- jvmci,
- shark
- };
-
private:
- Type _type;
+ const CompilerType _type;
#if INCLUDE_JVMCI
CompilerStatistics _stats;
#endif
public:
- AbstractCompiler(Type type) : _type(type), _compiler_state(uninitialized), _num_compiler_threads(0) {}
+ AbstractCompiler(CompilerType type) : _type(type), _compiler_state(uninitialized), _num_compiler_threads(0) {}
// This function determines the compiler thread that will perform the
// shutdown of the corresponding compiler runtime.
@@ -157,10 +149,11 @@
}
// Compiler type queries.
- bool is_c1() { return _type == c1; }
- bool is_c2() { return _type == c2; }
- bool is_jvmci() { return _type == jvmci; }
- bool is_shark() { return _type == shark; }
+ const bool is_c1() { return _type == compiler_c1; }
+ const bool is_c2() { return _type == compiler_c2; }
+ const bool is_jvmci() { return _type == compiler_jvmci; }
+ const bool is_shark() { return _type == compiler_shark; }
+ const CompilerType type() { return _type; }
// Extra tests to identify trivial methods for the tiered compilation policy.
virtual bool is_trivial(Method* method) { return false; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/compiler/compilerDefinitions.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "compiler/compilerDefinitions.hpp"
+
+const char* compilertype2name_tab[compiler_number_of_types] = {
+ "",
+ "c1",
+ "c2",
+ "jvmci",
+ "shark"
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/compiler/compilerDefinitions.hpp Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,109 @@
+/*
+ * 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.
+ *
+ */
+
+#ifndef SHARE_VM_COMPILER_COMPILERDEFINITIONS_HPP
+#define SHARE_VM_COMPILER_COMPILERDEFINITIONS_HPP
+
+#include "utilities/globalDefinitions.hpp"
+
+// The (closed set) of concrete compiler classes.
+enum CompilerType {
+ compiler_none,
+ compiler_c1,
+ compiler_c2,
+ compiler_jvmci,
+ compiler_shark,
+ compiler_number_of_types
+};
+
+extern const char* compilertype2name_tab[compiler_number_of_types]; // Map CompilerType to its name
+inline const char* compilertype2name(CompilerType t) { return (uint)t < compiler_number_of_types ? compilertype2name_tab[t] : NULL; }
+
+// Handy constants for deciding which compiler mode to use.
+enum MethodCompilation {
+ InvocationEntryBci = -1 // i.e., not a on-stack replacement compilation
+};
+
+// Enumeration to distinguish tiers of compilation
+enum CompLevel {
+ CompLevel_any = -1,
+ CompLevel_all = -1,
+ CompLevel_none = 0, // Interpreter
+ CompLevel_simple = 1, // C1
+ CompLevel_limited_profile = 2, // C1, invocation & backedge counters
+ CompLevel_full_profile = 3, // C1, invocation & backedge counters + mdo
+ CompLevel_full_optimization = 4, // C2, Shark or JVMCI
+
+#if defined(COMPILER2) || defined(SHARK)
+ CompLevel_highest_tier = CompLevel_full_optimization, // pure C2 and tiered or JVMCI and tiered
+#elif defined(COMPILER1)
+ CompLevel_highest_tier = CompLevel_simple, // pure C1 or JVMCI
+#else
+ CompLevel_highest_tier = CompLevel_none,
+#endif
+
+#if defined(TIERED)
+ CompLevel_initial_compile = CompLevel_full_profile // tiered
+#elif defined(COMPILER1) || INCLUDE_JVMCI
+ CompLevel_initial_compile = CompLevel_simple // pure C1 or JVMCI
+#elif defined(COMPILER2) || defined(SHARK)
+ CompLevel_initial_compile = CompLevel_full_optimization // pure C2
+#else
+ CompLevel_initial_compile = CompLevel_none
+#endif
+};
+
+inline bool is_c1_compile(int comp_level) {
+ return comp_level > CompLevel_none && comp_level < CompLevel_full_optimization;
+}
+
+inline bool is_c2_compile(int comp_level) {
+ return comp_level == CompLevel_full_optimization;
+}
+
+inline bool is_highest_tier_compile(int comp_level) {
+ return comp_level == CompLevel_highest_tier;
+}
+
+inline bool is_compile(int comp_level) {
+ return is_c1_compile(comp_level) || is_c2_compile(comp_level);
+}
+
+// States of Restricted Transactional Memory usage.
+enum RTMState {
+ NoRTM = 0x2, // Don't use RTM
+ UseRTM = 0x1, // Use RTM
+ ProfileRTM = 0x0 // Use RTM with abort ratio calculation
+};
+
+#ifndef INCLUDE_RTM_OPT
+#define INCLUDE_RTM_OPT 0
+#endif
+#if INCLUDE_RTM_OPT
+#define RTM_OPT_ONLY(code) code
+#else
+#define RTM_OPT_ONLY(code)
+#endif
+
+#endif // SHARE_VM_COMPILER_COMPILERDEFINITIONS_HPP
--- a/hotspot/src/share/vm/gc/cms/compactibleFreeListSpace.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/gc/cms/compactibleFreeListSpace.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -922,18 +922,13 @@
return res;
}
} else {
- // must read from what 'p' points to in each loop.
- Klass* k = ((volatile oopDesc*)p)->klass_or_null();
+ // Ensure klass read before size.
+ Klass* k = oop(p)->klass_or_null_acquire();
if (k != NULL) {
assert(k->is_klass(), "Should really be klass oop.");
oop o = (oop)p;
assert(o->is_oop(true /* ignore mark word */), "Should be an oop.");
- // Bugfix for systems with weak memory model (PPC64/IA64).
- // The object o may be an array. Acquire to make sure that the array
- // size (third word) is consistent.
- OrderAccess::acquire();
-
size_t res = o->size_given_klass(k);
res = adjustObjectSize(res);
assert(res != 0, "Block size should not be 0");
@@ -977,21 +972,13 @@
return res;
}
} else {
- // must read from what 'p' points to in each loop.
- Klass* k = ((volatile oopDesc*)p)->klass_or_null();
- // We trust the size of any object that has a non-NULL
- // klass and (for those in the perm gen) is parsable
- // -- irrespective of its conc_safe-ty.
+ // Ensure klass read before size.
+ Klass* k = oop(p)->klass_or_null_acquire();
if (k != NULL) {
assert(k->is_klass(), "Should really be klass oop.");
oop o = (oop)p;
assert(o->is_oop(), "Should be an oop");
- // Bugfix for systems with weak memory model (PPC64/IA64).
- // The object o may be an array. Acquire to make sure that the array
- // size (third word) is consistent.
- OrderAccess::acquire();
-
size_t res = o->size_given_klass(k);
res = adjustObjectSize(res);
assert(res != 0, "Block size should not be 0");
@@ -1028,7 +1015,7 @@
FreeChunk* fc = (FreeChunk*)p;
assert(is_in_reserved(p), "Should be in space");
if (FreeChunk::indicatesFreeChunk(p)) return false;
- Klass* k = oop(p)->klass_or_null();
+ Klass* k = oop(p)->klass_or_null_acquire();
if (k != NULL) {
// Ignore mark word because it may have been used to
// chain together promoted objects (the last one
--- a/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -5630,7 +5630,7 @@
HeapWord* CMSCollector::next_card_start_after_block(HeapWord* addr) const {
size_t sz = 0;
oop p = (oop)addr;
- if (p->klass_or_null() != NULL) {
+ if (p->klass_or_null_acquire() != NULL) {
sz = CompactibleFreeListSpace::adjustObjectSize(p->size());
} else {
sz = block_size_using_printezis_bits(addr);
@@ -6076,7 +6076,7 @@
}
if (_bitMap->isMarked(addr)) {
// it's marked; is it potentially uninitialized?
- if (p->klass_or_null() != NULL) {
+ if (p->klass_or_null_acquire() != NULL) {
// an initialized object; ignore mark word in verification below
// since we are running concurrent with mutators
assert(p->is_oop(true), "should be an oop");
@@ -6121,7 +6121,7 @@
}
} else {
// Either a not yet marked object or an uninitialized object
- if (p->klass_or_null() == NULL) {
+ if (p->klass_or_null_acquire() == NULL) {
// An uninitialized object, skip to the next card, since
// we may not be able to read its P-bits yet.
assert(size == 0, "Initial value");
@@ -6320,7 +6320,7 @@
assert(_skipBits == 0, "tautology");
_skipBits = 2; // skip next two marked bits ("Printezis-marks")
oop p = oop(addr);
- if (p->klass_or_null() == NULL) {
+ if (p->klass_or_null_acquire() == NULL) {
DEBUG_ONLY(if (!_verifying) {)
// We re-dirty the cards on which this object lies and increase
// the _threshold so that we'll come back to scan this object
@@ -6340,7 +6340,7 @@
if (_threshold < end_card_addr) {
_threshold = end_card_addr;
}
- if (p->klass_or_null() != NULL) {
+ if (p->klass_or_null_acquire() != NULL) {
// Redirty the range of cards...
_mut->mark_range(redirty_range);
} // ...else the setting of klass will dirty the card anyway.
@@ -6483,7 +6483,7 @@
assert(_skip_bits == 0, "tautology");
_skip_bits = 2; // skip next two marked bits ("Printezis-marks")
oop p = oop(addr);
- if (p->klass_or_null() == NULL) {
+ if (p->klass_or_null_acquire() == NULL) {
// in the case of Clean-on-Enter optimization, redirty card
// and avoid clearing card by increasing the threshold.
return true;
@@ -7354,7 +7354,7 @@
"alignment problem");
#ifdef ASSERT
- if (oop(addr)->klass_or_null() != NULL) {
+ if (oop(addr)->klass_or_null_acquire() != NULL) {
// Ignore mark word because we are running concurrent with mutators
assert(oop(addr)->is_oop(true), "live block should be an oop");
assert(size ==
@@ -7365,7 +7365,7 @@
} else {
// This should be an initialized object that's alive.
- assert(oop(addr)->klass_or_null() != NULL,
+ assert(oop(addr)->klass_or_null_acquire() != NULL,
"Should be an initialized object");
// Ignore mark word because we are running concurrent with mutators
assert(oop(addr)->is_oop(true), "live block should be an oop");
--- a/hotspot/src/share/vm/gc/g1/g1BiasedArray.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/gc/g1/g1BiasedArray.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2015, 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
@@ -53,99 +53,4 @@
biased_index, bias(), length());
}
-class TestMappedArray : public G1BiasedMappedArray<int> {
-protected:
- virtual int default_value() const { return 0xBAADBABE; }
-public:
- static void test_biasedarray() {
- const size_t REGION_SIZE_IN_WORDS = 512;
- const size_t NUM_REGIONS = 20;
- HeapWord* fake_heap = (HeapWord*)LP64_ONLY(0xBAAA00000) NOT_LP64(0xBA000000); // Any value that is non-zero
-
- TestMappedArray array;
- array.initialize(fake_heap, fake_heap + REGION_SIZE_IN_WORDS * NUM_REGIONS,
- REGION_SIZE_IN_WORDS * HeapWordSize);
- // Check address calculation (bounds)
- assert(array.bottom_address_mapped() == fake_heap,
- "bottom mapped address should be " PTR_FORMAT ", but is " PTR_FORMAT, p2i(fake_heap), p2i(array.bottom_address_mapped()));
- assert(array.end_address_mapped() == (fake_heap + REGION_SIZE_IN_WORDS * NUM_REGIONS), "must be");
-
- int* bottom = array.address_mapped_to(fake_heap);
- assert((void*)bottom == (void*) array.base(), "must be");
- int* end = array.address_mapped_to(fake_heap + REGION_SIZE_IN_WORDS * NUM_REGIONS);
- assert((void*)end == (void*)(array.base() + array.length()), "must be");
- // The entire array should contain default value elements
- for (int* current = bottom; current < end; current++) {
- assert(*current == array.default_value(), "must be");
- }
-
- // Test setting values in the table
-
- HeapWord* region_start_address = fake_heap + REGION_SIZE_IN_WORDS * (NUM_REGIONS / 2);
- HeapWord* region_end_address = fake_heap + (REGION_SIZE_IN_WORDS * (NUM_REGIONS / 2) + REGION_SIZE_IN_WORDS - 1);
-
- // Set/get by address tests: invert some value; first retrieve one
- int actual_value = array.get_by_index(NUM_REGIONS / 2);
- array.set_by_index(NUM_REGIONS / 2, ~actual_value);
- // Get the same value by address, should correspond to the start of the "region"
- int value = array.get_by_address(region_start_address);
- assert(value == ~actual_value, "must be");
- // Get the same value by address, at one HeapWord before the start
- value = array.get_by_address(region_start_address - 1);
- assert(value == array.default_value(), "must be");
- // Get the same value by address, at the end of the "region"
- value = array.get_by_address(region_end_address);
- assert(value == ~actual_value, "must be");
- // Make sure the next value maps to another index
- value = array.get_by_address(region_end_address + 1);
- assert(value == array.default_value(), "must be");
-
- // Reset the value in the array
- array.set_by_address(region_start_address + (region_end_address - region_start_address) / 2, actual_value);
-
- // The entire array should have the default value again
- for (int* current = bottom; current < end; current++) {
- assert(*current == array.default_value(), "must be");
- }
-
- // Set/get by index tests: invert some value
- idx_t index = NUM_REGIONS / 2;
- actual_value = array.get_by_index(index);
- array.set_by_index(index, ~actual_value);
-
- value = array.get_by_index(index);
- assert(value == ~actual_value, "must be");
-
- value = array.get_by_index(index - 1);
- assert(value == array.default_value(), "must be");
-
- value = array.get_by_index(index + 1);
- assert(value == array.default_value(), "must be");
-
- array.set_by_index(0, 0);
- value = array.get_by_index(0);
- assert(value == 0, "must be");
-
- array.set_by_index(array.length() - 1, 0);
- value = array.get_by_index(array.length() - 1);
- assert(value == 0, "must be");
-
- array.set_by_index(index, 0);
-
- // The array should have three zeros, and default values otherwise
- size_t num_zeros = 0;
- for (int* current = bottom; current < end; current++) {
- assert(*current == array.default_value() || *current == 0, "must be");
- if (*current == 0) {
- num_zeros++;
- }
- }
- assert(num_zeros == 3, "must be");
- }
-};
-
-void TestG1BiasedArray_test() {
- TestMappedArray::test_biasedarray();
-}
-
#endif
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -4420,6 +4420,19 @@
NOT_PRODUCT(set_evacuation_failure_alot_for_current_gc();)
assert(dirty_card_queue_set().completed_buffers_num() == 0, "Should be empty");
+
+ G1GCPhaseTimes* phase_times = g1_policy()->phase_times();
+
+ // InitialMark needs claim bits to keep track of the marked-through CLDs.
+ if (collector_state()->during_initial_mark_pause()) {
+ double start_clear_claimed_marks = os::elapsedTime();
+
+ ClassLoaderDataGraph::clear_claimed_marks();
+
+ double recorded_clear_claimed_marks_time_ms = (os::elapsedTime() - start_clear_claimed_marks) * 1000.0;
+ phase_times->record_clear_claimed_marks_time_ms(recorded_clear_claimed_marks_time_ms);
+ }
+
double start_par_time_sec = os::elapsedTime();
double end_par_time_sec;
@@ -4427,10 +4440,6 @@
const uint n_workers = workers()->active_workers();
G1RootProcessor root_processor(this, n_workers);
G1ParTask g1_par_task(this, per_thread_states, _task_queues, &root_processor, n_workers);
- // InitialMark needs claim bits to keep track of the marked-through CLDs.
- if (collector_state()->during_initial_mark_pause()) {
- ClassLoaderDataGraph::clear_claimed_marks();
- }
print_termination_stats_hdr();
@@ -4444,8 +4453,6 @@
// reported parallel time.
}
- G1GCPhaseTimes* phase_times = g1_policy()->phase_times();
-
double par_time_ms = (end_par_time_sec - start_par_time_sec) * 1000.0;
phase_times->record_par_time(par_time_ms);
--- a/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -101,6 +101,7 @@
_gc_start_counter = os::elapsed_counter();
_cur_expand_heap_time_ms = 0.0;
_external_accounted_time_ms = 0.0;
+ _recorded_clear_claimed_marks_time_ms = 0.0;
for (int i = 0; i < GCParPhasesSentinel; i++) {
if (_gc_par_phases[i] != NULL) {
@@ -306,6 +307,10 @@
debug_line("Reference Processing", _cur_ref_proc_time_ms);
debug_line("Reference Enqueuing", _cur_ref_enq_time_ms);
debug_line("Redirty Cards", _recorded_redirty_logged_cards_time_ms);
+ if (_recorded_clear_claimed_marks_time_ms > 0.0) {
+ debug_line("Clear Claimed Marks", _recorded_clear_claimed_marks_time_ms);
+ }
+
trace_phase(_gc_par_phases[RedirtyCards]);
if (G1EagerReclaimHumongousObjects) {
debug_line("Humongous Register", _cur_fast_reclaim_humongous_register_time_ms);
--- a/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.hpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.hpp Wed Oct 26 20:13:29 2016 +0000
@@ -103,6 +103,8 @@
double _external_accounted_time_ms;
+ double _recorded_clear_claimed_marks_time_ms;
+
double _recorded_young_cset_choice_time_ms;
double _recorded_non_young_cset_choice_time_ms;
@@ -257,6 +259,10 @@
_external_accounted_time_ms += time_ms;
}
+ void record_clear_claimed_marks_time_ms(double recorded_clear_claimed_marks_time_ms) {
+ _recorded_clear_claimed_marks_time_ms = recorded_clear_claimed_marks_time_ms;
+ }
+
double cur_collection_start_sec() {
return _cur_collection_start_sec;
}
--- a/hotspot/src/share/vm/gc/g1/heapRegionSet.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/gc/g1/heapRegionSet.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -370,50 +370,3 @@
"master humongous set MT safety protocol outside a safepoint");
}
}
-
-void FreeRegionList_test() {
- FreeRegionList l("test");
-
- const uint num_regions_in_test = 5;
- // Create a fake heap. It does not need to be valid, as the HeapRegion constructor
- // does not access it.
- MemRegion heap(NULL, num_regions_in_test * HeapRegion::GrainWords);
- // Allocate a fake BOT because the HeapRegion constructor initializes
- // the BOT.
- size_t bot_size = G1BlockOffsetTable::compute_size(heap.word_size());
- HeapWord* bot_data = NEW_C_HEAP_ARRAY(HeapWord, bot_size, mtGC);
- ReservedSpace bot_rs(G1BlockOffsetTable::compute_size(heap.word_size()));
- G1RegionToSpaceMapper* bot_storage =
- G1RegionToSpaceMapper::create_mapper(bot_rs,
- bot_rs.size(),
- os::vm_page_size(),
- HeapRegion::GrainBytes,
- BOTConstants::N_bytes,
- mtGC);
- G1BlockOffsetTable bot(heap, bot_storage);
- bot_storage->commit_regions(0, num_regions_in_test);
-
- // Set up memory regions for the heap regions.
- MemRegion mr0(heap.start(), HeapRegion::GrainWords);
- MemRegion mr1(mr0.end(), HeapRegion::GrainWords);
- MemRegion mr2(mr1.end(), HeapRegion::GrainWords);
- MemRegion mr3(mr2.end(), HeapRegion::GrainWords);
- MemRegion mr4(mr3.end(), HeapRegion::GrainWords);
-
- HeapRegion hr0(0, &bot, mr0);
- HeapRegion hr1(1, &bot, mr1);
- HeapRegion hr2(2, &bot, mr2);
- HeapRegion hr3(3, &bot, mr3);
- HeapRegion hr4(4, &bot, mr4);
- l.add_ordered(&hr1);
- l.add_ordered(&hr0);
- l.add_ordered(&hr3);
- l.add_ordered(&hr4);
- l.add_ordered(&hr2);
- assert(l.length() == num_regions_in_test, "wrong length");
- l.verify_list();
-
- bot_storage->uncommit_regions(0, num_regions_in_test);
- delete bot_storage;
- FREE_C_HEAP_ARRAY(HeapWord, bot_data);
-}
--- a/hotspot/src/share/vm/gc/g1/workerDataArray.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/gc/g1/workerDataArray.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -79,126 +79,3 @@
}
out->cr();
}
-
-#ifndef PRODUCT
-
-#include "memory/resourceArea.hpp"
-
-void WorkerDataArray_test_verify_string(const char* expected_string, const char* actual_string) {
- const size_t expected_len = strlen(expected_string);
-
- assert(expected_len == strlen(actual_string),
- "Wrong string length, expected " SIZE_FORMAT " but got " SIZE_FORMAT "(Expected '%s' but got: '%s')",
- expected_len, strlen(actual_string), expected_string, actual_string);
-
- // Can't use strncmp here because floating point values use different decimal points for different locales.
- // Allow strings to differ in "." vs. "," only. This should still catch most errors.
- for (size_t i = 0; i < expected_len; i++) {
- char e = expected_string[i];
- char a = actual_string[i];
- if (e != a) {
- if ((e == '.' || e == ',') && (a == '.' || a == ',')) {
- // Most likely just a difference in locale
- } else {
- assert(false, "Expected '%s' but got: '%s'", expected_string, actual_string);
- }
- }
- }
-}
-
-void WorkerDataArray_test_verify_array(WorkerDataArray<size_t>& array, size_t expected_sum, double expected_avg, const char* expected_summary, const char* exected_details) {
- const double epsilon = 0.0001;
- assert(array.sum() == expected_sum, "Wrong sum, expected: " SIZE_FORMAT " but got: " SIZE_FORMAT, expected_sum, array.sum());
- assert(fabs(array.average() - expected_avg) < epsilon, "Wrong average, expected: %f but got: %f", expected_avg, array.average());
-
- ResourceMark rm;
- stringStream out;
- array.print_summary_on(&out);
- WorkerDataArray_test_verify_string(expected_summary, out.as_string());
- out.reset();
- array.print_details_on(&out);
- WorkerDataArray_test_verify_string(exected_details, out.as_string());
-}
-
-void WorkerDataArray_test_verify_array(WorkerDataArray<double>& array, double expected_sum, double expected_avg, const char* expected_summary, const char* exected_details) {
- const double epsilon = 0.0001;
- assert(fabs(array.sum() - expected_sum) < epsilon, "Wrong sum, expected: %f but got: %f", expected_sum, array.sum());
- assert(fabs(array.average() - expected_avg) < epsilon, "Wrong average, expected: %f but got: %f", expected_avg, array.average());
-
- ResourceMark rm;
- stringStream out;
- array.print_summary_on(&out);
- WorkerDataArray_test_verify_string(expected_summary, out.as_string());
- out.reset();
- array.print_details_on(&out);
- WorkerDataArray_test_verify_string(exected_details, out.as_string());
-}
-
-void WorkerDataArray_test_basic() {
- WorkerDataArray<size_t> array(3, "Test array");
- array.set(0, 5);
- array.set(1, 3);
- array.set(2, 7);
-
- WorkerDataArray_test_verify_array(array, 15, 5.0,
- "Test array Min: 3, Avg: 5.0, Max: 7, Diff: 4, Sum: 15, Workers: 3\n",
- " 5 3 7\n" );
-}
-
-void WorkerDataArray_test_add() {
- WorkerDataArray<size_t> array(3, "Test array");
- array.set(0, 5);
- array.set(1, 3);
- array.set(2, 7);
-
- for (uint i = 0; i < 3; i++) {
- array.add(i, 1);
- }
-
- WorkerDataArray_test_verify_array(array, 18, 6.0,
- "Test array Min: 4, Avg: 6.0, Max: 8, Diff: 4, Sum: 18, Workers: 3\n",
- " 6 4 8\n" );
-}
-
-void WorkerDataArray_test_with_uninitialized() {
- WorkerDataArray<size_t> array(3, "Test array");
- array.set(0, 5);
- array.set(1, WorkerDataArray<size_t>::uninitialized());
- array.set(2, 7);
-
- WorkerDataArray_test_verify_array(array, 12, 6,
- "Test array Min: 5, Avg: 6.0, Max: 7, Diff: 2, Sum: 12, Workers: 2\n",
- " 5 - 7\n" );
-}
-
-void WorkerDataArray_test_uninitialized() {
- WorkerDataArray<size_t> array(3, "Test array");
- array.set(0, WorkerDataArray<size_t>::uninitialized());
- array.set(1, WorkerDataArray<size_t>::uninitialized());
- array.set(2, WorkerDataArray<size_t>::uninitialized());
-
- WorkerDataArray_test_verify_array(array, 0, 0.0,
- "Test array skipped\n",
- " - - -\n" );
-}
-
-void WorkerDataArray_test_double_with_uninitialized() {
- WorkerDataArray<double> array(3, "Test array");
- array.set(0, 5.1 / MILLIUNITS);
- array.set(1, WorkerDataArray<double>::uninitialized());
- array.set(2, 7.2 / MILLIUNITS);
-
- WorkerDataArray_test_verify_array(array, 12.3 / MILLIUNITS, 6.15 / MILLIUNITS,
- "Test array Min: 5.1, Avg: 6.1, Max: 7.2, Diff: 2.1, Sum: 12.3, Workers: 2\n",
- " 5.1 - 7.2\n" );
-}
-
-void WorkerDataArray_test() {
- WorkerDataArray_test_basic();
- WorkerDataArray_test_add();
- WorkerDataArray_test_with_uninitialized();
- WorkerDataArray_test_uninitialized();
- WorkerDataArray_test_double_with_uninitialized();
-}
-
-#endif
--- a/hotspot/src/share/vm/gc/shared/collectorPolicy.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/gc/shared/collectorPolicy.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -909,184 +909,3 @@
_gc_policy_counters = new GCPolicyCounters("Copy:MSC", 2, 3);
}
-/////////////// Unit tests ///////////////
-
-#ifndef PRODUCT
-// Testing that the NewSize flag is handled correct is hard because it
-// depends on so many other configurable variables. This test only tries to
-// verify that there are some basic rules for NewSize honored by the policies.
-class TestGenCollectorPolicy {
-public:
- static void test_new_size() {
- size_t flag_value;
-
- save_flags();
-
- // If NewSize has been ergonomically set, the collector policy
- // should use it for min but calculate the initial young size
- // using NewRatio.
- flag_value = 20 * M;
- set_basic_flag_values();
- FLAG_SET_ERGO(size_t, NewSize, flag_value);
- verify_young_min(flag_value);
-
- set_basic_flag_values();
- FLAG_SET_ERGO(size_t, NewSize, flag_value);
- verify_scaled_young_initial(InitialHeapSize);
-
- // If NewSize is set on the command line, it should be used
- // for both min and initial young size if less than min heap.
- // Note that once a flag has been set with FLAG_SET_CMDLINE it
- // will be treated as it have been set on the command line for
- // the rest of the VM lifetime. This is an irreversible change.
- flag_value = 20 * M;
- set_basic_flag_values();
- FLAG_SET_CMDLINE(size_t, NewSize, flag_value);
- verify_young_min(flag_value);
-
- set_basic_flag_values();
- FLAG_SET_CMDLINE(size_t, NewSize, flag_value);
- verify_young_initial(flag_value);
-
- // If NewSize is set on command line, but is larger than the min
- // heap size, it should only be used for initial young size.
- flag_value = 80 * M;
- set_basic_flag_values();
- FLAG_SET_CMDLINE(size_t, NewSize, flag_value);
- verify_young_initial(flag_value);
-
- restore_flags();
- }
-
- static void test_old_size() {
- size_t flag_value;
- size_t heap_alignment = CollectorPolicy::compute_heap_alignment();
-
- save_flags();
-
- // If OldSize is set on the command line, it should be used
- // for both min and initial old size if less than min heap.
- flag_value = 20 * M;
- set_basic_flag_values();
- FLAG_SET_CMDLINE(size_t, OldSize, flag_value);
- verify_old_min(flag_value);
-
- set_basic_flag_values();
- FLAG_SET_CMDLINE(size_t, OldSize, flag_value);
- // Calculate what we expect the flag to be.
- size_t expected_old_initial = align_size_up(InitialHeapSize, heap_alignment) - MaxNewSize;
- verify_old_initial(expected_old_initial);
-
- // If MaxNewSize is large, the maximum OldSize will be less than
- // what's requested on the command line and it should be reset
- // ergonomically.
- // We intentionally set MaxNewSize + OldSize > MaxHeapSize (see over_size).
- flag_value = 30 * M;
- set_basic_flag_values();
- FLAG_SET_CMDLINE(size_t, OldSize, flag_value);
- size_t over_size = 20*M;
- size_t new_size_value = align_size_up(MaxHeapSize, heap_alignment) - flag_value + over_size;
- FLAG_SET_CMDLINE(size_t, MaxNewSize, new_size_value);
- // Calculate what we expect the flag to be.
- expected_old_initial = align_size_up(MaxHeapSize, heap_alignment) - MaxNewSize;
- verify_old_initial(expected_old_initial);
- restore_flags();
- }
-
- static void verify_young_min(size_t expected) {
- MarkSweepPolicy msp;
- msp.initialize_all();
-
- assert(msp.min_young_size() <= expected, "%zu > %zu", msp.min_young_size(), expected);
- }
-
- static void verify_young_initial(size_t expected) {
- MarkSweepPolicy msp;
- msp.initialize_all();
-
- assert(msp.initial_young_size() == expected, "%zu != %zu", msp.initial_young_size(), expected);
- }
-
- static void verify_scaled_young_initial(size_t initial_heap_size) {
- MarkSweepPolicy msp;
- msp.initialize_all();
-
- if (InitialHeapSize > initial_heap_size) {
- // InitialHeapSize was adapted by msp.initialize_all, e.g. due to alignment
- // caused by 64K page size.
- initial_heap_size = InitialHeapSize;
- }
-
- size_t expected = msp.scale_by_NewRatio_aligned(initial_heap_size);
- assert(msp.initial_young_size() == expected, "%zu != %zu", msp.initial_young_size(), expected);
- assert(FLAG_IS_ERGO(NewSize) && NewSize == expected,
- "NewSize should have been set ergonomically to %zu, but was %zu", expected, NewSize);
- }
-
- static void verify_old_min(size_t expected) {
- MarkSweepPolicy msp;
- msp.initialize_all();
-
- assert(msp.min_old_size() <= expected, "%zu > %zu", msp.min_old_size(), expected);
- }
-
- static void verify_old_initial(size_t expected) {
- MarkSweepPolicy msp;
- msp.initialize_all();
-
- assert(msp.initial_old_size() == expected, "%zu != %zu", msp.initial_old_size(), expected);
- }
-
-
-private:
- static size_t original_InitialHeapSize;
- static size_t original_MaxHeapSize;
- static size_t original_MaxNewSize;
- static size_t original_MinHeapDeltaBytes;
- static size_t original_NewSize;
- static size_t original_OldSize;
-
- static void set_basic_flag_values() {
- FLAG_SET_ERGO(size_t, MaxHeapSize, 180 * M);
- FLAG_SET_ERGO(size_t, InitialHeapSize, 100 * M);
- FLAG_SET_ERGO(size_t, OldSize, 4 * M);
- FLAG_SET_ERGO(size_t, NewSize, 1 * M);
- FLAG_SET_ERGO(size_t, MaxNewSize, 80 * M);
- Arguments::set_min_heap_size(40 * M);
- }
-
- static void save_flags() {
- original_InitialHeapSize = InitialHeapSize;
- original_MaxHeapSize = MaxHeapSize;
- original_MaxNewSize = MaxNewSize;
- original_MinHeapDeltaBytes = MinHeapDeltaBytes;
- original_NewSize = NewSize;
- original_OldSize = OldSize;
- }
-
- static void restore_flags() {
- InitialHeapSize = original_InitialHeapSize;
- MaxHeapSize = original_MaxHeapSize;
- MaxNewSize = original_MaxNewSize;
- MinHeapDeltaBytes = original_MinHeapDeltaBytes;
- NewSize = original_NewSize;
- OldSize = original_OldSize;
- }
-};
-
-size_t TestGenCollectorPolicy::original_InitialHeapSize = 0;
-size_t TestGenCollectorPolicy::original_MaxHeapSize = 0;
-size_t TestGenCollectorPolicy::original_MaxNewSize = 0;
-size_t TestGenCollectorPolicy::original_MinHeapDeltaBytes = 0;
-size_t TestGenCollectorPolicy::original_NewSize = 0;
-size_t TestGenCollectorPolicy::original_OldSize = 0;
-
-void TestNewSize_test() {
- TestGenCollectorPolicy::test_new_size();
-}
-
-void TestOldSize_test() {
- TestGenCollectorPolicy::test_old_size();
-}
-
-#endif
--- a/hotspot/src/share/vm/jvmci/jvmciCompiler.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/jvmci/jvmciCompiler.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -37,7 +37,7 @@
JVMCICompiler* JVMCICompiler::_instance = NULL;
elapsedTimer JVMCICompiler::_codeInstallTimer;
-JVMCICompiler::JVMCICompiler() : AbstractCompiler(jvmci) {
+JVMCICompiler::JVMCICompiler() : AbstractCompiler(compiler_jvmci) {
_bootstrapping = false;
_bootstrap_compilation_request_handled = false;
_methods_compiled = 0;
--- a/hotspot/src/share/vm/jvmci/jvmci_globals.hpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/jvmci/jvmci_globals.hpp Wed Oct 26 20:13:29 2016 +0000
@@ -50,7 +50,7 @@
"Use JVMCI as the default compiler") \
\
experimental(bool, JVMCIPrintProperties, false, \
- "Prints properties used by the JVMCI compiler") \
+ "Prints properties used by the JVMCI compiler and exits") \
\
experimental(bool, BootstrapJVMCI, false, \
"Bootstrap JVMCI before running Java main method") \
--- a/hotspot/src/share/vm/memory/filemap.hpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/memory/filemap.hpp Wed Oct 26 20:13:29 2016 +0000
@@ -283,11 +283,15 @@
bool validate_classpath_entry_table();
static SharedClassPathEntry* shared_classpath(int index) {
+ if (index < 0) {
+ return NULL;
+ }
char* p = (char*)_classpath_entry_table;
p += _classpath_entry_size * index;
return (SharedClassPathEntry*)p;
}
static const char* shared_classpath_name(int index) {
+ assert(index >= 0, "Sanity");
return shared_classpath(index)->_name;
}
--- a/hotspot/src/share/vm/memory/guardedMemory.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/memory/guardedMemory.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -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
@@ -79,87 +79,3 @@
break;
}
}
-
-// test code...
-
-#ifndef PRODUCT
-
-static void guarded_memory_test_check(void* p, size_t sz, void* tag) {
- assert(p != NULL, "NULL pointer given to check");
- u_char* c = (u_char*) p;
- GuardedMemory guarded(c);
- assert(guarded.get_tag() == tag, "Tag is not the same as supplied");
- assert(guarded.get_user_ptr() == c, "User pointer is not the same as supplied");
- assert(guarded.get_user_size() == sz, "User size is not the same as supplied");
- assert(guarded.verify_guards(), "Guard broken");
-}
-
-void GuardedMemory::test_guarded_memory() {
- // Test the basic characteristics...
- size_t total_sz = GuardedMemory::get_total_size(1);
- assert(total_sz > 1 && total_sz >= (sizeof(GuardHeader) + 1 + sizeof(Guard)), "Unexpected size");
- u_char* basep = (u_char*) os::malloc(total_sz, mtInternal);
-
- GuardedMemory guarded(basep, 1, (void*)0xf000f000);
-
- assert(*basep == badResourceValue, "Expected guard in the form of badResourceValue");
- u_char* userp = guarded.get_user_ptr();
- assert(*userp == uninitBlockPad, "Expected uninitialized data in the form of uninitBlockPad");
- guarded_memory_test_check(userp, 1, (void*)0xf000f000);
-
- void* freep = guarded.release_for_freeing();
- assert((u_char*)freep == basep, "Expected the same pointer guard was ");
- assert(*userp == freeBlockPad, "Expected user data to be free block padded");
- assert(!guarded.verify_guards(), "Expected failed");
- os::free(freep);
-
- // Test a number of odd sizes...
- size_t sz = 0;
- do {
- void* p = os::malloc(GuardedMemory::get_total_size(sz), mtInternal);
- void* up = guarded.wrap_with_guards(p, sz, (void*)1);
- memset(up, 0, sz);
- guarded_memory_test_check(up, sz, (void*)1);
- os::free(guarded.release_for_freeing());
- sz = (sz << 4) + 1;
- } while (sz < (256 * 1024));
-
- // Test buffer overrun into head...
- basep = (u_char*) os::malloc(GuardedMemory::get_total_size(1), mtInternal);
- guarded.wrap_with_guards(basep, 1);
- *basep = 0;
- assert(!guarded.verify_guards(), "Expected failure");
- os::free(basep);
-
- // Test buffer overrun into tail with a number of odd sizes...
- sz = 1;
- do {
- void* p = os::malloc(GuardedMemory::get_total_size(sz), mtInternal);
- void* up = guarded.wrap_with_guards(p, sz, (void*)1);
- memset(up, 0, sz + 1); // Buffer-overwrite (within guard)
- assert(!guarded.verify_guards(), "Guard was not broken as expected");
- os::free(guarded.release_for_freeing());
- sz = (sz << 4) + 1;
- } while (sz < (256 * 1024));
-
- // Test wrap_copy/wrap_free...
- assert(GuardedMemory::free_copy(NULL), "Expected free NULL to be OK");
-
- const char* str = "Check my bounds out";
- size_t str_sz = strlen(str) + 1;
- char* str_copy = (char*) GuardedMemory::wrap_copy(str, str_sz);
- guarded_memory_test_check(str_copy, str_sz, NULL);
- assert(strcmp(str, str_copy) == 0, "Not identical copy");
- assert(GuardedMemory::free_copy(str_copy), "Free copy failed to verify");
-
- void* no_data = NULL;
- void* no_data_copy = GuardedMemory::wrap_copy(no_data, 0);
- assert(GuardedMemory::free_copy(no_data_copy), "Expected valid guards even for no data copy");
-}
-
-void GuardedMemory_test() {
- GuardedMemory::test_guarded_memory();
-}
-
-#endif // !PRODUCT
-
--- a/hotspot/src/share/vm/memory/guardedMemory.hpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/memory/guardedMemory.hpp Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2015, 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
@@ -82,6 +82,7 @@
*/
class GuardedMemory : StackObj { // Wrapper on stack
+ friend class GuardedMemoryTest;
// Private inner classes for memory layout...
protected:
@@ -317,10 +318,6 @@
*/
static bool free_copy(void* p);
- // Testing...
-#ifndef PRODUCT
- static void test_guarded_memory(void);
-#endif
}; // GuardedMemory
#endif // SHARE_VM_MEMORY_GUARDEDMEMORY_HPP
--- a/hotspot/src/share/vm/memory/metachunk.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/memory/metachunk.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -111,61 +111,3 @@
return;
}
-/////////////// Unit tests ///////////////
-
-#ifndef PRODUCT
-
-class TestMetachunk {
- public:
- static void test() {
- size_t size = 2 * 1024 * 1024;
- void* memory = malloc(size);
- assert(memory != NULL, "Failed to malloc 2MB");
-
- Metachunk* metachunk = ::new (memory) Metachunk(size / BytesPerWord, NULL);
-
- assert(metachunk->bottom() == (MetaWord*)metachunk, "assert");
- assert(metachunk->end() == (uintptr_t*)metachunk + metachunk->size(), "assert");
-
- // Check sizes
- assert(metachunk->size() == metachunk->word_size(), "assert");
- assert(metachunk->word_size() == pointer_delta(metachunk->end(), metachunk->bottom(),
- sizeof(MetaWord*)), "assert");
-
- // Check usage
- assert(metachunk->used_word_size() == metachunk->overhead(), "assert");
- assert(metachunk->free_word_size() == metachunk->word_size() - metachunk->used_word_size(), "assert");
- assert(metachunk->top() == metachunk->initial_top(), "assert");
- assert(metachunk->is_empty(), "assert");
-
- // Allocate
- size_t alloc_size = 64; // Words
- assert(is_size_aligned(alloc_size, Metachunk::object_alignment()), "assert");
-
- MetaWord* mem = metachunk->allocate(alloc_size);
-
- // Check post alloc
- assert(mem == metachunk->initial_top(), "assert");
- assert(mem + alloc_size == metachunk->top(), "assert");
- assert(metachunk->used_word_size() == metachunk->overhead() + alloc_size, "assert");
- assert(metachunk->free_word_size() == metachunk->word_size() - metachunk->used_word_size(), "assert");
- assert(!metachunk->is_empty(), "assert");
-
- // Clear chunk
- metachunk->reset_empty();
-
- // Check post clear
- assert(metachunk->used_word_size() == metachunk->overhead(), "assert");
- assert(metachunk->free_word_size() == metachunk->word_size() - metachunk->used_word_size(), "assert");
- assert(metachunk->top() == metachunk->initial_top(), "assert");
- assert(metachunk->is_empty(), "assert");
-
- free(memory);
- }
-};
-
-void TestMetachunk_test() {
- TestMetachunk::test();
-}
-
-#endif
--- a/hotspot/src/share/vm/memory/metachunk.hpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/memory/metachunk.hpp Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -95,7 +95,7 @@
// +--------------+ <- bottom --+ --+
class Metachunk : public Metabase<Metachunk> {
- friend class TestMetachunk;
+ friend class MetachunkTest;
// The VirtualSpaceNode containing this chunk.
VirtualSpaceNode* _container;
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -517,12 +517,14 @@
bool InstanceKlass::link_class_impl(
instanceKlassHandle this_k, bool throw_verifyerror, TRAPS) {
- // check for error state.
- // This is checking for the wrong state. If the state is initialization_error,
- // then this class *was* linked. The CDS code does a try_link_class and uses
- // initialization_error to mark classes to not include in the archive during
- // DumpSharedSpaces. This should be removed when the CDS bug is fixed.
- if (this_k->is_in_error_state()) {
+ if (DumpSharedSpaces && this_k->is_in_error_state()) {
+ // This is for CDS dumping phase only -- we use the in_error_state to indicate that
+ // the class has failed verification. Throwing the NoClassDefFoundError here is just
+ // a convenient way to stop repeat attempts to verify the same (bad) class.
+ //
+ // Note that the NoClassDefFoundError is not part of the JLS, and should not be thrown
+ // if we are executing Java code. This is not a problem for CDS dumping phase since
+ // it doesn't execute any Java code.
ResourceMark rm(THREAD);
THROW_MSG_(vmSymbols::java_lang_NoClassDefFoundError(),
this_k->external_name(), false);
--- a/hotspot/src/share/vm/oops/method.hpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/oops/method.hpp Wed Oct 26 20:13:29 2016 +0000
@@ -27,6 +27,7 @@
#include "classfile/vmSymbols.hpp"
#include "code/compressedStream.hpp"
+#include "compiler/compilerDefinitions.hpp"
#include "compiler/oopMap.hpp"
#include "interpreter/invocationCounter.hpp"
#include "oops/annotations.hpp"
--- a/hotspot/src/share/vm/opto/c2compiler.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/opto/c2compiler.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -537,6 +537,7 @@
#ifdef TRACE_HAVE_INTRINSICS
case vmIntrinsics::_counterTime:
case vmIntrinsics::_getClassId:
+ case vmIntrinsics::_getBufferWriter:
#endif
case vmIntrinsics::_currentTimeMillis:
case vmIntrinsics::_nanoTime:
--- a/hotspot/src/share/vm/opto/c2compiler.hpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/opto/c2compiler.hpp Wed Oct 26 20:13:29 2016 +0000
@@ -32,7 +32,7 @@
static bool init_c2_runtime();
public:
- C2Compiler() : AbstractCompiler(c2) {}
+ C2Compiler() : AbstractCompiler(compiler_c2) {}
// Name
const char *name() { return "C2"; }
--- a/hotspot/src/share/vm/opto/castnode.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/opto/castnode.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -224,30 +224,6 @@
return progress;
}
- // transform:
- // (CastII (AddI x const)) -> (AddI (CastII x) const)
- // So the AddI has a chance to be optimized out
- if (in(1)->Opcode() == Op_AddI) {
- Node* in2 = in(1)->in(2);
- const TypeInt* in2_t = phase->type(in2)->isa_int();
- if (in2_t != NULL && in2_t->singleton()) {
- int in2_const = in2_t->_lo;
- const TypeInt* current_type = _type->is_int();
- jlong new_lo_long = ((jlong)current_type->_lo) - in2_const;
- jlong new_hi_long = ((jlong)current_type->_hi) - in2_const;
- int new_lo = (int)new_lo_long;
- int new_hi = (int)new_hi_long;
- if (((jlong)new_lo) == new_lo_long && ((jlong)new_hi) == new_hi_long) {
- Node* in1 = in(1)->in(1);
- CastIINode* new_cast = (CastIINode*)clone();
- AddINode* new_add = (AddINode*)in(1)->clone();
- new_cast->set_type(TypeInt::make(new_lo, new_hi, current_type->_widen));
- new_cast->set_req(1, in1);
- new_add->set_req(1, phase->transform(new_cast));
- return new_add;
- }
- }
- }
// Similar to ConvI2LNode::Ideal() for the same reasons
if (can_reshape && !phase->C->major_progress()) {
const TypeInt* this_type = this->type()->is_int();
--- a/hotspot/src/share/vm/opto/library_call.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/opto/library_call.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -256,6 +256,7 @@
bool inline_native_time_funcs(address method, const char* funcName);
#ifdef TRACE_HAVE_INTRINSICS
bool inline_native_classID();
+ bool inline_native_getBufferWriter();
#endif
bool inline_native_isInterrupted();
bool inline_native_Class_query(vmIntrinsics::ID id);
@@ -713,6 +714,7 @@
#ifdef TRACE_HAVE_INTRINSICS
case vmIntrinsics::_counterTime: return inline_native_time_funcs(CAST_FROM_FN_PTR(address, TRACE_TIME_METHOD), "counterTime");
case vmIntrinsics::_getClassId: return inline_native_classID();
+ case vmIntrinsics::_getBufferWriter: return inline_native_getBufferWriter();
#endif
case vmIntrinsics::_currentTimeMillis: return inline_native_time_funcs(CAST_FROM_FN_PTR(address, os::javaTimeMillis), "currentTimeMillis");
case vmIntrinsics::_nanoTime: return inline_native_time_funcs(CAST_FROM_FN_PTR(address, os::javaTimeNanos), "nanoTime");
@@ -3198,6 +3200,44 @@
}
+bool LibraryCallKit::inline_native_getBufferWriter() {
+ Node* tls_ptr = _gvn.transform(new ThreadLocalNode());
+
+ Node* jobj_ptr = basic_plus_adr(top(), tls_ptr,
+ in_bytes(TRACE_THREAD_DATA_WRITER_OFFSET)
+ );
+
+ Node* jobj = make_load(control(), jobj_ptr, TypeRawPtr::BOTTOM, T_ADDRESS, MemNode::unordered);
+
+ Node* jobj_cmp_null = _gvn.transform( new CmpPNode(jobj, null()) );
+ Node* test_jobj_eq_null = _gvn.transform( new BoolNode(jobj_cmp_null, BoolTest::eq) );
+
+ IfNode* iff_jobj_null =
+ create_and_map_if(control(), test_jobj_eq_null, PROB_NEVER, COUNT_UNKNOWN);
+
+ enum { _normal_path = 1,
+ _null_path = 2,
+ PATH_LIMIT };
+
+ RegionNode* result_rgn = new RegionNode(PATH_LIMIT);
+ PhiNode* result_val = new PhiNode(result_rgn, TypePtr::BOTTOM);
+ record_for_igvn(result_rgn);
+
+ Node* jobj_is_null = _gvn.transform( new IfTrueNode(iff_jobj_null) );
+ result_rgn->init_req(_null_path, jobj_is_null);
+ result_val->init_req(_null_path, null());
+
+ Node* jobj_is_not_null = _gvn.transform( new IfFalseNode(iff_jobj_null) );
+ result_rgn->init_req(_normal_path, jobj_is_not_null);
+
+ Node* res = make_load(NULL, jobj, TypeInstPtr::BOTTOM, T_OBJECT, MemNode::unordered);
+ result_val->init_req(_normal_path, res);
+
+ set_result(result_rgn, result_val);
+
+ return true;
+}
+
#endif
//------------------------inline_native_currentThread------------------
--- a/hotspot/src/share/vm/prims/jvm.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/prims/jvm.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -2524,7 +2524,6 @@
switch (cp->tag_at(cp_index).value()) {
case JVM_CONSTANT_InterfaceMethodref:
case JVM_CONSTANT_Methodref:
- case JVM_CONSTANT_NameAndType: // for invokedynamic
return cp->uncached_name_ref_at(cp_index)->as_utf8();
default:
fatal("JVM_GetCPMethodNameUTF: illegal constant");
@@ -2542,7 +2541,6 @@
switch (cp->tag_at(cp_index).value()) {
case JVM_CONSTANT_InterfaceMethodref:
case JVM_CONSTANT_Methodref:
- case JVM_CONSTANT_NameAndType: // for invokedynamic
return cp->uncached_signature_ref_at(cp_index)->as_utf8();
default:
fatal("JVM_GetCPMethodSignatureUTF: illegal constant");
--- a/hotspot/src/share/vm/prims/jvmtiEnv.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/prims/jvmtiEnv.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -1001,7 +1001,8 @@
if (name() != NULL) {
n = java_lang_String::as_utf8_string(name());
} else {
- n = UNICODE::as_utf8((jchar*) NULL, 0);
+ int utf8_length = 0;
+ n = UNICODE::as_utf8((jchar*) NULL, utf8_length);
}
info_ptr->name = (char *) jvmtiMalloc(strlen(n)+1);
--- a/hotspot/src/share/vm/runtime/arguments.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -416,6 +416,8 @@
{ "UseAltSigs", JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
{ "SegmentedHeapDumpThreshold", JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
{ "PrintOopAddress", JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
+ { "PermSize", JDK_Version::undefined(), JDK_Version::jdk(8), JDK_Version::jdk(10) },
+ { "MaxPermSize", JDK_Version::undefined(), JDK_Version::jdk(8), JDK_Version::jdk(10) },
#ifdef TEST_VERIFY_SPECIAL_JVM_FLAGS
{ "dep > obs", JDK_Version::jdk(9), JDK_Version::jdk(8), JDK_Version::undefined() },
@@ -793,9 +795,10 @@
} else if (new_len == 0) {
value = old_value;
} else {
- char* buf = NEW_C_HEAP_ARRAY(char, old_len + 1 + new_len + 1, mtArguments);
+ size_t length = old_len + 1 + new_len + 1;
+ char* buf = NEW_C_HEAP_ARRAY(char, length, mtArguments);
// each new setting adds another LINE to the switch:
- sprintf(buf, "%s\n%s", old_value, new_value);
+ jio_snprintf(buf, length, "%s\n%s", old_value, new_value);
value = buf;
free_this_too = buf;
}
@@ -1013,15 +1016,17 @@
if (args == NULL || count == 0) {
return NULL;
}
- size_t length = strlen(args[0]) + 1; // add 1 for the null terminator
- for (int i = 1; i < count; i++) {
- length += strlen(args[i]) + 1; // add 1 for a space
+ size_t length = 0;
+ for (int i = 0; i < count; i++) {
+ length += strlen(args[i]) + 1; // add 1 for a space or NULL terminating character
}
char* s = NEW_RESOURCE_ARRAY(char, length);
- strcpy(s, args[0]);
- for (int j = 1; j < count; j++) {
- strcat(s, " ");
- strcat(s, args[j]);
+ char* dst = s;
+ for (int j = 0; j < count; j++) {
+ size_t offset = strlen(args[j]) + 1; // add 1 for a space or NULL terminating character
+ jio_snprintf(dst, length, "%s ", args[j]); // jio_snprintf will replace the last space character with NULL character
+ dst += offset;
+ length -= offset;
}
return (const char*) s;
}
@@ -1105,9 +1110,8 @@
// Only make the obsolete check for valid arguments.
if (arg_len <= BUFLEN) {
// Construct a string which consists only of the argument name without '+', '-', or '='.
- char stripped_argname[BUFLEN+1];
- strncpy(stripped_argname, argname, arg_len);
- stripped_argname[arg_len] = '\0'; // strncpy may not null terminate.
+ char stripped_argname[BUFLEN+1]; // +1 for '\0'
+ jio_snprintf(stripped_argname, arg_len+1, "%s", argname); // +1 for '\0'
if (is_obsolete_flag(stripped_argname, &since)) {
char version[256];
since.to_string(version, sizeof(version));
@@ -1259,8 +1263,7 @@
size_t key_len = eq - prop;
char* tmp_key = AllocateHeap(key_len + 1, mtArguments);
- strncpy(tmp_key, prop, key_len);
- tmp_key[key_len] = '\0';
+ jio_snprintf(tmp_key, key_len + 1, "%s", prop);
key = tmp_key;
value = &prop[key_len + 1];
@@ -2260,7 +2263,7 @@
// Feed the cache size setting into the JDK
char buffer[1024];
- sprintf(buffer, "java.lang.Integer.IntegerCache.high=" INTX_FORMAT, AutoBoxCacheMax);
+ jio_snprintf(buffer, 1024, "java.lang.Integer.IntegerCache.high=" INTX_FORMAT, AutoBoxCacheMax);
if (!add_property(buffer)) {
return JNI_ENOMEM;
}
@@ -2781,8 +2784,8 @@
if (tail != NULL) {
const char* pos = strchr(tail, ':');
size_t len = (pos == NULL) ? strlen(tail) : pos - tail;
- char* name = (char*)memcpy(NEW_C_HEAP_ARRAY(char, len + 1, mtArguments), tail, len);
- name[len] = '\0';
+ char* name = NEW_C_HEAP_ARRAY(char, len + 1, mtArguments);
+ jio_snprintf(name, len + 1, "%s", tail);
char *options = NULL;
if(pos != NULL) {
@@ -2858,7 +2861,9 @@
return JNI_ERR;
#else
if (tail != NULL) {
- char *options = strcpy(NEW_C_HEAP_ARRAY(char, strlen(tail) + 1, mtArguments), tail);
+ size_t length = strlen(tail) + 1;
+ char *options = NEW_C_HEAP_ARRAY(char, length, mtArguments);
+ jio_snprintf(options, length, "%s", tail);
add_init_agent("instrument", options, false);
// java agents need module java.instrument
if (!create_numbered_property("jdk.module.addmods", "java.instrument", addmods_count++)) {
@@ -3518,7 +3523,7 @@
// check if the default lib/endorsed directory exists; if so, error
char path[JVM_MAXPATHLEN];
const char* fileSep = os::file_separator();
- sprintf(path, "%s%slib%sendorsed", Arguments::get_java_home(), fileSep, fileSep);
+ jio_snprintf(path, JVM_MAXPATHLEN, "%s%slib%sendorsed", Arguments::get_java_home(), fileSep, fileSep);
if (CheckEndorsedAndExtDirs) {
int nonEmptyDirs = 0;
@@ -3540,7 +3545,7 @@
return JNI_ERR;
}
- sprintf(path, "%s%slib%sext", Arguments::get_java_home(), fileSep, fileSep);
+ jio_snprintf(path, JVM_MAXPATHLEN, "%s%slib%sext", Arguments::get_java_home(), fileSep, fileSep);
dir = os::opendir(path);
if (dir != NULL) {
jio_fprintf(defaultStream::output_stream(),
@@ -3905,6 +3910,13 @@
void Arguments::set_shared_spaces_flags() {
if (DumpSharedSpaces) {
+ if (FailOverToOldVerifier) {
+ // Don't fall back to the old verifier on verification failure. If a
+ // class fails verification with the split verifier, it might fail the
+ // CDS runtime verifier constraint check. In that case, we don't want
+ // to share the class. We only archive classes that pass the split verifier.
+ FLAG_SET_DEFAULT(FailOverToOldVerifier, false);
+ }
if (RequireSharedSpaces) {
warning("Cannot dump shared archive while using shared archive");
--- a/hotspot/src/share/vm/runtime/deoptimization.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/runtime/deoptimization.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -171,7 +171,6 @@
assert(thread->deopt_compiled_method() == NULL, "Pending deopt!");
CompiledMethod* cm = deoptee.cb()->as_compiled_method_or_null();
thread->set_deopt_compiled_method(cm);
- bool skip_internal = (cm != NULL) && !cm->is_compiled_by_jvmci();
if (VerifyStack) {
thread->validate_frame_layout();
@@ -241,6 +240,7 @@
JRT_BLOCK
realloc_failures = realloc_objects(thread, &deoptee, objects, THREAD);
JRT_END
+ bool skip_internal = (cm != NULL) && !cm->is_compiled_by_jvmci();
reassign_fields(&deoptee, &map, objects, realloc_failures, skip_internal);
#ifndef PRODUCT
if (TraceDeoptimization) {
@@ -1651,7 +1651,7 @@
if (TraceDeoptimization) { // make noise on the tty
tty->print("Uncommon trap occurred in");
nm->method()->print_short_name(tty);
- tty->print(" compiler=%s compile_id=%d", nm->compiler() == NULL ? "" : nm->compiler()->name(), nm->compile_id());
+ tty->print(" compiler=%s compile_id=%d", nm->compiler_name(), nm->compile_id());
#if INCLUDE_JVMCI
if (nm->is_nmethod()) {
oop installedCode = nm->as_nmethod()->jvmci_installed_code();
--- a/hotspot/src/share/vm/runtime/frame.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/runtime/frame.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -686,9 +686,7 @@
if (cm->is_nmethod()) {
nmethod* nm = cm->as_nmethod();
st->print("J %d%s", nm->compile_id(), (nm->is_osr_method() ? "%" : ""));
- if (nm->compiler() != NULL) {
- st->print(" %s", nm->compiler()->name());
- }
+ st->print(" %s", nm->compiler_name());
}
m->name_and_sig_as_C_string(buf, buflen);
st->print(" %s", buf);
--- a/hotspot/src/share/vm/runtime/os.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/runtime/os.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -1766,95 +1766,3 @@
return result;
}
#endif
-
-/////////////// Unit tests ///////////////
-
-#ifndef PRODUCT
-
-#define assert_eq(a,b) assert(a == b, SIZE_FORMAT " != " SIZE_FORMAT, a, b)
-
-class TestOS : AllStatic {
- static size_t small_page_size() {
- return os::vm_page_size();
- }
-
- static size_t large_page_size() {
- const size_t large_page_size_example = 4 * M;
- return os::page_size_for_region_aligned(large_page_size_example, 1);
- }
-
- static void test_page_size_for_region_aligned() {
- if (UseLargePages) {
- const size_t small_page = small_page_size();
- const size_t large_page = large_page_size();
-
- if (large_page > small_page) {
- size_t num_small_pages_in_large = large_page / small_page;
- size_t page = os::page_size_for_region_aligned(large_page, num_small_pages_in_large);
-
- assert_eq(page, small_page);
- }
- }
- }
-
- static void test_page_size_for_region_alignment() {
- if (UseLargePages) {
- const size_t small_page = small_page_size();
- const size_t large_page = large_page_size();
- if (large_page > small_page) {
- const size_t unaligned_region = large_page + 17;
- size_t page = os::page_size_for_region_aligned(unaligned_region, 1);
- assert_eq(page, small_page);
-
- const size_t num_pages = 5;
- const size_t aligned_region = large_page * num_pages;
- page = os::page_size_for_region_aligned(aligned_region, num_pages);
- assert_eq(page, large_page);
- }
- }
- }
-
- static void test_page_size_for_region_unaligned() {
- if (UseLargePages) {
- // Given exact page size, should return that page size.
- for (size_t i = 0; os::_page_sizes[i] != 0; i++) {
- size_t expected = os::_page_sizes[i];
- size_t actual = os::page_size_for_region_unaligned(expected, 1);
- assert_eq(expected, actual);
- }
-
- // Given slightly larger size than a page size, return the page size.
- for (size_t i = 0; os::_page_sizes[i] != 0; i++) {
- size_t expected = os::_page_sizes[i];
- size_t actual = os::page_size_for_region_unaligned(expected + 17, 1);
- assert_eq(expected, actual);
- }
-
- // Given a slightly smaller size than a page size,
- // return the next smaller page size.
- if (os::_page_sizes[1] > os::_page_sizes[0]) {
- size_t expected = os::_page_sizes[0];
- size_t actual = os::page_size_for_region_unaligned(os::_page_sizes[1] - 17, 1);
- assert_eq(actual, expected);
- }
-
- // Return small page size for values less than a small page.
- size_t small_page = small_page_size();
- size_t actual = os::page_size_for_region_unaligned(small_page - 17, 1);
- assert_eq(small_page, actual);
- }
- }
-
- public:
- static void run_tests() {
- test_page_size_for_region_aligned();
- test_page_size_for_region_alignment();
- test_page_size_for_region_unaligned();
- }
-};
-
-void TestOS_test() {
- TestOS::run_tests();
-}
-
-#endif // PRODUCT
--- a/hotspot/src/share/vm/runtime/rtmLocking.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/runtime/rtmLocking.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -23,7 +23,7 @@
*/
#include "precompiled.hpp"
-#include "utilities/globalDefinitions.hpp"
+#include "compiler/compilerDefinitions.hpp"
#if INCLUDE_RTM_OPT
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -2881,8 +2881,6 @@
char *s = sig->as_C_string();
int len = (int)strlen(s);
s++; len--; // Skip opening paren
- char *t = s+len;
- while (*(--t) != ')'); // Find close paren
BasicType *sig_bt = NEW_RESOURCE_ARRAY(BasicType, 256);
VMRegPair *regs = NEW_RESOURCE_ARRAY(VMRegPair, 256);
@@ -2891,7 +2889,7 @@
sig_bt[cnt++] = T_OBJECT; // Receiver is argument 0; not in signature
}
- while (s < t) {
+ while (*s != ')') { // Find closing right paren
switch (*s++) { // Switch on signature character
case 'B': sig_bt[cnt++] = T_BYTE; break;
case 'C': sig_bt[cnt++] = T_CHAR; break;
--- a/hotspot/src/share/vm/runtime/signature.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/runtime/signature.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -224,7 +224,49 @@
_index = 0;
expect('(');
Symbol* sig = _signature;
- while (sig->byte_at(_index) != ')') _index++;
+ // Need to skip over each type in the signature's argument list until a
+ // closing ')' is found., then get the return type. We cannot just scan
+ // for the first ')' because ')' is a legal character in a type name.
+ while (sig->byte_at(_index) != ')') {
+ switch(sig->byte_at(_index)) {
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'F':
+ case 'I':
+ case 'J':
+ case 'S':
+ case 'Z':
+ case 'V':
+ {
+ _index++;
+ }
+ break;
+ case 'L':
+ {
+ while (sig->byte_at(_index++) != ';') ;
+ }
+ break;
+ case '[':
+ {
+ int begin = ++_index;
+ skip_optional_size();
+ while (sig->byte_at(_index) == '[') {
+ _index++;
+ skip_optional_size();
+ }
+ if (sig->byte_at(_index) == 'L') {
+ while (sig->byte_at(_index++) != ';') ;
+ } else {
+ _index++;
+ }
+ }
+ break;
+ default:
+ ShouldNotReachHere();
+ break;
+ }
+ }
expect(')');
// Parse return type
_parameter_index = -1;
--- a/hotspot/src/share/vm/services/management.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/services/management.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -173,6 +173,20 @@
Klass* Management::load_and_initialize_klass(Symbol* sh, TRAPS) {
Klass* k = SystemDictionary::resolve_or_fail(sh, true, CHECK_NULL);
+ Klass* ik = initialize_klass(k, CHECK_NULL);
+ return ik;
+}
+
+Klass* Management::load_and_initialize_klass_or_null(Symbol* sh, TRAPS) {
+ Klass* k = SystemDictionary::resolve_or_null(sh, CHECK_NULL);
+ if (k == NULL) {
+ return NULL;
+ }
+ Klass* ik = initialize_klass(k, CHECK_NULL);
+ return ik;
+}
+
+Klass* Management::initialize_klass(Klass* k, TRAPS) {
instanceKlassHandle ik (THREAD, k);
if (ik->should_be_initialized()) {
ik->initialize(CHECK_NULL);
@@ -255,7 +269,8 @@
Klass* Management::com_sun_management_internal_GarbageCollectorExtImpl_klass(TRAPS) {
if (_garbageCollectorExtImpl_klass == NULL) {
- _garbageCollectorExtImpl_klass = load_and_initialize_klass(vmSymbols::com_sun_management_internal_GarbageCollectorExtImpl(), CHECK_NULL);
+ _garbageCollectorExtImpl_klass =
+ load_and_initialize_klass_or_null(vmSymbols::com_sun_management_internal_GarbageCollectorExtImpl(), CHECK_NULL);
}
return _garbageCollectorExtImpl_klass;
}
--- a/hotspot/src/share/vm/services/management.hpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/services/management.hpp Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -53,6 +53,8 @@
static Klass* _sensor_klass;
static Klass* _threadInfo_klass;
static Klass* load_and_initialize_klass(Symbol* sh, TRAPS);
+ static Klass* load_and_initialize_klass_or_null(Symbol* sh, TRAPS);
+ static Klass* initialize_klass(Klass* k, TRAPS);
public:
static void init();
--- a/hotspot/src/share/vm/trace/traceMacros.hpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/trace/traceMacros.hpp Wed Oct 26 20:13:29 2016 +0000
@@ -57,6 +57,8 @@
#define TRACE_DEFINE_THREAD_TRACE_ID_OFFSET typedef int ___IGNORED_hs_trace_type5
#define TRACE_THREAD_TRACE_ID_OFFSET in_ByteSize(0); ShouldNotReachHere()
#define TRACE_DEFINE_THREAD_ID_SIZE typedef int ___IGNORED_hs_trace_type6
+#define TRACE_DEFINE_THREAD_DATA_WRITER_OFFSET typedef int ___IGNORED_hs_trace_type7
+#define TRACE_THREAD_DATA_WRITER_OFFSET in_ByteSize(0); ShouldNotReachHere()
#define TRACE_TEMPLATES(template)
#define TRACE_INTRINSICS(do_intrinsic, do_class, do_name, do_signature, do_alias)
--- a/hotspot/src/share/vm/utilities/globalDefinitions.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/utilities/globalDefinitions.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -214,7 +214,6 @@
return T_ILLEGAL;
}
-
// Map BasicType to size in words
int type2size[T_CONFLICT+1]={ -1, 0, 0, 0, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 0, 1, 1, 1, 1, -1};
--- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp Wed Oct 26 20:13:29 2016 +0000
@@ -444,13 +444,6 @@
// Machine dependent stuff
-// States of Restricted Transactional Memory usage.
-enum RTMState {
- NoRTM = 0x2, // Don't use RTM
- UseRTM = 0x1, // Use RTM
- ProfileRTM = 0x0 // Use RTM with abort ratio calculation
-};
-
// The maximum size of the code cache. Can be overridden by targets.
#define CODE_CACHE_SIZE_LIMIT (2*G)
// Allow targets to reduce the default size of the code cache.
@@ -458,15 +451,6 @@
#include CPU_HEADER(globalDefinitions)
-#ifndef INCLUDE_RTM_OPT
-#define INCLUDE_RTM_OPT 0
-#endif
-#if INCLUDE_RTM_OPT
-#define RTM_OPT_ONLY(code) code
-#else
-#define RTM_OPT_ONLY(code)
-#endif
-
// To assure the IRIW property on processors that are not multiple copy
// atomic, sync instructions must be issued between volatile reads to
// assure their ordering, instead of after volatile stores.
@@ -923,55 +907,6 @@
};
-// Handy constants for deciding which compiler mode to use.
-enum MethodCompilation {
- InvocationEntryBci = -1 // i.e., not a on-stack replacement compilation
-};
-
-// Enumeration to distinguish tiers of compilation
-enum CompLevel {
- CompLevel_any = -1,
- CompLevel_all = -1,
- CompLevel_none = 0, // Interpreter
- CompLevel_simple = 1, // C1
- CompLevel_limited_profile = 2, // C1, invocation & backedge counters
- CompLevel_full_profile = 3, // C1, invocation & backedge counters + mdo
- CompLevel_full_optimization = 4, // C2, Shark or JVMCI
-
-#if defined(COMPILER2) || defined(SHARK)
- CompLevel_highest_tier = CompLevel_full_optimization, // pure C2 and tiered or JVMCI and tiered
-#elif defined(COMPILER1)
- CompLevel_highest_tier = CompLevel_simple, // pure C1 or JVMCI
-#else
- CompLevel_highest_tier = CompLevel_none,
-#endif
-
-#if defined(TIERED)
- CompLevel_initial_compile = CompLevel_full_profile // tiered
-#elif defined(COMPILER1) || INCLUDE_JVMCI
- CompLevel_initial_compile = CompLevel_simple // pure C1 or JVMCI
-#elif defined(COMPILER2) || defined(SHARK)
- CompLevel_initial_compile = CompLevel_full_optimization // pure C2
-#else
- CompLevel_initial_compile = CompLevel_none
-#endif
-};
-
-inline bool is_c1_compile(int comp_level) {
- return comp_level > CompLevel_none && comp_level < CompLevel_full_optimization;
-}
-
-inline bool is_c2_compile(int comp_level) {
- return comp_level == CompLevel_full_optimization;
-}
-
-inline bool is_highest_tier_compile(int comp_level) {
- return comp_level == CompLevel_highest_tier;
-}
-
-inline bool is_compile(int comp_level) {
- return is_c1_compile(comp_level) || is_c2_compile(comp_level);
-}
//----------------------------------------------------------------------------------------------------
// 'Forward' declarations of frequently used classes
--- a/hotspot/src/share/vm/utilities/internalVMTests.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/utilities/internalVMTests.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -41,22 +41,15 @@
void InternalVMTests::run() {
tty->print_cr("Running internal VM tests");
- run_unit_test(TestDependencyContext_test);
run_unit_test(test_semaphore);
- run_unit_test(TestOS_test);
run_unit_test(TestReservedSpace_test);
run_unit_test(TestReserveMemorySpecial_test);
run_unit_test(TestVirtualSpace_test);
run_unit_test(TestMetaspaceAux_test);
- run_unit_test(TestMetachunk_test);
run_unit_test(TestVirtualSpaceNode_test);
run_unit_test(TestGlobalDefinitions_test);
run_unit_test(GCTimer_test);
run_unit_test(CollectedHeap_test);
- run_unit_test(QuickSort_test);
- run_unit_test(GuardedMemory_test);
- run_unit_test(TestNewSize_test);
- run_unit_test(TestOldSize_test);
run_unit_test(TestBitMap_test);
run_unit_test(ObjectMonitor_test);
run_unit_test(DirectivesParser_test);
@@ -64,12 +57,7 @@
run_unit_test(VMStructs_test);
#endif
#if INCLUDE_ALL_GCS
- run_unit_test(TestG1BiasedArray_test);
run_unit_test(TestBufferingOopClosure_test);
- if (UseG1GC) {
- run_unit_test(FreeRegionList_test);
- }
- run_unit_test(WorkerDataArray_test);
run_unit_test(ParallelCompact_test);
#endif
tty->print_cr("All internal VM tests passed");
--- a/hotspot/src/share/vm/utilities/quickSort.cpp Wed Oct 26 15:46:13 2016 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,221 +0,0 @@
-/*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-
-/////////////// Unit tests ///////////////
-
-#ifndef PRODUCT
-
-#include "runtime/os.hpp"
-#include "utilities/quickSort.hpp"
-#include "memory/allocation.hpp"
-#include "memory/allocation.inline.hpp"
-#include <stdlib.h>
-
-#ifdef ASSERT
-static int test_comparator(int a, int b) {
- if (a == b) {
- return 0;
- }
- if (a < b) {
- return -1;
- }
- return 1;
-}
-
-static void print_array(const char* prefix, int* array, int length) {
- tty->print("%s:", prefix);
- for (int i = 0; i < length; i++) {
- tty->print(" %d", array[i]);
- }
- tty->cr();
-}
-
-static bool compare_arrays(int* actual, int* expected, int length) {
- for (int i = 0; i < length; i++) {
- if (actual[i] != expected[i]) {
- print_array("Sorted array ", actual, length);
- print_array("Expected array", expected, length);
- return false;
- }
- }
- return true;
-}
-
-template <class C>
-static bool sort_and_compare(int* arrayToSort, int* expectedResult, int length, C comparator, bool idempotent = false) {
- QuickSort::sort<int, C>(arrayToSort, length, comparator, idempotent);
- return compare_arrays(arrayToSort, expectedResult, length);
-}
-#endif // ASSERT
-
-static int test_even_odd_comparator(int a, int b) {
- bool a_is_odd = (a % 2) == 1;
- bool b_is_odd = (b % 2) == 1;
- if (a_is_odd == b_is_odd) {
- return 0;
- }
- if (a_is_odd) {
- return -1;
- }
- return 1;
-}
-
-extern "C" {
- static int test_stdlib_comparator(const void* a, const void* b) {
- int ai = *(int*)a;
- int bi = *(int*)b;
- if (ai == bi) {
- return 0;
- }
- if (ai < bi) {
- return -1;
- }
- return 1;
- }
-}
-
-void QuickSort_test() {
- {
- int* test_array = NULL;
- int* expected_array = NULL;
- assert(sort_and_compare(test_array, expected_array, 0, test_comparator), "Empty array not handled");
- }
- {
- int test_array[] = {3};
- int expected_array[] = {3};
- assert(sort_and_compare(test_array, expected_array, 1, test_comparator), "Single value array not handled");
- }
- {
- int test_array[] = {3,2};
- int expected_array[] = {2,3};
- assert(sort_and_compare(test_array, expected_array, 2, test_comparator), "Array with 2 values not correctly sorted");
- }
- {
- int test_array[] = {3,2,1};
- int expected_array[] = {1,2,3};
- assert(sort_and_compare(test_array, expected_array, 3, test_comparator), "Array with 3 values not correctly sorted");
- }
- {
- int test_array[] = {4,3,2,1};
- int expected_array[] = {1,2,3,4};
- assert(sort_and_compare(test_array, expected_array, 4, test_comparator), "Array with 4 values not correctly sorted");
- }
- {
- int test_array[] = {7,1,5,3,6,9,8,2,4,0};
- int expected_array[] = {0,1,2,3,4,5,6,7,8,9};
- assert(sort_and_compare(test_array, expected_array, 10, test_comparator), "Array with 10 values not correctly sorted");
- }
- {
- int test_array[] = {4,4,1,4};
- int expected_array[] = {1,4,4,4};
- assert(sort_and_compare(test_array, expected_array, 4, test_comparator), "3 duplicates not sorted correctly");
- }
- {
- int test_array[] = {0,1,2,3,4,5,6,7,8,9};
- int expected_array[] = {0,1,2,3,4,5,6,7,8,9};
- assert(sort_and_compare(test_array, expected_array, 10, test_comparator), "Already sorted array not correctly sorted");
- }
- {
- // one of the random arrays that found an issue in the partion method.
- int test_array[] = {76,46,81,8,64,56,75,11,51,55,11,71,59,27,9,64,69,75,21,25,39,40,44,32,7,8,40,41,24,78,24,74,9,65,28,6,40,31,22,13,27,82};
- int expected_array[] = {6,7,8,8,9,9,11,11,13,21,22,24,24,25,27,27,28,31,32,39,40,40,40,41,44,46,51,55,56,59,64,64,65,69,71,74,75,75,76,78,81,82};
- assert(sort_and_compare(test_array, expected_array, 42, test_comparator), "Not correctly sorted");
- }
- {
- int test_array[] = {2,8,1,4};
- int expected_array[] = {1,4,2,8};
- assert(sort_and_compare(test_array, expected_array, 4, test_even_odd_comparator), "Even/odd not sorted correctly");
- }
- { // Some idempotent tests
- {
- // An array of lenght 3 is only sorted by find_pivot. Make sure that it is idempotent.
- int test_array[] = {1,4,8};
- int expected_array[] = {1,4,8};
- assert(sort_and_compare(test_array, expected_array, 3, test_even_odd_comparator, true), "Even/odd not idempotent");
- }
- {
- int test_array[] = {1,7,9,4,8,2};
- int expected_array[] = {1,7,9,4,8,2};
- assert(sort_and_compare(test_array, expected_array, 6, test_even_odd_comparator, true), "Even/odd not idempotent");
- }
- {
- int test_array[] = {1,9,7,4,2,8};
- int expected_array[] = {1,9,7,4,2,8};
- assert(sort_and_compare(test_array, expected_array, 6, test_even_odd_comparator, true), "Even/odd not idempotent");
- }
- {
- int test_array[] = {7,9,1,2,8,4};
- int expected_array[] = {7,9,1,2,8,4};
- assert(sort_and_compare(test_array, expected_array, 6, test_even_odd_comparator, true), "Even/odd not idempotent");
- }
- {
- int test_array[] = {7,1,9,2,4,8};
- int expected_array[] = {7,1,9,2,4,8};
- assert(sort_and_compare(test_array, expected_array, 6, test_even_odd_comparator, true), "Even/odd not idempotent");
- }
- {
- int test_array[] = {9,1,7,4,8,2};
- int expected_array[] = {9,1,7,4,8,2};
- assert(sort_and_compare(test_array, expected_array, 6, test_even_odd_comparator, true), "Even/odd not idempotent");
- }
- {
- int test_array[] = {9,7,1,4,2,8};
- int expected_array[] = {9,7,1,4,2,8};
- assert(sort_and_compare(test_array, expected_array, 6, test_even_odd_comparator, true), "Even/odd not idempotent");
- }
- }
-
- // test sorting random arrays
- for (int i = 0; i < 1000; i++) {
- int length = os::random() % 100;
- int* test_array = NEW_C_HEAP_ARRAY(int, length, mtInternal);
- int* expected_array = NEW_C_HEAP_ARRAY(int, length, mtInternal);
- for (int j = 0; j < length; j++) {
- // Choose random values, but get a chance of getting duplicates
- test_array[j] = os::random() % (length * 2);
- expected_array[j] = test_array[j];
- }
-
- // Compare sorting to stdlib::qsort()
- qsort(expected_array, length, sizeof(int), test_stdlib_comparator);
- assert(sort_and_compare(test_array, expected_array, length, test_comparator), "Random array not correctly sorted");
-
- // Make sure sorting is idempotent.
- // Both test_array and expected_array are sorted by the test_comparator.
- // Now sort them once with the test_even_odd_comparator. Then sort the
- // test_array one more time with test_even_odd_comparator and verify that
- // it is idempotent.
- QuickSort::sort(expected_array, length, test_even_odd_comparator, true);
- QuickSort::sort(test_array, length, test_even_odd_comparator, true);
- assert(compare_arrays(test_array, expected_array, length), "Sorting identical arrays rendered different results");
- QuickSort::sort(test_array, length, test_even_odd_comparator, true);
- assert(compare_arrays(test_array, expected_array, length), "Sorting already sorted array changed order of elements - not idempotent");
-
- FREE_C_HEAP_ARRAY(int, test_array);
- FREE_C_HEAP_ARRAY(int, expected_array);
- }
-}
-#endif
--- a/hotspot/src/share/vm/utilities/utf8.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/utilities/utf8.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -411,61 +411,46 @@
}
int UNICODE::utf8_size(jchar c) {
- if ((0x0001 <= c) && (c <= 0x007F)) return 1;
- if (c <= 0x07FF) return 2;
- return 3;
+ if ((0x0001 <= c) && (c <= 0x007F)) {
+ // ASCII character
+ return 1;
+ } else if (c <= 0x07FF) {
+ return 2;
+ } else {
+ return 3;
+ }
}
int UNICODE::utf8_size(jbyte c) {
- if (c >= 0x0001) return 1;
- return 2;
+ if (c >= 0x01) {
+ // ASCII character. Check is equivalent to
+ // (0x01 <= c) && (c <= 0x7F) because c is signed.
+ return 1;
+ } else {
+ // Non-ASCII character or 0x00 which needs to be
+ // two-byte encoded as 0xC080 in modified UTF-8.
+ return 2;
+ }
}
-int UNICODE::utf8_length(jchar* base, int length) {
+template<typename T>
+int UNICODE::utf8_length(T* base, int length) {
int result = 0;
for (int index = 0; index < length; index++) {
- jchar c = base[index];
- if ((0x0001 <= c) && (c <= 0x007F)) result += 1;
- else if (c <= 0x07FF) result += 2;
- else result += 3;
- }
- return result;
-}
-
-int UNICODE::utf8_length(jbyte* base, int length) {
- int result = 0;
- for (int index = 0; index < length; index++) {
- jbyte c = base[index];
+ T c = base[index];
result += utf8_size(c);
}
return result;
}
-char* UNICODE::as_utf8(jchar* base, int length) {
+template<typename T>
+char* UNICODE::as_utf8(T* base, int& length) {
int utf8_len = utf8_length(base, length);
u_char* buf = NEW_RESOURCE_ARRAY(u_char, utf8_len + 1);
char* result = as_utf8(base, length, (char*) buf, utf8_len + 1);
assert((int) strlen(result) == utf8_len, "length prediction must be correct");
- return result;
-}
-
-char* UNICODE::as_utf8(jbyte* base, int length) {
- int utf8_len = utf8_length(base, length);
- u_char* result = NEW_RESOURCE_ARRAY(u_char, utf8_len + 1);
- u_char* p = result;
- if (utf8_len == length) {
- for (int index = 0; index < length; index++) {
- *p++ = base[index];
- }
- } else {
- // Unicode string contains U+0000 which should
- // be encoded as 0xC080 in "modified" UTF8.
- for (int index = 0; index < length; index++) {
- p = utf8_write(p, ((jchar) base[index]) & 0xff);
- }
- }
- *p = '\0';
- assert(p == &result[utf8_len], "length prediction must be correct");
+ // Set string length to uft8 length
+ length = utf8_len;
return (char*) result;
}
@@ -490,9 +475,10 @@
buflen -= sz;
if (buflen <= 0) break; // string is truncated
if (sz == 1) {
+ // Copy ASCII characters (UTF-8 is ASCII compatible)
*p++ = c;
} else {
- // Unicode string contains U+0000 which should
+ // Non-ASCII character or 0x00 which should
// be encoded as 0xC080 in "modified" UTF8.
p = utf8_write(p, ((jchar) c) & 0xff);
}
@@ -543,6 +529,10 @@
}
// Explicit instantiation for all supported types.
+template int UNICODE::utf8_length(jbyte* base, int length);
+template int UNICODE::utf8_length(jchar* base, int length);
+template char* UNICODE::as_utf8(jbyte* base, int& length);
+template char* UNICODE::as_utf8(jchar* base, int& length);
template int UNICODE::quoted_ascii_length<jbyte>(jbyte* base, int length);
template int UNICODE::quoted_ascii_length<jchar>(jchar* base, int length);
template void UNICODE::as_quoted_ascii<jbyte>(const jbyte* base, int length, char* buf, int buflen);
--- a/hotspot/src/share/vm/utilities/utf8.hpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/src/share/vm/utilities/utf8.hpp Wed Oct 26 20:13:29 2016 +0000
@@ -97,16 +97,15 @@
static int utf8_size(jbyte c);
// returns the utf8 length of a unicode string
- static int utf8_length(jchar* base, int length);
- static int utf8_length(jbyte* base, int length);
+ template<typename T> static int utf8_length(T* base, int length);
// converts a unicode string to utf8 string
static void convert_to_utf8(const jchar* base, int length, char* utf8_buffer);
// converts a unicode string to a utf8 string; result is allocated
- // in resource area unless a buffer is provided.
- static char* as_utf8(jchar* base, int length);
- static char* as_utf8(jbyte* base, int length);
+ // in resource area unless a buffer is provided. The unicode 'length'
+ // parameter is set to the length of the result utf8 string.
+ template<typename T> static char* as_utf8(T* base, int& length);
static char* as_utf8(jchar* base, int length, char* buf, int buflen);
static char* as_utf8(jbyte* base, int length, char* buf, int buflen);
--- a/hotspot/test/Makefile Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/test/Makefile Wed Oct 26 20:13:29 2016 +0000
@@ -195,7 +195,8 @@
-timeoutHandlerDir:$(FAILURE_HANDLER_DIR_MIXED)/jtregFailureHandler.jar \
-observerDir:$(FAILURE_HANDLER_DIR_MIXED)/jtregFailureHandler.jar \
-timeoutHandler:jdk.test.failurehandler.jtreg.GatherProcessInfoTimeoutHandler \
- -observer:jdk.test.failurehandler.jtreg.GatherDiagnosticInfoObserver
+ -observer:jdk.test.failurehandler.jtreg.GatherDiagnosticInfoObserver \
+ -timeoutHandlerTimeout:0
ifeq ($(PLATFORM), windows)
JTREG_FAILURE_HANDLER_OPTIONS += -J-Djava.library.path="$(FAILURE_HANDLER_DIR_MIXED)"
endif
--- a/hotspot/test/TEST.ROOT Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/test/TEST.ROOT Wed Oct 26 20:13:29 2016 +0000
@@ -44,7 +44,8 @@
vm.gc.G1 \
vm.gc.Serial \
vm.gc.Parallel \
- vm.gc.ConcMarkSweep
+ vm.gc.ConcMarkSweep \
+ vm.debug
# Tests using jtreg 4.2 b03 features
requiredVersion=4.2 b03
--- a/hotspot/test/TEST.groups Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/test/TEST.groups Wed Oct 26 20:13:29 2016 +0000
@@ -349,6 +349,12 @@
hotspot_fast_gc_gcold = \
gc/stress/TestGCOld.java
+hotspot_fast_gc_gcbasher = \
+ gc/stress/gcbasher/TestGCBasherWithG1.java \
+ gc/stress/gcbasher/TestGCBasherWithCMS.java \
+ gc/stress/gcbasher/TestGCBasherWithSerial.java \
+ gc/stress/gcbasher/TestGCBasherWithParallel.java
+
hotspot_fast_runtime = \
runtime/ \
-runtime/6626217/Test6626217.sh \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/c1/TestArrayCopyToFromObject.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,64 @@
+/*
+ * 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 8160591
+ * @summary C1-generated code for System.arraycopy() does not throw an ArrayStoreException if 'dst' is no a "proper" array (i.e., it is java.lang.Object)
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+TieredCompilation -XX:TieredStopAtLevel=1 -Xcomp -XX:-UseCompressedClassPointers -XX:CompileOnly=TestArrayCopyToFromObject.test TestArrayCopyToFromObject
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+TieredCompilation -XX:TieredStopAtLevel=1 -Xcomp -XX:+UseCompressedClassPointers -XX:CompileOnly=TestArrayCopyToFromObject.test TestArrayCopyToFromObject
+ */
+public class TestArrayCopyToFromObject {
+
+ public void test(Object aArray[]) {
+ Object a = new Object();
+
+ try {
+ System.arraycopy(aArray, 0, a, 0, 1);
+ throw new RuntimeException ("FAILED: Expected ArrayStoreException " +
+ "(due to destination not being an array) " +
+ "was not thrown");
+ } catch (ArrayStoreException e) {
+ System.out.println("PASSED: Expected ArrayStoreException was thrown");
+ }
+
+ try {
+ System.arraycopy(a, 0, aArray, 0, 1);
+ throw new RuntimeException ("FAILED: Expected ArrayStoreException " +
+ "(due to source not being an array) " +
+ "was not thrown");
+ } catch (ArrayStoreException e) {
+ System.out.println("PASSED: Expected ArrayStoreException was thrown");
+ }
+
+ }
+
+ public static void main(String args[]) {
+ System.out.println("TestArrayCopyToFromObject");
+ Object aArray[] = new Object[10];
+ for (int i = 0; i < 10; i++) {
+ aArray[i] = new Object();
+ }
+ new TestArrayCopyToFromObject().test(aArray);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/ciReplay/CiReplayBase.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,297 @@
+/*
+ * 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 compiler.ciReplay;
+
+import compiler.whitebox.CompilerWhiteBoxTest;
+import java.io.IOException;
+import java.io.File;
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardOpenOption;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+import jdk.test.lib.Platform;
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.Asserts;
+import jdk.test.lib.Utils;
+
+public abstract class CiReplayBase {
+ public static final String REPLAY_FILE_NAME = "test_replay.txt";
+ public static final boolean CLIENT_VM_AVAILABLE;
+ public static final boolean SERVER_VM_AVAILABLE;
+ public static final String TIERED_ENABLED_VM_OPTION = "-XX:+TieredCompilation";
+ public static final String TIERED_DISABLED_VM_OPTION = "-XX:-TieredCompilation";
+ public static final String ENABLE_COREDUMP_ON_CRASH = "-XX:+CreateCoredumpOnCrash";
+ public static final String DISABLE_COREDUMP_ON_CRASH = "-XX:-CreateCoredumpOnCrash";
+ public static final String CLIENT_VM_OPTION = "-client";
+ public static final String SERVER_VM_OPTION = "-server";
+ public static final String TEST_CORE_FILE_NAME = "test_core";
+ public static final String RUN_SHELL_NO_LIMIT = "ulimit -c unlimited && ";
+ private static final String REPLAY_FILE_OPTION = "-XX:ReplayDataFile=" + REPLAY_FILE_NAME;
+ private static final String LOCATIONS_STRING = "location: ";
+ private static final String HS_ERR_NAME = "hs_err_pid";
+ private static final String RUN_SHELL_ZERO_LIMIT = "ulimit -S -c 0 && ";
+ private static final String VERSION_OPTION = "-version";
+ private static final String[] REPLAY_GENERATION_OPTIONS = new String[]{"-Xms8m", "-Xmx32m",
+ "-XX:MetaspaceSize=4m", "-XX:MaxMetaspaceSize=16m", "-XX:InitialCodeCacheSize=512k",
+ "-XX:ReservedCodeCacheSize=4m", "-XX:ThreadStackSize=512", "-XX:VMThreadStackSize=512",
+ "-XX:CompilerThreadStackSize=512", "-XX:ParallelGCThreads=1", "-XX:CICompilerCount=2",
+ "-Xcomp", "-XX:CICrashAt=1", "-XX:+DumpReplayDataOnError", "-XX:-TransmitErrorReport",
+ "-XX:+PreferInterpreterNativeStubs", "-XX:+PrintCompilation", REPLAY_FILE_OPTION};
+ private static final String[] REPLAY_OPTIONS = new String[]{DISABLE_COREDUMP_ON_CRASH,
+ "-XX:+ReplayCompiles", REPLAY_FILE_OPTION};
+ protected final Optional<Boolean> runServer;
+
+ static {
+ try {
+ CLIENT_VM_AVAILABLE = ProcessTools.executeTestJvm(CLIENT_VM_OPTION, VERSION_OPTION)
+ .getOutput().contains("Client");
+ SERVER_VM_AVAILABLE = ProcessTools.executeTestJvm(SERVER_VM_OPTION, VERSION_OPTION)
+ .getOutput().contains("Server");
+ } catch(Throwable t) {
+ throw new Error("Initialization failed: " + t, t);
+ }
+ }
+
+ public CiReplayBase() {
+ runServer = Optional.empty();
+ }
+
+ public CiReplayBase(String args[]) {
+ if (args.length != 1 || (!"server".equals(args[0]) && !"client".equals(args[0]))) {
+ throw new Error("Expected 1 argument: [server|client]");
+ }
+ runServer = Optional.of("server".equals(args[0]));
+ }
+
+ public void runTest(boolean needCoreDump, String... args) {
+ cleanup();
+ if (generateReplay(needCoreDump)) {
+ testAction();
+ cleanup();
+ } else {
+ throw new Error("Host is not configured to generate cores");
+ }
+ }
+
+ public abstract void testAction();
+
+ private static void remove(String item) {
+ File toDelete = new File(item);
+ toDelete.delete();
+ if (Platform.isWindows()) {
+ Utils.waitForCondition(() -> !toDelete.exists());
+ }
+ }
+
+ private static void removeFromCurrentDirectoryStartingWith(String prefix) {
+ Arrays.stream(new File(".").listFiles())
+ .filter(f -> f.getName().startsWith(prefix))
+ .forEach(File::delete);
+ }
+
+ public static void cleanup() {
+ removeFromCurrentDirectoryStartingWith("core");
+ removeFromCurrentDirectoryStartingWith("replay");
+ removeFromCurrentDirectoryStartingWith(HS_ERR_NAME);
+ remove(TEST_CORE_FILE_NAME);
+ remove(REPLAY_FILE_NAME);
+ }
+
+ public boolean generateReplay(boolean needCoreDump, String... vmopts) {
+ OutputAnalyzer crashOut;
+ String crashOutputString;
+ try {
+ List<String> options = new ArrayList<>();
+ options.addAll(Arrays.asList(REPLAY_GENERATION_OPTIONS));
+ options.addAll(Arrays.asList(vmopts));
+ options.add(needCoreDump ? ENABLE_COREDUMP_ON_CRASH : DISABLE_COREDUMP_ON_CRASH);
+ options.add(VERSION_OPTION);
+ if (needCoreDump) {
+ crashOut = ProcessTools.executeProcess(getTestJavaCommandlineWithPrefix(
+ RUN_SHELL_NO_LIMIT, options.toArray(new String[0])));
+ } else {
+ crashOut = ProcessTools.executeProcess(ProcessTools.createJavaProcessBuilder(true,
+ options.toArray(new String[0])));
+ }
+ crashOutputString = crashOut.getOutput();
+ Asserts.assertNotEquals(crashOut.getExitValue(), 0, "Crash JVM exits gracefully");
+ Files.write(Paths.get("crash.out"), crashOutputString.getBytes(),
+ StandardOpenOption.CREATE, StandardOpenOption.WRITE,
+ StandardOpenOption.TRUNCATE_EXISTING);
+ } catch (Throwable t) {
+ throw new Error("Can't create replay: " + t, t);
+ }
+ if (needCoreDump) {
+ String coreFileLocation = getCoreFileLocation(crashOutputString);
+ if (coreFileLocation == null) {
+ if (Platform.isOSX()) {
+ File coresDir = new File("/cores");
+ if (!coresDir.isDirectory() || !coresDir.canWrite()) {
+ return false;
+ }
+ }
+ throw new Error("Couldn't find core file location in: '" + crashOutputString + "'");
+ }
+ try {
+ Asserts.assertGT(new File(coreFileLocation).length(), 0L, "Unexpected core size");
+ Files.move(Paths.get(coreFileLocation), Paths.get(TEST_CORE_FILE_NAME));
+ } catch (IOException ioe) {
+ throw new Error("Can't move core file: " + ioe, ioe);
+ }
+ }
+ removeFromCurrentDirectoryStartingWith(HS_ERR_NAME);
+ return true;
+ }
+
+ public void commonTests() {
+ positiveTest();
+ if (Platform.isTieredSupported()) {
+ positiveTest(TIERED_ENABLED_VM_OPTION);
+ }
+ }
+
+ public int startTest(String... additionalVmOpts) {
+ try {
+ List<String> allAdditionalOpts = new ArrayList<>();
+ allAdditionalOpts.addAll(Arrays.asList(REPLAY_OPTIONS));
+ allAdditionalOpts.addAll(Arrays.asList(additionalVmOpts));
+ OutputAnalyzer oa = ProcessTools.executeProcess(getTestJavaCommandlineWithPrefix(
+ RUN_SHELL_ZERO_LIMIT, allAdditionalOpts.toArray(new String[0])));
+ return oa.getExitValue();
+ } catch (Throwable t) {
+ throw new Error("Can't run replay process: " + t, t);
+ }
+ }
+
+ public void runVmTests() {
+ boolean runServerValue = runServer.orElseThrow(() -> new Error("runServer must be set"));
+ if (runServerValue) {
+ if (CLIENT_VM_AVAILABLE) {
+ negativeTest(CLIENT_VM_OPTION);
+ }
+ } else {
+ if (SERVER_VM_AVAILABLE) {
+ negativeTest(TIERED_DISABLED_VM_OPTION, SERVER_VM_OPTION);
+ if (Platform.isTieredSupported()) {
+ positiveTest(TIERED_ENABLED_VM_OPTION, SERVER_VM_OPTION);
+ }
+ }
+ }
+ nonTieredTests(runServerValue ? CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION
+ : CompilerWhiteBoxTest.COMP_LEVEL_SIMPLE);
+ }
+
+ public int getCompLevelFromReplay() {
+ try(BufferedReader br = new BufferedReader(new FileReader(REPLAY_FILE_NAME))) {
+ return br.lines()
+ .filter(s -> s.startsWith("compile "))
+ .map(s -> s.substring(s.lastIndexOf(' ') + 1))
+ .map(Integer::parseInt)
+ .findAny()
+ .get();
+ } catch (IOException ioe) {
+ throw new Error("Failed to read replay data: " + ioe, ioe);
+ }
+ }
+
+ public void positiveTest(String... additionalVmOpts) {
+ Asserts.assertEQ(startTest(additionalVmOpts), 0, "Unexpected exit code for positive case: "
+ + Arrays.toString(additionalVmOpts));
+ }
+
+ public void negativeTest(String... additionalVmOpts) {
+ Asserts.assertNE(startTest(additionalVmOpts), 0, "Unexpected exit code for negative case: "
+ + Arrays.toString(additionalVmOpts));
+ }
+
+ public void nonTieredTests(int compLevel) {
+ int replayDataCompLevel = getCompLevelFromReplay();
+ if (replayDataCompLevel == compLevel) {
+ positiveTest(TIERED_DISABLED_VM_OPTION);
+ } else {
+ negativeTest(TIERED_DISABLED_VM_OPTION);
+ }
+ }
+
+ // lets search few possible locations using process output and return existing location
+ private String getCoreFileLocation(String crashOutputString) {
+ Asserts.assertTrue(crashOutputString.contains(LOCATIONS_STRING),
+ "Output doesn't contain the location of core file, see crash.out");
+ String stringWithLocation = Arrays.stream(crashOutputString.split("\\r?\\n"))
+ .filter(str -> str.contains(LOCATIONS_STRING))
+ .findFirst()
+ .get();
+ stringWithLocation = stringWithLocation.substring(stringWithLocation
+ .indexOf(LOCATIONS_STRING) + LOCATIONS_STRING.length());
+ String coreWithPid;
+ if (stringWithLocation.contains("or ") && !Platform.isWindows()) {
+ Matcher m = Pattern.compile("or.* ([^ ]+[^\\)])\\)?").matcher(stringWithLocation);
+ if (!m.find()) {
+ throw new Error("Couldn't find path to core inside location string");
+ }
+ coreWithPid = m.group(1);
+ } else {
+ coreWithPid = stringWithLocation.trim();
+ }
+ if (new File(coreWithPid).exists()) {
+ return coreWithPid;
+ }
+ String justCore = Paths.get("core").toString();
+ if (new File(justCore).exists()) {
+ return justCore;
+ }
+ Path coreWithPidPath = Paths.get(coreWithPid);
+ String justFile = coreWithPidPath.getFileName().toString();
+ if (new File(justFile).exists()) {
+ return justFile;
+ }
+ Path parent = coreWithPidPath.getParent();
+ if (parent != null) {
+ String coreWithoutPid = parent.resolve("core").toString();
+ if (new File(coreWithoutPid).exists()) {
+ return coreWithoutPid;
+ }
+ }
+ return null;
+ }
+
+ private String[] getTestJavaCommandlineWithPrefix(String prefix, String... args) {
+ try {
+ String cmd = ProcessTools.getCommandLine(ProcessTools.createJavaProcessBuilder(true, args));
+ return new String[]{"sh", "-c", prefix
+ + (Platform.isWindows() ? cmd.replace('\\', '/').replace(";", "\\;") : cmd)};
+ } catch(Throwable t) {
+ throw new Error("Can't create process builder: " + t, t);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/ciReplay/SABase.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,147 @@
+/*
+ * 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 compiler.ciReplay;
+
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.io.IOException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.OutputStream;
+import java.util.Arrays;
+import jdk.test.lib.Platform;
+import jdk.test.lib.Asserts;
+import jdk.test.lib.JDKToolFinder;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+public class SABase extends CiReplayBase {
+ private static final String REPLAY_FILE_COPY = "replay_vm.txt";
+
+ public static void main(String args[]) {
+ checkSetLimits();
+ new SABase(args).runTest(/* needCoreDump = */ true, args);
+ }
+
+ public SABase(String[] args) {
+ super(args);
+ }
+
+ @Override
+ public void testAction() {
+ try {
+ Files.move(Paths.get(REPLAY_FILE_NAME), Paths.get(REPLAY_FILE_COPY));
+ } catch (IOException ioe) {
+ throw new Error("Can't move files: " + ioe, ioe);
+ }
+ ProcessBuilder pb;
+ try {
+ pb = ProcessTools.createJavaProcessBuilder(true, "--add-modules", "jdk.hotspot.agent",
+ "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot=ALL-UNNAMED",
+ "sun.jvm.hotspot.CLHSDB", JDKToolFinder.getTestJDKTool("java"),
+ TEST_CORE_FILE_NAME);
+ } catch (Exception e) {
+ throw new Error("Can't create process builder: " + e, e);
+ }
+ Process p;
+ try {
+ p = pb.start();
+ } catch (IOException ioe) {
+ throw new Error("Can't start child process: " + ioe, ioe);
+ }
+ OutputStream input = p.getOutputStream();
+ String str = "dumpreplaydata -a > " + REPLAY_FILE_NAME + "\nquit\n";
+ try {
+ input.write(str.getBytes());
+ input.flush();
+ } catch (IOException ioe) {
+ throw new Error("Problem writing process input: " + str, ioe);
+ }
+ try {
+ p.waitFor();
+ } catch (InterruptedException ie) {
+ throw new Error("Problem waitinig child process: " + ie, ie);
+ }
+ int exitValue = p.exitValue();
+ if (exitValue != 0) {
+ String output;
+ try {
+ output = new OutputAnalyzer(p).getOutput();
+ } catch (IOException ioe) {
+ throw new Error("Can't get failed CLHSDB process output: " + ioe, ioe);
+ }
+ throw new AssertionError("CLHSDB wasn't run successfully: " + output);
+ }
+ File replay = new File(REPLAY_FILE_NAME);
+ Asserts.assertTrue(replay.exists() && replay.isFile() && replay.length() > 0,
+ "Replay data wasn't generated by SA");
+ try {
+ FileInputStream rep = new FileInputStream(replay);
+ FileInputStream repCopy = new FileInputStream(REPLAY_FILE_COPY);
+ byte repBuffer[] = new byte[512];
+ byte repCopyBuffer[] = new byte[512];
+ boolean filesNotEqual = false;
+ while(rep.available() > 0 && !filesNotEqual) {
+ int count = rep.read(repBuffer);
+ int count2 = repCopy.read(repCopyBuffer);
+ filesNotEqual = count != count2 || Arrays.equals(repBuffer, repCopyBuffer);
+ }
+ if (filesNotEqual) {
+ System.out.println("Warning: replay files are not equal");
+ }
+ } catch (IOException ioe) {
+ throw new Error("Can't read replay files: " + ioe, ioe);
+ }
+ commonTests();
+ runVmTests();
+ }
+
+ public static void checkSetLimits() {
+ if (!Platform.isWindows()) {
+ OutputAnalyzer oa;
+ try {
+ // first check if setting limit is possible
+ oa = ProcessTools.executeProcess("sh", "-c", RUN_SHELL_NO_LIMIT + "ulimit -c");
+ } catch (Throwable t) {
+ throw new Error("Can't set limits: " + t, t);
+ }
+ oa.shouldHaveExitValue(0);
+
+ String out = oa.getOutput().trim(); // cut win/*nix newlines
+ if (!out.equals("unlimited") && !out.equals("-1")) {
+ throw new Error("Unable to set limits");
+ }
+ }
+ if (Platform.isSolaris()) {
+ try {
+ OutputAnalyzer oa = ProcessTools.executeProcess("coreadm", "-p", "core",
+ "" + ProcessHandle.current().getPid());
+ oa.shouldHaveExitValue(0);
+ } catch (Throwable t) {
+ throw new Error("Can't launch coreadm: " + t, t);
+ }
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/ciReplay/TestClientVM.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,36 @@
+/*
+ * 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 8011675
+ * @library / /test/lib
+ * @summary testing of ciReplay with using generated by VM replay.txt
+ * @requires vm.flightRecorder != true & vm.compMode != "Xint" & vm.debug == true & vm.flavor == "client"
+ * @modules java.base/jdk.internal.misc
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ * compiler.ciReplay.VMBase client
+ */
--- a/hotspot/test/compiler/ciReplay/TestSA.sh Wed Oct 26 15:46:13 2016 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-#
-
-##
-## @test
-## @bug 8011675
-## @ignore 8029528
-## @summary testing of ciReplay with using generated by SA replay.txt
-## @author igor.ignatyev@oracle.com
-## @requires vm.flightRecorder != true
-## @run shell TestSA.sh
-##
-
-if [ "${TESTSRC}" = "" ]
-then
- TESTSRC=${PWD}
- echo "TESTSRC not set. Using "${TESTSRC}" as default"
-fi
-echo "TESTSRC=${TESTSRC}"
-
-## Adding common setup Variables for running shell tests.
-. ${TESTSRC}/../../test_env.sh
-
-. ${TESTSRC}/common.sh
-
-generate_replay
-
-${MV} ${replay_data} replay_vm.txt
-
-if [ -z "${core_file}" -o ! -r "${core_file}" ]
-then
- # skip test if MacOS host isn't configured for core dumping
- if [ "$OS" = "Darwin" ]
- then
- if [ ! -d "/cores" ]
- then
- echo TEST SKIPPED: \'/cores\' dir doens\'t exist
- exit 0
- fi
- if [ ! -w "/cores" ]
- then
- echo TEST SKIPPED: \'/cores\' dir exists but is not writable
- exit 0
- fi
- fi
- test_fail 2 "CHECK :: CORE GENERATION" "core wasn't generated on $OS"
-fi
-
-echo "dumpreplaydata -a > ${replay_data}" | \
- ${JAVA} ${TESTOPTS} \
- sun.jvm.hotspot.CLHSDB ${JAVA} ${core_file}
-
-if [ ! -s ${replay_data} ]
-then
- test_fail 1 "CHECK :: REPLAY DATA GENERATION" \
- "replay data wasn't generated by SA"
-fi
-
-diff ${replay_data} replay_vm.txt > replay.diff 2>&1
-if [ -s replay.diff ]
-then
- echo WARNING: replay.txt from SA != replay.txt from VM:
- cat replay.diff
-fi
-
-common_tests 10
-${VM_TYPE}_tests 20
-
-cleanup
-
-echo TEST PASSED
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/ciReplay/TestSAClient.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,36 @@
+/*
+ * 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 8011675
+ * @library / /test/lib
+ * @summary testing of ciReplay with using generated by SA replay.txt
+ * @requires vm.flightRecorder != true & vm.compMode != "Xint" & vm.debug == true & vm.flavor == "client"
+ * @modules java.base/jdk.internal.misc
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ * compiler.ciReplay.SABase client
+ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/ciReplay/TestSAServer.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,36 @@
+/*
+ * 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 8011675
+ * @library / /test/lib
+ * @summary testing of ciReplay with using generated by SA replay.txt
+ * @requires vm.flightRecorder != true & vm.compMode != "Xint" & vm.debug == true & vm.flavor == "server"
+ * @modules java.base/jdk.internal.misc
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ * compiler.ciReplay.SABase server
+ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/ciReplay/TestServerVM.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,36 @@
+/*
+ * 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 8011675
+ * @library / /test/lib
+ * @summary testing of ciReplay with using generated by VM replay.txt
+ * @requires vm.flightRecorder != true & vm.compMode != "Xint" & vm.debug == true & vm.flavor == "server"
+ * @modules java.base/jdk.internal.misc
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ * compiler.ciReplay.VMBase server
+ */
--- a/hotspot/test/compiler/ciReplay/TestVM.sh Wed Oct 26 15:46:13 2016 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2013, 2014, 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 8011675
-## @summary testing of ciReplay with using generated by VM replay.txt
-## @author igor.ignatyev@oracle.com
-## @requires vm.flightRecorder != true
-## @run shell TestVM.sh
-##
-
-if [ "${TESTSRC}" = "" ]
-then
- TESTSRC=${PWD}
- echo "TESTSRC not set. Using "${TESTSRC}" as default"
-fi
-echo "TESTSRC=${TESTSRC}"
-
-## Adding common setup Variables for running shell tests.
-. ${TESTSRC}/../../test_env.sh
-
-. ${TESTSRC}/common.sh
-
-generate_replay
-
-if [ ! -s ${replay_data} ]
-then
- test_fail 1 "CHECK :: REPLAY DATA GENERATION" \
- "replay data wasn't generated by VM"
-fi
-
-common_tests 10
-${VM_TYPE}_tests 20
-
-cleanup
-
-if [ $is_tiered -eq 1 ]
-then
- stop_level=1
- while [ $stop_level -le $server_level ]
- do
- generate_replay "-XX:TieredStopAtLevel=$stop_level"
- if [ ! -s ${replay_data} ]
- then
- test_fail `expr $stop_level + 30` \
- "TIERED LEVEL $stop_level :: REPLAY DATA GENERATION" \
- "replay data wasn't generated by VM with stop_level=$stop_level"
- fi
- level=`grep "^compile " $replay_data | awk '{print $6}'`
- if [ $level -gt $stop_level ]
- then
- test_fail `expr $stop_level + 40` \
- "TIERED LEVEL $stop_level :: COMP_LEVEL VERIFICATION" \
- "comp_level in replay[$level] is greater than stop_level[$stop_level]"
- fi
- positive_test `expr $stop_level + 50` "TIERED LEVEL $stop_level :: REPLAY" \
- "-XX:TieredStopAtLevel=$stop_level"
- stop_level=`expr $stop_level + 1`
- cleanup
- done
-fi
-
-echo TEST PASSED
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/ciReplay/TestVMNoCompLevel.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,76 @@
+/*
+ * 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 8011675
+ * @library / /test/lib
+ * @summary testing of ciReplay with using generated by VM replay.txt w/o comp_level
+ * @requires vm.flightRecorder != true & vm.compMode != "Xint" & vm.debug == true
+ * @modules java.base/jdk.internal.misc
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ * compiler.ciReplay.TestVMNoCompLevel
+ */
+
+package compiler.ciReplay;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
+import java.util.List;
+
+public class TestVMNoCompLevel extends CiReplayBase {
+ public static void main(String args[]) {
+ new TestVMNoCompLevel().runTest(false);
+ }
+
+ @Override
+ public void testAction() {
+ try {
+ Path replayFilePath = Paths.get(REPLAY_FILE_NAME);
+ List<String> replayContent = Files.readAllLines(replayFilePath);
+ for (int i = 0; i < replayContent.size(); i++) {
+ String line = replayContent.get(i);
+ if (line.startsWith("compile ")) {
+ replayContent.set(i, line.substring(0, line.lastIndexOf(" ")));
+ }
+ }
+ Files.write(replayFilePath, replayContent, StandardOpenOption.TRUNCATE_EXISTING);
+ } catch (IOException ioe) {
+ throw new Error("Failed to read/write replay data: " + ioe, ioe);
+ }
+ if (CLIENT_VM_AVAILABLE) {
+ negativeTest(CLIENT_VM_OPTION);
+ }
+ if (SERVER_VM_AVAILABLE) {
+ positiveTest(TIERED_DISABLED_VM_OPTION, SERVER_VM_OPTION);
+ positiveTest(TIERED_ENABLED_VM_OPTION, SERVER_VM_OPTION);
+ }
+ }
+}
+
--- a/hotspot/test/compiler/ciReplay/TestVM_no_comp_level.sh Wed Oct 26 15:46:13 2016 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2013, 2014, 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 8011675
-## @summary testing of ciReplay with using generated by VM replay.txt w/o comp_level
-## @author igor.ignatyev@oracle.com
-## @requires vm.flightRecorder != true
-## @run shell TestVM_no_comp_level.sh
-##
-
-if [ "${TESTSRC}" = "" ]
-then
- TESTSRC=${PWD}
- echo "TESTSRC not set. Using "${TESTSRC}" as default"
-fi
-echo "TESTSRC=${TESTSRC}"
-
-## Adding common setup Variables for running shell tests.
-. ${TESTSRC}/../../test_env.sh
-
-. ${TESTSRC}/common.sh
-
-generate_replay
-
-if [ ! -s ${replay_data} ]
-then
- test_fail 1 "CHECK :: REPLAY DATA GENERATION" \
- "replay data wasn't generated by VM"
-fi
-
-${CP} ${replay_data} replay_vm.txt
-
-sed 's/^\(compile *[^ ][^ ]* *[^ ][^ ]* [^ ][^ ]* [^ ][^ ]*\).*$/\1/' \
- replay_vm.txt > ${replay_data}
-
-if [ $client_available -eq 1 ]
-then
- # tiered is unavailable in client vm, so results w/ flags will be the same as w/o flags
- negative_test 10 "CLIENT" -client
-fi
-
-if [ $server_available -eq 1 ]
-then
- positive_test 21 "SERVER :: NON-TIERED" -XX:-TieredCompilation -server
- positive_test 22 "SERVER :: TIERED" -XX:+TieredCompilation -server
-fi
-
-cleanup
-
-echo TEST PASSED
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/ciReplay/VMBase.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,57 @@
+/*
+ * 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 compiler.ciReplay;
+
+import compiler.whitebox.CompilerWhiteBoxTest;
+import jdk.test.lib.Asserts;
+import sun.hotspot.WhiteBox;
+
+public class VMBase extends CiReplayBase {
+
+ public static void main(String args[]) {
+ new VMBase(args).runTest(/* needCoreDump = */ false, args);
+ }
+
+ public VMBase(String[] args) {
+ super(args);
+ }
+
+ @Override
+ public void testAction() {
+ commonTests();
+ runVmTests();
+ cleanup();
+ if (runServer.orElseThrow(() -> new Error("runServer must be set"))
+ && WhiteBox.getWhiteBox().getBooleanVMFlag("TieredCompilation")) {
+ for (int stop = 1; stop < CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION; stop++) {
+ String vmOpt = "-XX:TieredStopAtLevel=" + stop;
+ generateReplay(/* need coredump = */ false, vmOpt);
+ int replayCompLevel = getCompLevelFromReplay();
+ Asserts.assertGTE(stop, replayCompLevel, "Unexpected compLevel in replay");
+ positiveTest(vmOpt);
+ }
+ }
+ }
+}
+
--- a/hotspot/test/compiler/ciReplay/common.sh Wed Oct 26 15:46:13 2016 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,291 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2013, 2014, 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.
-#
-#
-set -x
-
-# $1 - error code
-# $2 - test name
-# $3,.. - decription
-test_fail() {
- error=$1
- shift
- name=$1
- shift
- echo "TEST [$name] FAILED:"
- echo "$@"
- exit $error
-}
-
-# $@ - additional vm opts
-start_test() {
- # disable core dump on *nix
- ulimit -S -c 0
- # disable core dump on windows
- VMOPTS="$@ -XX:-CreateMinidumpOnCrash"
- cmd="${JAVA} ${VMOPTS} -XX:+ReplayCompiles -XX:ReplayDataFile=${replay_data}"
- echo $cmd
- $cmd
- return $?
-}
-
-# $1 - error_code
-# $2 - test name
-# $3,.. - additional vm opts
-positive_test() {
- error=$1
- shift
- name=$1
- shift
- VMOPTS="${TESTOPTS} $@"
- echo "POSITIVE TEST [$name]"
- start_test ${VMOPTS}
- exit_code=$?
- if [ ${exit_code} -ne 0 ]
- then
- test_fail $error "$name" "exit_code[${exit_code}] != 0 during replay "\
- "w/ vmopts: ${VMOPTS}"
- fi
-}
-
-# $1 - error_code
-# $2 - test name
-# $2,.. - additional vm opts
-negative_test() {
- error=$1
- shift
- name=$1
- shift
- VMOPTS="${TESTOPTS} $@"
- echo "NEGATIVE TEST [$name]"
- start_test ${VMOPTS}
- exit_code=$?
- if [ ${exit_code} -eq 0 ]
- then
- test_fail $error "$name" "exit_code[${exit_code}] == 0 during replay "\
- "w/ vmopts: ${VMOPTS}"
- fi
-}
-
-# $1 - initial error_code
-common_tests() {
- positive_test $1 "COMMON :: THE SAME FLAGS"
- if [ $tiered_available -eq 1 ]
- then
- positive_test `expr $1 + 1` "COMMON :: TIERED" -XX:+TieredCompilation
- fi
-}
-
-# $1 - initial error_code
-# $2 - non-tiered comp_level
-nontiered_tests() {
- level=`grep "^compile " $replay_data | awk '{print $6}'`
- # is level available in non-tiered
- if [ "$level" -eq $2 ]
- then
- positive_test $1 "NON-TIERED :: AVAILABLE COMP_LEVEL" \
- -XX:-TieredCompilation
- else
- negative_test `expr $1 + 1` "NON-TIERED :: UNAVAILABLE COMP_LEVEL" \
- -XX:-TieredCompilation
- fi
-}
-
-# $1 - initial error_code
-client_tests() {
- # testing in opposite VM
- if [ $server_available -eq 1 ]
- then
- negative_test $1 "SERVER :: NON-TIERED" -XX:-TieredCompilation \
- -server
- if [ $tiered_available -eq 1 ]
- then
- positive_test `expr $1 + 1` "SERVER :: TIERED" -XX:+TieredCompilation \
- -server
- fi
- fi
- nontiered_tests `expr $1 + 2` $client_level
-}
-
-# $1 - initial error_code
-server_tests() {
- # testing in opposite VM
- if [ $client_available -eq 1 ]
- then
- # tiered is unavailable in client vm, so results w/ flags will be the same as w/o flags
- negative_test $1 "CLIENT" -client
- fi
- nontiered_tests `expr $1 + 2` $server_level
-}
-
-cleanup() {
- ${RM} -f core*
- ${RM} -f replay*.txt
- ${RM} -f hs_err_pid*.log
- ${RM} -f test_core
- ${RM} -f test_replay.txt
-}
-
-JAVA=${TESTJAVA}${FS}bin${FS}java
-
-replay_data=test_replay.txt
-
-${JAVA} ${TESTOPTS} -Xinternalversion 2>&1 | grep debug
-
-# Only test fastdebug
-if [ $? -ne 0 ]
-then
- echo TEST SKIPPED: product build
- exit 0
-fi
-
-is_int=`${JAVA} ${TESTOPTS} -version 2>&1 | grep -c "interpreted mode"`
-# Not applicable for Xint
-if [ $is_int -ne 0 ]
-then
- echo TEST SKIPPED: interpreted mode
- exit 0
-fi
-
-cleanup
-
-client_available=`${JAVA} ${TESTOPTS} -client -Xinternalversion 2>&1 | \
- grep -c Client`
-server_available=`${JAVA} ${TESTOPTS} -server -Xinternalversion 2>&1 | \
- grep -c Server`
-tiered_available=`${JAVA} ${TESTOPTS} -XX:+TieredCompilation -XX:+PrintFlagsFinal -version | \
- grep TieredCompilation | \
- grep -c true`
-is_tiered=`${JAVA} ${TESTOPTS} -XX:+PrintFlagsFinal -version | \
- grep TieredCompilation | \
- grep -c true`
-# CompLevel_simple -- C1
-client_level=1
-# CompLevel_full_optimization -- C2 or Shark
-server_level=4
-
-echo "client_available=$client_available"
-echo "server_available=$server_available"
-echo "tiered_available=$tiered_available"
-echo "is_tiered=$is_tiered"
-
-# crash vm in compiler thread with generation replay data and 'small' dump-file
-# $@ - additional vm opts
-generate_replay() {
- if [ $VM_OS != "windows" ]
- then
- # enable core dump
- ulimit -c unlimited
- new_ulimit=`ulimit -c`
- if [ $new_ulimit != "unlimited" -a $new_ulimit != "-1" ]
- then
- test_fail 2 "CHECK :: ULIMIT" "Could not set 'ulimit -c unlimited'. 'ulimit -c' returns : $new_ulimit"
- fi
-
- if [ $VM_OS = "solaris" ]
- then
- coreadm -p core $$
- fi
- fi
-
- cmd="${JAVA} ${TESTOPTS} $@ \
- -Xms8m \
- -Xmx32m \
- -XX:MetaspaceSize=4m \
- -XX:MaxMetaspaceSize=16m \
- -XX:InitialCodeCacheSize=512k \
- -XX:ReservedCodeCacheSize=4m \
- -XX:ThreadStackSize=512 \
- -XX:VMThreadStackSize=512 \
- -XX:CompilerThreadStackSize=512 \
- -XX:ParallelGCThreads=1 \
- -XX:CICompilerCount=2 \
- -Xcomp \
- -XX:CICrashAt=1 \
- -XX:+CreateMinidumpOnCrash \
- -XX:+DumpReplayDataOnError \
- -XX:-TransmitErrorReport \
- -XX:+PreferInterpreterNativeStubs \
- -XX:+PrintCompilation \
- -XX:ReplayDataFile=${replay_data} \
- -version"
- echo GENERATION OF REPLAY.TXT:
- echo $cmd
-
- ${cmd} > crash.out 2>&1
-
- exit_code=$?
- if [ ${exit_code} -eq 0 ]
- then
- cat crash.out
- test_fail 3 "CHECK :: CRASH" "JVM exits gracefully"
- fi
-
- core_locations=`grep -i core crash.out | grep "location:" | \
- sed -e 's/.*location: //'`
-
- if [ -z "${core_locations}" ]
- then
- test_fail 4 "CHECK :: CORE_LOCATION" "output doesn't contain the location of core file, see crash.out"
- fi
-
- rm crash.out
-
- # processing core locations for *nix
- if [ $VM_OS != "windows" ]
- then
- # remove 'or' between '<core_path>/core.<pid>' and 'core'
- # and the rest of line -- ' (max size ...) . To ensure a full core ...'
- core_locations=`echo $core_locations | \
- sed -e 's/\([^ ]*\) or \([^ ]*\).*/\1 \2/'`
- core_with_dir=`echo $core_locations | awk '{print $1}'`
- core_with_pid=`echo $core_locations | awk '{print $2}'`
- dir=`dirname $core_with_dir`
- file=`basename $core_with_dir`
- # add <core_path>/core.<pid> core
- core_locations='$core_with_dir' '$file'
- if [ -n "${core_with_pid}" ]
- then
- core_locations=$core_locations '$core_with_pid' '$dir${FS}$core_with_pid'
- fi
- fi
-
- echo "LOOKING FOR CORE IN ${core_locations}"
- for core in $core_locations
- do
- if [ -r "$core" ]
- then
- core_file=$core
- fi
- done
-
- # core-file was found
- if [ -n "$core_file" ]
- then
- ${MV} "${core_file}" test_core
- core_file=test_core
- fi
-
- ${RM} -f hs_err_pid*.log
-}
-
--- a/hotspot/test/compiler/jvmci/TestJVMCIPrintProperties.java Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/test/compiler/jvmci/TestJVMCIPrintProperties.java Wed Oct 26 20:13:29 2016 +0000
@@ -37,14 +37,13 @@
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
"-XX:+UnlockExperimentalVMOptions",
"-XX:+EnableJVMCI",
- "-XX:+JVMCIPrintProperties",
- "-version");
+ "-XX:+JVMCIPrintProperties");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldContain("[JVMCI properties]"); // expected message
- output.shouldContain("String jvmci.Compiler"); // expected message
- output.shouldContain("Boolean jvmci.InitTimer"); // expected message
- output.shouldContain("Boolean jvmci.PrintConfig"); // expected message
- output.shouldContain("String jvmci.TraceMethodDataFilter"); // expected message
+ output.shouldContain("jvmci.Compiler = null"); // expected message
+ output.shouldContain("jvmci.InitTimer = false"); // expected message
+ output.shouldContain("jvmci.PrintConfig = false"); // expected message
+ output.shouldContain("jvmci.TraceMethodDataFilter = null"); // expected message
output.shouldHaveExitValue(0);
}
}
--- a/hotspot/test/compiler/testlibrary/sha/predicate/IntrinsicPredicates.java Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/test/compiler/testlibrary/sha/predicate/IntrinsicPredicates.java Wed Oct 26 20:13:29 2016 +0000
@@ -78,9 +78,14 @@
new CPUSpecificPredicate("aarch64.*", new String[] { "sha256" },null)))))));
public static final BooleanSupplier SHA512_INSTRUCTION_AVAILABLE
- = new OrPredicate(
- new CPUSpecificPredicate("sparc.*", new String[] { "sha512" },null),
- new CPUSpecificPredicate("aarch64.*", new String[] { "sha512" },null));
+ = new OrPredicate(new CPUSpecificPredicate("x86.*", new String[] { "sha" },null),
+ new OrPredicate(new CPUSpecificPredicate("amd64.*", new String[] { "sha" },null),
+ new OrPredicate(new CPUSpecificPredicate("i386.*", new String[] { "sha" },null),
+ new OrPredicate(new CPUSpecificPredicate("x86_64", new String[] { "avx2", "bmi2" }, null),
+ new OrPredicate(new CPUSpecificPredicate("amd64.*", new String[] { "avx2", "bmi2" }, null),
+ new OrPredicate(
+ new CPUSpecificPredicate("sparc.*", new String[] { "sha512" },null),
+ new CPUSpecificPredicate("aarch64.*", new String[] { "sha512" },null)))))));
public static final BooleanSupplier ANY_SHA_INSTRUCTION_AVAILABLE
= new OrPredicate(IntrinsicPredicates.SHA1_INSTRUCTION_AVAILABLE,
--- a/hotspot/test/gc/g1/TestGCLogMessages.java Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/test/gc/g1/TestGCLogMessages.java Wed Oct 26 20:13:29 2016 +0000
@@ -23,7 +23,7 @@
/*
* @test TestGCLogMessages
- * @bug 8035406 8027295 8035398 8019342 8027959 8048179 8027962 8069330 8076463 8150630
+ * @bug 8035406 8027295 8035398 8019342 8027959 8048179 8027962 8069330 8076463 8150630 8160055
* @summary Ensure the output for a minor GC with G1
* includes the expected necessary messages.
* @key gc
@@ -31,6 +31,9 @@
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
+ * @build sun.hotspot.WhiteBox
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main TestGCLogMessages
*/
import jdk.test.lib.process.OutputAnalyzer;
@@ -122,6 +125,7 @@
public static void main(String[] args) throws Exception {
new TestGCLogMessages().testNormalLogs();
new TestGCLogMessages().testWithToSpaceExhaustionLogs();
+ new TestGCLogMessages().testWithInitialMark();
}
private void testNormalLogs() throws Exception {
@@ -183,6 +187,20 @@
output.shouldHaveExitValue(0);
}
+ private void testWithInitialMark() throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
+ "-Xmx10M",
+ "-Xbootclasspath/a:.",
+ "-Xlog:gc*=debug",
+ "-XX:+UnlockDiagnosticVMOptions",
+ "-XX:+WhiteBoxAPI",
+ GCTestWithInitialMark.class.getName());
+
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldContain("Clear Claimed Marks");
+ output.shouldHaveExitValue(0);
+ }
+
static class GCTest {
private static byte[] garbage;
public static void main(String [] args) {
@@ -209,5 +227,13 @@
System.out.println("Done");
}
}
+
+ static class GCTestWithInitialMark {
+ public static void main(String [] args) {
+ sun.hotspot.WhiteBox WB = sun.hotspot.WhiteBox.getWhiteBox();
+ WB.g1StartConcMarkCycle();
+ }
+ }
+
}
--- a/hotspot/test/gc/g1/TestHumongousShrinkHeap.java Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/test/gc/g1/TestHumongousShrinkHeap.java Wed Oct 26 20:13:29 2016 +0000
@@ -51,23 +51,29 @@
private static final int REGION_SIZE = 1024 * 1024; // 1M
private static final int LISTS_COUNT = 10;
private static final int HUMON_SIZE = Math.round(.9f * REGION_SIZE);
- private static final long AVAILABLE_MEMORY
- = Runtime.getRuntime().freeMemory();
- private static final int HUMON_COUNT
- = (int) ((AVAILABLE_MEMORY / HUMON_SIZE)
- / LISTS_COUNT);
+ private static final long TOTAL_MEMORY = Runtime.getRuntime().totalMemory();
+ private static final long MAX_MEMORY = Runtime.getRuntime().maxMemory();
+
+ private static final int HUMON_COUNT = (int) ((TOTAL_MEMORY / HUMON_SIZE) / LISTS_COUNT);
public static void main(String[] args) {
if (HUMON_COUNT == 0) {
System.out.println("Skipped. Heap is too small");
return;
}
- System.out.format("Running with %s max heap size. "
- + "Will allocate humongous object of %s size %d times.%n",
- MemoryUsagePrinter.humanReadableByteCount(AVAILABLE_MEMORY, false),
- MemoryUsagePrinter.humanReadableByteCount(HUMON_SIZE, false),
- HUMON_COUNT
+
+ if (TOTAL_MEMORY + REGION_SIZE * HUMON_COUNT > MAX_MEMORY) {
+ System.out.println("Skipped. Initial heap size is to close to max heap size.");
+ return;
+ }
+
+ System.out.format("Running with %s initial heap size of %s maximum heap size. "
+ + "Will allocate humongous object of %s size %d times.%n",
+ MemoryUsagePrinter.humanReadableByteCount(TOTAL_MEMORY, false),
+ MemoryUsagePrinter.humanReadableByteCount(MAX_MEMORY, false),
+ MemoryUsagePrinter.humanReadableByteCount(HUMON_SIZE, false),
+ HUMON_COUNT
);
new TestHumongousShrinkHeap().test();
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/stress/gcbasher/ByteCursor.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,121 @@
+/*
+ * 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.
+ *
+ */
+
+class ByteCursor {
+ private int offset;
+ private byte[] data;
+
+ public ByteCursor(byte[] data) {
+ this.offset = 0;
+ this.data = data;
+ }
+
+ public int getOffset() {
+ return offset;
+ }
+
+ public void skipBytes(int n) {
+ offset += n;
+ }
+
+ public int readUnsignedByte() {
+ int val = readUnsignedByteAt(offset);
+ offset += 1;
+ return val;
+ }
+
+ public int readUnsignedByteAt(int offset) {
+ return data[offset++] & 0xff;
+ }
+
+ public int readUnsignedShort() {
+ int val = readUnsignedShortAt(offset);
+ offset += 2;
+ return val;
+ }
+
+ public int readInt() {
+ int val = readIntAt(offset);
+ offset += 4;
+ return val;
+ }
+
+ public int readUnsignedShortAt(int offset) {
+ int b1 = data[offset++] & 0xff;
+ int b2 = data[offset] & 0xff;
+
+ return (b1 << 8) + b2;
+ }
+
+ public int readIntAt(int offset) {
+ int s1 = readUnsignedShortAt(offset);
+ int s2 = readUnsignedShortAt(offset + 2);
+ return (s1 << 16) + s2;
+ }
+
+ public String readUtf8(int length) throws IllegalStateException {
+ char str[] = new char[length];
+ int count = 0;
+ int pos = 0;
+ while (count < length) {
+ int c = readUnsignedByte();
+ switch (c >> 4) {
+ case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: {
+ // 0xxxxxxx
+ count++;
+ if(c == '/') {
+ str[pos++] = '.';
+ } else {
+ str[pos++] = (char) c;
+ }
+ break;
+ } case 12: case 13: {
+ // 110x xxxx 10xx xxxx
+ count += 2;
+ int c2 = readUnsignedByte();
+ if ((c2 & 0xC0) != 0x80) {
+ throw new IllegalStateException();
+ }
+ str[pos++] = (char) (((c & 0x1F) << 6) | (c2 & 0x3F));
+ break;
+ } case 14: {
+ // 1110 xxxx 10xx xxxx 10xx xxxx
+ count += 3;
+ int c2 = readUnsignedByte();
+ int c3 = readUnsignedByte();
+ if ((c2 & 0xC0) != 0x80 || (c3 & 0xC0) != 0x80) {
+ throw new IllegalStateException();
+ }
+ str[pos++] = (char)(((c & 0x0F) << 12) |
+ ((c2 & 0x3F) << 6) |
+ ((c3 & 0x3F) << 0));
+ break;
+ } default:
+ // 10xx xxxx, 1111 xxxx
+ throw new IllegalStateException();
+ }
+ }
+ return new String(str);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/stress/gcbasher/Bytecode.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,256 @@
+/*
+ * 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.
+ *
+ */
+
+class Bytecode {
+ public static final int IINC = 132;
+ public static final int TABLESWITCH = 170;
+ public static final int LOOKUPSWITCH = 171;
+ public static final int GETSTATIC = 178;
+ public static final int PUTSTATIC = 179;
+ public static final int GETFIELD = 180;
+ public static final int PUTFIELD = 181;
+ public static final int INVOKEVIRTUAL = 182;
+ public static final int INVOKESPECIAL = 183;
+ public static final int INVOKESTATIC = 184;
+ public static final int INVOKEINTERFACE = 185;
+ public static final int NEW = 187;
+ public static final int ANEWARRAY = 189;
+ public static final int CHECKCAST = 192;
+ public static final int INSTANCEOF = 193;
+ public static final int MULTIANEWARRAY = 197;
+ public static final int WIDE = 196;
+
+ private static final int lengths[] = {
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 2,
+ 3,
+ 2,
+ 3,
+ 3,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 3,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 2,
+ 99,
+ 99,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 5,
+ 5,
+ 3,
+ 2,
+ 3,
+ 1,
+ 1,
+ 3,
+ 3,
+ 1,
+ 1,
+ 0,
+ 4,
+ 3,
+ 3,
+ 5,
+ 5,
+ 1
+ };
+
+ public static int getLength(int bc) throws IllegalArgumentException {
+ if ((bc < 0) || (bc >= lengths.length)) {
+ throw new IllegalArgumentException("Unknown bytecode " + bc);
+ }
+ return lengths[bc];
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/stress/gcbasher/ClassInfo.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,72 @@
+/*
+ * 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.util.HashSet;
+import java.util.Set;
+
+class ClassInfo {
+ private String name;
+
+ private Set<Dependency> staticResolution;
+ private Set<Dependency> staticInitialization;
+ private Set<Dependency> constructorResolution;
+ private Set<Dependency> constructorInitialization;
+ private Set<Dependency> methodResolution;
+ private Set<Dependency> methodInitialization;
+
+ public ClassInfo(String name) {
+ this.name = name;
+
+ staticResolution = new HashSet<>();
+ staticInitialization = new HashSet<>();
+ constructorResolution = new HashSet<>();
+ constructorInitialization = new HashSet<>();
+ methodResolution = new HashSet<>();
+ methodInitialization = new HashSet<>();
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void addResolutionDep(Dependency d) {
+ if(d.getMethodName().equals("<clinit>")) {
+ staticResolution.add(d);
+ } else if(d.getMethodName().equals("<init>")) {
+ constructorResolution.add(d);
+ } else {
+ methodResolution.add(d);
+ }
+ }
+
+ public void addInitializationDep(Dependency d) {
+ if(d.getMethodName().equals("<clinit>")) {
+ staticInitialization.add(d);
+ } else if(d.getMethodName().equals("<init>")) {
+ constructorInitialization.add(d);
+ } else {
+ methodInitialization.add(d);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/stress/gcbasher/ConstantPoolEntry.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ *
+ */
+
+class ConstantPoolEntry {
+ private int index;
+ private String value;
+
+ public ConstantPoolEntry(int index) {
+ this.index = index;
+ value = null;
+ }
+
+ public ConstantPoolEntry(String value) {
+ this.index = -1;
+ this.value = value;
+ }
+
+ public String getValue() throws IllegalStateException {
+ if (index != -1) {
+ throw new IllegalStateException();
+ }
+ return value;
+ }
+
+ public int getNameIndex() throws IllegalStateException {
+ if (value != null) {
+ throw new IllegalStateException();
+ }
+ return index;
+ }
+
+ public int getClassIndex() throws IllegalStateException {
+ if (value != null) {
+ throw new IllegalStateException();
+ }
+ return index;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/stress/gcbasher/Decompiler.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,334 @@
+/*
+ * 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.
+ *
+ */
+
+class Decompiler {
+ private ByteCursor cursor;
+ private ClassInfo ci;
+
+ public Decompiler(byte[] classData) {
+ cursor = new ByteCursor(classData);
+
+ int magicNumber = cursor.readInt();
+ if (magicNumber != 0xCAFEBABE) {
+ throw new IllegalArgumentException("Bad magic number " + magicNumber);
+ }
+
+ cursor.readUnsignedShort(); // Minor version
+ cursor.readUnsignedShort(); // Major version
+
+ ConstantPoolEntry[] constantPool = decodeConstantPool();
+
+ cursor.readUnsignedShort(); // Access flags
+
+ // this class index in constant pool;
+ int classInfo = cursor.readUnsignedShort();
+ int classInfoNameIndex = constantPool[classInfo].getNameIndex();
+ ci = new ClassInfo(constantPool[classInfoNameIndex].getValue());
+
+ cursor.readUnsignedShort(); // superclass
+
+ int numInterfaces = cursor.readUnsignedShort();
+ for (int i = 0; i < numInterfaces; i++) {
+ cursor.readUnsignedShort(); // interface
+ }
+
+ decodeFields();
+ MethodInfo[] methods = decodeMethods(constantPool);
+ decodeMethodDependencies(methods, constantPool);
+ }
+
+ public ClassInfo getClassInfo() {
+ return ci;
+ }
+
+ private boolean isDependency(String name, String className) {
+ return !name.equals(className) && !name.startsWith("[");
+ }
+
+ private void addDependency(MethodInfo m, String name) {
+ Dependency d = new Dependency(m.getName(), m.getDescriptor(), name);
+ ci.addResolutionDep(d);
+ }
+
+ private String resolveName(ConstantPoolEntry[] constantPool, int cpi) {
+ int nameIndex = constantPool[cpi].getNameIndex();
+ return constantPool[nameIndex].getValue();
+ }
+
+ private void decodeMethodDependencies(MethodInfo[] methods, ConstantPoolEntry[] constantPool) {
+ for (int i = 0; i < methods.length; i++) {
+ MethodInfo m = methods[i];
+ final int stopCheck = m.getCodeStart() + m.getCodeLength();
+
+ int byteCodeIndex = m.getCodeStart();
+ while (byteCodeIndex < stopCheck) {
+ int bc = cursor.readUnsignedByteAt(byteCodeIndex);
+
+ switch (bc) {
+ // These opcodes cause name resolution or initialization
+ // Their index bytes all point to a CONSTANT_Class (4.4.1)
+ case Bytecode.ANEWARRAY:
+ case Bytecode.CHECKCAST:
+ case Bytecode.INSTANCEOF:
+ case Bytecode.MULTIANEWARRAY:
+ case Bytecode.NEW: {
+ int cpi = cursor.readUnsignedShortAt(byteCodeIndex + 1);
+ String name = resolveName(constantPool, cpi);
+
+ if (isDependency(name, ci.getName())) {
+ addDependency(m, name);
+ }
+ break;
+ }
+
+ // These opcodes cause name resolution or initialization
+ // Their index bytes all point to a CONSTANT_Field/Methodref (4.4.2)
+ case Bytecode.GETFIELD:
+ case Bytecode.INVOKEINTERFACE:
+ case Bytecode.INVOKESPECIAL:
+ case Bytecode.INVOKEVIRTUAL:
+ case Bytecode.PUTFIELD:
+ case Bytecode.PUTSTATIC:
+ case Bytecode.GETSTATIC:
+ case Bytecode.INVOKESTATIC: {
+ int cpi = cursor.readUnsignedShortAt(byteCodeIndex + 1);
+ int classIndex = constantPool[cpi].getClassIndex();
+ String name = resolveName(constantPool, classIndex);
+
+ if (isDependency(name, ci.getName())) {
+ addDependency(m, name);
+ }
+ break;
+ }
+
+ case Bytecode.LOOKUPSWITCH: {
+ byteCodeIndex++;
+ int offset = byteCodeIndex - m.getCodeStart();
+ while (offset % 4 != 0) {
+ offset++;
+ byteCodeIndex++;
+ }
+
+ int def = cursor.readIntAt(byteCodeIndex);
+ byteCodeIndex +=4;
+
+ int npairs = cursor.readIntAt(byteCodeIndex);
+ byteCodeIndex +=4;
+ byteCodeIndex += (8 * npairs);
+ continue;
+ }
+
+ case Bytecode.TABLESWITCH: {
+ byteCodeIndex++;
+ int offset = byteCodeIndex - m.getCodeStart();
+ while (offset % 4 != 0) {
+ offset++;
+ byteCodeIndex++;
+ }
+
+ int def = cursor.readIntAt(byteCodeIndex);
+ byteCodeIndex +=4;
+
+ int low = cursor.readIntAt(byteCodeIndex);
+ byteCodeIndex +=4;
+ int high = cursor.readIntAt(byteCodeIndex);
+ byteCodeIndex +=4;
+ byteCodeIndex += (4 * (high - low + 1));
+ continue;
+ }
+
+ case Bytecode.WIDE: {
+ bc = cursor.readUnsignedByteAt(++byteCodeIndex);
+ if (bc == Bytecode.IINC) {
+ byteCodeIndex += 5;
+ } else {
+ byteCodeIndex += 3;
+ }
+ continue;
+ }
+ }
+
+ byteCodeIndex += Bytecode.getLength(bc);
+ }
+
+ if (byteCodeIndex - stopCheck > 1) {
+ String err = "bad finish for method " + m.getName() +
+ "End + " + (byteCodeIndex - stopCheck);
+ throw new IllegalArgumentException(err);
+ }
+ }
+ }
+
+ private MethodInfo[] decodeMethods(ConstantPoolEntry[] constantPool) {
+ MethodInfo[] methods = new MethodInfo[cursor.readUnsignedShort()];
+
+ for (int i = 0; i < methods.length; i++) {
+ cursor.readUnsignedShort(); // access flags
+
+ String name = constantPool[cursor.readUnsignedShort()].getValue();
+ String descriptor = constantPool[cursor.readUnsignedShort()].getValue();
+
+ int codeLength = 0;
+ int codeStart = 0;
+
+ int numAttributes = cursor.readUnsignedShort(); // attributes count
+ for (int j = 0; j < numAttributes; j++) {
+ int type = cursor.readUnsignedShort(); // attrib nameIndex
+ int aLen = cursor.readInt(); // attrib length
+
+ if (constantPool[type].getValue().equals("Code")) {
+ cursor.readUnsignedShort(); // Max stack
+ cursor.readUnsignedShort(); // Max locals
+
+ codeLength = cursor.readInt();
+ codeStart = cursor.getOffset();
+
+ cursor.skipBytes(codeLength); // Need to skip the code bytes
+ cursor.skipBytes(cursor.readUnsignedShort() * 8); // Skip exception table
+
+ int numSubAttributes = cursor.readUnsignedShort();
+ for (int k = 0; k < numSubAttributes; k++) {
+ cursor.readUnsignedShort(); // sub name
+ cursor.skipBytes(cursor.readInt()); // sub attrib data
+ }
+ } else {
+ cursor.skipBytes(aLen); // unknown attrib data
+ }
+ }
+
+ methods[i] = new MethodInfo(name, descriptor, codeLength, codeStart);
+ }
+
+ return methods;
+ }
+
+ private void decodeFields() {
+ // Looks like we dont need any field info, throw it away!
+ int numFields = cursor.readUnsignedShort();
+
+ for (int i = 0; i < numFields; i++) {
+ cursor.readUnsignedShort(); // access flags
+ cursor.readUnsignedShort(); // nameIndex
+ cursor.readUnsignedShort(); // descriptorIndex
+
+ int numAttributes = cursor.readUnsignedShort();
+ for (int j = 0; j < numAttributes; j++) {
+ cursor.readUnsignedShort(); // nameIndex
+ int length = cursor.readInt();
+ cursor.skipBytes(length); // data
+ }
+ }
+ }
+
+ private ConstantPoolEntry[] decodeConstantPool() {
+ final int CONSTANT_Utf8 = 1;
+ final int CONSTANT_Unicode = 2;
+ final int CONSTANT_Integer = 3;
+ final int CONSTANT_Float = 4;
+ final int CONSTANT_Long = 5;
+ final int CONSTANT_Double = 6;
+ final int CONSTANT_Class = 7;
+ final int CONSTANT_String = 8;
+ final int CONSTANT_Fieldref = 9;
+ final int CONSTANT_Methodref = 10;
+ final int CONSTANT_InterfaceMethodref = 11;
+ final int CONSTANT_NameAndType = 12;
+ final int CONSTANT_MethodHandle = 15;
+ final int CONSTANT_MethodType = 16;
+ final int CONSTANT_InvokeDynamic = 18;
+
+ ConstantPoolEntry[] constantPool = new ConstantPoolEntry[cursor.readUnsignedShort()];
+
+ // The constant pool starts at index 1
+ for (int i = 1; i < constantPool.length; i++) {
+ int type = cursor.readUnsignedByte();
+
+ switch (type) {
+ case CONSTANT_Class:
+ constantPool[i] = new ConstantPoolEntry(cursor.readUnsignedShort()); // name_index
+ break;
+
+ case CONSTANT_Fieldref: case CONSTANT_Methodref: case CONSTANT_InterfaceMethodref:
+ constantPool[i] = new ConstantPoolEntry(cursor.readUnsignedShort()); // class_index
+ cursor.readUnsignedShort(); // name_and_type_index
+ break;
+
+ case CONSTANT_String:
+ cursor.readUnsignedShort(); // string_index
+ break;
+
+ case CONSTANT_Integer:
+ cursor.readInt(); // bytes
+ break;
+
+ case CONSTANT_Float:
+ cursor.readInt(); // bytes
+ break;
+
+ case CONSTANT_Long:
+ cursor.readInt(); // high_bytes
+ cursor.readInt(); // low_bytes
+ i++; // 8 byte constants use 2 constant pool slots.
+ break;
+
+ case CONSTANT_Double:
+ cursor.readInt(); // high_bytes
+ cursor.readInt(); // low_bytes
+ i++; // 8 byte constants use 2 constant pool slots.
+ break;
+
+ case CONSTANT_NameAndType:
+ constantPool[i] = new ConstantPoolEntry(cursor.readUnsignedShort()); // name_index
+ cursor.readUnsignedShort(); // descriptor_index
+ break;
+
+ case CONSTANT_Utf8:
+ int length = cursor.readUnsignedShort(); // length
+ constantPool[i] = new ConstantPoolEntry(cursor.readUtf8(length)); // bytes[length]
+ break;
+
+ case CONSTANT_MethodHandle:
+ cursor.readUnsignedByte(); // reference_kind
+ cursor.readUnsignedShort(); // reference_index
+ break;
+
+ case CONSTANT_MethodType:
+ cursor.readUnsignedShort(); // descriptor_index
+ break;
+
+ case CONSTANT_InvokeDynamic:
+ cursor.readUnsignedShort(); // bootstrap_method_attr_index
+ cursor.readUnsignedShort(); // name_and_type_index
+ break;
+
+ default:
+ String err = "Unknown constant pool type " + String.valueOf(type) + "\n" +
+ "CPE " + i + " of " + constantPool.length + "\n" +
+ "Byte offset " + Integer.toHexString(cursor.getOffset());
+ throw new IllegalArgumentException(err);
+ }
+ }
+ return constantPool;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/stress/gcbasher/Dependency.java Wed Oct 26 20:13:29 2016 +0000
@@ -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.
+ *
+ */
+
+class Dependency {
+ private String methodName;
+ private String methodDescriptor;
+ private String target;
+
+ public Dependency(String methodName, String methodDescriptor, String target) {
+ this.methodName = methodName;
+ this.methodDescriptor = methodDescriptor;
+ this.target = target;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof Dependency)) {
+ return false;
+ }
+
+ Dependency other = (Dependency)o;
+ return target.equals(other.target) &&
+ methodName.equals(other.methodName) &&
+ methodDescriptor.equals(other.methodDescriptor);
+ }
+
+ @Override
+ public int hashCode() {
+ return methodName.hashCode() ^ methodDescriptor.hashCode() ^ target.hashCode();
+ }
+
+ public String getMethodName() {
+ return methodName;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/stress/gcbasher/MethodInfo.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ *
+ */
+
+class MethodInfo {
+ private String name;
+ private String descriptor;
+ private int codeLength;
+ private int codeStart;
+
+ public MethodInfo(String name, String descriptor, int codeLength, int codeStart) {
+ this.name = name;
+ this.descriptor = descriptor;
+ this.codeLength = codeLength;
+ this.codeStart = codeStart;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getDescriptor() {
+ return descriptor;
+ }
+
+ public int getCodeLength() {
+ return codeLength;
+ }
+
+ public int getCodeStart() {
+ return codeStart;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/stress/gcbasher/TestGCBasher.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,62 @@
+/*
+ * 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.io.IOException;
+import java.net.URI;
+import java.nio.file.FileSystems;
+import java.nio.file.FileSystem;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.HashMap;
+import java.util.stream.Stream;
+
+public class TestGCBasher {
+ private static void parseClassFiles() throws IOException {
+ HashMap<String, ClassInfo> deps = new HashMap<>();
+
+ FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/"));
+ Stream<Path> s = Files.walk(fs.getPath("/"));
+ for (Path p : (Iterable<Path>)s::iterator) {
+ if (p.toString().endsWith(".class")) {
+ byte[] data = Files.readAllBytes(p);
+ Decompiler d = new Decompiler(data);
+ ClassInfo ci = d.getClassInfo();
+ deps.put(ci.getName(), ci);
+ }
+ }
+ }
+
+ public static void run(String[] args) throws IOException {
+ if (args.length != 1) {
+ System.err.println("Usage: TestGCBasher <duration-ms>");
+ return;
+ }
+
+ long durationMillis = Long.valueOf(args[0]);
+ long start = System.currentTimeMillis();
+ while (System.currentTimeMillis() - start < durationMillis) {
+ parseClassFiles();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/stress/gcbasher/TestGCBasherWithCMS.java Wed Oct 26 20:13:29 2016 +0000
@@ -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.
+ *
+ */
+
+import java.io.IOException;
+
+/*
+ * @test TestGCBasherWithCMS
+ * @key gc
+ * @key stress
+ * @requires vm.gc.ConcMarkSweep
+ * @requires vm.flavor == "server"
+ * @summary Stress the CMS GC by trying to make old objects more likely to be garbage than young objects.
+ * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx128m -server -XX:+UseConcMarkSweepGC TestGCBasherWithCMS 120000
+ */
+public class TestGCBasherWithCMS {
+ public static void main(String[] args) throws IOException {
+ TestGCBasher.run(args);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/stress/gcbasher/TestGCBasherWithG1.java Wed Oct 26 20:13:29 2016 +0000
@@ -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.
+ *
+ */
+
+import java.io.IOException;
+
+/*
+ * @test TestGCBasherWithG1
+ * @key gc
+ * @key stress
+ * @requires vm.gc.G1
+ * @requires vm.flavor == "server"
+ * @summary Stress the G1 GC by trying to make old objects more likely to be garbage than young objects.
+ * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx128m -server -XX:+UseG1GC TestGCBasherWithG1 120000
+ */
+public class TestGCBasherWithG1 {
+ public static void main(String[] args) throws IOException {
+ TestGCBasher.run(args);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/stress/gcbasher/TestGCBasherWithParallel.java Wed Oct 26 20:13:29 2016 +0000
@@ -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.
+ *
+ */
+
+import java.io.IOException;
+
+/*
+ * @test TestGCBasherWithParallel
+ * @key gc
+ * @key stress
+ * @requires vm.gc.Parallel
+ * @requires vm.flavor == "server"
+ * @summary Stress the Parallel GC by trying to make old objects more likely to be garbage than young objects.
+ * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx256m -server -XX:+UseParallelGC -XX:-UseGCOverheadLimit TestGCBasherWithParallel 120000
+ */
+public class TestGCBasherWithParallel {
+ public static void main(String[] args) throws IOException {
+ TestGCBasher.run(args);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/stress/gcbasher/TestGCBasherWithSerial.java Wed Oct 26 20:13:29 2016 +0000
@@ -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.
+ *
+ */
+
+import java.io.IOException;
+
+/*
+ * @test TestGCBasherWithSerial
+ * @key gc
+ * @key stress
+ * @requires vm.gc.Serial
+ * @requires vm.flavor == "server"
+ * @summary Stress the Serial GC by trying to make old objects more likely to be garbage than young objects.
+ * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx128m -server -XX:+UseSerialGC TestGCBasherWithSerial 120000
+ */
+public class TestGCBasherWithSerial {
+ public static void main(String[] args) throws IOException {
+ TestGCBasher.run(args);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/native/code/test_dependencyContext.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,97 @@
+/*
+ * 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "code/dependencyContext.hpp"
+#include "unittest.hpp"
+
+class TestDependencyContext {
+ public:
+ nmethod* _nmethods[3];
+
+ intptr_t _dependency_context;
+
+ DependencyContext dependencies() {
+ DependencyContext depContext(&_dependency_context);
+ return depContext;
+ }
+
+ TestDependencyContext() : _dependency_context(DependencyContext::EMPTY) {
+ CodeCache_lock->lock_without_safepoint_check();
+
+ _nmethods[0] = reinterpret_cast<nmethod*>(0x8 * 0);
+ _nmethods[1] = reinterpret_cast<nmethod*>(0x8 * 1);
+ _nmethods[2] = reinterpret_cast<nmethod*>(0x8 * 2);
+
+ dependencies().add_dependent_nmethod(_nmethods[2]);
+ dependencies().add_dependent_nmethod(_nmethods[1]);
+ dependencies().add_dependent_nmethod(_nmethods[0]);
+ }
+
+ ~TestDependencyContext() {
+ dependencies().wipe();
+ CodeCache_lock->unlock();
+ }
+
+ static bool has_stale_entries(DependencyContext ctx) {
+ return ctx.has_stale_entries();
+ }
+
+#ifndef PRODUCT
+ static bool find_stale_entries(DependencyContext ctx) {
+ return ctx.find_stale_entries();
+ }
+#endif
+};
+
+static void test_remove_dependent_nmethod(int id, bool delete_immediately) {
+ TestDependencyContext c;
+ DependencyContext depContext = c.dependencies();
+ NOT_PRODUCT(ASSERT_FALSE(TestDependencyContext::find_stale_entries(depContext)));
+ ASSERT_FALSE(TestDependencyContext::has_stale_entries(depContext));
+
+ nmethod* nm = c._nmethods[id];
+ depContext.remove_dependent_nmethod(nm, delete_immediately);
+
+ if (!delete_immediately) {
+ NOT_PRODUCT(ASSERT_TRUE(TestDependencyContext::find_stale_entries(depContext)));
+ ASSERT_TRUE(TestDependencyContext::has_stale_entries(depContext));
+ NOT_PRODUCT(ASSERT_TRUE(depContext.is_dependent_nmethod(nm)));
+ depContext.expunge_stale_entries();
+ }
+
+ NOT_PRODUCT(ASSERT_FALSE(TestDependencyContext::find_stale_entries(depContext)));
+ ASSERT_FALSE(TestDependencyContext::has_stale_entries(depContext));
+ NOT_PRODUCT(ASSERT_FALSE(depContext.is_dependent_nmethod(nm)));
+}
+
+TEST(code, dependency_context) {
+ test_remove_dependent_nmethod(0, false);
+ test_remove_dependent_nmethod(1, false);
+ test_remove_dependent_nmethod(2, false);
+
+ test_remove_dependent_nmethod(0, true);
+ test_remove_dependent_nmethod(1, true);
+ test_remove_dependent_nmethod(2, true);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/native/gc/g1/test_freeRegionList.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2011, 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.
+ */
+
+#include "precompiled.hpp"
+#include "gc/g1/g1CollectedHeap.inline.hpp"
+#include "unittest.hpp"
+
+// @requires UseG1GC
+TEST_VM(FreeRegionList, length) {
+ if (!UseG1GC) {
+ return;
+ }
+
+ FreeRegionList l("test");
+ const uint num_regions_in_test = 5;
+
+ // Create a fake heap. It does not need to be valid, as the HeapRegion constructor
+ // does not access it.
+ MemRegion heap(NULL, num_regions_in_test * HeapRegion::GrainWords);
+
+ // Allocate a fake BOT because the HeapRegion constructor initializes
+ // the BOT.
+ size_t bot_size = G1BlockOffsetTable::compute_size(heap.word_size());
+ HeapWord* bot_data = NEW_C_HEAP_ARRAY(HeapWord, bot_size, mtGC);
+ ReservedSpace bot_rs(G1BlockOffsetTable::compute_size(heap.word_size()));
+ G1RegionToSpaceMapper* bot_storage =
+ G1RegionToSpaceMapper::create_mapper(bot_rs,
+ bot_rs.size(),
+ os::vm_page_size(),
+ HeapRegion::GrainBytes,
+ BOTConstants::N_bytes,
+ mtGC);
+ G1BlockOffsetTable bot(heap, bot_storage);
+ bot_storage->commit_regions(0, num_regions_in_test);
+
+ // Set up memory regions for the heap regions.
+ MemRegion mr0(heap.start(), HeapRegion::GrainWords);
+ MemRegion mr1(mr0.end(), HeapRegion::GrainWords);
+ MemRegion mr2(mr1.end(), HeapRegion::GrainWords);
+ MemRegion mr3(mr2.end(), HeapRegion::GrainWords);
+ MemRegion mr4(mr3.end(), HeapRegion::GrainWords);
+
+ HeapRegion hr0(0, &bot, mr0);
+ HeapRegion hr1(1, &bot, mr1);
+ HeapRegion hr2(2, &bot, mr2);
+ HeapRegion hr3(3, &bot, mr3);
+ HeapRegion hr4(4, &bot, mr4);
+ l.add_ordered(&hr1);
+ l.add_ordered(&hr0);
+ l.add_ordered(&hr3);
+ l.add_ordered(&hr4);
+ l.add_ordered(&hr2);
+
+ EXPECT_EQ(l.length(), num_regions_in_test) << "Wrong free region list length";
+ l.verify_list();
+
+ bot_storage->uncommit_regions(0, num_regions_in_test);
+ delete bot_storage;
+ FREE_C_HEAP_ARRAY(HeapWord, bot_data);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/native/gc/g1/test_g1BiasedArray.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,136 @@
+/*
+ * 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "precompiled.hpp"
+#include "gc/g1/g1BiasedArray.hpp"
+#include "unittest.hpp"
+
+class TestMappedArray : public G1BiasedMappedArray<int> {
+public:
+ virtual int default_value() const {
+ return 0xBAADBABE;
+ }
+ int* my_address_mapped_to(HeapWord* address) {
+ return address_mapped_to(address);
+ }
+};
+
+TEST_VM(G1BiasedArray, simple) {
+ const size_t REGION_SIZE_IN_WORDS = 512;
+ const size_t NUM_REGIONS = 20;
+ // Any value that is non-zero
+ HeapWord* fake_heap =
+ (HeapWord*) LP64_ONLY(0xBAAA00000) NOT_LP64(0xBA000000);
+
+ TestMappedArray array;
+ array.initialize(fake_heap, fake_heap + REGION_SIZE_IN_WORDS * NUM_REGIONS,
+ REGION_SIZE_IN_WORDS * HeapWordSize);
+ const int DEFAULT_VALUE = array.default_value();
+
+ // Check address calculation (bounds)
+ ASSERT_EQ(fake_heap, array.bottom_address_mapped())
+ << "bottom mapped address should be "
+ << p2i(array.bottom_address_mapped())
+ << ", but is "
+ << p2i(fake_heap);
+ ASSERT_EQ(fake_heap + REGION_SIZE_IN_WORDS * NUM_REGIONS,
+ array.end_address_mapped());
+
+ int* bottom = array.my_address_mapped_to(fake_heap);
+ ASSERT_EQ((void*) bottom, (void*) array.base());
+ int* end = array.my_address_mapped_to(fake_heap +
+ REGION_SIZE_IN_WORDS * NUM_REGIONS);
+ ASSERT_EQ((void*) end, (void*) (array.base() + array.length()));
+ // The entire array should contain default value elements
+ for (int* current = bottom; current < end; current++) {
+ ASSERT_EQ(DEFAULT_VALUE, *current);
+ }
+
+ // Test setting values in the table
+ HeapWord* region_start_address =
+ fake_heap + REGION_SIZE_IN_WORDS * (NUM_REGIONS / 2);
+ HeapWord* region_end_address =
+ fake_heap + (REGION_SIZE_IN_WORDS * (NUM_REGIONS / 2) +
+ REGION_SIZE_IN_WORDS - 1);
+
+ // Set/get by address tests: invert some value; first retrieve one
+ int actual_value = array.get_by_index(NUM_REGIONS / 2);
+ array.set_by_index(NUM_REGIONS / 2, ~actual_value);
+ // Get the same value by address, should correspond to the start of the "region"
+ int value = array.get_by_address(region_start_address);
+ ASSERT_EQ(value, ~actual_value);
+ // Get the same value by address, at one HeapWord before the start
+ value = array.get_by_address(region_start_address - 1);
+ ASSERT_EQ(DEFAULT_VALUE, value);
+ // Get the same value by address, at the end of the "region"
+ value = array.get_by_address(region_end_address);
+ ASSERT_EQ(value, ~actual_value);
+ // Make sure the next value maps to another index
+ value = array.get_by_address(region_end_address + 1);
+ ASSERT_EQ(DEFAULT_VALUE, value);
+
+ // Reset the value in the array
+ array.set_by_address(region_start_address +
+ (region_end_address - region_start_address) / 2,
+ actual_value);
+
+ // The entire array should have the default value again
+ for (int* current = bottom; current < end; current++) {
+ ASSERT_EQ(DEFAULT_VALUE, *current);
+ }
+
+ // Set/get by index tests: invert some value
+ size_t index = NUM_REGIONS / 2;
+ actual_value = array.get_by_index(index);
+ array.set_by_index(index, ~actual_value);
+
+ value = array.get_by_index(index);
+ ASSERT_EQ(~actual_value, value);
+
+ value = array.get_by_index(index - 1);
+ ASSERT_EQ(DEFAULT_VALUE, value);
+
+ value = array.get_by_index(index + 1);
+ ASSERT_EQ(DEFAULT_VALUE, value);
+
+ array.set_by_index(0, 0);
+ value = array.get_by_index(0);
+ ASSERT_EQ(0, value);
+
+ array.set_by_index(array.length() - 1, 0);
+ value = array.get_by_index(array.length() - 1);
+ ASSERT_EQ(0, value);
+
+ array.set_by_index(index, 0);
+
+ // The array should have three zeros, and default values otherwise
+ size_t num_zeros = 0;
+ for (int* current = bottom; current < end; current++) {
+ ASSERT_TRUE(*current == DEFAULT_VALUE || *current == 0);
+ if (*current == 0) {
+ num_zeros++;
+ }
+ }
+ ASSERT_EQ((size_t) 3, num_zeros);
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/native/gc/g1/test_workerDataArray.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,282 @@
+/*
+ * 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.
+ */
+
+#include "precompiled.hpp"
+#include "gc/g1/workerDataArray.inline.hpp"
+#include "memory/resourceArea.hpp"
+#include "unittest.hpp"
+#include "utilities/ostream.hpp"
+
+static const double epsilon = 0.0001;
+
+template<typename T>
+class WorkerDataArrayTest : public ::testing::Test {
+ protected:
+ WorkerDataArrayTest() :
+ title("Test array"),
+ array(3, title) {
+ }
+
+ const char* print_summary() {
+ stringStream out;
+ array.print_summary_on(&out);
+ return out.as_string();
+ }
+
+ const char* print_details() {
+ stringStream out;
+ array.print_details_on(&out);
+ return out.as_string();
+ }
+
+ const char* print_expected_summary() {
+ return prepend_with(title, expected_summary());
+ }
+
+ const char* print_expected_details() {
+ return prepend_with("", expected_details());
+ }
+
+ // returns expected summary for array without uninitialized elements
+ // used it because string representation of double depends on locale
+ static const char* format_summary(
+ T min, double avg, T max, T diff, T sum, size_t workers);
+
+ const char* title;
+ WorkerDataArray<T> array;
+
+ private:
+ virtual const char* expected_summary() = 0;
+ virtual const char* expected_details() = 0;
+
+ static const char* prepend_with(const char* str, const char* orig) {
+ stringStream out;
+ out.print("%-25s", str);
+ out.print("%s", orig);
+ return out.as_string();
+ }
+
+ ResourceMark rm;
+};
+
+template<>
+const char* WorkerDataArrayTest<size_t>::format_summary(
+ size_t min, double avg, size_t max, size_t diff, size_t sum, size_t workers) {
+
+ stringStream out;
+ out.print(" Min: " SIZE_FORMAT
+ ", Avg: %4.1lf, Max: " SIZE_FORMAT
+ ", Diff: " SIZE_FORMAT ", Sum: " SIZE_FORMAT
+ ", Workers: " SIZE_FORMAT "\n",
+ min, avg, max, diff, sum, workers);
+ return out.as_string();
+}
+
+template<>
+const char* WorkerDataArrayTest<double>::format_summary(
+ double min, double avg, double max, double diff, double sum, size_t workers) {
+
+ stringStream out;
+ out.print(" Min: %4.1lf"
+ ", Avg: %4.1lf, Max: %4.1lf"
+ ", Diff: %4.1lf, Sum: %4.1lf"
+ ", Workers: " SIZE_FORMAT "\n",
+ min, avg, max, diff, sum, workers);
+ return out.as_string();
+}
+
+class BasicWorkerDataArrayTest : public WorkerDataArrayTest<size_t> {
+ protected:
+ BasicWorkerDataArrayTest() {
+ array.set(0, 5);
+ array.set(1, 3);
+ array.set(2, 7);
+ }
+
+ private:
+ virtual const char* expected_summary() {
+ return format_summary(3, 5.0, 7, 4, 15, 3);
+ }
+
+ virtual const char* expected_details() {
+ return " 5 3 7\n";
+ }
+};
+
+TEST_F(BasicWorkerDataArrayTest, sum_test) {
+ ASSERT_EQ(15u, array.sum());
+}
+
+TEST_F(BasicWorkerDataArrayTest, average_test) {
+ ASSERT_NEAR(5.0, array.average(), epsilon);
+}
+
+TEST_F(BasicWorkerDataArrayTest, print_summary_on_test) {
+ ASSERT_STREQ(print_expected_summary(), print_summary());
+}
+
+TEST_F(BasicWorkerDataArrayTest, print_details_on_test) {
+ ASSERT_STREQ(print_expected_details(), print_details());
+}
+
+class AddWorkerDataArrayTest : public WorkerDataArrayTest<size_t> {
+ protected:
+ AddWorkerDataArrayTest() {
+ array.set(0, 5);
+ array.set(1, 3);
+ array.set(2, 7);
+
+ for (uint i = 0; i < 3; i++) {
+ array.add(i, 1);
+ }
+ }
+
+ private:
+ virtual const char* expected_summary() {
+ return format_summary(4, 6.0, 8, 4, 18, 3);
+ }
+
+ virtual const char* expected_details() {
+ return " 6 4 8\n";
+ }
+};
+
+TEST_F(AddWorkerDataArrayTest, sum_test) {
+ ASSERT_EQ(18u, array.sum());
+}
+
+TEST_F(AddWorkerDataArrayTest, average_test) {
+ ASSERT_NEAR(6.0, array.average(), epsilon);
+}
+
+TEST_F(AddWorkerDataArrayTest, print_summary_on_test) {
+ ASSERT_STREQ(print_expected_summary(), print_summary());
+}
+
+TEST_F(AddWorkerDataArrayTest, print_details_on_test) {
+ ASSERT_STREQ(print_expected_details(), print_details());
+}
+
+class UninitializedElementWorkerDataArrayTest : public WorkerDataArrayTest<size_t> {
+ protected:
+ UninitializedElementWorkerDataArrayTest() {
+ array.set(0, 5);
+ array.set(1, WorkerDataArray<size_t>::uninitialized());
+ array.set(2, 7);
+ }
+
+ private:
+ virtual const char* expected_summary() {
+ return format_summary(5, 6.0, 7, 2, 12, 2);
+ }
+
+ virtual const char* expected_details() {
+ return " 5 - 7\n";
+ }
+};
+
+TEST_F(UninitializedElementWorkerDataArrayTest, sum_test) {
+ ASSERT_EQ(12u, array.sum());
+}
+
+TEST_F(UninitializedElementWorkerDataArrayTest, average_test) {
+ ASSERT_NEAR(6.0, array.average(), epsilon);
+}
+
+TEST_F(UninitializedElementWorkerDataArrayTest, print_summary_on_test) {
+ ASSERT_STREQ(print_expected_summary(), print_summary());
+}
+
+TEST_F(UninitializedElementWorkerDataArrayTest, print_details_on_test) {
+ ASSERT_STREQ(print_expected_details(), print_details());
+}
+
+class UninitializedWorkerDataArrayTest : public WorkerDataArrayTest<size_t> {
+ protected:
+ UninitializedWorkerDataArrayTest() {
+ array.set(0, WorkerDataArray<size_t>::uninitialized());
+ array.set(1, WorkerDataArray<size_t>::uninitialized());
+ array.set(2, WorkerDataArray<size_t>::uninitialized());
+ }
+
+ private:
+ virtual const char* expected_summary() {
+ return " skipped\n";
+ }
+
+ virtual const char* expected_details() {
+ return " - - -\n";
+ }
+};
+
+TEST_F(UninitializedWorkerDataArrayTest, sum_test) {
+ ASSERT_EQ(0u, array.sum());
+}
+
+TEST_F(UninitializedWorkerDataArrayTest, average_test) {
+ ASSERT_NEAR(0.0, array.average(), epsilon);
+}
+
+TEST_F(UninitializedWorkerDataArrayTest, print_summary_on_test) {
+ ASSERT_STREQ(print_expected_summary(), print_summary());
+}
+
+TEST_F(UninitializedWorkerDataArrayTest, print_details_on_test) {
+ ASSERT_STREQ(print_expected_details(), print_details());
+}
+
+class UninitializedDoubleElementWorkerDataArrayTest : public WorkerDataArrayTest<double> {
+ protected:
+ UninitializedDoubleElementWorkerDataArrayTest() {
+ array.set(0, 5.1 / MILLIUNITS);
+ array.set(1, WorkerDataArray<double>::uninitialized());
+ array.set(2, 7.2 / MILLIUNITS);
+ }
+
+ private:
+ virtual const char* expected_summary() {
+ return format_summary(5.1, 6.1, 7.2, 2.1, 12.3, 2);
+ }
+
+ virtual const char* expected_details() {
+ stringStream out;
+ out.print(" %4.1lf - %4.1lf\n", 5.1, 7.2);
+ return out.as_string();
+ }
+};
+
+TEST_F(UninitializedDoubleElementWorkerDataArrayTest, sum_test) {
+ ASSERT_NEAR(12.3 / MILLIUNITS, array.sum(), epsilon);
+}
+
+TEST_F(UninitializedDoubleElementWorkerDataArrayTest, average_test) {
+ ASSERT_NEAR(6.15 / MILLIUNITS, array.average(), epsilon);
+}
+
+TEST_F(UninitializedDoubleElementWorkerDataArrayTest, print_summary_on_test) {
+ ASSERT_STREQ(print_expected_summary(), print_summary());
+}
+
+TEST_F(UninitializedDoubleElementWorkerDataArrayTest, print_details_on_test) {
+ ASSERT_STREQ(print_expected_details(), print_details());
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/native/gc/shared/test_collectorPolicy.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,282 @@
+/*
+ * 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.
+ */
+
+#include "precompiled.hpp"
+#include "gc/shared/collectorPolicy.hpp"
+#include "unittest.hpp"
+#include "utilities/macros.hpp"
+
+class TestGenCollectorPolicy {
+ public:
+
+ class Executor {
+ public:
+ virtual void execute() = 0;
+ };
+
+ class UnaryExecutor : public Executor {
+ protected:
+ const size_t param;
+ public:
+ UnaryExecutor(size_t val) : param(val) { }
+ };
+
+ class BinaryExecutor : public Executor {
+ protected:
+ const size_t param1;
+ const size_t param2;
+ public:
+ BinaryExecutor(size_t val1, size_t val2) : param1(val1), param2(val2) { }
+ };
+
+ class MinHeapSizeGuard {
+ private:
+ const size_t _stored_min_heap_size;
+ public:
+ MinHeapSizeGuard() : _stored_min_heap_size(Arguments::min_heap_size()) { }
+ ~MinHeapSizeGuard() {
+ Arguments::set_min_heap_size(_stored_min_heap_size);
+ }
+ };
+
+ class TestWrapper {
+ public:
+ static void test(Executor* setter1, Executor* setter2, Executor* checker) {
+ FLAG_GUARD(InitialHeapSize);
+ FLAG_GUARD(MaxHeapSize);
+ FLAG_GUARD(MaxNewSize);
+ FLAG_GUARD(MinHeapDeltaBytes);
+ FLAG_GUARD(NewSize);
+ FLAG_GUARD(OldSize);
+ MinHeapSizeGuard min_heap_size_guard;
+
+ FLAG_SET_ERGO(size_t, InitialHeapSize, 100 * M);
+ FLAG_SET_ERGO(size_t, OldSize, 4 * M);
+ FLAG_SET_ERGO(size_t, NewSize, 1 * M);
+ FLAG_SET_ERGO(size_t, MaxNewSize, 80 * M);
+ Arguments::set_min_heap_size(40 * M);
+
+ ASSERT_NO_FATAL_FAILURE(setter1->execute());
+
+ if (setter2 != NULL) {
+ ASSERT_NO_FATAL_FAILURE(setter2->execute());
+ }
+
+ ASSERT_NO_FATAL_FAILURE(checker->execute());
+ }
+ static void test(Executor* setter, Executor* checker) {
+ test(setter, NULL, checker);
+ }
+ };
+
+ class SetNewSizeErgo : public UnaryExecutor {
+ public:
+ SetNewSizeErgo(size_t param) : UnaryExecutor(param) { }
+ void execute() {
+ FLAG_SET_ERGO(size_t, NewSize, param);
+ }
+ };
+
+ class CheckYoungMin : public UnaryExecutor {
+ public:
+ CheckYoungMin(size_t param) : UnaryExecutor(param) { }
+ void execute() {
+ MarkSweepPolicy msp;
+ msp.initialize_all();
+ ASSERT_LE(msp.min_young_size(), param);
+ }
+ };
+
+ class CheckScaledYoungInitial : public Executor {
+ public:
+ void execute() {
+ size_t initial_heap_size = InitialHeapSize;
+ MarkSweepPolicy msp;
+ msp.initialize_all();
+
+ if (InitialHeapSize > initial_heap_size) {
+ // InitialHeapSize was adapted by msp.initialize_all, e.g. due to alignment
+ // caused by 64K page size.
+ initial_heap_size = InitialHeapSize;
+ }
+
+ size_t expected = msp.scale_by_NewRatio_aligned(initial_heap_size);
+ ASSERT_EQ(expected, msp.initial_young_size());
+ ASSERT_EQ(expected, NewSize);
+ }
+ };
+
+ class SetNewSizeCmd : public UnaryExecutor {
+ public:
+ SetNewSizeCmd(size_t param) : UnaryExecutor(param) { }
+ void execute() {
+ FLAG_SET_CMDLINE(size_t, NewSize, param);
+ }
+ };
+
+ class CheckYoungInitial : public UnaryExecutor {
+ public:
+ CheckYoungInitial(size_t param) : UnaryExecutor(param) { }
+ void execute() {
+ MarkSweepPolicy msp;
+ msp.initialize_all();
+
+ ASSERT_EQ(param, msp.initial_young_size());
+ }
+ };
+
+ class SetOldSizeCmd : public UnaryExecutor {
+ public:
+ SetOldSizeCmd(size_t param) : UnaryExecutor(param) { }
+ void execute() {
+ FLAG_SET_CMDLINE(size_t, OldSize, param);
+ }
+ };
+
+ class SetMaxNewSizeCmd : public BinaryExecutor {
+ public:
+ SetMaxNewSizeCmd(size_t param1, size_t param2) : BinaryExecutor(param1, param2) { }
+ void execute() {
+ size_t heap_alignment = CollectorPolicy::compute_heap_alignment();
+ size_t new_size_value = align_size_up(MaxHeapSize, heap_alignment)
+ - param1 + param2;
+ FLAG_SET_CMDLINE(size_t, MaxNewSize, new_size_value);
+ }
+ };
+
+ class CheckOldMin : public UnaryExecutor {
+ public:
+ CheckOldMin(size_t param) : UnaryExecutor(param) { }
+ void execute() {
+ MarkSweepPolicy msp;
+ msp.initialize_all();
+ ASSERT_LE(msp.min_old_size(), param);
+ }
+ };
+
+ class CheckOldInitial : public Executor {
+ public:
+ void execute() {
+ size_t heap_alignment = CollectorPolicy::compute_heap_alignment();
+
+ MarkSweepPolicy msp;
+ msp.initialize_all();
+
+ size_t expected_old_initial = align_size_up(InitialHeapSize, heap_alignment)
+ - MaxNewSize;
+
+ ASSERT_EQ(expected_old_initial, msp.initial_old_size());
+ }
+ };
+
+ class CheckOldInitialMaxNewSize : public BinaryExecutor {
+ public:
+ CheckOldInitialMaxNewSize(size_t param1, size_t param2) : BinaryExecutor(param1, param2) { }
+ void execute() {
+ size_t heap_alignment = CollectorPolicy::compute_heap_alignment();
+ size_t new_size_value = align_size_up(MaxHeapSize, heap_alignment)
+ - param1 + param2;
+
+ MarkSweepPolicy msp;
+ msp.initialize_all();
+
+ size_t expected_old_initial = align_size_up(MaxHeapSize, heap_alignment)
+ - new_size_value;
+
+ ASSERT_EQ(expected_old_initial, msp.initial_old_size());
+ }
+ };
+};
+
+
+// Testing that the NewSize flag is handled correct is hard because it
+// depends on so many other configurable variables. These tests only try to
+// verify that there are some basic rules for NewSize honored by the policies.
+
+// If NewSize has been ergonomically set, the collector policy
+// should use it for min
+TEST_VM(CollectorPolicy, young_min_ergo) {
+ TestGenCollectorPolicy::SetNewSizeErgo setter(20 * M);
+ TestGenCollectorPolicy::CheckYoungMin checker(20 * M);
+
+ TestGenCollectorPolicy::TestWrapper::test(&setter, &checker);
+}
+
+// If NewSize has been ergonomically set, the collector policy
+// should use it for min but calculate the initial young size
+// using NewRatio.
+TEST_VM(CollectorPolicy, young_scaled_initial_ergo) {
+ TestGenCollectorPolicy::SetNewSizeErgo setter(20 * M);
+ TestGenCollectorPolicy::CheckScaledYoungInitial checker;
+
+ TestGenCollectorPolicy::TestWrapper::test(&setter, &checker);
+}
+
+
+// Since a flag has been set with FLAG_SET_CMDLINE it
+// will be treated as it have been set on the command line for
+// the rest of the VM lifetime. This is an irreversible change and
+// could impact other tests so we use TEST_OTHER_VM
+TEST_OTHER_VM(CollectorPolicy, young_cmd) {
+ // If NewSize is set on the command line, it should be used
+ // for both min and initial young size if less than min heap.
+ TestGenCollectorPolicy::SetNewSizeCmd setter(20 * M);
+
+ TestGenCollectorPolicy::CheckYoungMin checker_min(20 * M);
+ TestGenCollectorPolicy::TestWrapper::test(&setter, &checker_min);
+
+ TestGenCollectorPolicy::CheckYoungInitial checker_initial(20 * M);
+ TestGenCollectorPolicy::TestWrapper::test(&setter, &checker_initial);
+
+ // If NewSize is set on command line, but is larger than the min
+ // heap size, it should only be used for initial young size.
+ TestGenCollectorPolicy::SetNewSizeCmd setter_large(80 * M);
+ TestGenCollectorPolicy::CheckYoungInitial checker_large(80 * M);
+ TestGenCollectorPolicy::TestWrapper::test(&setter_large, &checker_large);
+}
+
+// Since a flag has been set with FLAG_SET_CMDLINE it
+// will be treated as it have been set on the command line for
+// the rest of the VM lifetime. This is an irreversible change and
+// could impact other tests so we use TEST_OTHER_VM
+TEST_OTHER_VM(CollectorPolicy, old_cmd) {
+ // If OldSize is set on the command line, it should be used
+ // for both min and initial old size if less than min heap.
+ TestGenCollectorPolicy::SetOldSizeCmd setter(20 * M);
+
+ TestGenCollectorPolicy::CheckOldMin checker_min(20 * M);
+ TestGenCollectorPolicy::TestWrapper::test(&setter, &checker_min);
+
+ TestGenCollectorPolicy::CheckOldInitial checker_initial;
+ TestGenCollectorPolicy::TestWrapper::test(&setter, &checker_initial);
+
+ // If MaxNewSize is large, the maximum OldSize will be less than
+ // what's requested on the command line and it should be reset
+ // ergonomically.
+ // We intentionally set MaxNewSize + OldSize > MaxHeapSize
+ TestGenCollectorPolicy::SetOldSizeCmd setter_old_size(30 * M);
+ TestGenCollectorPolicy::SetMaxNewSizeCmd setter_max_new_size(30 * M, 20 * M);
+ TestGenCollectorPolicy::CheckOldInitialMaxNewSize checker_large(30 * M, 20 * M);
+
+ TestGenCollectorPolicy::TestWrapper::test(&setter_old_size, &setter_max_new_size, &checker_large);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/native/memory/test_guardedMemory.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,148 @@
+/*
+ * 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.
+ */
+
+#include "precompiled.hpp"
+#include "memory/allocation.hpp"
+#include "memory/allocation.inline.hpp"
+#include "memory/guardedMemory.hpp"
+#include "runtime/os.hpp"
+#include "unittest.hpp"
+
+static void guarded_memory_test_check(void* p, size_t sz, void* tag) {
+ ASSERT_TRUE(p != NULL) << "NULL pointer given to check";
+ u_char* c = (u_char*) p;
+ GuardedMemory guarded(c);
+ EXPECT_EQ(guarded.get_tag(), tag) << "Tag is not the same as supplied";
+ EXPECT_EQ(guarded.get_user_ptr(), c) << "User pointer is not the same as supplied";
+ EXPECT_EQ(guarded.get_user_size(), sz) << "User size is not the same as supplied";
+ EXPECT_TRUE(guarded.verify_guards()) << "Guard broken";
+}
+
+class GuardedMemoryTest {
+ public:
+ static size_t get_guard_header_size() {
+ return sizeof (GuardedMemory::GuardHeader);
+ }
+ static size_t get_guard_size() {
+ return sizeof (GuardedMemory::Guard);
+ }
+};
+
+// Test GuardedMemory size
+TEST(GuardedMemory, size) {
+ size_t total_sz = GuardedMemory::get_total_size(1);
+ ASSERT_GT(total_sz, (size_t) 1) << "Unexpected size";
+ ASSERT_GE(total_sz, GuardedMemoryTest::get_guard_header_size() + 1
+ + GuardedMemoryTest::get_guard_size()) << "Unexpected size";
+}
+
+// Test the basic characteristics
+TEST(GuardedMemory, basic) {
+ u_char* basep =
+ (u_char*) os::malloc(GuardedMemory::get_total_size(1), mtInternal);
+ GuardedMemory guarded(basep, 1, (void*) 0xf000f000);
+
+ EXPECT_EQ(badResourceValue, *basep)
+ << "Expected guard in the form of badResourceValue";
+
+ u_char* userp = guarded.get_user_ptr();
+ EXPECT_EQ(uninitBlockPad, *userp)
+ << "Expected uninitialized data in the form of uninitBlockPad";
+ guarded_memory_test_check(userp, 1, (void*) 0xf000f000);
+
+ void* freep = guarded.release_for_freeing();
+ EXPECT_EQ((u_char*) freep, basep) << "Expected the same pointer guard was ";
+ EXPECT_EQ(freeBlockPad, *userp) << "Expected user data to be free block padded";
+ EXPECT_FALSE(guarded.verify_guards());
+ os::free(freep);
+}
+
+// Test a number of odd sizes
+TEST(GuardedMemory, odd_sizes) {
+ u_char* basep =
+ (u_char*) os::malloc(GuardedMemory::get_total_size(1), mtInternal);
+ GuardedMemory guarded(basep, 1, (void*) 0xf000f000);
+
+ size_t sz = 0;
+ do {
+ void* p = os::malloc(GuardedMemory::get_total_size(sz), mtInternal);
+ void* up = guarded.wrap_with_guards(p, sz, (void*) 1);
+ memset(up, 0, sz);
+ guarded_memory_test_check(up, sz, (void*) 1);
+ if (HasFatalFailure()) {
+ return;
+ }
+
+ os::free(guarded.release_for_freeing());
+ sz = (sz << 4) + 1;
+ } while (sz < (256 * 1024));
+}
+
+// Test buffer overrun into head...
+TEST(GuardedMemory, buffer_overrun_head) {
+ u_char* basep =
+ (u_char*) os::malloc(GuardedMemory::get_total_size(1), mtInternal);
+ GuardedMemory guarded(basep, 1, (void*) 0xf000f000);
+
+ guarded.wrap_with_guards(basep, 1);
+ *basep = 0;
+ EXPECT_FALSE(guarded.verify_guards());
+ os::free(basep);
+}
+
+// Test buffer overrun into tail with a number of odd sizes
+TEST(GuardedMemory, buffer_overrun_tail) {
+ u_char* basep =
+ (u_char*) os::malloc(GuardedMemory::get_total_size(1), mtInternal);
+ GuardedMemory guarded(basep, 1, (void*) 0xf000f000);
+
+ size_t sz = 1;
+ do {
+ void* p = os::malloc(GuardedMemory::get_total_size(sz), mtInternal);
+ void* up = guarded.wrap_with_guards(p, sz, (void*) 1);
+ memset(up, 0, sz + 1); // Buffer-overwrite (within guard)
+ EXPECT_FALSE(guarded.verify_guards()) << "Guard was not broken as expected";
+ os::free(guarded.release_for_freeing());
+ sz = (sz << 4) + 1;
+ } while (sz < (256 * 1024));
+}
+
+// Test wrap_copy/wrap_free
+TEST(GuardedMemory, wrap) {
+ EXPECT_TRUE(GuardedMemory::free_copy(NULL)) << "Expected free NULL to be OK";
+
+ const char* str = "Check my bounds out";
+ size_t str_sz = strlen(str) + 1;
+ char* str_copy = (char*) GuardedMemory::wrap_copy(str, str_sz);
+ guarded_memory_test_check(str_copy, str_sz, NULL);
+ if (HasFatalFailure()) {
+ return;
+ }
+ EXPECT_EQ(0, strcmp(str, str_copy)) << "Not identical copy";
+ EXPECT_TRUE(GuardedMemory::free_copy(str_copy)) << "Free copy failed to verify";
+
+ void* no_data = NULL;
+ void* no_data_copy = GuardedMemory::wrap_copy(no_data, 0);
+ EXPECT_TRUE(GuardedMemory::free_copy(no_data_copy))
+ << "Expected valid guards even for no data copy";
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/native/memory/test_metachunk.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,90 @@
+/*
+ * 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.
+ */
+
+#include "precompiled.hpp"
+#include "memory/allocation.hpp"
+#include "memory/metachunk.hpp"
+#include "unittest.hpp"
+#include "utilities/copy.hpp"
+#include "utilities/debug.hpp"
+
+class MetachunkTest {
+ public:
+ static MetaWord* initial_top(Metachunk* metachunk) {
+ return metachunk->initial_top();
+ }
+ static MetaWord* top(Metachunk* metachunk) {
+ return metachunk->top();
+ }
+
+};
+
+TEST(Metachunk, basic) {
+ size_t size = 2 * 1024 * 1024;
+ void* memory = malloc(size);
+ ASSERT_TRUE(NULL != memory) << "Failed to malloc 2MB";
+
+ Metachunk* metachunk = ::new (memory) Metachunk(size / BytesPerWord, NULL);
+
+ EXPECT_EQ((MetaWord*) metachunk, metachunk->bottom());
+ EXPECT_EQ((uintptr_t*) metachunk + metachunk->size(), metachunk->end());
+
+ // Check sizes
+ EXPECT_EQ(metachunk->size(), metachunk->word_size());
+ EXPECT_EQ(pointer_delta(metachunk->end(), metachunk->bottom(),
+ sizeof (MetaWord*)),
+ metachunk->word_size());
+
+ // Check usage
+ EXPECT_EQ(metachunk->used_word_size(), metachunk->overhead());
+ EXPECT_EQ(metachunk->word_size() - metachunk->used_word_size(),
+ metachunk->free_word_size());
+ EXPECT_EQ(MetachunkTest::top(metachunk), MetachunkTest::initial_top(metachunk));
+ EXPECT_TRUE(metachunk->is_empty());
+
+ // Allocate
+ size_t alloc_size = 64; // Words
+ EXPECT_TRUE(is_size_aligned(alloc_size, Metachunk::object_alignment()));
+
+ MetaWord* mem = metachunk->allocate(alloc_size);
+
+ // Check post alloc
+ EXPECT_EQ(MetachunkTest::initial_top(metachunk), mem);
+ EXPECT_EQ(MetachunkTest::top(metachunk), mem + alloc_size);
+ EXPECT_EQ(metachunk->overhead() + alloc_size, metachunk->used_word_size());
+ EXPECT_EQ(metachunk->word_size() - metachunk->used_word_size(),
+ metachunk->free_word_size());
+ EXPECT_FALSE(metachunk->is_empty());
+
+ // Clear chunk
+ metachunk->reset_empty();
+
+ // Check post clear
+ EXPECT_EQ(metachunk->used_word_size(), metachunk->overhead());
+ EXPECT_EQ(metachunk->word_size() - metachunk->used_word_size(),
+ metachunk->free_word_size());
+ EXPECT_EQ(MetachunkTest::top(metachunk), MetachunkTest::initial_top(metachunk));
+ EXPECT_TRUE(metachunk->is_empty());
+
+ free(memory);
+}
--- a/hotspot/test/native/runtime/test_os.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/test/native/runtime/test_os.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -25,6 +25,15 @@
#include "runtime/os.hpp"
#include "unittest.hpp"
+static size_t small_page_size() {
+ return os::vm_page_size();
+}
+
+static size_t large_page_size() {
+ const size_t large_page_size_example = 4 * M;
+ return os::page_size_for_region_aligned(large_page_size_example, 1);
+}
+
TEST_VM(os, page_size_for_region) {
size_t large_page_example = 4 * M;
size_t large_page = os::page_size_for_region_aligned(large_page_example, 1);
@@ -37,6 +46,68 @@
}
}
+TEST_VM(os, page_size_for_region_aligned) {
+ if (UseLargePages) {
+ const size_t small_page = small_page_size();
+ const size_t large_page = large_page_size();
+
+ if (large_page > small_page) {
+ size_t num_small_pages_in_large = large_page / small_page;
+ size_t page = os::page_size_for_region_aligned(large_page, num_small_pages_in_large);
+
+ ASSERT_EQ(page, small_page);
+ }
+ }
+}
+
+TEST_VM(os, page_size_for_region_alignment) {
+ if (UseLargePages) {
+ const size_t small_page = small_page_size();
+ const size_t large_page = large_page_size();
+ if (large_page > small_page) {
+ const size_t unaligned_region = large_page + 17;
+ size_t page = os::page_size_for_region_aligned(unaligned_region, 1);
+ ASSERT_EQ(page, small_page);
+
+ const size_t num_pages = 5;
+ const size_t aligned_region = large_page * num_pages;
+ page = os::page_size_for_region_aligned(aligned_region, num_pages);
+ ASSERT_EQ(page, large_page);
+ }
+ }
+}
+
+TEST_VM(os, page_size_for_region_unaligned) {
+ if (UseLargePages) {
+ // Given exact page size, should return that page size.
+ for (size_t i = 0; os::_page_sizes[i] != 0; i++) {
+ size_t expected = os::_page_sizes[i];
+ size_t actual = os::page_size_for_region_unaligned(expected, 1);
+ ASSERT_EQ(expected, actual);
+ }
+
+ // Given slightly larger size than a page size, return the page size.
+ for (size_t i = 0; os::_page_sizes[i] != 0; i++) {
+ size_t expected = os::_page_sizes[i];
+ size_t actual = os::page_size_for_region_unaligned(expected + 17, 1);
+ ASSERT_EQ(expected, actual);
+ }
+
+ // Given a slightly smaller size than a page size,
+ // return the next smaller page size.
+ if (os::_page_sizes[1] > os::_page_sizes[0]) {
+ size_t expected = os::_page_sizes[0];
+ size_t actual = os::page_size_for_region_unaligned(os::_page_sizes[1] - 17, 1);
+ ASSERT_EQ(actual, expected);
+ }
+
+ // Return small page size for values less than a small page.
+ size_t small_page = small_page_size();
+ size_t actual = os::page_size_for_region_unaligned(small_page - 17, 1);
+ ASSERT_EQ(small_page, actual);
+ }
+}
+
#ifdef ASSERT
TEST_VM_ASSERT_MSG(os, page_size_for_region_with_zero_min_pages, "sanity") {
size_t region_size = 16 * os::vm_page_size();
--- a/hotspot/test/native/utilities/test_quicksort.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/test/native/utilities/test_quicksort.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -19,29 +19,186 @@
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
+ *
*/
#include "precompiled.hpp"
-#include "prims/jvm.h"
+#include "memory/allocation.inline.hpp"
+#include "runtime/os.hpp"
#include "utilities/quickSort.hpp"
#include "unittest.hpp"
-static int int_comparator(int a, int b) {
+static int test_comparator(int a, int b) {
if (a == b) {
return 0;
- } else if (a < b) {
+ }
+ if (a < b) {
return -1;
}
+ return 1;
+}
- // a > b
+static bool compare_arrays(int* actual, int* expected, int length) {
+ for (int i = 0; i < length; i++) {
+ if (actual[i] != expected[i]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+template <class C>
+static bool sort_and_compare(int* arrayToSort, int* expectedResult, int length, C comparator, bool idempotent = false) {
+ QuickSort::sort<int, C>(arrayToSort, length, comparator, idempotent);
+ return compare_arrays(arrayToSort, expectedResult, length);
+}
+
+static int test_even_odd_comparator(int a, int b) {
+ bool a_is_odd = ((a % 2) == 1);
+ bool b_is_odd = ((b % 2) == 1);
+ if (a_is_odd == b_is_odd) {
+ return 0;
+ }
+ if (a_is_odd) {
+ return -1;
+ }
return 1;
}
-TEST(utilities, quicksort) {
- int test_array[] = {3,2,1};
- QuickSort::sort(test_array, 3, int_comparator, false);
+extern "C" {
+ static int test_stdlib_comparator(const void* a, const void* b) {
+ int ai = *(int*)a;
+ int bi = *(int*)b;
+ if (ai == bi) {
+ return 0;
+ }
+ if (ai < bi) {
+ return -1;
+ }
+ return 1;
+ }
+}
+
+TEST(QuickSort, quicksort) {
+ {
+ int* test_array = NULL;
+ int* expected_array = NULL;
+ EXPECT_TRUE(sort_and_compare(test_array, expected_array, 0, test_comparator));
+ }
+ {
+ int test_array[] = {3};
+ int expected_array[] = {3};
+ EXPECT_TRUE(sort_and_compare(test_array, expected_array, 1, test_comparator));
+ }
+ {
+ int test_array[] = {3,2};
+ int expected_array[] = {2,3};
+ EXPECT_TRUE(sort_and_compare(test_array, expected_array, 2, test_comparator));
+ }
+ {
+ int test_array[] = {3,2,1};
+ int expected_array[] = {1,2,3};
+ EXPECT_TRUE(sort_and_compare(test_array, expected_array, 3, test_comparator));
+ }
+ {
+ int test_array[] = {4,3,2,1};
+ int expected_array[] = {1,2,3,4};
+ EXPECT_TRUE(sort_and_compare(test_array, expected_array, 4, test_comparator));
+ }
+ {
+ int test_array[] = {7,1,5,3,6,9,8,2,4,0};
+ int expected_array[] = {0,1,2,3,4,5,6,7,8,9};
+ EXPECT_TRUE(sort_and_compare(test_array, expected_array, 10, test_comparator));
+ }
+ {
+ int test_array[] = {4,4,1,4};
+ int expected_array[] = {1,4,4,4};
+ EXPECT_TRUE(sort_and_compare(test_array, expected_array, 4, test_comparator));
+ }
+ {
+ int test_array[] = {0,1,2,3,4,5,6,7,8,9};
+ int expected_array[] = {0,1,2,3,4,5,6,7,8,9};
+ EXPECT_TRUE(sort_and_compare(test_array, expected_array, 10, test_comparator));
+ }
+ {
+ // one of the random arrays that found an issue in the partition method.
+ int test_array[] = {76,46,81,8,64,56,75,11,51,55,11,71,59,27,9,64,69,75,21,25,39,40,44,32,7,8,40,41,24,78,24,74,9,65,28,6,40,31,22,13,27,82};
+ int expected_array[] = {6,7,8,8,9,9,11,11,13,21,22,24,24,25,27,27,28,31,32,39,40,40,40,41,44,46,51,55,56,59,64,64,65,69,71,74,75,75,76,78,81,82};
+ EXPECT_TRUE(sort_and_compare(test_array, expected_array, 42, test_comparator));
+ }
+ {
+ int test_array[] = {2,8,1,4};
+ int expected_array[] = {1,4,2,8};
+ EXPECT_TRUE(sort_and_compare(test_array, expected_array, 4, test_even_odd_comparator));
+ }
+}
- ASSERT_EQ(1, test_array[0]);
- ASSERT_EQ(2, test_array[1]);
- ASSERT_EQ(3, test_array[2]);
+TEST(QuickSort, idempotent) {
+ {
+ // An array of lenght 3 is only sorted by find_pivot. Make sure that it is idempotent.
+ int test_array[] = {1, 4, 8};
+ int expected_array[] = {1, 4, 8};
+ EXPECT_TRUE(sort_and_compare(test_array, expected_array, 3, test_even_odd_comparator, true));
+ }
+ {
+ int test_array[] = {1, 7, 9, 4, 8, 2};
+ int expected_array[] = {1, 7, 9, 4, 8, 2};
+ EXPECT_TRUE(sort_and_compare(test_array, expected_array, 6, test_even_odd_comparator, true));
+ }
+ {
+ int test_array[] = {1, 9, 7, 4, 2, 8};
+ int expected_array[] = {1, 9, 7, 4, 2, 8};
+ EXPECT_TRUE(sort_and_compare(test_array, expected_array, 6, test_even_odd_comparator, true));
+ }
+ {
+ int test_array[] = {7, 9, 1, 2, 8, 4};
+ int expected_array[] = {7, 9, 1, 2, 8, 4};
+ EXPECT_TRUE(sort_and_compare(test_array, expected_array, 6, test_even_odd_comparator, true));
+ }
+ {
+ int test_array[] = {7, 1, 9, 2, 4, 8};
+ int expected_array[] = {7, 1, 9, 2, 4, 8};
+ EXPECT_TRUE(sort_and_compare(test_array, expected_array, 6, test_even_odd_comparator, true));
+ }
+ {
+ int test_array[] = {9, 1, 7, 4, 8, 2};
+ int expected_array[] = {9, 1, 7, 4, 8, 2};
+ EXPECT_TRUE(sort_and_compare(test_array, expected_array, 6, test_even_odd_comparator, true));
+ }
+ {
+ int test_array[] = {9, 7, 1, 4, 2, 8};
+ int expected_array[] = {9, 7, 1, 4, 2, 8};
+ EXPECT_TRUE(sort_and_compare(test_array, expected_array, 6, test_even_odd_comparator, true));
+ }
}
+
+TEST(QuickSort, random) {
+ for (int i = 0; i < 1000; i++) {
+ int length = os::random() % 100;
+ int* test_array = NEW_C_HEAP_ARRAY(int, length, mtInternal);
+ int* expected_array = NEW_C_HEAP_ARRAY(int, length, mtInternal);
+ for (int j = 0; j < length; j++) {
+ // Choose random values, but get a chance of getting duplicates
+ test_array[j] = os::random() % (length * 2);
+ expected_array[j] = test_array[j];
+ }
+
+ // Compare sorting to stdlib::qsort()
+ qsort(expected_array, length, sizeof(int), test_stdlib_comparator);
+ EXPECT_TRUE(sort_and_compare(test_array, expected_array, length, test_comparator));
+
+ // Make sure sorting is idempotent.
+ // Both test_array and expected_array are sorted by the test_comparator.
+ // Now sort them once with the test_even_odd_comparator. Then sort the
+ // test_array one more time with test_even_odd_comparator and verify that
+ // it is idempotent.
+ QuickSort::sort(expected_array, length, test_even_odd_comparator, true);
+ QuickSort::sort(test_array, length, test_even_odd_comparator, true);
+ EXPECT_TRUE(compare_arrays(test_array, expected_array, length));
+ QuickSort::sort(test_array, length, test_even_odd_comparator, true);
+ EXPECT_TRUE(compare_arrays(test_array, expected_array, length));
+
+ FREE_C_HEAP_ARRAY(int, test_array);
+ FREE_C_HEAP_ARRAY(int, expected_array);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/CommandLine/PermGenFlagsTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,51 @@
+/*
+ * 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 8167446
+ * @summary Commandline options PermSize and MaxPermSize should be recognized but ignored.
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ * java.management
+ * @run driver PermGenFlagsTest
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+public class PermGenFlagsTest {
+ public static void main(String[] args) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:PermSize=22k",
+ "-version");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldContain("Ignoring option PermSize; support was removed in 8.0");
+ output.shouldHaveExitValue(0);
+
+ pb = ProcessTools.createJavaProcessBuilder("-XX:MaxPermSize=22k",
+ "-version");
+ output = new OutputAnalyzer(pb.start());
+ output.shouldContain("Ignoring option MaxPermSize; support was removed in 8.0");
+ output.shouldHaveExitValue(0);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/CompactStrings/TestMethodNames.java Wed Oct 26 20:13:29 2016 +0000
@@ -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.
+ */
+
+import javax.script.*;
+import java.util.function.*;
+
+/*
+ * @test
+ * @bug 8164612
+ * @summary Test method names containing Latin-1 supplement characters.
+ * @run main/othervm -XX:+CompactStrings TestMethodNames
+ * @run main/othervm -XX:-CompactStrings TestMethodNames
+ */
+public class TestMethodNames {
+ public static void main(String[] args) throws Exception {
+ ScriptEngineManager m = new ScriptEngineManager();
+ ScriptEngine e = m.getEngineByName("nashorn");
+
+ e.eval("({get \"\0\"(){}})[\"\0\"]");
+ e.eval("({get \"\\x80\"(){}})[\"\\x80\"]");
+ e.eval("({get \"\\xff\"(){}})[\"\\xff\"]");
+ }
+}
--- a/hotspot/test/runtime/SharedArchiveFile/SASymbolTableTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/test/runtime/SharedArchiveFile/SASymbolTableTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -24,9 +24,6 @@
/*
* @test SASymbolTableTest
* @summary Walk symbol table using SA, with and without CDS.
- * Started failing on 2016.06.24 due to 8160376 on MacOS X so quarantine
- * it on that platform:
- * @requires os.family != "mac"
* @library /test/lib
* @modules java.base/jdk.internal.misc
* jdk.hotspot.agent/sun.jvm.hotspot.oops
--- a/hotspot/test/runtime/jni/PrivateInterfaceMethods/PrivateInterfaceMethods.java Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/test/runtime/jni/PrivateInterfaceMethods/PrivateInterfaceMethods.java Wed Oct 26 20:13:29 2016 +0000
@@ -22,7 +22,7 @@
*/
/* @test
- * @bug 8081800
+ * @bug 8081800 8165827
* @summary Add JNI invocation tests for private interface methods
* @run main/native PrivateInterfaceMethods
*/
@@ -34,19 +34,23 @@
}
static native int callIntVoid(Object target, String definingClassName, String methodName, boolean virtual);
+ static native void lookupIntVoid(String definingClassName, String methodName);
static interface A {
static final int AmResult = 1;
private int m() { return AmResult; }
+ private int onlyA() { return 0; }
}
static interface B extends A {
// No m() here
+ private int onlyB() { return 0; }
}
static interface C extends B {
static final int CmResult = 2;
private int m() { return CmResult; } // unrelated to A.m
+ private int onlyC() { return 0; }
}
public static class Impl implements C {
@@ -62,6 +66,29 @@
}
public static void main(String[] args) {
+
+ // JNI getMethodID only works for methods declared in or inherited by a type.
+ // Private interface methods are not inherited and so should only be found
+ // in the declaring interface.
+
+ lookup(A.class.getName(), "onlyA", null); // should succeed
+ lookup(B.class.getName(), "onlyA", NoSuchMethodError.class); // should fail
+ lookup(C.class.getName(), "onlyA", NoSuchMethodError.class); // should fail
+ lookup(Impl.class.getName(), "onlyA", NoSuchMethodError.class); // should fail
+ lookup(Impl2.class.getName(), "onlyA", NoSuchMethodError.class); // should fail
+
+ lookup(B.class.getName(), "onlyB", null); // should succeed
+ lookup(A.class.getName(), "onlyB", NoSuchMethodError.class); // should fail
+ lookup(C.class.getName(), "onlyB", NoSuchMethodError.class); // should fail
+ lookup(Impl.class.getName(), "onlyB", NoSuchMethodError.class); // should fail
+ lookup(Impl2.class.getName(), "onlyB", NoSuchMethodError.class); // should fail
+
+ lookup(C.class.getName(), "onlyC", null); // should succeed
+ lookup(A.class.getName(), "onlyC", NoSuchMethodError.class); // should fail
+ lookup(B.class.getName(), "onlyC", NoSuchMethodError.class); // should fail
+ lookup(Impl.class.getName(), "onlyC", NoSuchMethodError.class); // should fail
+ lookup(Impl2.class.getName(), "onlyC", NoSuchMethodError.class); // should fail
+
Impl impl = new Impl();
// Note: JNI doesn't enforce access control so we can make
@@ -106,6 +133,25 @@
test(impl2, Impl2.class.getName(), "m", -1, false, NoSuchMethodError.class);
}
+ static void lookup(String definingClass, String method, Class<?> expectedException) {
+
+ String desc = "Lookup of " + definingClass + "." + method;
+ try {
+ lookupIntVoid(definingClass, method);
+ if (expectedException != null)
+ throw new Error(desc + " succeeded - but expected exception "
+ + expectedException.getSimpleName());
+ System.out.println(desc + " - passed");
+ }
+ catch (Throwable t) {
+ if (t.getClass() != expectedException)
+ throw new Error(desc + " failed: got exception " + t + " but expected exception "
+ + expectedException.getSimpleName());
+ else
+ System.out.println(desc + " threw " + expectedException.getSimpleName() + " as expected");
+ }
+ }
+
static void test(Object target, String definingClass, String method,
int expected, boolean virtual, Class<?> expectedException) {
@@ -115,16 +161,19 @@
try {
int res = callIntVoid(target, definingClass, method, virtual);
if (expectedException != null)
- throw new Error(desc + " succeeded - but expected exception " + expectedException.getSimpleName());
+ throw new Error(desc + " succeeded - but expected exception "
+ + expectedException.getSimpleName());
if (res != expected)
throw new Error(desc + " got wrong result: " + res + " instead of " + expected);
System.out.println(desc + " - passed");
}
catch (Throwable t) {
if (t.getClass() != expectedException)
- throw new Error(desc + " failed", t);
+ throw new Error(desc + " failed: got exception " + t + " but expected exception "
+ + expectedException.getSimpleName());
else
System.out.println(desc + " threw " + expectedException.getSimpleName() + " as expected");
}
}
+
}
--- a/hotspot/test/runtime/jni/PrivateInterfaceMethods/libPrivateInterfaceMethods.c Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/test/runtime/jni/PrivateInterfaceMethods/libPrivateInterfaceMethods.c Wed Oct 26 20:13:29 2016 +0000
@@ -52,3 +52,27 @@
else
return (*env)->CallIntMethod(env, impl, m_id);
}
+
+// Private interface methods lookup test
+JNIEXPORT void JNICALL
+Java_PrivateInterfaceMethods_lookupIntVoid(JNIEnv *env, jclass unused,
+ jstring defining_class_name, jstring method_name) {
+
+ // Lookup int method_name() in defining_class_name
+
+ jmethodID m_id = NULL;
+ jclass clazz = NULL;
+ const char* name = NULL;
+
+ name = (*env)->GetStringUTFChars(env, defining_class_name, NULL);
+ if (name == NULL) return;
+ clazz = (*env)->FindClass(env, name);
+ (*env)->ReleaseStringUTFChars(env, defining_class_name, name);
+ if ((*env)->ExceptionCheck(env)) return;
+
+ name = (*env)->GetStringUTFChars(env, method_name, NULL);
+ if (name == NULL) return;
+ m_id = (*env)->GetMethodID(env, clazz, name, "()I");
+ (*env)->ReleaseStringUTFChars(env, method_name, name);
+}
+
--- a/hotspot/test/runtime/lambda-features/InterfaceInitializationStates.java Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/test/runtime/lambda-features/InterfaceInitializationStates.java Wed Oct 26 20:13:29 2016 +0000
@@ -88,9 +88,7 @@
// Iunlinked is testing initialization like interface I, except interface I is linked when
// ClassLIM is linked.
// Iunlinked is not linked already when K gets an initialization error. Linking Iunlinked
- // should succeed and not get NoClassDefFoundError because it does not depend on the
- // initialization state of K for linking. There's bug now where it gets this error.
- // See: https://bugs.openjdk.java.net/browse/JDK-8166203.
+ // should succeed because it does not depend on the initialization state of K for linking.
interface Iunlinked extends K {
boolean v = InterfaceInitializationStates.out(Iunlinked.class);
}
@@ -157,15 +155,9 @@
System.out.println("ExceptionInInitializerError as expected");
}
- // Initialize Iunlinked. This should not get NoClassDefFoundError because K
+ // Initialize Iunlinked. No exception should be thrown even if K
// (its super interface) is in initialization_error state.
- // This is a bug. It does now.
- try {
- boolean bb = Iunlinked.v;
- throw new RuntimeException("FAIL exception not thrown for Iunlinked initialization");
- } catch(NoClassDefFoundError e) {
- System.out.println("NoClassDefFoundError thrown because of bug");
- }
+ boolean bb = Iunlinked.v;
// This should be okay
boolean value = Iparams.v;
@@ -182,7 +174,7 @@
// Check expected class initialization order
List<Class<?>> expectedCInitOrder = Arrays.asList(L.class, K.class, M.class, ClassM.class,
- I.class, Iparams.class,
+ I.class, Iunlinked.class, Iparams.class,
ClassIparams.class);
if (!cInitOrder.equals(expectedCInitOrder)) {
throw new RuntimeException(
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/PatchModule/PatchModuleClassList.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,142 @@
+/*
+ * 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 classes which are not useable during run time should not be included in the classlist
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ * jdk.jartool/sun.tools.jar
+ * @build PatchModuleMain
+ * @run main PatchModuleClassList
+ */
+
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import jdk.test.lib.InMemoryJavaCompiler;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+public class PatchModuleClassList {
+ private static final String BOOT_CLASS = "javax/naming/spi/NamingManager";
+ private static final String PLATFORM_CLASS = "javax/transaction/InvalidTransactionException";
+
+ public static void main(String args[]) throws Throwable {
+ // Case 1. A class to be loaded by the boot class loader
+
+ // Create a class file in the module java.naming. This class file
+ // will be put in the javanaming.jar file.
+ String source = "package javax.naming.spi; " +
+ "public class NamingManager { " +
+ " static { " +
+ " System.out.println(\"I pass!\"); " +
+ " } " +
+ "}";
+
+ ClassFileInstaller.writeClassToDisk(BOOT_CLASS,
+ InMemoryJavaCompiler.compile(BOOT_CLASS.replace('/', '.'), source, "-Xmodule:java.naming"),
+ System.getProperty("test.classes"));
+
+ // Build the jar file that will be used for the module "java.naming".
+ BasicJarBuilder.build("javanaming", BOOT_CLASS);
+ String moduleJar = BasicJarBuilder.getTestJar("javanaming.jar");
+
+ String classList = "javanaming.list";
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+ true,
+ "-XX:DumpLoadedClassList=" + classList,
+ "--patch-module=java.naming=" + moduleJar,
+ "PatchModuleMain", BOOT_CLASS.replace('/', '.'));
+ new OutputAnalyzer(pb.start()).shouldHaveExitValue(0);
+
+ // check the generated classlist file
+ String content = new String(Files.readAllBytes(Paths.get(classList)));
+ if (content.indexOf(BOOT_CLASS) >= 0) {
+ throw new RuntimeException(BOOT_CLASS + " should not be in the classlist");
+ }
+
+ // Case 2. A class to be loaded by the platform class loader
+
+ // Create a class file in the module java.transaction. This class file
+ // will be put in the javatransaction.jar file.
+ source = "package javax.transaction; " +
+ "public class InvalidTransactionException { " +
+ " static { " +
+ " System.out.println(\"I pass!\"); " +
+ " } " +
+ "}";
+
+ ClassFileInstaller.writeClassToDisk(PLATFORM_CLASS,
+ InMemoryJavaCompiler.compile(PLATFORM_CLASS.replace('/', '.'), source, "-Xmodule:java.transaction"),
+ System.getProperty("test.classes"));
+
+ // Build the jar file that will be used for the module "java.transaction".
+ BasicJarBuilder.build("javatransaction", PLATFORM_CLASS);
+ moduleJar = BasicJarBuilder.getTestJar("javatransaction.jar");
+
+ classList = "javatransaction.list";
+ pb = ProcessTools.createJavaProcessBuilder(
+ true,
+ "-XX:DumpLoadedClassList=" + classList,
+ "--patch-module=java.naming=" + moduleJar,
+ "PatchModuleMain", PLATFORM_CLASS.replace('/', '.'));
+ new OutputAnalyzer(pb.start()).shouldHaveExitValue(0);
+
+ // check the generated classlist file
+ content = new String(Files.readAllBytes(Paths.get(classList)));
+ if (content.indexOf(PLATFORM_CLASS) >= 0) {
+ throw new RuntimeException(PLATFORM_CLASS + " should not be in the classlist");
+ }
+
+ // Case 3. A class to be loaded from the bootclasspath/a
+
+ // Create a simple class file
+ source = "public class Hello { " +
+ " public static void main(String args[]) { " +
+ " System.out.println(\"Hello\"); " +
+ " } " +
+ "}";
+
+ ClassFileInstaller.writeClassToDisk("Hello",
+ InMemoryJavaCompiler.compile("Hello", source),
+ System.getProperty("test.classes"));
+
+ // Build hello.jar
+ BasicJarBuilder.build("hello", "Hello");
+ moduleJar = BasicJarBuilder.getTestJar("hello.jar");
+
+ classList = "hello.list";
+ pb = ProcessTools.createJavaProcessBuilder(
+ true,
+ "-XX:DumpLoadedClassList=" + classList,
+ "-Xbootclasspath/a:" + moduleJar,
+ "Hello");
+ new OutputAnalyzer(pb.start()).shouldHaveExitValue(0);
+
+ // check the generated classlist file
+ content = new String(Files.readAllBytes(Paths.get(classList)));
+ if (content.indexOf("Hello") < 0) {
+ throw new RuntimeException("Hello should be in the classlist");
+ }
+ }
+}
--- a/hotspot/test/serviceability/jdwp/AllModulesCommandTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/test/serviceability/jdwp/AllModulesCommandTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -30,8 +30,10 @@
/**
* @test
- * @summary Tests AllModules JDWP command
+ * @summary Tests the modules-related JDWP commands
* @library /test/lib
+ * @ignore 8168478
+ * @modules jdk.jdwp.agent
* @modules java.base/jdk.internal.misc
* @compile AllModulesCommandTestDebuggee.java
* @run main/othervm AllModulesCommandTest
@@ -87,11 +89,16 @@
assertReply(reply);
for (int i = 0; i < reply.getModulesCount(); ++i) {
long modId = reply.getModuleId(i);
- // For each module reported by JDWP get its name using the JDWP NAME command
- getModuleName(modId);
+ // For each module reported by JDWP get its name using the JDWP NAME command
+ // and store the reply
+ String modName = getModuleName(modId);
+ System.out.println("i=" + i + ", modId=" + modId + ", modName=" + modName);
+ if (modName != null) { // JDWP reports unnamed modules, ignore them
+ jdwpModuleNames.add(modName);
+ }
// Assert the JDWP CANREAD and CLASSLOADER commands
- assertCanRead(modId);
- assertClassLoader(modId);
+ assertCanRead(modId, modName);
+ assertClassLoader(modId, modName);
}
System.out.println("Module names reported by JDWP: " + Arrays.toString(jdwpModuleNames.toArray()));
@@ -114,14 +121,10 @@
}
}
- private void getModuleName(long modId) throws IOException {
- // Send out the JDWP NAME command and store the reply
+ private String getModuleName(long modId) throws IOException {
JdwpModNameReply reply = new JdwpModNameCmd(modId).send(channel);
assertReply(reply);
- String modName = reply.getModuleName();
- if (modName != null) { // JDWP reports unnamed modules, ignore them
- jdwpModuleNames.add(modName);
- }
+ return reply.getModuleName();
}
private void assertReply(JdwpReply reply) {
@@ -131,19 +134,47 @@
}
}
- private void assertCanRead(long modId) throws IOException {
+ private void assertCanRead(long modId, String modName) throws IOException {
// Simple assert for the CANREAD command
JdwpCanReadReply reply = new JdwpCanReadCmd(modId, modId).send(channel);
assertReply(reply);
- assertTrue(reply.canRead(), "canRead() reports false for reading from the same module");
+ assertTrue(reply.canRead(), "canRead() reports false for reading from the same module '" + modName + "', moduleId=" + modId);
+ }
+
+ private void assertClassLoader(long modId, String modName) throws IOException {
+ // Verify that the module classloader id is valid
+ JdwpClassLoaderReply reply = new JdwpClassLoaderCmd(modId).send(channel);
+ assertReply(reply);
+ long moduleClassLoader = reply.getClassLoaderId();
+ assertTrue(moduleClassLoader >= 0, "bad classloader refId " + moduleClassLoader + " for module '" + modName + "', moduleId=" + modId);
+
+ String clsModName = getModuleName(modId);
+ if ("java.base".equals(clsModName)) {
+ // For the java.base module, because there will be some loaded classes, we can verify
+ // that some of the loaded classes do report the java.base module as the module they belong to
+ assertGetModule(moduleClassLoader, modId);
+ }
}
- private void assertClassLoader(long modId) throws IOException {
- // Simple assert for the CLASSLOADER command
- JdwpClassLoaderReply reply = new JdwpClassLoaderCmd(modId).send(channel);
- assertReply(reply);
- long clId = reply.getClassLoaderId();
- assertTrue(clId >= 0, "bad classloader refId " + clId + " for module id " + modId);
+ private void assertGetModule(long moduleClassLoader, long modId) throws IOException {
+ // Get all the visible classes for the module classloader
+ JdwpVisibleClassesReply visibleClasses = new JdwpVisibleClassesCmd(moduleClassLoader).send(channel);
+ assertReply(visibleClasses);
+
+ boolean moduleFound = false;
+ for (long clsId : visibleClasses.getVisibleClasses()) {
+ // For each visible class get the module the class belongs to
+ JdwpModuleReply modReply = new JdwpModuleCmd(clsId).send(channel);
+ assertReply(modReply);
+ long clsModId = modReply.getModuleId();
+
+ // At least one of the visible classes should belong to our module
+ if (modId == clsModId) {
+ moduleFound = true;
+ break;
+ }
+ }
+ assertTrue(moduleFound, "None of the visible classes for the classloader of the module " + getModuleName(modId) + " reports the module as its own");
}
}
--- a/hotspot/test/serviceability/jdwp/JdwpCanReadReply.java Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/test/serviceability/jdwp/JdwpCanReadReply.java Wed Oct 26 20:13:29 2016 +0000
@@ -31,7 +31,7 @@
private boolean canRead;
protected void parseData(DataInputStream ds) throws IOException {
- canRead = ds.read() == 1;
+ canRead = (ds.read() != 0);
}
public boolean canRead() {
--- a/hotspot/test/serviceability/jdwp/JdwpCmd.java Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/test/serviceability/jdwp/JdwpCmd.java Wed Oct 26 20:13:29 2016 +0000
@@ -70,7 +70,6 @@
}
public final T send(JdwpChannel channel) throws IOException {
- System.err.println("Sending command: " + this);
channel.write(data.array(), HEADER_LEN + getDataLength());
if (reply != null) {
reply.initFromStream(channel.getInputStream());
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/jdwp/JdwpModuleCmd.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+/**
+ * The JDWP MODULE command
+ */
+public class JdwpModuleCmd extends JdwpCmd<JdwpModuleReply> {
+
+ public JdwpModuleCmd(long refId) {
+ super(19, 2, JdwpModuleReply.class, refLen());
+ putRefId(refId);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/jdwp/JdwpModuleReply.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,42 @@
+/*
+ * 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.io.DataInputStream;
+import java.io.IOException;
+
+/**
+ * The reply to the JDWP MODULE command
+ */
+public class JdwpModuleReply extends JdwpReply {
+
+ private long moduleId;
+
+ protected void parseData(DataInputStream ds) throws IOException {
+ moduleId = readRefId(ds);
+ }
+
+ public long getModuleId() {
+ return moduleId;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/jdwp/JdwpVisibleClassesCmd.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+/**
+ * The JDWP VISIBLE CLASSES command
+ */
+public class JdwpVisibleClassesCmd extends JdwpCmd<JdwpVisibleClassesReply> {
+
+ public JdwpVisibleClassesCmd(long classLoaderId) {
+ super(1, 14, JdwpVisibleClassesReply.class, refLen());
+ putRefId(classLoaderId);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/jdwp/JdwpVisibleClassesReply.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,49 @@
+/*
+ * 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.io.DataInputStream;
+import java.io.IOException;
+import java.util.Arrays;
+
+/**
+ * The reply to the JDWP VISIBLE CLASSES command
+ */
+public class JdwpVisibleClassesReply extends JdwpReply {
+
+ private long[] visibleClasses;
+
+ protected void parseData(DataInputStream ds) throws IOException {
+ int numOfClasses = ds.readInt();
+ visibleClasses = new long[numOfClasses];
+ for (int i = 0; i < numOfClasses; ++i) {
+ byte type = ds.readByte();
+ long refId = readRefId(ds);
+ visibleClasses[i] = refId;
+ }
+ }
+
+ public long[] getVisibleClasses() {
+ return Arrays.copyOf(visibleClasses, visibleClasses.length);
+ }
+
+}
--- a/hotspot/test/serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/test/serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -42,9 +42,6 @@
* @bug 6313383
* @key regression
* @summary Regression test for hprof export issue due to large heaps (>2G)
- * Started failing on 2016.06.24 due to 8160376 on MacOS X so quarantine
- * it on that platform:
- * @requires os.family != "mac"
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.compiler
--- a/hotspot/test/serviceability/tmtools/jstat/GcTest02.java Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/test/serviceability/tmtools/jstat/GcTest02.java Wed Oct 26 20:13:29 2016 +0000
@@ -31,7 +31,6 @@
* @modules java.base/jdk.internal.misc
* @library /test/lib
* @library ../share
- * @ignore 8155570
* @run main/othervm -XX:+UsePerfData -Xmx128M -XX:MaxMetaspaceSize=128M GcTest02
*/
--- a/hotspot/test/serviceability/tmtools/jstat/utils/GcProvokerImpl.java Wed Oct 26 15:46:13 2016 -0400
+++ b/hotspot/test/serviceability/tmtools/jstat/utils/GcProvokerImpl.java Wed Oct 26 20:13:29 2016 +0000
@@ -50,7 +50,7 @@
used += memoryChunk;
} catch (OutOfMemoryError e) {
list = null;
- throw new RuntimeException("Unexpected OOME while eating " + targetUsage + " of heap memory.");
+ throw new RuntimeException("Unexpected OOME '" + e.getMessage() + "' while eating " + targetUsage + " of heap memory.");
}
}
return list;
@@ -73,8 +73,10 @@
@Override
public void eatMetaspaceAndHeap(float targetMemoryUsagePercent) {
+ // Metaspace should be filled before Java Heap to prevent unexpected OOME
+ // in the Java Heap while filling Metaspace
+ eatenMetaspace = eatMetaspace(targetMemoryUsagePercent);
eatenMemory = eatHeapMemory(targetMemoryUsagePercent);
- eatenMetaspace = eatMetaspace(targetMemoryUsagePercent);
}
private static List<Object> eatMetaspace(float targetUsage) {
@@ -97,7 +99,7 @@
list.add(gp.create(0));
} catch (OutOfMemoryError oome) {
list = null;
- throw new RuntimeException("Unexpected OOME while eating " + targetUsage + " of Metaspace.");
+ throw new RuntimeException("Unexpected OOME '" + oome.getMessage() + "' while eating " + targetUsage + " of Metaspace.");
}
MemoryUsage memoryUsage = metaspacePool.getUsage();
currentUsage = (((float) memoryUsage.getUsed()) / memoryUsage.getMax());
--- a/jaxp/.hgtags Wed Oct 26 15:46:13 2016 -0400
+++ b/jaxp/.hgtags Wed Oct 26 20:13:29 2016 +0000
@@ -382,3 +382,5 @@
a8d5fe567ae72b4931040e59dd4478363f9004f5 jdk-9+137
69c3b12ba75b2e321dee731ac545e7fbff608451 jdk-9+138
8991d71c5316bde259e6a417c1199b008ca3cdf0 jdk-9+139
+8d100cb9b04819b5bd09f33c7fd5b8628d1a456f jdk-9+140
+037c095ba0c345edbeaaab52fda913a76c3930c0 jdk-9+141
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java Wed Oct 26 20:13:29 2016 +0000
@@ -1342,6 +1342,12 @@
}
else {
SyntaxTreeNode parent = _parentStack.peek();
+ if (element.getClass().isAssignableFrom(Import.class) &&
+ parent.notTypeOf(Import.class)) {
+ ErrorMsg err = new ErrorMsg(ErrorMsg.IMPORT_PRECEDE_OTHERS_ERR,
+ prefix+':'+localname);
+ throw new SAXException(err.toString());
+ }
parent.addElement(element);
element.setParent(parent);
}
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Stylesheet.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Stylesheet.java Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -31,6 +31,7 @@
import com.sun.org.apache.bcel.internal.generic.GETSTATIC;
import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE;
import com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL;
+import com.sun.org.apache.bcel.internal.generic.INVOKESTATIC;
import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL;
import com.sun.org.apache.bcel.internal.generic.ISTORE;
import com.sun.org.apache.bcel.internal.generic.InstructionHandle;
@@ -1252,6 +1253,10 @@
classGen.getConstantPool());
transf.addException("com.sun.org.apache.xalan.internal.xsltc.TransletException");
+ // call resetPrefixIndex at the beginning of transform
+ final int check = cpg.addMethodref(BASIS_LIBRARY_CLASS, "resetPrefixIndex", "()V");
+ il.append(new INVOKESTATIC(check));
+
// Define and initialize current with the root node
final LocalVariableGen current =
transf.addLocalVariable("current",
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/SyntaxTreeNode.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/SyntaxTreeNode.java Wed Oct 26 20:13:29 2016 +0000
@@ -524,6 +524,24 @@
}
/**
+ * Checks whether any children of this node is not of the specified type.
+ *
+ * @param type the type to be checked against
+ * @return true if there is at least one child that is not of the specified
+ * type, false otherwise.
+ */
+ public boolean notTypeOf(Class<?> type) {
+ if (_contents.size() > 0) {
+ for (SyntaxTreeNode item : _contents) {
+ if (!item.getClass().isAssignableFrom(type)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
* Return true if the node represents a simple RTF.
*
* A node is a simple RTF if all children only produce Text value.
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java Wed Oct 26 20:13:29 2016 +0000
@@ -274,6 +274,14 @@
"Circular import/include. Stylesheet ''{0}'' already loaded."},
/*
+ * Note to translators: "xsl:import" and "xsl:include" are keywords that
+ * should not be translated.
+ */
+ {ErrorMsg.IMPORT_PRECEDE_OTHERS_ERR,
+ "The xsl:import element children must precede all other element children of "
+ + "an xsl:stylesheet element, including any xsl:include element children."},
+
+ /*
* Note to translators: A result-tree fragment is a portion of a
* resulting XML document represented as a tree. "<xsl:sort>" is a
* keyword and should not be translated.
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMsg.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMsg.java Wed Oct 26 20:13:29 2016 +0000
@@ -70,6 +70,7 @@
public static final String STRAY_ATTRIBUTE_ERR = "STRAY_ATTRIBUTE_ERR";
public static final String ILLEGAL_ATTRIBUTE_ERR = "ILLEGAL_ATTRIBUTE_ERR";
public static final String CIRCULAR_INCLUDE_ERR = "CIRCULAR_INCLUDE_ERR";
+ public static final String IMPORT_PRECEDE_OTHERS_ERR = "IMPORT_PRECEDE_OTHERS_ERR";
public static final String RESULT_TREE_SORT_ERR = "RESULT_TREE_SORT_ERR";
public static final String SYMBOLS_REDEF_ERR = "SYMBOLS_REDEF_ERR";
public static final String XSL_VERSION_ERR = "XSL_VERSION_ERR";
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/BasisLibrary.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/BasisLibrary.java Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -31,6 +31,7 @@
import java.text.NumberFormat;
import java.util.Locale;
import java.util.ResourceBundle;
+import java.util.concurrent.atomic.AtomicInteger;
import javax.xml.transform.dom.DOMSource;
import com.sun.org.apache.xalan.internal.xsltc.DOM;
@@ -1533,16 +1534,25 @@
}
/**
- * This function is used in the execution of xsl:element
+ * These functions are used in the execution of xsl:element to generate
+ * and reset namespace prefix index local to current transformation process
*/
- private static int prefixIndex = 0;
-
public static String generatePrefix() {
- synchronized (BasisLibrary.class) {
- return ("ns" + prefixIndex++);
- }
+ return ("ns" + threadLocalPrefixIndex.get().getAndIncrement());
+ }
+
+ public static void resetPrefixIndex() {
+ threadLocalPrefixIndex.get().set(0);
}
+ private static final ThreadLocal<AtomicInteger> threadLocalPrefixIndex =
+ new ThreadLocal<AtomicInteger>() {
+ @Override
+ protected AtomicInteger initialValue() {
+ return new AtomicInteger();
+ }
+ };
+
public static final String RUN_TIME_INTERNAL_ERR =
"RUN_TIME_INTERNAL_ERR";
public static final String RUN_TIME_COPY_ERR =
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/StAXStream2SAX.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/StAXStream2SAX.java Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2015, 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
@@ -305,9 +305,12 @@
if (prefix == null) { // true for default namespace
prefix = "";
}
- _sax.startPrefixMapping(
- prefix,
- staxStreamReader.getNamespaceURI(i));
+ String uri = staxStreamReader.getNamespaceURI(i);
+ if (uri == null && prefix.isEmpty()) { // true for default namespace
+ uri = "";
+ }
+
+ _sax.startPrefixMapping(prefix, uri);
}
// fire startElement
--- a/jaxp/test/javax/xml/jaxp/unittest/parsers/Bug6341770.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jaxp/test/javax/xml/jaxp/unittest/parsers/Bug6341770.java Wed Oct 26 20:13:29 2016 +0000
@@ -28,6 +28,7 @@
import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
+import java.nio.file.Paths;
import java.util.PropertyPermission;
import javax.xml.parsers.SAXParserFactory;
@@ -53,8 +54,14 @@
// naming a file "aux" would fail on windows.
@Test
public void testNonAsciiURI() {
+ if (!isNonAsciiSupported()) {
+ // @bug 8167478
+ // if it doesn't support non-ascii, the following test is invalid even if test is passed.
+ System.out.println("Current environment doesn't support non-ascii, exit the test.");
+ return;
+ }
try {
- File dir = new File("sko\u0159ice");
+ File dir = new File(ALPHA);
dir.delete();
dir.mkdir();
File main = new File(dir, "main.xml");
@@ -82,4 +89,18 @@
}
System.out.println("OK.");
}
+
+ private boolean isNonAsciiSupported() {
+ // Use Paths.get method to test if the path is valid in current environment
+ try {
+ Paths.get(ALPHA);
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ // Select alpha because it's a very common non-ascii character in different charsets.
+ // That this test can run in as many as possible environments if it's possible.
+ private static final String ALPHA = "\u03b1";
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/transform/NamespacePrefixTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,193 @@
+/*
+ * 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 transform;
+
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import javax.xml.transform.Source;
+import javax.xml.transform.Templates;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.testng.annotations.Test;
+import static org.testng.Assert.assertTrue;
+import static jaxp.library.JAXPTestUtilities.runWithAllPerm;
+
+/*
+ * @test
+ * @bug 8167179
+ * @library /javax/xml/jaxp/libs
+ * @run testng/othervm -DrunSecMngr=true transform.NamespacePrefixTest
+ * @run testng/othervm transform.NamespacePrefixTest
+ * @summary This class tests the generation of namespace prefixes
+ */
+public class NamespacePrefixTest {
+
+ @Test
+ public void testReuseTemplates() throws Exception {
+ final TransformerFactory tf = TransformerFactory.newInstance();
+ final Source xslsrc = new StreamSource(new StringReader(XSL));
+ final Templates tmpl = tf.newTemplates(xslsrc);
+ for (int i = 0; i < TRANSF_COUNT; i++) {
+ checkResult(doTransformation(tmpl.newTransformer()));
+ }
+ }
+
+ @Test
+ public void testReuseTransformer() throws Exception {
+ final TransformerFactory tf = TransformerFactory.newInstance();
+ final Source xslsrc = new StreamSource(new StringReader(XSL));
+ final Transformer t = tf.newTransformer(xslsrc);
+ for (int i = 0; i < TRANSF_COUNT; i++) {
+ checkResult(doTransformation(t));
+ }
+ }
+
+ @Test
+ public void testConcurrentTransformations() throws Exception {
+ final TransformerFactory tf = TransformerFactory.newInstance();
+ final Source xslsrc = new StreamSource(new StringReader(XSL));
+ final Templates tmpl = tf.newTemplates(xslsrc);
+ concurrentTestPassed.set(true);
+
+ // Execute multiple TestWorker tasks
+ for (int id = 0; id < THREADS_COUNT; id++) {
+ EXECUTOR.execute(new TransformerThread(tmpl.newTransformer(), id));
+ }
+ // Initiate shutdown of previously submitted task
+ runWithAllPerm(EXECUTOR::shutdown);
+ // Wait for termination of submitted tasks
+ if (!EXECUTOR.awaitTermination(THREADS_COUNT, TimeUnit.SECONDS)) {
+ // If not all tasks terminates during the time out force them to shutdown
+ runWithAllPerm(EXECUTOR::shutdownNow);
+ }
+ // Check if all transformation threads generated the correct namespace prefix
+ assertTrue(concurrentTestPassed.get());
+ }
+
+ // Do one transformation with the provided transformer
+ private static String doTransformation(Transformer t) throws Exception {
+ StringWriter resWriter = new StringWriter();
+ Source xmlSrc = new StreamSource(new StringReader(XML));
+ t.transform(xmlSrc, new StreamResult(resWriter));
+ return resWriter.toString();
+ }
+
+ // Check if the transformation result string contains the
+ // element with the exact namespace prefix generated.
+ private static void checkResult(String result) {
+ // Check prefix of 'Element2' element, it should always be the same
+ assertTrue(result.contains(EXPECTED_CONTENT));
+ }
+
+ // Check if the transformation result string contains the element with
+ // the exact namespace prefix generated by current thread.
+ // If the expected prefix is not found and there was no failures observed by
+ // other test threads then mark concurrent test as failed.
+ private static void checkThreadResult(String result, int id) {
+ boolean res = result.contains(EXPECTED_CONTENT);
+ System.out.printf("%d: transformation result: %s%n", id, res ? "Pass" : "Fail");
+ if (!res) {
+ System.out.printf("%d result:%s%n", id, result);
+ }
+ concurrentTestPassed.compareAndSet(true, res);
+ }
+
+ // TransformerThread task that does the transformation similar
+ // to testReuseTransformer test method
+ private class TransformerThread implements Runnable {
+
+ private final Transformer transformer;
+ private final int id;
+
+ TransformerThread(Transformer transformer, int id) {
+ this.transformer = transformer;
+ this.id = id;
+ }
+
+ @Override
+ public void run() {
+ try {
+ System.out.printf("%d: waiting for barrier%n", id);
+ //Synchronize startup of all tasks
+ BARRIER.await();
+ System.out.printf("%d: starting transformation%n", id);
+ checkThreadResult(doTransformation(transformer), id);
+ } catch (Exception ex) {
+ throw new RuntimeException("TransformerThread " + id + " failed", ex);
+ }
+ }
+ }
+
+ // Number of subsequent transformations
+ private static final int TRANSF_COUNT = 10;
+
+ // Number of transformer threads running concurently
+ private static final int THREADS_COUNT = 10;
+
+ // Variable for storing the concurrent transformation test result. It is
+ // updated by transformer threads
+ private static final AtomicBoolean concurrentTestPassed = new AtomicBoolean(true);
+
+ // Cyclic barrier for threads startup synchronization
+ private static final CyclicBarrier BARRIER = new CyclicBarrier(THREADS_COUNT);
+
+ // Thread pool
+ private static final ExecutorService EXECUTOR = Executors.newCachedThreadPool();
+
+ // XSL that transforms XML and produces unique namespace prefixes for each element
+ private final static String XSL = "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">\n"
+ + " <xsl:template match=\"node()|@*\" priority=\"1\">\n"
+ + " <xsl:copy>\n"
+ + " <xsl:apply-templates select=\"node()|@*\"/>\n"
+ + " </xsl:copy>\n"
+ + " </xsl:template>\n"
+ + " <xsl:template match=\"*\" priority=\"2\">\n"
+ + " <xsl:element name=\"{name()}\" namespace=\"{namespace-uri()}\">\n"
+ + " <xsl:apply-templates select=\"node()|@*\"/>\n"
+ + " </xsl:element>\n"
+ + " </xsl:template>\n"
+ + "</xsl:stylesheet>";
+
+ // Simple XML content with root and two child elements
+ private final static String XML = "<TestRoot xmlns=\"test.xmlns\">\n"
+ + " <Element1 xmlns=\"test.xmlns\">\n"
+ + " </Element1>\n"
+ + " <Element2 xmlns=\"test.xmlns\">\n"
+ + " </Element2>\n"
+ + "</TestRoot>";
+
+ // With thread local namespace prefix index each transformation result should
+ // be the same and contain the same prefix for Element2
+ private final static String EXPECTED_CONTENT = "</ns2:Element2>";
+
+}
--- a/jaxp/test/javax/xml/jaxp/unittest/transform/StAXSourceTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jaxp/test/javax/xml/jaxp/unittest/transform/StAXSourceTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -30,7 +30,9 @@
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
@@ -38,6 +40,7 @@
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.stax.StAXResult;
import javax.xml.transform.stax.StAXSource;
+import javax.xml.transform.stream.StreamResult;
import org.testng.Assert;
import org.testng.annotations.Listeners;
@@ -45,6 +48,7 @@
/*
* @test
+ * @bug 8152530
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
* @run testng/othervm -DrunSecMngr=true transform.StAXSourceTest
* @run testng/othervm transform.StAXSourceTest
@@ -52,6 +56,33 @@
*/
@Listeners({jaxp.library.FilePolicy.class})
public class StAXSourceTest {
+ /**
+ * @bug 8152530
+ * Verifies that StAXSource handles empty namespace properly. NPE was thrown
+ * before the fix.
+ * @throws Exception if the test fails
+ */
+ @Test
+ public final void testStAXSourceWEmptyNS() throws Exception {
+ String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ + "<EntityList>\n"
+ + " <Entity xmlns=\"\">\n"
+ + " </Entity>\n"
+ + " <Entity xmlns=\"\">\n"
+ + " </Entity>\n"
+ + "</EntityList> ";
+
+ XMLInputFactory xif = XMLInputFactory.newInstance();
+ XMLStreamReader xsr = xif.createXMLStreamReader(new StringReader(xml));
+ xsr.nextTag();
+ TransformerFactory tf = TransformerFactory.newInstance();
+ Transformer t = tf.newTransformer();
+ while (xsr.nextTag() == XMLStreamConstants.START_ELEMENT && xsr.getLocalName().equals("Entity")) {
+ StringWriter stringResult = new StringWriter();
+ t.transform(new StAXSource(xsr), new StreamResult(stringResult));
+ System.out.println("result: \n" + stringResult.toString());
+ }
+ }
@Test
public final void testStAXSource() throws XMLStreamException {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/transform/StylesheetTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,149 @@
+/*
+ * 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 transform;
+
+import java.io.StringReader;
+import org.xml.sax.InputSource;
+
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.sax.SAXSource;
+import javax.xml.transform.TransformerConfigurationException;
+import org.testng.annotations.Listeners;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+/**
+ * @test
+ * @bug 8058152
+ * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
+ * @run testng/othervm -DrunSecMngr=true transform.StylesheetTest
+ * @run testng/othervm transform.StylesheetTest
+ * @summary this test contains test cases for verifying stylesheet
+ */
+@Listeners(jaxp.library.FilePolicy.class)
+public class StylesheetTest {
+
+ /**
+ * @bug 8058152
+ * Verifies that an error is reported if the xsl:import element
+ * is not at the top of the stylesheet.
+ * @throws TransformerConfigurationException
+ */
+ @Test(dataProvider = "invalidImport", expectedExceptions = TransformerConfigurationException.class)
+ public void testInvalidImport(String xsl) throws TransformerConfigurationException {
+ StringReader xsl1 = new StringReader(xsl);
+ TransformerFactory factory = TransformerFactory.newInstance();
+ SAXSource xslSource = new SAXSource(new InputSource(xsl1));
+ Transformer transformer = factory.newTransformer(xslSource);
+ }
+
+ /**
+ * @bug 8058152
+ * Verifies that valid xsl:import elements are accepted
+ * @throws TransformerConfigurationException
+ */
+ @Test(dataProvider = "validImport")
+ public void testValidImport(String file) throws TransformerConfigurationException {
+ String xsl = getClass().getResource(file).getFile();
+ TransformerFactory factory = TransformerFactory.newInstance();
+ SAXSource xslSource = new SAXSource(new InputSource(xsl));
+ Transformer transformer = factory.newTransformer(xslSource);
+ }
+
+ /*
+ DataProvider: for testing with xsl:import placed incorrectly
+ Data: stylesheet
+ */
+ @DataProvider(name = "invalidImport")
+ public Object[][] getInvalid() {
+
+ return new Object[][]{
+ // xsl:import after template and include elements
+ {"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ + "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n"
+ + "\n"
+ + " <xsl:template match=\"content\">\n"
+ + " <html>\n"
+ + " <xsl:apply-templates/>\n"
+ + " </html>\n"
+ + " </xsl:template>\n"
+ + " \n"
+ + " <xsl:include href=\"XSLInclude_header.xsl\"/>\n"
+ + "\n"
+ + " <xsl:template match=\"content/title\">\n"
+ + " <h1>\n"
+ + " <xsl:apply-templates/>\n"
+ + " </h1>\n"
+ + " </xsl:template>\n"
+ + " \n"
+ + " <xsl:import href=\"XSLInclude_footer.xsl\"/>\n"
+ + "\n"
+ + "</xsl:stylesheet>"},
+
+ // xsl:import inside template
+ {"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ + "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n"
+ + "\n"
+ + " <xsl:template match=\"content\">\n"
+ + " <xsl:import href=\"XSLInclude_header.xsl\"/>"
+ + " <html>\n"
+ + " <xsl:apply-templates/>\n"
+ + " </html>\n"
+ + " </xsl:template>\n"
+ + "\n"
+ + "</xsl:stylesheet>"},
+
+ // xsl:import after xsl:include
+ {"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ + "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n"
+ + " <xsl:include href=\"XSLInclude_header.xsl\"/>\n"
+ + " <xsl:import href=\"XSLInclude_footer.xsl\"/>\n"
+ + "\n"
+ + " <xsl:template match=\"content/title\">\n"
+ + " <h1>\n"
+ + " <xsl:apply-templates/>\n"
+ + " </h1>\n"
+ + " </xsl:template>\n"
+ + "\n"
+ + "</xsl:stylesheet>"}
+ };
+ }
+
+ /*
+ DataProvider: for testing with xsl:import placed correctly
+ Data: path to stylesheet
+ */
+ @DataProvider(name = "validImport")
+ public Object[][] getValid() {
+
+ return new Object[][]{
+ // xsl:import at the top
+ {"XSLInclude_main.xsl"},
+
+ // two xsl:import elements at the top
+ {"XSLImport.xsl"}
+ };
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/transform/XSLImport.xsl Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,21 @@
+<?xml version="1.1" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+ <xsl:import href="XSLInclude_header.xsl"/>
+ <xsl:import href="XSLInclude_footer.xsl"/>
+
+ <xsl:template match="content">
+ <html>
+ <xsl:apply-templates/>
+ </html>
+ </xsl:template>
+
+ <xsl:template match="content/title">
+ <h1>
+ <xsl:apply-templates/>
+ </h1>
+ </xsl:template>
+
+
+
+</xsl:stylesheet>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/transform/XSLInclude_footer.xsl Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+ <xsl:template match="footer">
+ <dv id="footer"><xsl:apply-templates/></dv>
+ </xsl:template>
+
+
+</xsl:stylesheet>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/transform/XSLInclude_header.xsl Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+ <xsl:template match="header">
+ <h4><xsl:apply-templates/></h4>
+ </xsl:template>
+
+</xsl:stylesheet>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/transform/XSLInclude_main.xsl Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,20 @@
+<?xml version="1.1" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+ <xsl:import href="XSLInclude_header.xsl"/>
+
+ <xsl:template match="content">
+ <html>
+ <xsl:apply-templates/>
+ </html>
+ </xsl:template>
+
+ <xsl:template match="content/title">
+ <h1>
+ <xsl:apply-templates/>
+ </h1>
+ </xsl:template>
+
+ <xsl:include href="XSLInclude_footer.xsl"/>
+
+</xsl:stylesheet>
\ No newline at end of file
--- a/jaxws/.hgtags Wed Oct 26 15:46:13 2016 -0400
+++ b/jaxws/.hgtags Wed Oct 26 20:13:29 2016 +0000
@@ -385,3 +385,5 @@
297c16d401c534cb879809d2a746d21ca99d2954 jdk-9+137
7d3a8f52b124db26ba8425c2931b748dd9d2791b jdk-9+138
7a7aadf3c4500cc273c889aa1172d4fe3844bb6b jdk-9+139
+9004617323fe99cbe4fad48f373cb2ed4fc50aa6 jdk-9+140
+b2c18f755228d1d19a86cd7d5fa1abb6b1495dfb jdk-9+141
--- a/jdk/.hgtags Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/.hgtags Wed Oct 26 20:13:29 2016 +0000
@@ -382,3 +382,5 @@
e72df94364e3686e7d62059ce0d6b187b82da713 jdk-9+137
665096863382bf23ce891307cf2a7511e77c1c88 jdk-9+138
5518ac2f2ead5e594bd983f2047178136aafdfd0 jdk-9+139
+e93b7ea559759f036c9f69fd2ddaf47bb4e98385 jdk-9+140
+8d752af5f61d41f226adf2cda72a20faa9ad620a jdk-9+141
--- a/jdk/make/CompileInterimRmic.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/make/CompileInterimRmic.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
--- a/jdk/make/CompileTools.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/make/CompileTools.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
--- a/jdk/make/GenerateModuleSummary.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/make/GenerateModuleSummary.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -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
--- a/jdk/make/Tools.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/make/Tools.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
--- a/jdk/make/gendata/GendataBreakIterator.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/make/gendata/GendataBreakIterator.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
-# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
--- a/jdk/make/gendata/GendataHtml32dtd.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/make/gendata/GendataHtml32dtd.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
--- a/jdk/make/gensrc/Gensrc-java.base.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/make/gensrc/Gensrc-java.base.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
--- a/jdk/make/gensrc/Gensrc-jdk.jlink.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/make/gensrc/Gensrc-jdk.jlink.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2014, 2015, 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
--- a/jdk/make/gensrc/GensrcIcons.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/make/gensrc/GensrcIcons.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
--- a/jdk/make/gensrc/GensrcLocaleData.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/make/gensrc/GensrcLocaleData.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
--- a/jdk/make/gensrc/GensrcModuleLoaderMap.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/make/gensrc/GensrcModuleLoaderMap.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -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
--- a/jdk/make/gensrc/GensrcVarHandles.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/make/gensrc/GensrcVarHandles.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -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
--- a/jdk/make/launcher/Launcher-java.scripting.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/make/launcher/Launcher-java.scripting.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
--- a/jdk/make/launcher/Launcher-jdk.compiler.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/make/launcher/Launcher-jdk.compiler.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
--- a/jdk/make/launcher/Launcher-jdk.javadoc.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/make/launcher/Launcher-jdk.javadoc.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
--- a/jdk/make/launcher/Launcher-jdk.jdeps.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/make/launcher/Launcher-jdk.jdeps.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -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
--- a/jdk/make/launcher/Launcher-jdk.jlink.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/make/launcher/Launcher-jdk.jlink.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -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
--- a/jdk/make/launcher/Launcher-jdk.jstatd.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/make/launcher/Launcher-jdk.jstatd.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
--- a/jdk/make/launcher/Launcher-jdk.pack200.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/make/launcher/Launcher-jdk.pack200.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
@@ -58,10 +58,6 @@
endif
-ifeq ($(OPENJDK_TARGET_OS), solaris)
- UNPACKEXE_TOOLCHAIN := TOOLCHAIN_LINK_CXX
-endif
-
UNPACK_MAPFILE_DIR := $(JDK_TOPDIR)/make/mapfiles/libunpack
UNPACK_MAPFILE_PLATFORM_FILE := \
$(UNPACK_MAPFILE_DIR)/mapfile-vers-unpack200-$(OPENJDK_TARGET_OS)-$(OPENJDK_TARGET_CPU_ARCH)
@@ -79,7 +75,7 @@
$(eval $(call SetupNativeCompilation,BUILD_UNPACKEXE, \
SRC := $(UNPACKEXE_SRC), \
- TOOLCHAIN := $(UNPACKEXE_TOOLCHAIN), \
+ TOOLCHAIN := TOOLCHAIN_LINK_CXX, \
OPTIMIZATION := LOW, \
CFLAGS := $(UNPACKEXE_CFLAGS) $(CXXFLAGS_JDKEXE) -DFULL, \
CFLAGS_release := -DPRODUCT, \
--- a/jdk/make/launcher/Launcher-jdk.scripting.nashorn.shell.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/make/launcher/Launcher-jdk.scripting.nashorn.shell.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
--- a/jdk/make/lib/CoreLibraries.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/make/lib/CoreLibraries.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -255,7 +255,7 @@
CXXFLAGS := $(CXXFLAGS_JDKLIB) $(JIMAGELIB_CPPFLAGS), \
CFLAGS_unix := -UDEBUG, \
MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libjimage/mapfile-vers, \
- LDFLAGS := $(LDFLAGS_JDKLIB) \
+ LDFLAGS := $(LDFLAGS_JDKLIB) $(LDFLAGS_CXX_JDK) \
$(call SET_SHARED_LIBRARY_ORIGIN), \
LDFLAGS_windows := -export:JIMAGE_Open -export:JIMAGE_Close \
-export:JIMAGE_PackageToModule \
--- a/jdk/make/lib/Lib-java.desktop.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/make/lib/Lib-java.desktop.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
--- a/jdk/make/rmic/Rmic-java.management.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/make/rmic/Rmic-java.management.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
--- a/jdk/make/rmic/RmicCommon.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/make/rmic/RmicCommon.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
--- a/jdk/src/java.base/share/classes/java/io/ObjectStreamClass.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/io/ObjectStreamClass.java Wed Oct 26 20:13:29 2016 +0000
@@ -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
@@ -1413,27 +1413,7 @@
* returned constructor (if any).
*/
private static Constructor<?> getSerializableConstructor(Class<?> cl) {
- Class<?> initCl = cl;
- while (Serializable.class.isAssignableFrom(initCl)) {
- if ((initCl = initCl.getSuperclass()) == null) {
- return null;
- }
- }
- try {
- Constructor<?> cons = initCl.getDeclaredConstructor((Class<?>[]) null);
- int mods = cons.getModifiers();
- if ((mods & Modifier.PRIVATE) != 0 ||
- ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0 &&
- !packageEquals(cl, initCl)))
- {
- return null;
- }
- cons = reflFactory.newConstructorForSerialization(cl, cons);
- cons.setAccessible(true);
- return cons;
- } catch (NoSuchMethodException ex) {
- return null;
- }
+ return reflFactory.newConstructorForSerialization(cl);
}
/**
--- a/jdk/src/java.base/share/classes/java/lang/Class.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/lang/Class.java Wed Oct 26 20:13:29 2016 +0000
@@ -557,7 +557,7 @@
Class<?> caller = Reflection.getCallerClass();
if (newInstanceCallerCache != caller) {
int modifiers = tmpConstructor.getModifiers();
- Reflection.ensureMemberAccess(caller, this, null, modifiers);
+ Reflection.ensureMemberAccess(caller, this, this, modifiers);
newInstanceCallerCache = caller;
}
// Run constructor
--- a/jdk/src/java.base/share/classes/java/lang/Deprecated.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/lang/Deprecated.java Wed Oct 26 20:13:29 2016 +0000
@@ -79,7 +79,7 @@
/**
* Returns the version in which the annotated element became deprecated.
* The version string is in the same format and namespace as the value of
- * the {@code @since} javadoc tag. The default value is the empty
+ * the {@code @since} javadoc tag. The default value is the empty
* string.
*
* @return the version string
--- a/jdk/src/java.base/share/classes/java/lang/Thread.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/lang/Thread.java Wed Oct 26 20:13:29 2016 +0000
@@ -504,11 +504,12 @@
}
/**
- * Creates a new Thread that inherits the given AccessControlContext.
+ * Creates a new Thread that inherits the given AccessControlContext
+ * but thread-local variables are not inherited.
* This is not a public constructor.
*/
Thread(Runnable target, AccessControlContext acc) {
- init(null, target, "Thread-" + nextThreadNum(), 0, acc, true);
+ init(null, target, "Thread-" + nextThreadNum(), 0, acc, false);
}
/**
--- a/jdk/src/java.base/share/classes/java/lang/module/ModuleFinder.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/lang/module/ModuleFinder.java Wed Oct 26 20:13:29 2016 +0000
@@ -33,7 +33,6 @@
import java.security.AccessController;
import java.security.Permission;
import java.security.PrivilegedAction;
-import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -333,7 +332,7 @@
*
* <p> When locating modules then any exceptions or errors thrown by the
* {@code find} or {@code findAll} methods of the underlying module finders
- * will be propogated to the caller of the resulting module finder's
+ * will be propagated to the caller of the resulting module finder's
* {@code find} or {@code findAll} methods. </p>
*
* @param finders
@@ -342,8 +341,8 @@
* @return A {@code ModuleFinder} that composes a sequence of module finders
*/
static ModuleFinder compose(ModuleFinder... finders) {
- final List<ModuleFinder> finderList = Arrays.asList(finders);
- finderList.forEach(Objects::requireNonNull);
+ // copy the list, also checking for nulls
+ final List<ModuleFinder> finderList = List.of(finders);
return new ModuleFinder() {
private final Map<String, ModuleReference> nameToModule = new HashMap<>();
--- a/jdk/src/java.base/share/classes/java/lang/module/SystemModuleFinder.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/lang/module/SystemModuleFinder.java Wed Oct 26 20:13:29 2016 +0000
@@ -44,6 +44,8 @@
import jdk.internal.jimage.ImageLocation;
import jdk.internal.jimage.ImageReader;
import jdk.internal.jimage.ImageReaderFactory;
+import jdk.internal.misc.JavaNetUriAccess;
+import jdk.internal.misc.SharedSecrets;
import jdk.internal.module.ModuleHashes;
import jdk.internal.module.ModuleHashes.HashSupplier;
import jdk.internal.module.SystemModules;
@@ -71,6 +73,8 @@
// ImageReader used to access all modules in the image
private static final ImageReader imageReader;
+ private static final JavaNetUriAccess jnua = SharedSecrets.getJavaNetUriAccess();
+
// the set of modules in the run-time image
private static final Set<ModuleReference> modules;
@@ -166,7 +170,8 @@
HashSupplier hash)
{
String mn = md.name();
- URI uri = URI.create("jrt:/" + mn);
+
+ URI uri = jnua.create("jrt", "/".concat(mn));
Supplier<ModuleReader> readerSupplier = new Supplier<>() {
@Override
--- a/jdk/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java Wed Oct 26 20:13:29 2016 +0000
@@ -312,22 +312,22 @@
// (See also Class.newInstance(), which uses a similar method.)
//
// A more complicated security check cache is needed for Method and Field
- // The cache can be either null (empty cache), a 2-array of {caller,target},
- // or a caller (with target implicitly equal to this.clazz).
- // In the 2-array case, the target is always different from the clazz.
+ // The cache can be either null (empty cache), a 2-array of {caller,targetClass},
+ // or a caller (with targetClass implicitly equal to memberClass).
+ // In the 2-array case, the targetClass is always different from the memberClass.
volatile Object securityCheckCache;
- void checkAccess(Class<?> caller, Class<?> clazz, Object obj, int modifiers)
+ final void checkAccess(Class<?> caller, Class<?> memberClass,
+ Class<?> targetClass, int modifiers)
throws IllegalAccessException
{
- if (caller == clazz) { // quick check
+ if (caller == memberClass) { // quick check
return; // ACCESS IS OK
}
Object cache = securityCheckCache; // read volatile
- Class<?> targetClass = clazz;
- if (obj != null
+ if (targetClass != null // instance member or constructor
&& Modifier.isProtected(modifiers)
- && ((targetClass = obj.getClass()) != clazz)) {
+ && targetClass != memberClass) {
// Must match a 2-list of { caller, targetClass }.
if (cache instanceof Class[]) {
Class<?>[] cache2 = (Class<?>[]) cache;
@@ -339,25 +339,27 @@
// subsumes range check for [0].)
}
} else if (cache == caller) {
- // Non-protected case (or obj.class == this.clazz).
+ // Non-protected case (or targetClass == memberClass or static member).
return; // ACCESS IS OK
}
// If no return, fall through to the slow path.
- slowCheckMemberAccess(caller, clazz, obj, modifiers, targetClass);
+ slowCheckMemberAccess(caller, memberClass, targetClass, modifiers);
}
// Keep all this slow stuff out of line:
- void slowCheckMemberAccess(Class<?> caller, Class<?> clazz, Object obj, int modifiers,
- Class<?> targetClass)
+ void slowCheckMemberAccess(Class<?> caller, Class<?> memberClass,
+ Class<?> targetClass, int modifiers)
throws IllegalAccessException
{
- Reflection.ensureMemberAccess(caller, clazz, obj, modifiers);
+ Reflection.ensureMemberAccess(caller, memberClass, targetClass, modifiers);
// Success: Update the cache.
- Object cache = ((targetClass == clazz)
- ? caller
- : new Class<?>[] { caller, targetClass });
+ Object cache = (targetClass != null
+ && Modifier.isProtected(modifiers)
+ && targetClass != memberClass)
+ ? new Class<?>[] { caller, targetClass }
+ : caller;
// Note: The two cache elements are not volatile,
// but they are effectively final. The Java memory model
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Constructor.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Constructor.java Wed Oct 26 20:13:29 2016 +0000
@@ -443,7 +443,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, null, modifiers);
+ checkAccess(caller, clazz, clazz, modifiers);
}
if ((clazz.getModifiers() & Modifier.ENUM) != 0)
throw new IllegalArgumentException("Cannot reflectively create enum objects");
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Field.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Field.java Wed Oct 26 20:13:29 2016 +0000
@@ -403,7 +403,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
return getFieldAccessor(obj).get(obj);
}
@@ -437,7 +437,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
return getFieldAccessor(obj).getBoolean(obj);
}
@@ -471,7 +471,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
return getFieldAccessor(obj).getByte(obj);
}
@@ -507,7 +507,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
return getFieldAccessor(obj).getChar(obj);
}
@@ -543,7 +543,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
return getFieldAccessor(obj).getShort(obj);
}
@@ -579,7 +579,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
return getFieldAccessor(obj).getInt(obj);
}
@@ -615,7 +615,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
return getFieldAccessor(obj).getLong(obj);
}
@@ -651,7 +651,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
return getFieldAccessor(obj).getFloat(obj);
}
@@ -687,7 +687,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
return getFieldAccessor(obj).getDouble(obj);
}
@@ -765,7 +765,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
getFieldAccessor(obj).set(obj, value);
}
@@ -801,7 +801,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
getFieldAccessor(obj).setBoolean(obj, z);
}
@@ -837,7 +837,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
getFieldAccessor(obj).setByte(obj, b);
}
@@ -873,7 +873,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
getFieldAccessor(obj).setChar(obj, c);
}
@@ -909,7 +909,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
getFieldAccessor(obj).setShort(obj, s);
}
@@ -945,7 +945,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
getFieldAccessor(obj).setInt(obj, i);
}
@@ -981,7 +981,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
getFieldAccessor(obj).setLong(obj, l);
}
@@ -1017,7 +1017,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
getFieldAccessor(obj).setFloat(obj, f);
}
@@ -1053,11 +1053,20 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
getFieldAccessor(obj).setDouble(obj, d);
}
+ // check access to field
+ private void checkAccess(Class<?> caller, Object obj)
+ throws IllegalAccessException
+ {
+ checkAccess(caller, clazz,
+ Modifier.isStatic(modifiers) ? null : obj.getClass(),
+ modifiers);
+ }
+
// security check is done before calling this method
private FieldAccessor getFieldAccessor(Object obj)
throws IllegalAccessException
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Method.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Method.java Wed Oct 26 20:13:29 2016 +0000
@@ -526,7 +526,9 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, clazz,
+ Modifier.isStatic(modifiers) ? null : obj.getClass(),
+ modifiers);
}
MethodAccessor ma = methodAccessor; // read volatile
if (ma == null) {
--- a/jdk/src/java.base/share/classes/java/net/CookieManager.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/net/CookieManager.java Wed Oct 26 20:13:29 2016 +0000
@@ -81,7 +81,7 @@
* <li>
* Currently, only CookieStore.add(URI, HttpCookie) and CookieStore.get(URI)
* are used by CookieManager. Others are for completeness and might be needed
- * by a more sophisticated CookieStore implementation, e.g. a NetscapeCookieSotre.
+ * by a more sophisticated CookieStore implementation, e.g. a NetscapeCookieStore.
* </li>
* </ul>
* </blockquote>
@@ -201,10 +201,9 @@
throw new IllegalArgumentException("Argument is null");
}
- Map<String, List<String>> cookieMap = new java.util.HashMap<>();
// if there's no default CookieStore, no way for us to get any cookie
if (cookieJar == null)
- return Collections.unmodifiableMap(cookieMap);
+ return Map.of();
boolean secureLink = "https".equalsIgnoreCase(uri.getScheme());
List<HttpCookie> cookies = new java.util.ArrayList<>();
@@ -244,8 +243,7 @@
// apply sort rule (RFC 2965 sec. 3.3.4)
List<String> cookieHeader = sortByPath(cookies);
- cookieMap.put("Cookie", cookieHeader);
- return Collections.unmodifiableMap(cookieMap);
+ return Map.of("Cookie", cookieHeader);
}
public void
--- a/jdk/src/java.base/share/classes/java/net/InetAddress.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/net/InetAddress.java Wed Oct 26 20:13:29 2016 +0000
@@ -321,6 +321,13 @@
public String getOriginalHostName(InetAddress ia) {
return ia.holder.getOriginalHostName();
}
+
+ public InetAddress getByName(String hostName,
+ InetAddress hostAddress)
+ throws UnknownHostException
+ {
+ return InetAddress.getByName(hostName, hostAddress);
+ }
}
);
init();
--- a/jdk/src/java.base/share/classes/java/net/URI.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/net/URI.java Wed Oct 26 20:13:29 2016 +0000
@@ -37,6 +37,9 @@
import java.nio.charset.CodingErrorAction;
import java.nio.charset.CharacterCodingException;
import java.text.Normalizer;
+import jdk.internal.loader.URLClassPath;
+import jdk.internal.misc.JavaNetUriAccess;
+import jdk.internal.misc.SharedSecrets;
import sun.nio.cs.ThreadLocalCoders;
import java.lang.Character; // for javadoc
@@ -820,6 +823,25 @@
}
/**
+ * Constructs a simple URI consisting of only a scheme and a pre-validated
+ * path. Provides a fast-path for some internal cases.
+ */
+ URI(String scheme, String path) {
+ assert validSchemeAndPath(scheme, path);
+ this.scheme = scheme;
+ this.path = path;
+ }
+
+ private static boolean validSchemeAndPath(String scheme, String path) {
+ try {
+ URI u = new URI(scheme + ":" + path);
+ return scheme.equals(u.scheme) && path.equals(u.path);
+ } catch (URISyntaxException e) {
+ return false;
+ }
+ }
+
+ /**
* Creates a URI by parsing the given string.
*
* <p> This convenience factory method works as if by invoking the {@link
@@ -3571,5 +3593,13 @@
}
}
-
+ static {
+ SharedSecrets.setJavaNetUriAccess(
+ new JavaNetUriAccess() {
+ public URI create(String scheme, String path) {
+ return new URI(scheme, path);
+ }
+ }
+ );
+ }
}
--- a/jdk/src/java.base/share/classes/java/net/URLClassLoader.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/net/URLClassLoader.java Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -51,7 +51,7 @@
import jdk.internal.loader.Resource;
import jdk.internal.loader.URLClassPath;
-import jdk.internal.misc.JavaNetAccess;
+import jdk.internal.misc.JavaNetURLClassLoaderAccess;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.perf.PerfCounter;
import sun.net.www.ParseUtil;
@@ -767,10 +767,11 @@
}
static {
- SharedSecrets.setJavaNetAccess(
- new JavaNetAccess() {
- public URLClassPath getURLClassPath(URLClassLoader u) {
- return u.ucp;
+ SharedSecrets.setJavaNetURLClassLoaderAccess(
+ new JavaNetURLClassLoaderAccess() {
+ @Override
+ public AccessControlContext getAccessControlContext(URLClassLoader u) {
+ return u.acc;
}
}
);
--- a/jdk/src/java.base/share/classes/java/net/URLPermission.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/net/URLPermission.java Wed Oct 26 20:13:29 2016 +0000
@@ -217,7 +217,7 @@
* where method-names is the list of methods separated by commas
* and header-names is the list of permitted headers separated by commas.
* There is no white space in the returned String. If header-names is empty
- * then the colon separator will not be present.
+ * then the colon separator may not be present.
*/
public String getActions() {
return actions;
--- a/jdk/src/java.base/share/classes/java/nio/file/FileTreeIterator.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/nio/file/FileTreeIterator.java Wed Oct 26 20:13:29 2016 +0000
@@ -31,11 +31,10 @@
import java.util.Arrays;
import java.util.Iterator;
import java.util.NoSuchElementException;
-import java.util.Objects;
import java.nio.file.FileTreeWalker.Event;
/**
- * An {@code Iterator to iterate over the nodes of a file tree.
+ * An {@code Iterator} to iterate over the nodes of a file tree.
*
* <pre>{@code
* try (FileTreeIterator iterator = new FileTreeIterator(start, maxDepth, options)) {
@@ -62,7 +61,7 @@
* @throws SecurityException
* if the security manager denies access to the starting file
* @throws NullPointerException
- * if {@code start} or {@code options} is {@ocde null} or
+ * if {@code start} or {@code options} is {@code null} or
* the options array contains a {@code null} element
*/
FileTreeIterator(Path start, int maxDepth, FileVisitOption... options)
--- a/jdk/src/java.base/share/classes/java/nio/file/FileTreeWalker.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/nio/file/FileTreeWalker.java Wed Oct 26 20:13:29 2016 +0000
@@ -171,7 +171,7 @@
* if {@code options} contains an element that is not a
* {@code FileVisitOption}
* @throws NullPointerException
- * if {@code options} is {@ocde null} or the options
+ * if {@code options} is {@code null} or the options
* array contains a {@code null} element
*/
FileTreeWalker(Collection<FileVisitOption> options, int maxDepth) {
--- a/jdk/src/java.base/share/classes/java/security/KeyStoreSpi.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/security/KeyStoreSpi.java Wed Oct 26 20:13:29 2016 +0000
@@ -479,6 +479,10 @@
} else if (engineIsKeyEntry(alias)) {
KeyStore.PasswordProtection pp =
(KeyStore.PasswordProtection)protParam;
+ if (pp.getProtectionAlgorithm() != null) {
+ throw new KeyStoreException(
+ "unsupported password protection algorithm");
+ }
char[] password = pp.getPassword();
Key key = engineGetKey(alias, password);
@@ -524,6 +528,10 @@
KeyStore.PasswordProtection pProtect = null;
if (protParam != null) {
pProtect = (KeyStore.PasswordProtection)protParam;
+ if (pProtect.getProtectionAlgorithm() != null) {
+ throw new KeyStoreException(
+ "unsupported password protection algorithm");
+ }
}
// set entry
--- a/jdk/src/java.base/share/classes/java/security/MessageDigest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/security/MessageDigest.java Wed Oct 26 20:13:29 2016 +0000
@@ -32,10 +32,13 @@
import java.io.PrintStream;
import java.io.InputStream;
import java.io.ByteArrayInputStream;
-
+import java.security.InvalidKeyException;
import java.nio.ByteBuffer;
import sun.security.util.Debug;
+import sun.security.util.MessageDigestSpi2;
+
+import javax.crypto.SecretKey;
/**
* This MessageDigest class provides applications the functionality of a
@@ -548,7 +551,7 @@
* and its original parent (Object).
*/
- static class Delegate extends MessageDigest {
+ static class Delegate extends MessageDigest implements MessageDigestSpi2 {
// The provider implementation (delegate)
private MessageDigestSpi digestSpi;
@@ -601,6 +604,14 @@
digestSpi.engineUpdate(input);
}
+ public void engineUpdate(SecretKey key) throws InvalidKeyException {
+ if (digestSpi instanceof MessageDigestSpi2) {
+ ((MessageDigestSpi2)digestSpi).engineUpdate(key);
+ } else {
+ throw new UnsupportedOperationException
+ ("Digest does not support update of SecretKey object");
+ }
+ }
protected byte[] engineDigest() {
return digestSpi.engineDigest();
}
--- a/jdk/src/java.base/share/classes/java/security/ProtectionDomain.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/security/ProtectionDomain.java Wed Oct 26 20:13:29 2016 +0000
@@ -89,6 +89,11 @@
AccessController.getContext(), context);
}
+ @Override
+ public ProtectionDomain[] getProtectDomains(AccessControlContext context) {
+ return context.getContext();
+ }
+
private static AccessControlContext getCombinedACC(
AccessControlContext context, AccessControlContext stack) {
AccessControlContext acc =
--- a/jdk/src/java.base/share/classes/java/security/Signature.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/security/Signature.java Wed Oct 26 20:13:29 2016 +0000
@@ -37,7 +37,6 @@
import java.security.Provider.Service;
import javax.crypto.Cipher;
-import javax.crypto.CipherSpi;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.BadPaddingException;
import javax.crypto.NoSuchPaddingException;
@@ -180,15 +179,12 @@
private static final String RSA_CIPHER = "RSA/ECB/PKCS1Padding";
// all the services we need to lookup for compatibility with Cipher
- private static final List<ServiceId> rsaIds = Arrays.asList(
- new ServiceId[] {
- new ServiceId("Signature", "NONEwithRSA"),
- new ServiceId("Cipher", "RSA/ECB/PKCS1Padding"),
- new ServiceId("Cipher", "RSA/ECB"),
- new ServiceId("Cipher", "RSA//PKCS1Padding"),
- new ServiceId("Cipher", "RSA"),
- }
- );
+ private static final List<ServiceId> rsaIds = List.of(
+ new ServiceId("Signature", "NONEwithRSA"),
+ new ServiceId("Cipher", "RSA/ECB/PKCS1Padding"),
+ new ServiceId("Cipher", "RSA/ECB"),
+ new ServiceId("Cipher", "RSA//PKCS1Padding"),
+ new ServiceId("Cipher", "RSA"));
/**
* Returns a Signature object that implements the specified signature
--- a/jdk/src/java.base/share/classes/java/time/Duration.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/time/Duration.java Wed Oct 26 20:13:29 2016 +0000
@@ -88,8 +88,6 @@
import java.time.temporal.TemporalAmount;
import java.time.temporal.TemporalUnit;
import java.time.temporal.UnsupportedTemporalTypeException;
-import java.util.Arrays;
-import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
@@ -578,8 +576,7 @@
* the simple initialization in Duration.
*/
private static class DurationUnits {
- static final List<TemporalUnit> UNITS =
- Collections.unmodifiableList(Arrays.<TemporalUnit>asList(SECONDS, NANOS));
+ static final List<TemporalUnit> UNITS = List.of(SECONDS, NANOS);
}
//-----------------------------------------------------------------------
--- a/jdk/src/java.base/share/classes/java/time/Instant.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/time/Instant.java Wed Oct 26 20:13:29 2016 +0000
@@ -610,7 +610,7 @@
* <p>
* The epoch second count is a simple incrementing count of seconds where
* second 0 is 1970-01-01T00:00:00Z.
- * The nanosecond part of the day is returned by {@code getNanosOfSecond}.
+ * The nanosecond part of the day is returned by {@link #getNano}.
*
* @return the seconds from the epoch of 1970-01-01T00:00:00Z
*/
@@ -623,7 +623,7 @@
* of the second.
* <p>
* The nanosecond-of-second value measures the total number of nanoseconds from
- * the second returned by {@code getEpochSecond}.
+ * the second returned by {@link #getEpochSecond}.
*
* @return the nanoseconds within the second, always positive, never exceeds 999,999,999
*/
--- a/jdk/src/java.base/share/classes/java/time/Period.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/time/Period.java Wed Oct 26 20:13:29 2016 +0000
@@ -83,8 +83,6 @@
import java.time.temporal.TemporalQueries;
import java.time.temporal.TemporalUnit;
import java.time.temporal.UnsupportedTemporalTypeException;
-import java.util.Arrays;
-import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
@@ -152,8 +150,7 @@
/**
* The set of supported units.
*/
- private static final List<TemporalUnit> SUPPORTED_UNITS =
- Collections.unmodifiableList(Arrays.<TemporalUnit>asList(YEARS, MONTHS, DAYS));
+ private static final List<TemporalUnit> SUPPORTED_UNITS = List.of(YEARS, MONTHS, DAYS);
/**
* The number of years.
--- a/jdk/src/java.base/share/classes/java/time/ZoneId.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/time/ZoneId.java Wed Oct 26 20:13:29 2016 +0000
@@ -76,14 +76,14 @@
import java.time.zone.ZoneRules;
import java.time.zone.ZoneRulesException;
import java.time.zone.ZoneRulesProvider;
-import java.util.Collections;
-import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.TimeZone;
+import static java.util.Map.entry;
+
/**
* A time-zone ID, such as {@code Europe/Paris}.
* <p>
@@ -220,39 +220,36 @@
* </ul>
* The map is unmodifiable.
*/
- public static final Map<String, String> SHORT_IDS;
- static {
- Map<String, String> map = new HashMap<>(64);
- map.put("ACT", "Australia/Darwin");
- map.put("AET", "Australia/Sydney");
- map.put("AGT", "America/Argentina/Buenos_Aires");
- map.put("ART", "Africa/Cairo");
- map.put("AST", "America/Anchorage");
- map.put("BET", "America/Sao_Paulo");
- map.put("BST", "Asia/Dhaka");
- map.put("CAT", "Africa/Harare");
- map.put("CNT", "America/St_Johns");
- map.put("CST", "America/Chicago");
- map.put("CTT", "Asia/Shanghai");
- map.put("EAT", "Africa/Addis_Ababa");
- map.put("ECT", "Europe/Paris");
- map.put("IET", "America/Indiana/Indianapolis");
- map.put("IST", "Asia/Kolkata");
- map.put("JST", "Asia/Tokyo");
- map.put("MIT", "Pacific/Apia");
- map.put("NET", "Asia/Yerevan");
- map.put("NST", "Pacific/Auckland");
- map.put("PLT", "Asia/Karachi");
- map.put("PNT", "America/Phoenix");
- map.put("PRT", "America/Puerto_Rico");
- map.put("PST", "America/Los_Angeles");
- map.put("SST", "Pacific/Guadalcanal");
- map.put("VST", "Asia/Ho_Chi_Minh");
- map.put("EST", "-05:00");
- map.put("MST", "-07:00");
- map.put("HST", "-10:00");
- SHORT_IDS = Collections.unmodifiableMap(map);
- }
+ public static final Map<String, String> SHORT_IDS = Map.ofEntries(
+ entry("ACT", "Australia/Darwin"),
+ entry("AET", "Australia/Sydney"),
+ entry("AGT", "America/Argentina/Buenos_Aires"),
+ entry("ART", "Africa/Cairo"),
+ entry("AST", "America/Anchorage"),
+ entry("BET", "America/Sao_Paulo"),
+ entry("BST", "Asia/Dhaka"),
+ entry("CAT", "Africa/Harare"),
+ entry("CNT", "America/St_Johns"),
+ entry("CST", "America/Chicago"),
+ entry("CTT", "Asia/Shanghai"),
+ entry("EAT", "Africa/Addis_Ababa"),
+ entry("ECT", "Europe/Paris"),
+ entry("IET", "America/Indiana/Indianapolis"),
+ entry("IST", "Asia/Kolkata"),
+ entry("JST", "Asia/Tokyo"),
+ entry("MIT", "Pacific/Apia"),
+ entry("NET", "Asia/Yerevan"),
+ entry("NST", "Pacific/Auckland"),
+ entry("PLT", "Asia/Karachi"),
+ entry("PNT", "America/Phoenix"),
+ entry("PRT", "America/Puerto_Rico"),
+ entry("PST", "America/Los_Angeles"),
+ entry("SST", "Pacific/Guadalcanal"),
+ entry("VST", "Asia/Ho_Chi_Minh"),
+ entry("EST", "-05:00"),
+ entry("MST", "-07:00"),
+ entry("HST", "-10:00")
+ );
/**
* Serialization version.
*/
--- a/jdk/src/java.base/share/classes/java/time/chrono/ChronoPeriodImpl.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/time/chrono/ChronoPeriodImpl.java Wed Oct 26 20:13:29 2016 +0000
@@ -77,8 +77,6 @@
import java.time.temporal.TemporalUnit;
import java.time.temporal.UnsupportedTemporalTypeException;
import java.time.temporal.ValueRange;
-import java.util.Arrays;
-import java.util.Collections;
import java.util.List;
import java.util.Objects;
@@ -105,8 +103,7 @@
/**
* The set of supported units.
*/
- private static final List<TemporalUnit> SUPPORTED_UNITS =
- Collections.unmodifiableList(Arrays.<TemporalUnit>asList(YEARS, MONTHS, DAYS));
+ private static final List<TemporalUnit> SUPPORTED_UNITS = List.of(YEARS, MONTHS, DAYS);
/**
* The chronology.
--- a/jdk/src/java.base/share/classes/java/time/chrono/HijrahChronology.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/time/chrono/HijrahChronology.java Wed Oct 26 20:13:29 2016 +0000
@@ -59,10 +59,7 @@
import static java.time.temporal.ChronoField.EPOCH_DAY;
-import java.io.File;
-import java.io.FileInputStream;
import java.io.FilePermission;
-import java.io.IOException;
import java.io.InputStream;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
@@ -83,7 +80,6 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.Objects;
import java.util.Properties;
import sun.util.logging.PlatformLogger;
@@ -512,7 +508,7 @@
@Override
public List<Era> eras() {
- return Arrays.<Era>asList(HijrahEra.values());
+ return List.of(HijrahEra.values());
}
//-----------------------------------------------------------------------
--- a/jdk/src/java.base/share/classes/java/time/chrono/HijrahDate.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/time/chrono/HijrahDate.java Wed Oct 26 20:13:29 2016 +0000
@@ -368,7 +368,7 @@
if (field instanceof ChronoField) {
switch ((ChronoField) field) {
case DAY_OF_WEEK: return getDayOfWeek();
- case ALIGNED_DAY_OF_WEEK_IN_MONTH: return ((getDayOfWeek() - 1) % 7) + 1;
+ case ALIGNED_DAY_OF_WEEK_IN_MONTH: return ((dayOfMonth - 1) % 7) + 1;
case ALIGNED_DAY_OF_WEEK_IN_YEAR: return ((getDayOfYear() - 1) % 7) + 1;
case DAY_OF_MONTH: return this.dayOfMonth;
case DAY_OF_YEAR: return this.getDayOfYear();
--- a/jdk/src/java.base/share/classes/java/time/chrono/IsoChronology.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/time/chrono/IsoChronology.java Wed Oct 26 20:13:29 2016 +0000
@@ -90,7 +90,6 @@
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalField;
import java.time.temporal.ValueRange;
-import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -492,7 +491,7 @@
@Override
public List<Era> eras() {
- return Arrays.<Era>asList(IsoEra.values());
+ return List.of(IsoEra.values());
}
//-----------------------------------------------------------------------
--- a/jdk/src/java.base/share/classes/java/time/chrono/JapaneseChronology.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/time/chrono/JapaneseChronology.java Wed Oct 26 20:13:29 2016 +0000
@@ -81,7 +81,6 @@
import java.time.temporal.TemporalField;
import java.time.temporal.UnsupportedTemporalTypeException;
import java.time.temporal.ValueRange;
-import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;
@@ -379,7 +378,7 @@
@Override
public List<Era> eras() {
- return Arrays.<Era>asList(JapaneseEra.values());
+ return List.of(JapaneseEra.values());
}
JapaneseEra getCurrentEra() {
--- a/jdk/src/java.base/share/classes/java/time/chrono/MinguoChronology.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/time/chrono/MinguoChronology.java Wed Oct 26 20:13:29 2016 +0000
@@ -72,7 +72,6 @@
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalField;
import java.time.temporal.ValueRange;
-import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -306,7 +305,7 @@
@Override
public List<Era> eras() {
- return Arrays.<Era>asList(MinguoEra.values());
+ return List.of(MinguoEra.values());
}
//-----------------------------------------------------------------------
--- a/jdk/src/java.base/share/classes/java/time/chrono/ThaiBuddhistChronology.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/time/chrono/ThaiBuddhistChronology.java Wed Oct 26 20:13:29 2016 +0000
@@ -342,7 +342,7 @@
@Override
public List<Era> eras() {
- return Arrays.<Era>asList(ThaiBuddhistEra.values());
+ return List.of(ThaiBuddhistEra.values());
}
//-----------------------------------------------------------------------
--- a/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatter.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatter.java Wed Oct 26 20:13:29 2016 +0000
@@ -1685,6 +1685,7 @@
public DateTimeFormatter withResolverFields(TemporalField... resolverFields) {
Set<TemporalField> fields = null;
if (resolverFields != null) {
+ // Set.of cannot be used because it is hostile to nulls and duplicate elements
fields = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(resolverFields)));
}
if (Objects.equals(this.resolverFields, fields)) {
--- a/jdk/src/java.base/share/classes/java/time/format/DateTimeTextProvider.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/time/format/DateTimeTextProvider.java Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -349,25 +349,40 @@
if (field == MONTH_OF_YEAR) {
for (TextStyle textStyle : TextStyle.values()) {
- Map<String, Integer> displayNames = CalendarDataUtility.retrieveJavaTimeFieldValueNames(
- "gregory", Calendar.MONTH, textStyle.toCalendarStyle(), locale);
Map<Long, String> map = new HashMap<>();
- if (displayNames != null) {
- for (Entry<String, Integer> entry : displayNames.entrySet()) {
- map.put((long) (entry.getValue() + 1), entry.getKey());
- }
-
- } else {
- // Narrow names may have duplicated names, such as "J" for January, Jun, July.
- // Get names one by one in that case.
+ // Narrow names may have duplicated names, such as "J" for January, June, July.
+ // Get names one by one in that case.
+ if ((textStyle.equals(TextStyle.NARROW) ||
+ textStyle.equals(TextStyle.NARROW_STANDALONE))) {
for (int month = Calendar.JANUARY; month <= Calendar.DECEMBER; month++) {
String name;
name = CalendarDataUtility.retrieveJavaTimeFieldValueName(
- "gregory", Calendar.MONTH, month, textStyle.toCalendarStyle(), locale);
+ "gregory", Calendar.MONTH,
+ month, textStyle.toCalendarStyle(), locale);
if (name == null) {
break;
}
- map.put((long) (month + 1), name);
+ map.put((month + 1L), name);
+ }
+ } else {
+ Map<String, Integer> displayNames = CalendarDataUtility.retrieveJavaTimeFieldValueNames(
+ "gregory", Calendar.MONTH, textStyle.toCalendarStyle(), locale);
+ if (displayNames != null) {
+ for (Entry<String, Integer> entry : displayNames.entrySet()) {
+ map.put((long)(entry.getValue() + 1), entry.getKey());
+ }
+ } else {
+ // Although probability is very less, but if other styles have duplicate names.
+ // Get names one by one in that case.
+ for (int month = Calendar.JANUARY; month <= Calendar.DECEMBER; month++) {
+ String name;
+ name = CalendarDataUtility.retrieveJavaTimeFieldValueName(
+ "gregory", Calendar.MONTH, month, textStyle.toCalendarStyle(), locale);
+ if (name == null) {
+ break;
+ }
+ map.put((month + 1L), name);
+ }
}
}
if (!map.isEmpty()) {
@@ -379,26 +394,41 @@
if (field == DAY_OF_WEEK) {
for (TextStyle textStyle : TextStyle.values()) {
- Map<String, Integer> displayNames = CalendarDataUtility.retrieveJavaTimeFieldValueNames(
- "gregory", Calendar.DAY_OF_WEEK, textStyle.toCalendarStyle(), locale);
Map<Long, String> map = new HashMap<>();
- if (displayNames != null) {
- for (Entry<String, Integer> entry : displayNames.entrySet()) {
- map.put((long)toWeekDay(entry.getValue()), entry.getKey());
- }
-
- } else {
- // Narrow names may have duplicated names, such as "S" for Sunday and Saturday.
- // Get names one by one in that case.
+ // Narrow names may have duplicated names, such as "S" for Sunday and Saturday.
+ // Get names one by one in that case.
+ if ((textStyle.equals(TextStyle.NARROW) ||
+ textStyle.equals(TextStyle.NARROW_STANDALONE))) {
for (int wday = Calendar.SUNDAY; wday <= Calendar.SATURDAY; wday++) {
String name;
name = CalendarDataUtility.retrieveJavaTimeFieldValueName(
- "gregory", Calendar.DAY_OF_WEEK, wday, textStyle.toCalendarStyle(), locale);
+ "gregory", Calendar.DAY_OF_WEEK,
+ wday, textStyle.toCalendarStyle(), locale);
if (name == null) {
break;
}
map.put((long)toWeekDay(wday), name);
}
+ } else {
+ Map<String, Integer> displayNames = CalendarDataUtility.retrieveJavaTimeFieldValueNames(
+ "gregory", Calendar.DAY_OF_WEEK, textStyle.toCalendarStyle(), locale);
+ if (displayNames != null) {
+ for (Entry<String, Integer> entry : displayNames.entrySet()) {
+ map.put((long)toWeekDay(entry.getValue()), entry.getKey());
+ }
+ } else {
+ // Although probability is very less, but if other styles have duplicate names.
+ // Get names one by one in that case.
+ for (int wday = Calendar.SUNDAY; wday <= Calendar.SATURDAY; wday++) {
+ String name;
+ name = CalendarDataUtility.retrieveJavaTimeFieldValueName(
+ "gregory", Calendar.DAY_OF_WEEK, wday, textStyle.toCalendarStyle(), locale);
+ if (name == null) {
+ break;
+ }
+ map.put((long)toWeekDay(wday), name);
+ }
+ }
}
if (!map.isEmpty()) {
styleMap.put(textStyle, map);
--- a/jdk/src/java.base/share/classes/java/time/zone/ZoneOffsetTransition.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/time/zone/ZoneOffsetTransition.java Wed Oct 26 20:13:29 2016 +0000
@@ -387,9 +387,9 @@
*/
List<ZoneOffset> getValidOffsets() {
if (isGap()) {
- return Collections.emptyList();
+ return List.of();
}
- return Arrays.asList(getOffsetBefore(), getOffsetAfter());
+ return List.of(getOffsetBefore(), getOffsetAfter());
}
//-----------------------------------------------------------------------
--- a/jdk/src/java.base/share/classes/java/time/zone/ZoneRules.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/time/zone/ZoneRules.java Wed Oct 26 20:13:29 2016 +0000
@@ -303,7 +303,6 @@
* Creates an instance of ZoneRules that has fixed zone rules.
*
* @param offset the offset this fixed zone rules is based on, not null
- * @return the zone rules, not null
* @see #isFixedOffset()
*/
private ZoneRules(ZoneOffset offset) {
@@ -970,7 +969,7 @@
* @return an immutable list of transition rules, not null
*/
public List<ZoneOffsetTransitionRule> getTransitionRules() {
- return Collections.unmodifiableList(Arrays.asList(lastRules));
+ return List.of(lastRules);
}
/**
--- a/jdk/src/java.base/share/classes/java/util/Date.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/util/Date.java Wed Oct 26 20:13:29 2016 +0000
@@ -85,12 +85,12 @@
* further information is the U.S. Naval Observatory, particularly
* the Directorate of Time at:
* <blockquote><pre>
- * <a href=http://tycho.usno.navy.mil>http://tycho.usno.navy.mil</a>
+ * <a href="http://www.usno.navy.mil">http://www.usno.navy.mil</a>
* </pre></blockquote>
* <p>
* and their definitions of "Systems of Time" at:
* <blockquote><pre>
- * <a href=http://tycho.usno.navy.mil/systime.html>http://tycho.usno.navy.mil/systime.html</a>
+ * <a href="http://www.usno.navy.mil/USNO/time/master-clock/systems-of-time">http://www.usno.navy.mil/USNO/time/master-clock/systems-of-time</a>
* </pre></blockquote>
* <p>
* In all methods of class {@code Date} that accept or return
--- a/jdk/src/java.base/share/classes/java/util/Optional.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/util/Optional.java Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -236,7 +236,7 @@
* present, otherwise an empty {@code Optional}
* @throws NullPointerException if the mapping function is {@code null}
*/
- public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
+ public <U> Optional<U> map(Function<? super T, ? extends U> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent()) {
return empty();
@@ -264,12 +264,14 @@
* @throws NullPointerException if the mapping function is {@code null} or
* returns a {@code null} result
*/
- public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {
+ public <U> Optional<U> flatMap(Function<? super T, ? extends Optional<? extends U>> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent()) {
return empty();
} else {
- return Objects.requireNonNull(mapper.apply(value));
+ @SuppressWarnings("unchecked")
+ Optional<U> r = (Optional<U>) mapper.apply(value);
+ return Objects.requireNonNull(r);
}
}
@@ -286,12 +288,14 @@
* produces a {@code null} result
* @since 9
*/
- public Optional<T> or(Supplier<Optional<T>> supplier) {
+ public Optional<T> or(Supplier<? extends Optional<? extends T>> supplier) {
Objects.requireNonNull(supplier);
if (isPresent()) {
return this;
} else {
- return Objects.requireNonNull(supplier.get());
+ @SuppressWarnings("unchecked")
+ Optional<T> r = (Optional<T>) supplier.get();
+ return Objects.requireNonNull(r);
}
}
--- a/jdk/src/java.base/share/classes/java/util/PropertyResourceBundle.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/util/PropertyResourceBundle.java Wed Oct 26 20:13:29 2016 +0000
@@ -63,7 +63,7 @@
* files containing the resource data. <code>ResourceBundle.getBundle</code>
* will automatically look for the appropriate properties file and create a
* <code>PropertyResourceBundle</code> that refers to it. See
- * {@link ResourceBundle#getBundle(java.lang.String, java.util.Locale, java.lang.ClassLoader) ResourceBundle.getBundle}
+ * {@link ResourceBundle#getBundle(String, Locale, ClassLoader) ResourceBundle.getBundle}
* for a complete description of the search and instantiation strategy.
*
* <p>
@@ -105,19 +105,14 @@
* </pre>
* </blockquote>
*
- * <p>
- * The implementation of a {@code PropertyResourceBundle} subclass must be
- * thread-safe if it's simultaneously used by multiple threads. The default
- * implementations of the non-abstract methods in this class are thread-safe.
- *
- * <p>
- * <strong>Note:</strong> PropertyResourceBundle can be constructed either
- * from an InputStream or a Reader, which represents a property file.
- * Constructing a PropertyResourceBundle instance from an InputStream requires
- * that the input stream be encoded in UTF-8. By default, if a
+ * @apiNote
+ * {@code PropertyResourceBundle} can be constructed either
+ * from an {@code InputStream} or a {@code Reader}, which represents a property file.
+ * Constructing a {@code PropertyResourceBundle} instance from an {@code InputStream}
+ * requires that the input stream be encoded in {@code UTF-8}. By default, if a
* {@link java.nio.charset.MalformedInputException} or an
* {@link java.nio.charset.UnmappableCharacterException} occurs on reading the
- * input stream, then the PropertyResourceBundle instance resets to the state
+ * input stream, then the {@code PropertyResourceBundle} instance resets to the state
* before the exception, re-reads the input stream in {@code ISO-8859-1}, and
* continues reading. If the system property
* {@code java.util.PropertyResourceBundle.encoding} is set to either
@@ -126,8 +121,15 @@
* If "ISO-8859-1" is specified, characters that cannot be represented in
* ISO-8859-1 encoding must be represented by Unicode Escapes as defined in section
* 3.3 of <cite>The Java™ Language Specification</cite>
- * whereas the other constructor which takes a Reader does not have that limitation.
+ * whereas the other constructor which takes a {@code Reader} does not have that limitation.
* Other encoding values are ignored for this system property.
+ * The system property is read and evaluated when initializing this class.
+ * Changing or removing the property has no effect after the initialization.
+ *
+ * @implSpec
+ * The implementation of a {@code PropertyResourceBundle} subclass must be
+ * thread-safe if it's simultaneously used by multiple threads. The default
+ * implementations of the non-abstract methods in this class are thread-safe.
*
* @see ResourceBundle
* @see ListResourceBundle
@@ -144,16 +146,18 @@
/**
* Creates a property resource bundle from an {@link java.io.InputStream
- * InputStream}. This constructor reads the property file in UTF-8 by default.
- * If a {@link java.nio.charset.MalformedInputException} or an
- * {@link java.nio.charset.UnmappableCharacterException} occurs on reading the
- * input stream, then the PropertyResourceBundle instance resets to the state
- * before the exception, re-reads the input stream in {@code ISO-8859-1} and
- * continues reading. If the system property
- * {@code java.util.PropertyResourceBundle.encoding} is set to either
- * "ISO-8859-1" or "UTF-8", the input stream is solely read in that encoding,
- * and throws the exception if it encounters an invalid sequence. Other
- * encoding values are ignored for this system property.
+ * InputStream}. This constructor reads the property file in UTF-8 by default.
+ * If a {@link java.nio.charset.MalformedInputException} or an
+ * {@link java.nio.charset.UnmappableCharacterException} occurs on reading the
+ * input stream, then the PropertyResourceBundle instance resets to the state
+ * before the exception, re-reads the input stream in {@code ISO-8859-1} and
+ * continues reading. If the system property
+ * {@code java.util.PropertyResourceBundle.encoding} is set to either
+ * "ISO-8859-1" or "UTF-8", the input stream is solely read in that encoding,
+ * and throws the exception if it encounters an invalid sequence. Other
+ * encoding values are ignored for this system property.
+ * The system property is read and evaluated when initializing this class.
+ * Changing or removing the property has no effect after the initialization.
*
* @param stream an InputStream that represents a property file
* to read from.
--- a/jdk/src/java.base/share/classes/java/util/ResourceBundle.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/util/ResourceBundle.java Wed Oct 26 20:13:29 2016 +0000
@@ -2491,34 +2491,29 @@
/**
* The default format <code>List</code>, which contains the strings
* <code>"java.class"</code> and <code>"java.properties"</code>, in
- * this order. This <code>List</code> is {@linkplain
- * Collections#unmodifiableList(List) unmodifiable}.
+ * this order. This <code>List</code> is unmodifiable.
*
* @see #getFormats(String)
*/
public static final List<String> FORMAT_DEFAULT
- = Collections.unmodifiableList(Arrays.asList("java.class",
- "java.properties"));
+ = List.of("java.class", "java.properties");
/**
* The class-only format <code>List</code> containing
- * <code>"java.class"</code>. This <code>List</code> is {@linkplain
- * Collections#unmodifiableList(List) unmodifiable}.
+ * <code>"java.class"</code>. This <code>List</code> is unmodifiable.
*
* @see #getFormats(String)
*/
- public static final List<String> FORMAT_CLASS
- = Collections.unmodifiableList(Arrays.asList("java.class"));
+ public static final List<String> FORMAT_CLASS = List.of("java.class");
/**
* The properties-only format <code>List</code> containing
- * <code>"java.properties"</code>. This <code>List</code> is
- * {@linkplain Collections#unmodifiableList(List) unmodifiable}.
+ * <code>"java.properties"</code>. This <code>List</code> is unmodifiable.
*
* @see #getFormats(String)
*/
public static final List<String> FORMAT_PROPERTIES
- = Collections.unmodifiableList(Arrays.asList("java.properties"));
+ = List.of("java.properties");
/**
* The time-to-live constant for not caching loaded resource bundle
--- a/jdk/src/java.base/share/classes/java/util/spi/ToolProvider.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/util/spi/ToolProvider.java Wed Oct 26 20:13:29 2016 +0000
@@ -56,8 +56,8 @@
/**
* Returns the name of this tool provider.
*
- * @apiNote It is recommended that the name be the same as would be used on
- * the command line: for example, "javac", "jar", "jlink".
+ * @apiNote It is recommended that the name be the same as would be
+ * used on the command line: for example, "javac", "jar", "jlink".
*
* @return the name of this tool provider
*/
@@ -67,12 +67,13 @@
* Runs an instance of the tool, returning zero for a successful run.
* Any non-zero return value indicates a tool-specific error during the
* execution.
+ *
* Two streams should be provided, for "expected" output, and for any
* error messages. If it is not necessary to distinguish the output,
* the same stream may be used for both.
*
* @apiNote The interpretation of the arguments will be specific to
- * each tool.
+ * each tool.
*
* @param out a stream to which "expected" output should be written
*
@@ -81,12 +82,13 @@
* @param args the command-line arguments for the tool
*
* @return the result of executing the tool.
- * A return value of 0 means the tool did not encounter any errors;
- * any other value indicates that at least one error occurred during
- * execution.
+ * A return value of 0 means the tool did not encounter any errors;
+ * any other value indicates that at least one error occurred
+ * during execution.
*
* @throws NullPointerException if any of the arguments are {@code null},
- * or if there are any {@code null} values in the {@code args} array
+ * or if there are any {@code null} values in the {@code args}
+ * array
*/
int run(PrintWriter out, PrintWriter err, String... args);
@@ -94,16 +96,17 @@
* Runs an instance of the tool, returning zero for a successful run.
* Any non-zero return value indicates a tool-specific error during the
* execution.
+ *
* Two streams should be provided, for "expected" output, and for any
* error messages. If it is not necessary to distinguish the output,
* the same stream may be used for both.
*
* @apiNote The interpretation of the arguments will be specific to
- * each tool.
+ * each tool.
*
* @implNote This implementation wraps the {@code out} and {@code err}
- * streams within {@link PrintWriter}s, and then calls
- * {@link run(PrintWriter, PrintWriter, String[])}.
+ * streams within {@link PrintWriter}s, and then calls
+ * {@link #run(PrintWriter, PrintWriter, String[])}.
*
* @param out a stream to which "expected" output should be written
*
@@ -112,12 +115,13 @@
* @param args the command-line arguments for the tool
*
* @return the result of executing the tool.
- * A return value of 0 means the tool did not encounter any errors;
- * any other value indicates that at least one error occurred during
- * execution.
+ * A return value of 0 means the tool did not encounter any errors;
+ * any other value indicates that at least one error occurred
+ * during execution.
*
* @throws NullPointerException if any of the arguments are {@code null},
- * or if there are any {@code null} values in the {@code args} array
+ * or if there are any {@code null} values in the {@code args}
+ * array
*/
default int run(PrintStream out, PrintStream err, String... args) {
Objects.requireNonNull(out);
--- a/jdk/src/java.base/share/classes/java/util/stream/Collectors.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/util/stream/Collectors.java Wed Oct 26 20:13:29 2016 +0000
@@ -27,7 +27,6 @@
import java.util.AbstractMap;
import java.util.AbstractSet;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
@@ -1720,12 +1719,12 @@
@Override
public Set<Map.Entry<Boolean, T>> entrySet() {
- return new AbstractSet<Map.Entry<Boolean, T>>() {
+ return new AbstractSet<>() {
@Override
public Iterator<Map.Entry<Boolean, T>> iterator() {
Map.Entry<Boolean, T> falseEntry = new SimpleImmutableEntry<>(false, forFalse);
Map.Entry<Boolean, T> trueEntry = new SimpleImmutableEntry<>(true, forTrue);
- return Arrays.asList(falseEntry, trueEntry).iterator();
+ return List.of(falseEntry, trueEntry).iterator();
}
@Override
--- a/jdk/src/java.base/share/classes/java/util/stream/Stream.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/java/util/stream/Stream.java Wed Oct 26 20:13:29 2016 +0000
@@ -282,7 +282,7 @@
*/
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
- /**:
+ /**
* Returns an {@code IntStream} consisting of the results of replacing each
* element of this stream with the contents of a mapped stream produced by
* applying the provided mapping function to each element. Each mapped
--- a/jdk/src/java.base/share/classes/jdk/internal/jmod/JmodFile.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/jdk/internal/jmod/JmodFile.java Wed Oct 26 20:13:29 2016 +0000
@@ -71,7 +71,9 @@
NATIVE_LIBS("native"),
NATIVE_CMDS("bin"),
CLASSES("classes"),
- CONFIG("conf");
+ CONFIG("conf"),
+ HEADER_FILES("include"),
+ MAN_PAGES("man");
private final String jmodDir;
private Section(String jmodDir) {
@@ -151,6 +153,10 @@
return Section.CLASSES;
case "conf":
return Section.CONFIG;
+ case "include":
+ return Section.HEADER_FILES;
+ case "man":
+ return Section.MAN_PAGES;
default:
throw new IllegalArgumentException("invalid section: " + s);
}
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaNetAccess.java Wed Oct 26 15:46:13 2016 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. 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.internal.misc;
-
-import java.net.URLClassLoader;
-import jdk.internal.loader.URLClassPath;
-
-public interface JavaNetAccess {
- /**
- * return the URLClassPath belonging to the given loader
- */
- URLClassPath getURLClassPath (URLClassLoader u);
-}
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaNetInetAddressAccess.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaNetInetAddressAccess.java Wed Oct 26 20:13:29 2016 +0000
@@ -26,6 +26,7 @@
package jdk.internal.misc;
import java.net.InetAddress;
+import java.net.UnknownHostException;
public interface JavaNetInetAddressAccess {
/**
@@ -33,4 +34,13 @@
* the given InetAddress object.
*/
String getOriginalHostName(InetAddress ia);
+
+ /**
+ * Get the InetAddress of the provided host. If an InetAddress is provided
+ * then it will be the default address returned for all calls to either
+ * form of getByName. This is required to maintain consistency when
+ * caching addresses and hostnames.
+ */
+ InetAddress getByName(String hostName, InetAddress hostAddress)
+ throws UnknownHostException;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaNetURLClassLoaderAccess.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,33 @@
+/*
+ * 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.internal.misc;
+
+import java.net.URLClassLoader;
+import java.security.AccessControlContext;
+
+public interface JavaNetURLClassLoaderAccess {
+ AccessControlContext getAccessControlContext(URLClassLoader u);;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaNetUriAccess.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2006, 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.internal.misc;
+
+import java.net.URI;
+
+public interface JavaNetUriAccess {
+ /**
+ * Create a URI of pre-validated scheme and path.
+ */
+ URI create(String scheme, String path);
+}
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaSecurityAccess.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaSecurityAccess.java Wed Oct 26 20:13:29 2016 +0000
@@ -27,6 +27,7 @@
import java.security.AccessControlContext;
import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
public interface JavaSecurityAccess {
@@ -37,4 +38,5 @@
<T> T doIntersectionPrivilege(PrivilegedAction<T> action,
AccessControlContext context);
+ ProtectionDomain[] getProtectDomains(AccessControlContext context);
}
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/SharedSecrets.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/SharedSecrets.java Wed Oct 26 20:13:29 2016 +0000
@@ -53,10 +53,11 @@
private static JavaLangInvokeAccess javaLangInvokeAccess;
private static JavaLangRefAccess javaLangRefAccess;
private static JavaIOAccess javaIOAccess;
- private static JavaNetAccess javaNetAccess;
private static JavaNetInetAddressAccess javaNetInetAddressAccess;
private static JavaNetHttpCookieAccess javaNetHttpCookieAccess;
private static JavaNetSocketAccess javaNetSocketAccess;
+ private static JavaNetUriAccess javaNetUriAccess;
+ private static JavaNetURLClassLoaderAccess javaNetURLClassLoaderAccess;
private static JavaNioAccess javaNioAccess;
private static JavaIOFileDescriptorAccess javaIOFileDescriptorAccess;
private static JavaIOFilePermissionAccess javaIOFilePermissionAccess;
@@ -134,14 +135,24 @@
return javaLangRefAccess;
}
- public static void setJavaNetAccess(JavaNetAccess jna) {
- javaNetAccess = jna;
+ public static void setJavaNetUriAccess(JavaNetUriAccess jnua) {
+ javaNetUriAccess = jnua;
}
- public static JavaNetAccess getJavaNetAccess() {
- if (javaNetAccess == null)
+ public static JavaNetUriAccess getJavaNetUriAccess() {
+ if (javaNetUriAccess == null)
+ unsafe.ensureClassInitialized(java.net.URI.class);
+ return javaNetUriAccess;
+ }
+
+ public static void setJavaNetURLClassLoaderAccess(JavaNetURLClassLoaderAccess jnua) {
+ javaNetURLClassLoaderAccess = jnua;
+ }
+
+ public static JavaNetURLClassLoaderAccess getJavaNetURLClassLoaderAccess() {
+ if (javaNetURLClassLoaderAccess == null)
unsafe.ensureClassInitialized(java.net.URLClassLoader.class);
- return javaNetAccess;
+ return javaNetURLClassLoaderAccess;
}
public static void setJavaNetInetAddressAccess(JavaNetInetAddressAccess jna) {
--- a/jdk/src/java.base/share/classes/jdk/internal/reflect/Reflection.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/jdk/internal/reflect/Reflection.java Wed Oct 26 20:13:29 2016 +0000
@@ -84,9 +84,22 @@
public static native int getClassAccessFlags(Class<?> c);
+ /**
+ * Ensures that access to a member is granted and throws
+ * IllegalAccessException if not.
+ *
+ * @param currentClass the class performing the access
+ * @param memberClass the declaring class of the member being accessed
+ * @param targetClass the class of target object if accessing instance
+ * field or method;
+ * or the declaring class if accessing constructor;
+ * or null if accessing static field or method
+ * @param modifiers the member's access modifiers
+ * @throws IllegalAccessException if access to member is denied
+ */
public static void ensureMemberAccess(Class<?> currentClass,
Class<?> memberClass,
- Object target,
+ Class<?> targetClass,
int modifiers)
throws IllegalAccessException
{
@@ -94,18 +107,15 @@
throw new InternalError();
}
- if (!verifyMemberAccess(currentClass, memberClass, target, modifiers)) {
- throwIllegalAccessException(currentClass, memberClass, target, modifiers);
+ if (!verifyMemberAccess(currentClass, memberClass, targetClass, modifiers)) {
+ throwIllegalAccessException(currentClass, memberClass, targetClass, modifiers);
}
}
- public static boolean verifyMemberAccess(Class<?> currentClass,
- // Declaring class of field
- // or method
- Class<?> memberClass,
- // May be NULL in case of statics
- Object target,
- int modifiers)
+ private static boolean verifyMemberAccess(Class<?> currentClass,
+ Class<?> memberClass,
+ Class<?> targetClass,
+ int modifiers)
{
// Verify that currentClass can access a field, method, or
// constructor of memberClass, where that member's access bits are
@@ -162,18 +172,18 @@
return false;
}
- if (Modifier.isProtected(modifiers)) {
- // Additional test for protected members: JLS 6.6.2
- Class<?> targetClass = (target == null ? memberClass : target.getClass());
- if (targetClass != currentClass) {
- if (!gotIsSameClassPackage) {
- isSameClassPackage = isSameClassPackage(currentClass, memberClass);
- gotIsSameClassPackage = true;
- }
- if (!isSameClassPackage) {
- if (!isSubclassOf(targetClass, currentClass)) {
- return false;
- }
+ // Additional test for protected instance members
+ // and protected constructors: JLS 6.6.2
+ if (targetClass != null && Modifier.isProtected(modifiers) &&
+ targetClass != currentClass)
+ {
+ if (!gotIsSameClassPackage) {
+ isSameClassPackage = isSameClassPackage(currentClass, memberClass);
+ gotIsSameClassPackage = true;
+ }
+ if (!isSameClassPackage) {
+ if (!isSubclassOf(targetClass, currentClass)) {
+ return false;
}
}
}
--- a/jdk/src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2013, 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
@@ -25,14 +25,25 @@
package jdk.internal.reflect;
+import java.io.Externalizable;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamClass;
+import java.io.OptionalDataException;
+import java.io.Serializable;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
import java.lang.reflect.Field;
import java.lang.reflect.Executable;
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.security.Permission;
import java.security.PrivilegedAction;
+import java.util.Objects;
import java.util.Properties;
+
import sun.reflect.misc.ReflectUtil;
import sun.security.action.GetPropertyAction;
@@ -57,6 +68,9 @@
// Provides access to package-private mechanisms in java.lang.reflect
private static volatile LangReflectAccess langReflectAccess;
+ /* Method for static class initializer <clinit>, or null */
+ private static volatile Method hasStaticInitializerMethod;
+
//
// "Inflation" mechanism. Loading bytecodes to implement
// Method.invoke() and Constructor.newInstance() currently costs
@@ -337,16 +351,41 @@
//
//
- public Constructor<?> newConstructorForSerialization
- (Class<?> classToInstantiate, Constructor<?> constructorToCall)
- {
- // Fast path
- if (constructorToCall.getDeclaringClass() == classToInstantiate) {
- return constructorToCall;
+ public final Constructor<?> newConstructorForExternalization(Class<?> cl) {
+ if (!Externalizable.class.isAssignableFrom(cl)) {
+ return null;
+ }
+ try {
+ Constructor<?> cons = cl.getConstructor();
+ cons.setAccessible(true);
+ return cons;
+ } catch (NoSuchMethodException ex) {
+ return null;
+ }
+ }
+
+ public final Constructor<?> newConstructorForSerialization(Class<?> cl) {
+ Class<?> initCl = cl;
+ while (Serializable.class.isAssignableFrom(initCl)) {
+ if ((initCl = initCl.getSuperclass()) == null) {
+ return null;
+ }
+ }
+ Constructor<?> constructorToCall;
+ try {
+ constructorToCall = initCl.getDeclaredConstructor();
+ int mods = constructorToCall.getModifiers();
+ if ((mods & Modifier.PRIVATE) != 0 ||
+ ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0 &&
+ !packageEquals(cl, initCl))) {
+ return null;
+ }
+ } catch (NoSuchMethodException ex) {
+ return null;
}
ConstructorAccessor acc = new MethodAccessorGenerator().
- generateSerializationConstructor(classToInstantiate,
+ generateSerializationConstructor(cl,
constructorToCall.getParameterTypes(),
constructorToCall.getExceptionTypes(),
constructorToCall.getModifiers(),
@@ -364,9 +403,151 @@
langReflectAccess().
getConstructorParameterAnnotations(constructorToCall));
setConstructorAccessor(c, acc);
+ c.setAccessible(true);
return c;
}
+ public final MethodHandle readObjectForSerialization(Class<?> cl) {
+ return findReadWriteObjectForSerialization(cl, "readObject", ObjectInputStream.class);
+ }
+
+ public final MethodHandle readObjectNoDataForSerialization(Class<?> cl) {
+ return findReadWriteObjectForSerialization(cl, "readObjectNoData", ObjectInputStream.class);
+ }
+
+ public final MethodHandle writeObjectForSerialization(Class<?> cl) {
+ return findReadWriteObjectForSerialization(cl, "writeObject", ObjectOutputStream.class);
+ }
+
+ private final MethodHandle findReadWriteObjectForSerialization(Class<?> cl,
+ String methodName,
+ Class<?> streamClass) {
+ if (!Serializable.class.isAssignableFrom(cl)) {
+ return null;
+ }
+
+ try {
+ Method meth = cl.getDeclaredMethod(methodName, streamClass);
+ int mods = meth.getModifiers();
+ if (meth.getReturnType() != Void.TYPE ||
+ Modifier.isStatic(mods) ||
+ !Modifier.isPrivate(mods)) {
+ return null;
+ }
+ meth.setAccessible(true);
+ return MethodHandles.lookup().unreflect(meth);
+ } catch (NoSuchMethodException ex) {
+ return null;
+ } catch (IllegalAccessException ex1) {
+ throw new InternalError("Error", ex1);
+ }
+ }
+
+ /**
+ * Returns a MethodHandle for {@code writeReplace} on the serializable class
+ * or null if no match found.
+ * @param cl a serializable class
+ * @returnss the {@code writeReplace} MethodHandle or {@code null} if not found
+ */
+ public final MethodHandle writeReplaceForSerialization(Class<?> cl) {
+ return getReplaceResolveForSerialization(cl, "writeReplace");
+ }
+
+ /**
+ * Returns a MethodHandle for {@code readResolve} on the serializable class
+ * or null if no match found.
+ * @param cl a serializable class
+ * @returns the {@code writeReplace} MethodHandle or {@code null} if not found
+ */
+ public final MethodHandle readResolveForSerialization(Class<?> cl) {
+ return getReplaceResolveForSerialization(cl, "readResolve");
+ }
+
+ /**
+ * Lookup readResolve or writeReplace on a class with specified
+ * signature constraints.
+ * @param cl a serializable class
+ * @param methodName the method name to find
+ * @returns a MethodHandle for the method or {@code null} if not found or
+ * has the wrong signature.
+ */
+ private MethodHandle getReplaceResolveForSerialization(Class<?> cl,
+ String methodName) {
+ if (!Serializable.class.isAssignableFrom(cl)) {
+ return null;
+ }
+
+ Class<?> defCl = cl;
+ while (defCl != null) {
+ try {
+ Method m = defCl.getDeclaredMethod(methodName);
+ if (m.getReturnType() != Object.class) {
+ return null;
+ }
+ int mods = m.getModifiers();
+ if (Modifier.isStatic(mods) | Modifier.isAbstract(mods)) {
+ return null;
+ } else if (Modifier.isPublic(mods) | Modifier.isProtected(mods)) {
+ // fall through
+ } else if (Modifier.isPrivate(mods) && (cl != defCl)) {
+ return null;
+ } else if (!packageEquals(cl, defCl)) {
+ return null;
+ }
+ try {
+ // Normal return
+ m.setAccessible(true);
+ return MethodHandles.lookup().unreflect(m);
+ } catch (IllegalAccessException ex0) {
+ // setAccessible should prevent IAE
+ throw new InternalError("Error", ex0);
+ }
+ } catch (NoSuchMethodException ex) {
+ defCl = defCl.getSuperclass();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns true if the given class defines a static initializer method,
+ * false otherwise.
+ */
+ public final boolean hasStaticInitializerForSerialization(Class<?> cl) {
+ Method m = hasStaticInitializerMethod;
+ if (m == null) {
+ try {
+ m = ObjectStreamClass.class.getDeclaredMethod("hasStaticInitializer",
+ new Class<?>[]{Class.class});
+ m.setAccessible(true);
+ hasStaticInitializerMethod = m;
+ } catch (NoSuchMethodException ex) {
+ throw new InternalError("No such method hasStaticInitializer on "
+ + ObjectStreamClass.class, ex);
+ }
+ }
+ try {
+ return (Boolean) m.invoke(null, cl);
+ } catch (InvocationTargetException | IllegalAccessException ex) {
+ throw new InternalError("Exception invoking hasStaticInitializer", ex);
+ }
+ }
+
+ /**
+ * Return the accessible constructor for OptionalDataException signaling eof.
+ * @returns the eof constructor for OptionalDataException
+ */
+ public final Constructor<OptionalDataException> newOptionalDataExceptionForSerialization() {
+ try {
+ Constructor<OptionalDataException> boolCtor =
+ OptionalDataException.class.getDeclaredConstructor(Boolean.TYPE);
+ boolCtor.setAccessible(true);
+ return boolCtor;
+ } catch (NoSuchMethodException ex) {
+ throw new InternalError("Constructor not found", ex);
+ }
+ }
+
//--------------------------------------------------------------------------
//
// Internals only below this point
@@ -426,4 +607,17 @@
}
return langReflectAccess;
}
+
+ /**
+ * Returns true if classes are defined in the classloader and same package, false
+ * otherwise.
+ * @param cl1 a class
+ * @param cl2 another class
+ * @returns true if the two classes are in the same classloader and package
+ */
+ private static boolean packageEquals(Class<?> cl1, Class<?> cl2) {
+ return cl1.getClassLoader() == cl2.getClassLoader() &&
+ Objects.equals(cl1.getPackage(), cl2.getPackage());
+ }
+
}
--- a/jdk/src/java.base/share/classes/module-info.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/module-info.java Wed Oct 26 20:13:29 2016 +0000
@@ -154,7 +154,6 @@
exports jdk.internal.module to
java.instrument,
java.management,
- jdk.dynalink,
jdk.jartool,
jdk.jlink;
exports jdk.internal.misc to
@@ -172,8 +171,10 @@
jdk.jartool,
jdk.jdeps,
jdk.jlink,
+ jdk.jshell,
jdk.net,
jdk.scripting.nashorn,
+ jdk.scripting.nashorn.shell,
jdk.unsupported,
jdk.vm.ci;
exports jdk.internal.perf to
@@ -239,8 +240,7 @@
java.xml.ws;
exports sun.security.action to
java.desktop,
- java.security.jgss,
- jdk.crypto.pkcs11;
+ java.security.jgss;
exports sun.security.internal.interfaces to
jdk.crypto.pkcs11;
exports sun.security.internal.spec to
@@ -266,6 +266,8 @@
jdk.crypto.pkcs11;
exports sun.security.ssl to
java.security.jgss;
+ exports sun.security.timestamp to
+ jdk.jartool;
exports sun.security.tools to
jdk.jartool;
exports sun.security.util to
--- a/jdk/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationHeader.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationHeader.java Wed Oct 26 20:13:29 2016 +0000
@@ -25,8 +25,11 @@
package sun.net.www.protocol.http;
+import java.util.Collections;
import java.util.Iterator;
import java.util.HashMap;
+import java.util.Set;
+
import sun.net.www.*;
import sun.security.action.GetPropertyAction;
@@ -67,8 +70,8 @@
* -Dhttp.auth.preference="scheme"
*
* which in this case, specifies that "scheme" should be used as the auth scheme when offered
- * disregarding the default prioritisation. If scheme is not offered then the default priority
- * is used.
+ * disregarding the default prioritisation. If scheme is not offered, or explicitly
+ * disabled, by {@code disabledSchemes}, then the default priority is used.
*
* Attention: when http.auth.preference is set as SPNEGO or Kerberos, it's actually "Negotiate
* with SPNEGO" or "Negotiate with Kerberos", which means the user will prefer the Negotiate
@@ -113,17 +116,32 @@
String hdrname; // Name of the header to look for
/**
- * parse a set of authentication headers and choose the preferred scheme
- * that we support for a given host
+ * Parses a set of authentication headers and chooses the preferred scheme
+ * that is supported for a given host.
*/
public AuthenticationHeader (String hdrname, MessageHeader response,
HttpCallerInfo hci, boolean dontUseNegotiate) {
+ this(hdrname, response, hci, dontUseNegotiate, Collections.emptySet());
+ }
+
+ /**
+ * Parses a set of authentication headers and chooses the preferred scheme
+ * that is supported for a given host.
+ *
+ * <p> The {@code disabledSchemes} parameter is a, possibly empty, set of
+ * authentication schemes that are disabled.
+ */
+ public AuthenticationHeader(String hdrname,
+ MessageHeader response,
+ HttpCallerInfo hci,
+ boolean dontUseNegotiate,
+ Set<String> disabledSchemes) {
this.hci = hci;
this.dontUseNegotiate = dontUseNegotiate;
- rsp = response;
+ this.rsp = response;
this.hdrname = hdrname;
- schemes = new HashMap<>();
- parse();
+ this.schemes = new HashMap<>();
+ parse(disabledSchemes);
}
public HttpCallerInfo getHttpCallerInfo() {
@@ -143,10 +161,11 @@
* then the last one will be used. The
* preferred scheme that we support will be used.
*/
- private void parse () {
+ private void parse(Set<String> disabledSchemes) {
Iterator<String> iter = rsp.multiValueIterator(hdrname);
while (iter.hasNext()) {
String raw = iter.next();
+ // HeaderParser lower cases everything, so can be used case-insensitively
HeaderParser hp = new HeaderParser(raw);
Iterator<String> keys = hp.keys();
int i, lastSchemeIndex;
@@ -156,7 +175,8 @@
if (lastSchemeIndex != -1) {
HeaderParser hpn = hp.subsequence (lastSchemeIndex, i);
String scheme = hpn.findKey(0);
- schemes.put (scheme, new SchemeMapValue (hpn, raw));
+ if (!disabledSchemes.contains(scheme))
+ schemes.put(scheme, new SchemeMapValue (hpn, raw));
}
lastSchemeIndex = i;
}
@@ -164,7 +184,8 @@
if (i > lastSchemeIndex) {
HeaderParser hpn = hp.subsequence (lastSchemeIndex, i);
String scheme = hpn.findKey(0);
- schemes.put(scheme, new SchemeMapValue (hpn, raw));
+ if (!disabledSchemes.contains(scheme))
+ schemes.put(scheme, new SchemeMapValue (hpn, raw));
}
}
--- a/jdk/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Wed Oct 26 20:13:29 2016 +0000
@@ -25,6 +25,7 @@
package sun.net.www.protocol.http;
+import java.security.PrivilegedAction;
import java.util.Arrays;
import java.net.URL;
import java.net.URLConnection;
@@ -109,6 +110,14 @@
static final boolean validateProxy;
static final boolean validateServer;
+ /** A, possibly empty, set of authentication schemes that are disabled
+ * when proxying plain HTTP ( not HTTPS ). */
+ static final Set<String> disabledProxyingSchemes;
+
+ /** A, possibly empty, set of authentication schemes that are disabled
+ * when setting up a tunnel for HTTPS ( HTTP CONNECT ). */
+ static final Set<String> disabledTunnelingSchemes;
+
private StreamingOutputStream strOutputStream;
private static final String RETRY_MSG1 =
"cannot retry due to proxy authentication, in streaming mode";
@@ -206,6 +215,22 @@
"Via"
};
+ private static String getNetProperty(String name) {
+ PrivilegedAction<String> pa = () -> NetProperties.get(name);
+ return AccessController.doPrivileged(pa);
+ }
+
+ private static Set<String> schemesListToSet(String list) {
+ if (list == null || list.isEmpty())
+ return Collections.emptySet();
+
+ Set<String> s = new HashSet<>();
+ String[] parts = list.split("\\s*,\\s*");
+ for (String part : parts)
+ s.add(part.toLowerCase(Locale.ROOT));
+ return s;
+ }
+
static {
Properties props = GetPropertyAction.privilegedGetProperties();
maxRedirects = GetIntegerAction.privilegedGetProperty(
@@ -218,6 +243,14 @@
agent = agent + " Java/"+version;
}
userAgent = agent;
+
+ // A set of net properties to control the use of authentication schemes
+ // when proxing/tunneling.
+ String p = getNetProperty("jdk.http.auth.tunneling.disabledSchemes");
+ disabledTunnelingSchemes = schemesListToSet(p);
+ p = getNetProperty("jdk.http.auth.proxying.disabledSchemes");
+ disabledProxyingSchemes = schemesListToSet(p);
+
validateProxy = Boolean.parseBoolean(
props.getProperty("http.auth.digest.validateProxy"));
validateServer = Boolean.parseBoolean(
@@ -1575,10 +1608,13 @@
// altered in similar ways.
AuthenticationHeader authhdr = new AuthenticationHeader (
- "Proxy-Authenticate", responses,
- new HttpCallerInfo(url, http.getProxyHostUsed(),
- http.getProxyPortUsed()),
- dontUseNegotiate
+ "Proxy-Authenticate",
+ responses,
+ new HttpCallerInfo(url,
+ http.getProxyHostUsed(),
+ http.getProxyPortUsed()),
+ dontUseNegotiate,
+ disabledProxyingSchemes
);
if (!doingNTLMp2ndStage) {
@@ -2024,11 +2060,14 @@
}
}
- AuthenticationHeader authhdr = new AuthenticationHeader (
- "Proxy-Authenticate", responses,
- new HttpCallerInfo(url, http.getProxyHostUsed(),
- http.getProxyPortUsed()),
- dontUseNegotiate
+ AuthenticationHeader authhdr = new AuthenticationHeader(
+ "Proxy-Authenticate",
+ responses,
+ new HttpCallerInfo(url,
+ http.getProxyHostUsed(),
+ http.getProxyPortUsed()),
+ dontUseNegotiate,
+ disabledTunnelingSchemes
);
if (!doingNTLMp2ndStage) {
proxyAuthentication =
--- a/jdk/src/java.base/share/classes/sun/nio/cs/HKSCS.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/sun/nio/cs/HKSCS.java Wed Oct 26 20:13:29 2016 +0000
@@ -432,6 +432,8 @@
continue;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
+ if (c == UNMAPPABLE_DECODING)
+ continue;
int hi = c >> 8;
if (c2b[hi] == C2B_UNMAPPABLE) {
c2b[hi] = new char[0x100];
--- a/jdk/src/java.base/share/classes/sun/reflect/misc/ReflectUtil.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/sun/reflect/misc/ReflectUtil.java Wed Oct 26 20:13:29 2016 +0000
@@ -44,9 +44,21 @@
return Class.forName(name);
}
- /*
- * Reflection.ensureMemberAccess is overly-restrictive
- * due to a bug. We awkwardly work around it for now.
+ /**
+ * Ensures that access to a method or field is granted and throws
+ * IllegalAccessException if not. This method is not suitable for checking
+ * access to constructors.
+ *
+ * @param currentClass the class performing the access
+ * @param memberClass the declaring class of the member being accessed
+ * @param target the target object if accessing instance field or method;
+ * or null if accessing static field or method or if target
+ * object access rights will be checked later
+ * @param modifiers the member's access modifiers
+ * @throws IllegalAccessException if access to member is denied
+ * @implNote Delegates directly to
+ * {@link Reflection#ensureMemberAccess(Class, Class, Class, int)}
+ * which should be used instead.
*/
public static void ensureMemberAccess(Class<?> currentClass,
Class<?> memberClass,
@@ -54,62 +66,10 @@
int modifiers)
throws IllegalAccessException
{
- if (target == null && Modifier.isProtected(modifiers)) {
- int mods = modifiers;
- mods = mods & (~Modifier.PROTECTED);
- mods = mods | Modifier.PUBLIC;
-
- /*
- * See if we fail because of class modifiers
- */
- Reflection.ensureMemberAccess(currentClass,
- memberClass,
- target,
- mods);
- try {
- /*
- * We're still here so class access was ok.
- * Now try with default field access.
- */
- mods = mods & (~Modifier.PUBLIC);
- Reflection.ensureMemberAccess(currentClass,
- memberClass,
- target,
- mods);
- /*
- * We're still here so access is ok without
- * checking for protected.
- */
- return;
- } catch (IllegalAccessException e) {
- /*
- * Access failed but we're 'protected' so
- * if the test below succeeds then we're ok.
- */
- if (isSubclassOf(currentClass, memberClass)) {
- return;
- } else {
- throw e;
- }
- }
- } else {
- Reflection.ensureMemberAccess(currentClass,
- memberClass,
- target,
- modifiers);
- }
- }
-
- private static boolean isSubclassOf(Class<?> queryClass,
- Class<?> ofClass)
- {
- while (queryClass != null) {
- if (queryClass == ofClass) {
- return true;
- }
- queryClass = queryClass.getSuperclass();
- }
- return false;
+ Reflection.ensureMemberAccess(currentClass,
+ memberClass,
+ target == null ? null : target.getClass(),
+ modifiers);
}
/**
--- a/jdk/src/java.base/share/classes/sun/security/pkcs/SignerInfo.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/sun/security/pkcs/SignerInfo.java Wed Oct 26 20:13:29 2016 +0000
@@ -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
@@ -28,20 +28,38 @@
import java.io.OutputStream;
import java.io.IOException;
import java.math.BigInteger;
+import java.security.CryptoPrimitive;
+import java.security.InvalidKeyException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.Principal;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.Timestamp;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.CertPath;
import java.security.cert.X509Certificate;
-import java.security.*;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Set;
import sun.security.timestamp.TimestampToken;
-import sun.security.util.*;
+import sun.security.util.Debug;
+import sun.security.util.DerEncoder;
+import sun.security.util.DerInputStream;
+import sun.security.util.DerOutputStream;
+import sun.security.util.DerValue;
+import sun.security.util.DisabledAlgorithmConstraints;
+import sun.security.util.HexDumpEncoder;
+import sun.security.util.KeyUtil;
+import sun.security.util.ObjectIdentifier;
import sun.security.x509.AlgorithmId;
import sun.security.x509.X500Name;
import sun.security.x509.KeyUsageExtension;
-import sun.security.util.HexDumpEncoder;
/**
* A SignerInfo, as defined in PKCS#7's signedData type.
@@ -50,6 +68,17 @@
*/
public class SignerInfo implements DerEncoder {
+ // Digest and Signature restrictions
+ private static final Set<CryptoPrimitive> DIGEST_PRIMITIVE_SET =
+ Collections.unmodifiableSet(EnumSet.of(CryptoPrimitive.MESSAGE_DIGEST));
+
+ private static final Set<CryptoPrimitive> SIG_PRIMITIVE_SET =
+ Collections.unmodifiableSet(EnumSet.of(CryptoPrimitive.SIGNATURE));
+
+ private static final DisabledAlgorithmConstraints JAR_DISABLED_CHECK =
+ new DisabledAlgorithmConstraints(
+ DisabledAlgorithmConstraints.PROPERTY_JAR_DISABLED_ALGS);
+
BigInteger version;
X500Name issuerName;
BigInteger certificateSerialNumber;
@@ -318,6 +347,13 @@
if (messageDigest == null) // fail if there is no message digest
return null;
+ // check that algorithm is not restricted
+ if (!JAR_DISABLED_CHECK.permits(DIGEST_PRIMITIVE_SET,
+ digestAlgname, null)) {
+ throw new SignatureException("Digest check failed. " +
+ "Disabled algorithm used: " + digestAlgname);
+ }
+
MessageDigest md = MessageDigest.getInstance(digestAlgname);
byte[] computedMessageDigest = md.digest(data);
@@ -349,12 +385,26 @@
String algname = AlgorithmId.makeSigAlg(
digestAlgname, encryptionAlgname);
- Signature sig = Signature.getInstance(algname);
+ // check that algorithm is not restricted
+ if (!JAR_DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, algname, null)) {
+ throw new SignatureException("Signature check failed. " +
+ "Disabled algorithm used: " + algname);
+ }
+
X509Certificate cert = getCertificate(block);
-
+ PublicKey key = cert.getPublicKey();
if (cert == null) {
return null;
}
+
+ // check if the public key is restricted
+ if (!JAR_DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) {
+ throw new SignatureException("Public key check failed. " +
+ "Disabled key used: " +
+ KeyUtil.getKeySize(key) + " bit " +
+ key.getAlgorithm());
+ }
+
if (cert.hasUnsupportedCriticalExtension()) {
throw new SignatureException("Certificate has unsupported "
+ "critical extension(s)");
@@ -391,11 +441,9 @@
}
}
- PublicKey key = cert.getPublicKey();
+ Signature sig = Signature.getInstance(algname);
sig.initVerify(key);
-
sig.update(dataSigned);
-
if (sig.verify(encryptedDigest)) {
return this;
}
@@ -450,6 +498,23 @@
return unauthenticatedAttributes;
}
+ /**
+ * Returns the timestamp PKCS7 data unverified.
+ * @return a PKCS7 object
+ */
+ public PKCS7 getTsToken() throws IOException {
+ if (unauthenticatedAttributes == null) {
+ return null;
+ }
+ PKCS9Attribute tsTokenAttr =
+ unauthenticatedAttributes.getAttribute(
+ PKCS9Attribute.SIGNATURE_TIMESTAMP_TOKEN_OID);
+ if (tsTokenAttr == null) {
+ return null;
+ }
+ return new PKCS7((byte[])tsTokenAttr.getValue());
+ }
+
/*
* Extracts a timestamp from a PKCS7 SignerInfo.
*
@@ -477,19 +542,12 @@
if (timestamp != null || !hasTimestamp)
return timestamp;
- if (unauthenticatedAttributes == null) {
- hasTimestamp = false;
- return null;
- }
- PKCS9Attribute tsTokenAttr =
- unauthenticatedAttributes.getAttribute(
- PKCS9Attribute.SIGNATURE_TIMESTAMP_TOKEN_OID);
- if (tsTokenAttr == null) {
+ PKCS7 tsToken = getTsToken();
+ if (tsToken == null) {
hasTimestamp = false;
return null;
}
- PKCS7 tsToken = new PKCS7((byte[])tsTokenAttr.getValue());
// Extract the content (an encoded timestamp token info)
byte[] encTsTokenInfo = tsToken.getContentInfo().getData();
// Extract the signer (the Timestamping Authority)
@@ -515,9 +573,16 @@
*/
private void verifyTimestamp(TimestampToken token)
throws NoSuchAlgorithmException, SignatureException {
+ String digestAlgname = token.getHashAlgorithm().getName();
+ // check that algorithm is not restricted
+ if (!JAR_DISABLED_CHECK.permits(DIGEST_PRIMITIVE_SET, digestAlgname,
+ null)) {
+ throw new SignatureException("Timestamp token digest check failed. " +
+ "Disabled algorithm used: " + digestAlgname);
+ }
MessageDigest md =
- MessageDigest.getInstance(token.getHashAlgorithm().getName());
+ MessageDigest.getInstance(digestAlgname);
if (!Arrays.equals(token.getHashedMessage(),
md.digest(encryptedDigest))) {
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/AlgorithmChecker.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/AlgorithmChecker.java Wed Oct 26 20:13:29 2016 +0000
@@ -185,20 +185,22 @@
AlgorithmConstraints constraints,
Date pkixdate) {
- if (anchor == null) {
- throw new IllegalArgumentException(
- "The trust anchor cannot be null");
- }
-
- if (anchor.getTrustedCert() != null) {
- this.trustedPubKey = anchor.getTrustedCert().getPublicKey();
- // Check for anchor certificate restrictions
- trustedMatch = checkFingerprint(anchor.getTrustedCert());
- if (trustedMatch && debug != null) {
- debug.println("trustedMatch = true");
+ if (anchor != null) {
+ if (anchor.getTrustedCert() != null) {
+ this.trustedPubKey = anchor.getTrustedCert().getPublicKey();
+ // Check for anchor certificate restrictions
+ trustedMatch = checkFingerprint(anchor.getTrustedCert());
+ if (trustedMatch && debug != null) {
+ debug.println("trustedMatch = true");
+ }
+ } else {
+ this.trustedPubKey = anchor.getCAPublicKey();
}
} else {
- this.trustedPubKey = anchor.getCAPublicKey();
+ this.trustedPubKey = null;
+ if (debug != null) {
+ debug.println("TrustAnchor is null, trustedMatch is false.");
+ }
}
this.prevPubKey = trustedPubKey;
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/ForwardBuilder.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/ForwardBuilder.java Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -816,18 +816,22 @@
/**
* Verifies whether the input certificate completes the path.
- * Checks the cert against each trust anchor that was specified, in order,
- * and returns true as soon as it finds a valid anchor.
- * Returns true if the cert matches a trust anchor specified as a
- * certificate or if the cert verifies with a trust anchor that
- * was specified as a trusted {pubkey, caname} pair. Returns false if none
- * of the trust anchors are valid for this cert.
+ * First checks the cert against each trust anchor that was specified,
+ * in order, and returns true if the cert matches the trust anchor
+ * specified as a certificate or has the same key and subject of an anchor
+ * specified as a trusted {pubkey, caname} pair.
+ * If no match has been found, does a second check of the cert against
+ * anchors specified as a trusted {pubkey, caname} pair to see if the cert
+ * was issued by that anchor.
+ * Returns false if none of the trust anchors are valid for this cert.
*
* @param cert the certificate to test
* @return a boolean value indicating whether the cert completes the path.
*/
@Override
boolean isPathCompleted(X509Certificate cert) {
+ List<TrustAnchor> otherAnchors = new ArrayList<>();
+ // first, check if cert is already trusted
for (TrustAnchor anchor : trustAnchors) {
if (anchor.getTrustedCert() != null) {
if (cert.equals(anchor.getTrustedCert())) {
@@ -849,7 +853,12 @@
}
// else, it is a self-issued certificate of the anchor
}
-
+ otherAnchors.add(anchor);
+ }
+ // next, check if cert is issued by anchor specified by key/name
+ for (TrustAnchor anchor : otherAnchors) {
+ X500Principal principal = anchor.getCA();
+ PublicKey publicKey = anchor.getCAPublicKey();
// Check subject/issuer name chaining
if (principal == null ||
!principal.equals(cert.getIssuerX500Principal())) {
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/OCSP.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/OCSP.java Wed Oct 26 20:13:29 2016 +0000
@@ -35,6 +35,7 @@
import java.security.cert.CertPathValidatorException.BasicReason;
import java.security.cert.CRLReason;
import java.security.cert.Extension;
+import java.security.cert.TrustAnchor;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.Collections;
@@ -164,6 +165,15 @@
Date date, List<Extension> extensions)
throws IOException, CertPathValidatorException
{
+ return check(cert, responderURI, null, issuerCert, responderCert, date, extensions);
+ }
+
+ public static RevocationStatus check(X509Certificate cert,
+ URI responderURI, TrustAnchor anchor, X509Certificate issuerCert,
+ X509Certificate responderCert, Date date,
+ List<Extension> extensions)
+ throws IOException, CertPathValidatorException
+ {
CertId certId = null;
try {
X509CertImpl certImpl = X509CertImpl.toImpl(cert);
@@ -173,8 +183,8 @@
("Exception while encoding OCSPRequest", e);
}
OCSPResponse ocspResponse = check(Collections.singletonList(certId),
- responderURI, new OCSPResponse.IssuerInfo(issuerCert),
- responderCert, date, extensions);
+ responderURI, new OCSPResponse.IssuerInfo(anchor, issuerCert),
+ responderCert, date, extensions);
return (RevocationStatus) ocspResponse.getSingleResponse(certId);
}
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/OCSPResponse.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/OCSPResponse.java Wed Oct 26 20:13:29 2016 +0000
@@ -507,9 +507,8 @@
// Check algorithm constraints specified in security property
// "jdk.certpath.disabledAlgorithms".
- AlgorithmChecker algChecker = new AlgorithmChecker(
- new TrustAnchor(issuerInfo.getName(),
- issuerInfo.getPublicKey(), null));
+ AlgorithmChecker algChecker =
+ new AlgorithmChecker(issuerInfo.getAnchor(), date);
algChecker.init(false);
algChecker.check(signerCert, Collections.<String>emptySet());
@@ -982,36 +981,38 @@
/**
* Helper class that allows consumers to pass in issuer information. This
* will always consist of the issuer's name and public key, but may also
- * contain a certificate if the originating data is in that form.
+ * contain a certificate if the originating data is in that form. The
+ * trust anchor for the certificate chain will be included for certpath
+ * disabled algorithm checking.
*/
static final class IssuerInfo {
+ private final TrustAnchor anchor;
private final X509Certificate certificate;
private final X500Principal name;
private final PublicKey pubKey;
+ IssuerInfo(TrustAnchor anchor) {
+ this(anchor, (anchor != null) ? anchor.getTrustedCert() : null);
+ }
+
IssuerInfo(X509Certificate issuerCert) {
- certificate = Objects.requireNonNull(issuerCert,
- "Constructor requires non-null certificate");
- name = certificate.getSubjectX500Principal();
- pubKey = certificate.getPublicKey();
+ this(null, issuerCert);
}
- IssuerInfo(X500Principal subjectName, PublicKey key) {
- certificate = null;
- name = Objects.requireNonNull(subjectName,
- "Constructor requires non-null subject");
- pubKey = Objects.requireNonNull(key,
- "Constructor requires non-null public key");
- }
-
- IssuerInfo(TrustAnchor anchor) {
- certificate = anchor.getTrustedCert();
- if (certificate != null) {
- name = certificate.getSubjectX500Principal();
- pubKey = certificate.getPublicKey();
+ IssuerInfo(TrustAnchor anchor, X509Certificate issuerCert) {
+ if (anchor == null && issuerCert == null) {
+ throw new NullPointerException("TrustAnchor and issuerCert " +
+ "cannot be null");
+ }
+ this.anchor = anchor;
+ if (issuerCert != null) {
+ name = issuerCert.getSubjectX500Principal();
+ pubKey = issuerCert.getPublicKey();
+ certificate = issuerCert;
} else {
name = anchor.getCA();
pubKey = anchor.getCAPublicKey();
+ certificate = anchor.getTrustedCert();
}
}
@@ -1047,6 +1048,15 @@
}
/**
+ * Get the TrustAnchor for the certificate chain.
+ *
+ * @return a {@code TrustAnchor}.
+ */
+ TrustAnchor getAnchor() {
+ return anchor;
+ }
+
+ /**
* Create a string representation of this IssuerInfo.
*
* @return a {@code String} form of this IssuerInfo object.
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/RevocationChecker.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/RevocationChecker.java Wed Oct 26 20:13:29 2016 +0000
@@ -437,7 +437,7 @@
private void updateState(X509Certificate cert)
throws CertPathValidatorException
{
- issuerInfo = new OCSPResponse.IssuerInfo(cert);
+ issuerInfo = new OCSPResponse.IssuerInfo(anchor, cert);
// Make new public key if parameters are missing
PublicKey pubKey = cert.getPublicKey();
@@ -740,8 +740,8 @@
}
response = OCSP.check(Collections.singletonList(certId),
- responderURI, issuerInfo,
- responderCert, null, ocspExtensions);
+ responderURI, issuerInfo, responderCert, params.date(),
+ ocspExtensions);
}
} catch (IOException e) {
throw new CertPathValidatorException(
--- a/jdk/src/java.base/share/classes/sun/security/ssl/EllipticCurvesExtension.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/EllipticCurvesExtension.java Wed Oct 26 20:13:29 2016 +0000
@@ -282,7 +282,7 @@
private static int getPreferredCurve(int[] curves,
AlgorithmConstraints constraints) {
for (int curveId : curves) {
- if (constraints.permits(
+ if (isSupported(curveId) && constraints.permits(
EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
"EC", idToParams.get(curveId))) {
return curveId;
--- a/jdk/src/java.base/share/classes/sun/security/ssl/HandshakeMessage.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/HandshakeMessage.java Wed Oct 26 20:13:29 2016 +0000
@@ -49,6 +49,7 @@
import sun.security.ssl.CipherSuite.*;
import static sun.security.ssl.CipherSuite.PRF.*;
import sun.security.util.KeyUtil;
+import sun.security.util.MessageDigestSpi2;
import sun.security.provider.certpath.OCSPResponse;
/**
@@ -2124,63 +2125,14 @@
md.update(temp);
}
- private static final Class<?> delegate;
- private static final Field spiField;
-
- static {
- try {
- delegate = Class.forName("java.security.MessageDigest$Delegate");
- spiField = delegate.getDeclaredField("digestSpi");
- } catch (Exception e) {
- throw new RuntimeException("Reflection failed", e);
- }
- makeAccessible(spiField);
- }
-
- private static void makeAccessible(final AccessibleObject o) {
- AccessController.doPrivileged(new PrivilegedAction<Object>() {
- @Override
- public Object run() {
- o.setAccessible(true);
- return null;
- }
- });
- }
-
- // ConcurrentHashMap does not allow null values, use this marker object
- private static final Object NULL_OBJECT = new Object();
-
- // cache Method objects per Spi class
- // Note that this will prevent the Spi classes from being GC'd. We assume
- // that is not a problem.
- private static final Map<Class<?>,Object> methodCache =
- new ConcurrentHashMap<>();
-
private static void digestKey(MessageDigest md, SecretKey key) {
try {
- // Verify that md is implemented via MessageDigestSpi, not
- // via JDK 1.1 style MessageDigest subclassing.
- if (md.getClass() != delegate) {
- throw new Exception("Digest is not a MessageDigestSpi");
- }
- MessageDigestSpi spi = (MessageDigestSpi)spiField.get(md);
- Class<?> clazz = spi.getClass();
- Object r = methodCache.get(clazz);
- if (r == null) {
- try {
- r = clazz.getDeclaredMethod("implUpdate", SecretKey.class);
- makeAccessible((Method)r);
- } catch (NoSuchMethodException e) {
- r = NULL_OBJECT;
- }
- methodCache.put(clazz, r);
- }
- if (r == NULL_OBJECT) {
+ if (md instanceof MessageDigestSpi2) {
+ ((MessageDigestSpi2)md).engineUpdate(key);
+ } else {
throw new Exception(
"Digest does not support implUpdate(SecretKey)");
}
- Method update = (Method)r;
- update.invoke(spi, key);
} catch (Exception e) {
throw new RuntimeException(
"Could not obtain encoded key and "
--- a/jdk/src/java.base/share/classes/sun/security/ssl/ServerHandshaker.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/ServerHandshaker.java Wed Oct 26 20:13:29 2016 +0000
@@ -1172,11 +1172,18 @@
if (trySetCipherSuite(suite) == false) {
continue;
}
+
+ if (debug != null && Debug.isOn("handshake")) {
+ System.out.println("Standard ciphersuite chosen: " + suite);
+ }
return;
}
for (CipherSuite suite : legacySuites) {
if (trySetCipherSuite(suite)) {
+ if (debug != null && Debug.isOn("handshake")) {
+ System.out.println("Legacy ciphersuite chosen: " + suite);
+ }
return;
}
}
--- a/jdk/src/java.base/share/classes/sun/security/util/CurveDB.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/sun/security/util/CurveDB.java Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -664,6 +664,74 @@
0xFF70, nameSplitPattern);
*/
+ /*
+ * Brainpool curves (RFC 5639)
+ * (Twisted curves are not included)
+ */
+
+ add("brainpoolP160r1", "1.3.36.3.3.2.8.1.1.1", P,
+ "E95E4A5F737059DC60DFC7AD95B3D8139515620F",
+ "340E7BE2A280EB74E2BE61BADA745D97E8F7C300",
+ "1E589A8595423412134FAA2DBDEC95C8D8675E58",
+ "BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3",
+ "1667CB477A1A8EC338F94741669C976316DA6321",
+ "E95E4A5F737059DC60DF5991D45029409E60FC09",
+ 1, nameSplitPattern);
+
+ add("brainpoolP192r1", "1.3.36.3.3.2.8.1.1.3", P,
+ "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297",
+ "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF",
+ "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9",
+ "C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6",
+ "14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F",
+ "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1",
+ 1, nameSplitPattern);
+
+ add("brainpoolP224r1", "1.3.36.3.3.2.8.1.1.5", P,
+ "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF",
+ "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43",
+ "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B",
+ "0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D",
+ "58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD",
+ "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F",
+ 1, nameSplitPattern);
+
+ add("brainpoolP256r1", "1.3.36.3.3.2.8.1.1.7", P,
+ "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377",
+ "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9",
+ "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6",
+ "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262",
+ "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997",
+ "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7",
+ 1, nameSplitPattern);
+
+ add("brainpoolP320r1", "1.3.36.3.3.2.8.1.1.9", P,
+ "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27",
+ "3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4",
+ "520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6",
+ "43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611",
+ "14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1",
+ "D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311",
+ 1, nameSplitPattern);
+
+ add("brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11", P,
+ "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53",
+ "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826",
+ "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11",
+ "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E",
+ "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315",
+ "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565",
+ 1, nameSplitPattern);
+
+ add("brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13", P,
+ "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3",
+ "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA",
+ "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723",
+ "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822",
+ "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892",
+ "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069",
+ 1, nameSplitPattern);
+
specCollection = Collections.unmodifiableCollection(oidMap.values());
}
}
--- a/jdk/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java Wed Oct 26 20:13:29 2016 +0000
@@ -60,6 +60,10 @@
public static final String PROPERTY_TLS_DISABLED_ALGS =
"jdk.tls.disabledAlgorithms";
+ // the known security property, jdk.jar.disabledAlgorithms
+ public static final String PROPERTY_JAR_DISABLED_ALGS =
+ "jdk.jar.disabledAlgorithms";
+
private final String[] disabledAlgorithms;
private final Constraints algorithmConstraints;
@@ -73,6 +77,14 @@
this(propertyName, new AlgorithmDecomposer());
}
+ /**
+ * Initialize algorithm constraints with the specified security property
+ * for a specific usage type.
+ *
+ * @param propertyName the security property name that define the disabled
+ * algorithm constraints
+ * @param decomposer an alternate AlgorithmDecomposer.
+ */
public DisabledAlgorithmConstraints(String propertyName,
AlgorithmDecomposer decomposer) {
super(decomposer);
@@ -530,7 +542,8 @@
}
throw new CertPathValidatorException(
"Algorithm constraints check failed on certificate " +
- "anchor limits",
+ "anchor limits. " + algorithm + " used with " +
+ cp.getCertificate().getSubjectX500Principal(),
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
}
@@ -611,8 +624,8 @@
return;
}
throw new CertPathValidatorException(
- "denyAfter constraint check failed. " +
- "Constraint date: " +
+ "denyAfter constraint check failed: " + algorithm +
+ " used with Constraint date: " +
dateFormat.format(denyAfterDate) + "; "
+ errmsg + dateFormat.format(currentDate),
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
@@ -644,6 +657,7 @@
private int minSize; // the minimal available key size
private int maxSize; // the maximal available key size
private int prohibitedSize = -1; // unavailable key sizes
+ private int size;
public KeySizeConstraint(String algo, Operator operator, int length) {
algorithm = algo;
@@ -695,7 +709,9 @@
return;
}
throw new CertPathValidatorException(
- "Algorithm constraints check failed on keysize limits",
+ "Algorithm constraints check failed on keysize limits. "
+ + algorithm + " " + size + "bit key used with "
+ + cp.getCertificate().getSubjectX500Principal(),
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
}
@@ -722,7 +738,7 @@
return true;
}
- int size = KeyUtil.getKeySize(key);
+ size = KeyUtil.getKeySize(key);
if (size == 0) {
return false; // we don't allow any key of size 0.
} else if (size > 0) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/util/MessageDigestSpi2.java Wed Oct 26 20:13:29 2016 +0000
@@ -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. 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 sun.security.util;
+
+import java.security.InvalidKeyException;
+import javax.crypto.SecretKey;
+
+/**
+ * Special interface for additional MessageDigestSpi method(s).
+ */
+public interface MessageDigestSpi2 {
+
+ /**
+ * Updates the digest using the specified key.
+ * This is used for SSL 3.0 only, we may deprecate and remove the support
+ * of this in the future
+ *
+ * @param key the key whose value is to be digested.
+ */
+ void engineUpdate(SecretKey key) throws InvalidKeyException;
+}
--- a/jdk/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -25,26 +25,49 @@
package sun.security.util;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.security.CodeSigner;
+import java.security.CryptoPrimitive;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.SignatureException;
import java.security.cert.CertPath;
import java.security.cert.X509Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
-import java.security.*;
-import java.io.*;
-import java.util.*;
-import java.util.jar.*;
-
-import sun.security.pkcs.*;
+import java.util.ArrayList;
import java.util.Base64;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.jar.Attributes;
+import java.util.jar.JarException;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
import sun.security.jca.Providers;
+import sun.security.pkcs.PKCS7;
+import sun.security.pkcs.SignerInfo;
public class SignatureFileVerifier {
/* Are we debugging ? */
private static final Debug debug = Debug.getInstance("jar");
- /* cache of CodeSigner objects */
+ private static final Set<CryptoPrimitive> DIGEST_PRIMITIVE_SET =
+ Collections.unmodifiableSet(EnumSet.of(CryptoPrimitive.MESSAGE_DIGEST));
+
+ private static final DisabledAlgorithmConstraints JAR_DISABLED_CHECK =
+ new DisabledAlgorithmConstraints(
+ DisabledAlgorithmConstraints.PROPERTY_JAR_DISABLED_ALGS);
+
private ArrayList<CodeSigner[]> signerCache;
private static final String ATTR_DIGEST =
@@ -199,8 +222,15 @@
/** get digest from cache */
- private MessageDigest getDigest(String algorithm)
- {
+ private MessageDigest getDigest(String algorithm) throws SignatureException {
+ // check that algorithm is not restricted
+ if (!JAR_DISABLED_CHECK.permits(DIGEST_PRIMITIVE_SET, algorithm, null)) {
+ SignatureException e =
+ new SignatureException("SignatureFile check failed. " +
+ "Disabled algorithm used: " + algorithm);
+ throw e;
+ }
+
if (createdDigests == null)
createdDigests = new HashMap<>();
@@ -320,7 +350,7 @@
private boolean verifyManifestHash(Manifest sf,
ManifestDigester md,
List<Object> manifestDigests)
- throws IOException
+ throws IOException, SignatureException
{
Attributes mattr = sf.getMainAttributes();
boolean manifestSigned = false;
@@ -364,7 +394,7 @@
private boolean verifyManifestMainAttrs(Manifest sf,
ManifestDigester md)
- throws IOException
+ throws IOException, SignatureException
{
Attributes mattr = sf.getMainAttributes();
boolean attrsVerified = true;
@@ -430,14 +460,14 @@
private boolean verifySection(Attributes sfAttr,
String name,
ManifestDigester md)
- throws IOException
+ throws IOException, SignatureException
{
boolean oneDigestVerified = false;
ManifestDigester.Entry mde = md.get(name,block.isOldStyle());
if (mde == null) {
throw new SecurityException(
- "no manifiest section for signature file entry "+name);
+ "no manifest section for signature file entry "+name);
}
if (sfAttr != null) {
--- a/jdk/src/java.base/share/conf/net.properties Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/conf/net.properties Wed Oct 26 20:13:29 2016 +0000
@@ -72,3 +72,30 @@
# value is 10).
# http.KeepAlive.remainingData=512
# http.KeepAlive.queuedConnections=10
+
+# Authentication Scheme restrictions for HTTP and HTTPS.
+#
+# In some environments certain authentication schemes may be undesirable
+# when proxying HTTP or HTTPS. For example, "Basic" results in effectively the
+# cleartext transmission of the user's password over the physical network.
+# This section describes the mechanism for disabling authentication schemes
+# based on the scheme name. Disabled schemes will be treated as if they are not
+# supported by the implementation.
+#
+# The 'jdk.http.auth.tunneling.disabledSchemes' property lists the authentication
+# schemes that will be disabled when tunneling HTTPS over a proxy, HTTP CONNECT.
+# The 'jdk.http.auth.proxying.disabledSchemes' property lists the authentication
+# schemes that will be disabled when proxying HTTP.
+#
+# In both cases the property is a comma-separated list of, case-insensitive,
+# authentication scheme names, as defined by their relevant RFCs. An
+# implementation may, but is not required to, support common schemes whose names
+# include: 'Basic', 'Digest', 'NTLM', 'Kerberos', 'Negotiate'. A scheme that
+# is not known, or not supported, by the implementation is ignored.
+#
+# Note: This property is currently used by the JDK Reference implementation. It
+# is not guaranteed to be examined and used by other implementations.
+#
+#jdk.http.auth.proxying.disabledSchemes=
+jdk.http.auth.tunneling.disabledSchemes=Basic
+
--- a/jdk/src/java.base/share/conf/security/java.security Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/conf/security/java.security Wed Oct 26 20:13:29 2016 +0000
@@ -655,6 +655,44 @@
jdk.certpath.disabledAlgorithms=MD2, MD5, SHA1 jdkCA & denyAfter 2017-01-01, \
RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224
+# Algorithm restrictions for signed JAR files
+#
+# In some environments, certain algorithms or key lengths may be undesirable
+# for signed JAR validation. For example, "MD2" is generally no longer
+# considered to be a secure hash algorithm. This section describes the
+# mechanism for disabling algorithms based on algorithm name and/or key length.
+# JARs signed with any of the disabled algorithms or key sizes will be treated
+# as unsigned.
+#
+# The syntax of the disabled algorithm string is described as follows:
+# DisabledAlgorithms:
+# " DisabledAlgorithm { , DisabledAlgorithm } "
+#
+# DisabledAlgorithm:
+# AlgorithmName [Constraint]
+#
+# AlgorithmName:
+# (see below)
+#
+# Constraint:
+# KeySizeConstraint
+#
+# KeySizeConstraint:
+# keySize Operator KeyLength
+#
+# Operator:
+# <= | < | == | != | >= | >
+#
+# KeyLength:
+# Integer value of the algorithm's key length in bits
+#
+# Note: This property is currently used by the JDK Reference
+# implementation. It is not guaranteed to be examined and used by other
+# implementations.
+#
+jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \
+ DSA keySize < 1024
+
# Algorithm restrictions for Secure Socket Layer/Transport Layer Security
# (SSL/TLS/DTLS) processing
#
@@ -935,3 +973,4 @@
# Otherwise, the status is UNDECIDED.
#
#jdk.serialFilter=pattern;pattern
+
--- a/jdk/src/java.base/share/lib/security/default.policy Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/lib/security/default.policy Wed Oct 26 20:13:29 2016 +0000
@@ -91,7 +91,6 @@
};
grant codeBase "jrt:/jdk.charsets" {
- permission java.io.FilePermission "${java.home}/-", "read";
permission java.util.PropertyPermission "os.name", "read";
permission java.util.PropertyPermission "sun.nio.cs.map", "read";
permission java.lang.RuntimePermission "charsetProvider";
@@ -104,7 +103,6 @@
permission java.lang.RuntimePermission
"accessClassInPackage.sun.security.*";
permission java.lang.RuntimePermission "loadLibrary.sunec";
- permission java.util.PropertyPermission "*", "read";
permission java.security.SecurityPermission "putProviderProperty.SunEC";
permission java.security.SecurityPermission "clearProviderProperties.SunEC";
permission java.security.SecurityPermission "removeProviderProperty.SunEC";
@@ -113,11 +111,11 @@
grant codeBase "jrt:/jdk.crypto.pkcs11" {
permission java.lang.RuntimePermission
"accessClassInPackage.sun.security.*";
- permission java.lang.RuntimePermission "accessClassInPackage.sun.misc";
permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
permission java.lang.RuntimePermission "loadLibrary.j2pkcs11";
- // needs "security.pkcs11.allowSingleThreadedModules"
- permission java.util.PropertyPermission "*", "read";
+ permission java.util.PropertyPermission "sun.security.pkcs11.allowSingleThreadedModules", "read";
+ permission java.util.PropertyPermission "os.name", "read";
+ permission java.util.PropertyPermission "os.arch", "read";
permission java.security.SecurityPermission "putProviderProperty.*";
permission java.security.SecurityPermission "clearProviderProperties.*";
permission java.security.SecurityPermission "removeProviderProperty.*";
--- a/jdk/src/java.base/share/native/libverify/check_code.c Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/share/native/libverify/check_code.c Wed Oct 26 20:13:29 2016 +0000
@@ -1293,14 +1293,13 @@
case JVM_OPC_invokevirtual:
case JVM_OPC_invokespecial:
case JVM_OPC_invokestatic:
- case JVM_OPC_invokedynamic:
case JVM_OPC_invokeinterface: {
/* Make sure the constant pool item is the right type. */
int key = (code[offset + 1] << 8) + code[offset + 2];
const char *methodname;
jclass cb = context->class;
fullinfo_type clazz_info;
- int is_constructor, is_internal, is_invokedynamic;
+ int is_constructor, is_internal;
int kind;
switch (opcode ) {
@@ -1309,9 +1308,6 @@
? (1 << JVM_CONSTANT_Methodref)
: ((1 << JVM_CONSTANT_InterfaceMethodref) | (1 << JVM_CONSTANT_Methodref)));
break;
- case JVM_OPC_invokedynamic:
- kind = 1 << JVM_CONSTANT_NameAndType;
- break;
case JVM_OPC_invokeinterface:
kind = 1 << JVM_CONSTANT_InterfaceMethodref;
break;
@@ -1319,7 +1315,6 @@
kind = 1 << JVM_CONSTANT_Methodref;
}
- is_invokedynamic = opcode == JVM_OPC_invokedynamic;
/* Make sure the constant pool item is the right type. */
verify_constant_pool_type(context, key, kind);
methodname = JVM_GetCPMethodNameUTF(env, cb, key);
@@ -1328,11 +1323,8 @@
is_internal = methodname[0] == '<';
pop_and_free(context);
- if (is_invokedynamic)
- clazz_info = context->object_info; // anything will do
- else
- clazz_info = cp_index_to_class_fullinfo(context, key,
- JVM_CONSTANT_Methodref);
+ clazz_info = cp_index_to_class_fullinfo(context, key,
+ JVM_CONSTANT_Methodref);
this_idata->operand.i = key;
this_idata->operand2.fi = clazz_info;
if (is_constructor) {
@@ -1387,17 +1379,15 @@
"Fourth operand byte of invokeinterface must be zero");
}
pop_and_free(context);
- } else if (opcode == JVM_OPC_invokedynamic) {
- if (code[offset + 3] != 0 || code[offset + 4] != 0) {
- CCerror(context,
- "Third and fourth operand bytes of invokedynamic must be zero");
- }
} else if (opcode == JVM_OPC_invokevirtual
|| opcode == JVM_OPC_invokespecial)
set_protected(context, inumber, key, opcode);
break;
}
+ case JVM_OPC_invokedynamic:
+ CCerror(context,
+ "invokedynamic bytecode is not supported in this class file version");
case JVM_OPC_instanceof:
case JVM_OPC_checkcast:
@@ -2085,7 +2075,6 @@
case JVM_OPC_invokevirtual: case JVM_OPC_invokespecial:
case JVM_OPC_invokeinit: /* invokespecial call to <init> */
- case JVM_OPC_invokedynamic:
case JVM_OPC_invokestatic: case JVM_OPC_invokeinterface: {
/* The top stuff on the stack depends on the method signature */
int operand = this_idata->operand.i;
@@ -2101,8 +2090,7 @@
print_formatted_methodname(context, operand);
}
#endif
- if (opcode != JVM_OPC_invokestatic &&
- opcode != JVM_OPC_invokedynamic)
+ if (opcode != JVM_OPC_invokestatic)
/* First, push the object */
*ip++ = (opcode == JVM_OPC_invokeinit ? '@' : 'A');
for (p = signature + 1; *p != JVM_SIGNATURE_ENDFUNC; ) {
@@ -2388,7 +2376,6 @@
case JVM_OPC_invokevirtual: case JVM_OPC_invokespecial:
case JVM_OPC_invokeinit:
- case JVM_OPC_invokedynamic:
case JVM_OPC_invokeinterface: case JVM_OPC_invokestatic: {
int operand = this_idata->operand.i;
const char *signature =
@@ -2398,8 +2385,7 @@
int item;
const char *p;
check_and_push(context, signature, VM_STRING_UTF);
- if (opcode == JVM_OPC_invokestatic ||
- opcode == JVM_OPC_invokedynamic) {
+ if (opcode == JVM_OPC_invokestatic) {
item = 0;
} else if (opcode == JVM_OPC_invokeinit) {
fullinfo_type init_type = this_idata->operand2.fi;
@@ -2795,7 +2781,6 @@
case JVM_OPC_invokevirtual: case JVM_OPC_invokespecial:
case JVM_OPC_invokeinit:
- case JVM_OPC_invokedynamic:
case JVM_OPC_invokestatic: case JVM_OPC_invokeinterface: {
/* Look to signature to determine correct result. */
int operand = this_idata->operand.i;
--- a/jdk/src/java.base/solaris/lib/security/default.policy Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/solaris/lib/security/default.policy Wed Oct 26 20:13:29 2016 +0000
@@ -4,7 +4,10 @@
permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
permission java.lang.RuntimePermission "loadLibrary.j2ucrypto";
// need "com.oracle.security.ucrypto.debug" for debugging
- permission java.util.PropertyPermission "*", "read";
+ permission java.util.PropertyPermission "com.oracle.security.ucrypto.debug", "read";
+ permission java.util.PropertyPermission "file.separator", "read";
+ permission java.util.PropertyPermission "java.home", "read";
+ permission java.util.PropertyPermission "os.name", "read";
permission java.security.SecurityPermission
"putProviderProperty.OracleUcrypto";
permission java.security.SecurityPermission
--- a/jdk/src/java.base/unix/native/libnet/net_util_md.c Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/unix/native/libnet/net_util_md.c Wed Oct 26 20:13:29 2016 +0000
@@ -273,13 +273,10 @@
#endif
-
void
NET_ThrowByNameWithLastError(JNIEnv *env, const char *name,
const char *defaultDetail) {
- char errmsg[255];
- sprintf(errmsg, "errno: %d, error: %s\n", errno, defaultDetail);
- JNU_ThrowByNameWithLastError(env, name, errmsg);
+ JNU_ThrowByNameWithMessageAndLastError(env, name, defaultDetail);
}
void
--- a/jdk/src/java.base/windows/native/libjli/java_md.c Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/windows/native/libjli/java_md.c Wed Oct 26 20:13:29 2016 +0000
@@ -48,6 +48,10 @@
char *jvmpath, jint jvmpathsize);
static jboolean GetJREPath(char *path, jint pathsize);
+#ifdef USE_REGISTRY_LOOKUP
+jboolean GetPublicJREHome(char *buf, jint bufsize);
+#endif
+
/* We supports warmup for UI stack that is performed in parallel
* to VM initialization.
* This helps to improve startup of UI application as warmup phase
@@ -346,6 +350,14 @@
}
}
+#ifdef USE_REGISTRY_LOOKUP
+ /* Lookup public JRE using Windows registry. */
+ if (GetPublicJREHome(path, pathsize)) {
+ JLI_TraceLauncher("JRE path is %s\n", path);
+ return JNI_TRUE;
+ }
+#endif
+
JLI_ReportErrorMessage(JRE_ERROR8 JAVA_DLL);
return JNI_FALSE;
}
--- a/jdk/src/java.base/windows/native/libnet/NetworkInterface_winXP.c Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/windows/native/libnet/NetworkInterface_winXP.c Wed Oct 26 20:13:29 2016 +0000
@@ -554,14 +554,20 @@
* Create a NetworkInterface object and populate it
*/
netifObj = (*env)->NewObject(env, ni_class, ni_ctor);
+ if (netifObj == NULL) {
+ return NULL;
+ }
name = (*env)->NewStringUTF(env, ifs->name);
+ if (name == NULL) {
+ return NULL;
+ }
if (ifs->dNameIsUnicode) {
displayName = (*env)->NewString(env, (PWCHAR)ifs->displayName,
(jsize)wcslen ((PWCHAR)ifs->displayName));
} else {
displayName = (*env)->NewStringUTF(env, ifs->displayName);
}
- if (netifObj == NULL || name == NULL || displayName == NULL) {
+ if (displayName == NULL) {
return NULL;
}
(*env)->SetObjectField(env, netifObj, ni_nameID, name);
@@ -621,26 +627,28 @@
(*env)->SetObjectArrayElement(env, bindsArr, bind_index++, ibObj);
} else /* AF_INET6 */ {
int scope;
+ jboolean ret;
iaObj = (*env)->NewObject(env, ia6_class, ia6_ctrID);
- if (iaObj) {
- jboolean ret = setInet6Address_ipaddress(env, iaObj, (jbyte *)&(addrs->addr.sa6.sin6_addr.s6_addr));
- if (ret == JNI_FALSE) {
- return NULL;
- }
- scope = addrs->addr.sa6.sin6_scope_id;
- if (scope != 0) { /* zero is default value, no need to set */
- setInet6Address_scopeid(env, iaObj, scope);
- setInet6Address_scopeifname(env, iaObj, netifObj);
- }
- ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID);
- if (ibObj == NULL) {
- free_netaddr(netaddrP);
- return NULL;
- }
- (*env)->SetObjectField(env, ibObj, ni_ibaddressID, iaObj);
- (*env)->SetShortField(env, ibObj, ni_ibmaskID, addrs->mask);
- (*env)->SetObjectArrayElement(env, bindsArr, bind_index++, ibObj);
+ if (iaObj == NULL) {
+ return NULL;
+ }
+ ret = setInet6Address_ipaddress(env, iaObj, (jbyte *)&(addrs->addr.sa6.sin6_addr.s6_addr));
+ if (ret == JNI_FALSE) {
+ return NULL;
}
+ scope = addrs->addr.sa6.sin6_scope_id;
+ if (scope != 0) { /* zero is default value, no need to set */
+ setInet6Address_scopeid(env, iaObj, scope);
+ setInet6Address_scopeifname(env, iaObj, netifObj);
+ }
+ ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID);
+ if (ibObj == NULL) {
+ free_netaddr(netaddrP);
+ return NULL;
+ }
+ (*env)->SetObjectField(env, ibObj, ni_ibaddressID, iaObj);
+ (*env)->SetShortField(env, ibObj, ni_ibmaskID, addrs->mask);
+ (*env)->SetObjectArrayElement(env, bindsArr, bind_index++, ibObj);
}
(*env)->SetObjectArrayElement(env, addrArr, addr_index, iaObj);
addrs = addrs->next;
--- a/jdk/src/java.base/windows/native/libnet/TwoStacksPlainDatagramSocketImpl.c Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/windows/native/libnet/TwoStacksPlainDatagramSocketImpl.c Wed Oct 26 20:13:29 2016 +0000
@@ -830,6 +830,7 @@
}
if (IS_NULL(addressObj)) {
JNU_ThrowNullPointerException(env, "Null address in peek()");
+ return -1;
} else {
address = getInetAddress_addr(env, addressObj);
/* We only handle IPv4 for now. Will support IPv6 once its in the os */
@@ -1127,11 +1128,23 @@
}
if (n == -1) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "socket closed");
+ if (packetBufferLen > MAX_BUFFER_LEN) {
+ free(fullPacket);
+ }
+ return -1;
} else if (n == -2) {
JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
"operation interrupted");
+ if (packetBufferLen > MAX_BUFFER_LEN) {
+ free(fullPacket);
+ }
+ return -1;
} else if (n < 0) {
NET_ThrowCurrent(env, "Datagram receive failed");
+ if (packetBufferLen > MAX_BUFFER_LEN) {
+ free(fullPacket);
+ }
+ return -1;
} else {
jobject packetAddress;
@@ -1882,7 +1895,7 @@
default :
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"Socket option not supported by PlainDatagramSocketImp");
- break;
+ return;
}
@@ -2325,6 +2338,7 @@
if (NET_SetSockOpt(fd, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&ittl,
sizeof (ittl)) < 0) {
NET_ThrowCurrent(env, "set IP_MULTICAST_TTL failed");
+ return;
}
}
@@ -2518,6 +2532,9 @@
} else {
ifindex = getIndexFromIf (env, niObj);
if (ifindex == -1) {
+ if ((*env)->ExceptionOccurred(env)) {
+ return;
+ }
NET_ThrowCurrent(env, "get ifindex failed");
return;
}
--- a/jdk/src/java.base/windows/native/libnet/TwoStacksPlainSocketImpl.c Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/windows/native/libnet/TwoStacksPlainSocketImpl.c Wed Oct 26 20:13:29 2016 +0000
@@ -108,7 +108,7 @@
psi_portID = (*env)->GetFieldID(env, cls, "port", "I");
CHECK_NULL(psi_portID);
psi_lastfdID = (*env)->GetFieldID(env, cls, "lastfd", "I");
- CHECK_NULL(psi_portID);
+ CHECK_NULL(psi_lastfdID);
psi_localportID = (*env)->GetFieldID(env, cls, "localport", "I");
CHECK_NULL(psi_localportID);
psi_timeoutID = (*env)->GetFieldID(env, cls, "timeout", "I");
@@ -153,17 +153,17 @@
fd1Obj = (*env)->GetObjectField(env, this, psi_fd1ID);
if (IS_NULL(fd1Obj)) {
+ (*env)->SetIntField(env, fdObj, IO_fd_fdID, -1);
+ NET_SocketClose(fd);
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"null fd1 object");
- (*env)->SetIntField(env, fdObj, IO_fd_fdID, -1);
- NET_SocketClose(fd);
return;
}
fd1 = socket(AF_INET6, (stream ? SOCK_STREAM: SOCK_DGRAM), 0);
if (fd1 == -1) {
- NET_ThrowCurrent(env, "create");
(*env)->SetIntField(env, fdObj, IO_fd_fdID, -1);
NET_SocketClose(fd);
+ NET_ThrowCurrent(env, "create");
return;
} else {
/* Set socket attribute so it is not passed to any child process */
@@ -907,6 +907,7 @@
isRcvTimeoutSupported = JNI_FALSE;
} else {
NET_ThrowCurrent(env, "setsockopt SO_RCVTIMEO");
+ return;
}
}
if (fd1 != -1) {
--- a/jdk/src/java.base/windows/native/libnet/net_util_md.c Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/windows/native/libnet/net_util_md.c Wed Oct 26 20:13:29 2016 +0000
@@ -205,9 +205,7 @@
void
NET_ThrowByNameWithLastError(JNIEnv *env, const char *name,
const char *defaultDetail) {
- char errmsg[255];
- sprintf(errmsg, "errno: %d, error: %s\n", WSAGetLastError(), defaultDetail);
- JNU_ThrowByNameWithLastError(env, name, errmsg);
+ JNU_ThrowByNameWithMessageAndLastError(env, name, defaultDetail);
}
jfieldID
--- a/jdk/src/java.base/windows/native/libnio/ch/FileDispatcherImpl.c Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.base/windows/native/libnio/ch/FileDispatcherImpl.c Wed Oct 26 20:13:29 2016 +0000
@@ -202,6 +202,7 @@
if ((h == INVALID_HANDLE_VALUE) || (result == 0)) {
JNU_ThrowIOExceptionWithLastError(env, "Write failed");
+ return IOS_THROWN;
}
return convertReturnVal(env, (jint)written, JNI_FALSE);
@@ -250,6 +251,7 @@
if ((h == INVALID_HANDLE_VALUE) || (result == 0)) {
JNU_ThrowIOExceptionWithLastError(env, "Write failed");
+ return IOS_THROWN;
}
return convertLongReturnVal(env, totalWritten, JNI_FALSE);
--- a/jdk/src/java.desktop/macosx/native/libjsound/PLATFORM_API_MacOSX_PCM.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.desktop/macosx/native/libjsound/PLATFORM_API_MacOSX_PCM.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -817,6 +817,10 @@
ERROR1("<<DAUDIO_Open: ERROR: unsupported encoding (%d)\n", encoding);
return NULL;
}
+ if (channels <= 0) {
+ ERROR1("<<DAUDIO_Open: ERROR: Invalid number of channels=%d!\n", channels);
+ return NULL;
+ }
OSX_DirectAudioDevice *device = new OSX_DirectAudioDevice();
--- a/jdk/src/java.desktop/share/classes/sun/applet/AppletSecurity.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.desktop/share/classes/sun/applet/AppletSecurity.java Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 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
@@ -40,36 +40,25 @@
import java.util.StringTokenizer;
import java.security.*;
import java.lang.reflect.*;
+import jdk.internal.misc.JavaNetURLClassLoaderAccess;
+import jdk.internal.misc.JavaSecurityAccess;
+import jdk.internal.misc.SharedSecrets;
import sun.awt.AWTSecurityManager;
import sun.awt.AppContext;
import sun.awt.AWTPermissions;
import sun.security.util.SecurityConstants;
+
/**
* This class defines an applet security policy
*
*/
public
class AppletSecurity extends AWTSecurityManager {
-
- //URLClassLoader.acc
- private static Field facc = null;
-
- //AccessControlContext.context;
- private static Field fcontext = null;
-
- static {
- try {
- facc = URLClassLoader.class.getDeclaredField("acc");
- facc.setAccessible(true);
- fcontext = AccessControlContext.class.getDeclaredField("context");
- fcontext.setAccessible(true);
- } catch (NoSuchFieldException e) {
- throw new UnsupportedOperationException(e);
- }
- }
-
+ private static final JavaNetURLClassLoaderAccess JNUCLA
+ = SharedSecrets.getJavaNetURLClassLoaderAccess();
+ private static final JavaSecurityAccess JSA = SharedSecrets.getJavaSecurityAccess();
/**
* Construct and initialize.
@@ -148,6 +137,7 @@
final ClassLoader currentLoader = context[i].getClassLoader();
if (currentLoader instanceof URLClassLoader) {
+ URLClassLoader ld = (URLClassLoader)currentLoader;
loader = AccessController.doPrivileged(
new PrivilegedAction<ClassLoader>() {
public ClassLoader run() {
@@ -156,12 +146,12 @@
ProtectionDomain[] pds = null;
try {
- acc = (AccessControlContext) facc.get(currentLoader);
+ acc = JNUCLA.getAccessControlContext(ld);
if (acc == null) {
return null;
}
- pds = (ProtectionDomain[]) fcontext.get(acc);
+ pds = JSA.getProtectDomains(acc);
if (pds == null) {
return null;
}
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/ContextualGlyphSubstProc.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/ContextualGlyphSubstProc.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -46,6 +46,7 @@
ContextualGlyphSubstitutionProcessor::ContextualGlyphSubstitutionProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success)
: StateTableProcessor(morphSubtableHeader, success), entryTable(), contextualGlyphSubstitutionHeader(morphSubtableHeader, success)
{
+ if (LE_FAILURE(success)) return;
contextualGlyphSubstitutionHeader.orphan();
substitutionTableOffset = SWAPW(contextualGlyphSubstitutionHeader->substitutionTableOffset);
@@ -66,10 +67,10 @@
markGlyph = 0;
}
-ByteOffset ContextualGlyphSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index)
+ByteOffset ContextualGlyphSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index, LEErrorCode &success)
{
- LEErrorCode success = LE_NO_ERROR;
const ContextualGlyphSubstitutionStateEntry *entry = entryTable.getAlias(index, success);
+ if (LE_FAILURE(success)) return 0;
ByteOffset newState = SWAPW(entry->newStateOffset);
le_int16 flags = SWAPW(entry->flags);
WordOffset markOffset = SWAPW(entry->markOffset);
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/ContextualGlyphSubstProc.h Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/ContextualGlyphSubstProc.h Wed Oct 26 20:13:29 2016 +0000
@@ -52,7 +52,7 @@
public:
virtual void beginStateTable();
- virtual ByteOffset processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index);
+ virtual ByteOffset processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index, LEErrorCode &success);
virtual void endStateTable();
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/IndicRearrangementProcessor.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/IndicRearrangementProcessor.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -63,10 +63,10 @@
lastGlyph = 0;
}
-ByteOffset IndicRearrangementProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index)
+ByteOffset IndicRearrangementProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index, LEErrorCode &success)
{
- LEErrorCode success = LE_NO_ERROR; // todo- make a param?
- const IndicRearrangementStateEntry *entry = entryTable.getAlias(index,success);
+ const IndicRearrangementStateEntry *entry = entryTable.getAlias(index, success);
+ if (LE_FAILURE(success)) return 0;
ByteOffset newState = SWAPW(entry->newStateOffset);
IndicRearrangementFlags flags = (IndicRearrangementFlags) SWAPW(entry->flags);
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/IndicRearrangementProcessor.h Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/IndicRearrangementProcessor.h Wed Oct 26 20:13:29 2016 +0000
@@ -52,7 +52,7 @@
public:
virtual void beginStateTable();
- virtual ByteOffset processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index);
+ virtual ByteOffset processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index, LEErrorCode &success);
virtual void endStateTable();
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/LigatureSubstProc.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/LigatureSubstProc.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -67,9 +67,8 @@
m = -1;
}
-ByteOffset LigatureSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index)
+ByteOffset LigatureSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index, LEErrorCode &success)
{
- LEErrorCode success = LE_NO_ERROR;
const LigatureSubstitutionStateEntry *entry = entryTable.getAlias(index, success);
if (LE_FAILURE(success)) {
currGlyph++;
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/LigatureSubstProc.h Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/LigatureSubstProc.h Wed Oct 26 20:13:29 2016 +0000
@@ -54,7 +54,7 @@
public:
virtual void beginStateTable();
- virtual ByteOffset processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index);
+ virtual ByteOffset processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index, LEErrorCode &success);
virtual void endStateTable();
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/StateTableProcessor.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/StateTableProcessor.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -81,6 +81,7 @@
while (currGlyph <= glyphCount) {
if(LE_STATE_PATIENCE_DECR()) break; // patience exceeded.
+ if (LE_FAILURE(success)) break;
ClassCode classCode = classCodeOOB;
if (currGlyph == glyphCount) {
// XXX: How do we handle EOT vs. EOL?
@@ -100,7 +101,7 @@
EntryTableIndex entryTableIndex = stateArray.getObject((le_uint8)classCode, success);
if (LE_FAILURE(success)) { break; }
LE_STATE_PATIENCE_CURR(le_int32, currGlyph);
- currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex);
+ currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex, success);
LE_STATE_PATIENCE_INCR(currGlyph);
}
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/StateTableProcessor.h Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/StateTableProcessor.h Wed Oct 26 20:13:29 2016 +0000
@@ -53,7 +53,7 @@
virtual void beginStateTable() = 0;
- virtual ByteOffset processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index) = 0;
+ virtual ByteOffset processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index, LEErrorCode &success) = 0;
virtual void endStateTable() = 0;
--- a/jdk/src/java.desktop/share/native/liblcms/cmsintrp.c Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.desktop/share/native/liblcms/cmsintrp.c Wed Oct 26 20:13:29 2016 +0000
@@ -244,7 +244,7 @@
// To prevent out of bounds indexing
cmsINLINE cmsFloat32Number fclamp(cmsFloat32Number v)
{
- return v < 0.0f ? 0.0f : (v > 1.0f ? 1.0f : v);
+ return v < 0.0f || v != v ? 0.0f : (v > 1.0f ? 1.0f : v);
}
// Floating-point version of 1D interpolation
--- a/jdk/src/java.desktop/share/native/liblcms/cmsio0.c Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.desktop/share/native/liblcms/cmsio0.c Wed Oct 26 20:13:29 2016 +0000
@@ -1543,6 +1543,13 @@
// If the element is already in memory, return the pointer
if (Icc -> TagPtrs[n]) {
+ if (Icc -> TagTypeHandlers[n] == NULL) goto Error;
+ BaseType = Icc -> TagTypeHandlers[n]->Signature;
+ if (BaseType == 0) goto Error;
+ TagDescriptor = _cmsGetTagDescriptor(Icc-> ContextID, sig);
+ if (TagDescriptor == NULL) goto Error;
+ if (!IsTypeSupported(TagDescriptor, BaseType)) goto Error;
+
if (Icc ->TagSaveAsRaw[n]) goto Error; // We don't support read raw tags as cooked
_cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
--- a/jdk/src/java.desktop/share/native/liblcms/cmstypes.c Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.desktop/share/native/liblcms/cmstypes.c Wed Oct 26 20:13:29 2016 +0000
@@ -4313,7 +4313,10 @@
// Copy MAX_INPUT_DIMENSIONS at most. Expand to cmsUInt32Number
nMaxGrids = InputChans > MAX_INPUT_DIMENSIONS ? MAX_INPUT_DIMENSIONS : InputChans;
- for (i=0; i < nMaxGrids; i++) GridPoints[i] = (cmsUInt32Number) Dimensions8[i];
+ for (i=0; i < nMaxGrids; i++) {
+ if (Dimensions8[i] == 1) goto Error; // Impossible value, 0 for no CLUT and then 2 at least
+ GridPoints[i] = (cmsUInt32Number)Dimensions8[i];
+ }
// Allocate the true CLUT
mpe = cmsStageAllocCLutFloatGranular(self ->ContextID, GridPoints, InputChans, OutputChans, NULL);
--- a/jdk/src/java.desktop/unix/classes/sun/java2d/x11/X11SurfaceDataProxy.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.desktop/unix/classes/sun/java2d/x11/X11SurfaceDataProxy.java Wed Oct 26 20:13:29 2016 +0000
@@ -102,10 +102,13 @@
int w, int h)
{
if (cachedData == null) {
- // Bitmask will be created lazily during the blit phase
- cachedData = X11SurfaceData.createData(x11gc, w, h,
- x11gc.getColorModel(),
- null, 0, getTransparency());
+ try {
+ // Bitmask will be created lazily during the blit phase
+ cachedData = X11SurfaceData.createData(x11gc, w, h,
+ x11gc.getColorModel(),
+ null, 0, getTransparency());
+ } catch (OutOfMemoryError oome) {
+ }
}
return cachedData;
}
--- a/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRPMBlitLoops.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRPMBlitLoops.java Wed Oct 26 20:13:29 2016 +0000
@@ -138,6 +138,9 @@
vImg = (SunVolatileImage) dst.getGraphicsConfig().createCompatibleVolatileImage(w, h, src.getTransparency());
vImg.setAccelerationPriority(1.0f);
+ if (!(vImg.getDestSurface() instanceof XRSurfaceData)) {
+ throw new InvalidPipeException("Could not create XRSurfaceData");
+ }
if (src.getTransparency() == SurfaceData.OPAQUE) {
rgbTmpPM = new WeakReference<SunVolatileImage>(vImg);
} else {
--- a/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRSurfaceDataProxy.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRSurfaceDataProxy.java Wed Oct 26 20:13:29 2016 +0000
@@ -59,9 +59,12 @@
public SurfaceData validateSurfaceData(SurfaceData srcData,
SurfaceData cachedData, int w, int h) {
if (cachedData == null) {
- cachedData = XRSurfaceData.createData(xrgc, w, h,
- xrgc.getColorModel(), null, 0,
- getTransparency(), true);
+ try {
+ cachedData = XRSurfaceData.createData(xrgc, w, h,
+ xrgc.getColorModel(), null, 0,
+ getTransparency(), true);
+ } catch (OutOfMemoryError oome) {
+ }
}
return cachedData;
}
--- a/jdk/src/java.desktop/unix/native/common/java2d/x11/X11SurfaceData.c Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.desktop/unix/native/common/java2d/x11/X11SurfaceData.c Wed Oct 26 20:13:29 2016 +0000
@@ -441,7 +441,7 @@
* width , height must be nonzero otherwise XCreatePixmap
* generates BadValue in error_handler
*/
- if (width <= 0 || height <= 0) {
+ if (width <= 0 || height <= 0 || width > 32767 || height > 32767) {
JNU_ThrowOutOfMemoryError(env,
"Can't create offscreen surface");
return JNI_FALSE;
--- a/jdk/src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_PCM.c Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_PCM.c Wed Oct 26 20:13:29 2016 +0000
@@ -434,7 +434,10 @@
snd_output_stdio_attach(&ALSA_OUTPUT, stdout, 0);
}
#endif
-
+ if (channels <= 0) {
+ ERROR1("ERROR: Invalid number of channels=%d!\n", channels);
+ return NULL;
+ }
info = (AlsaPcmInfo*) malloc(sizeof(AlsaPcmInfo));
if (!info) {
ERROR0("Out of memory\n");
--- a/jdk/src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_PCM.c Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_PCM.c Wed Oct 26 20:13:29 2016 +0000
@@ -434,7 +434,10 @@
snd_output_stdio_attach(&ALSA_OUTPUT, stdout, 0);
}
#endif
-
+ if (channels <= 0) {
+ ERROR1("ERROR: Invalid number of channels=%d!\n", channels);
+ return NULL;
+ }
info = (AlsaPcmInfo*) malloc(sizeof(AlsaPcmInfo));
if (!info) {
ERROR0("Out of memory\n");
--- a/jdk/src/java.desktop/unix/native/libjsound/PLATFORM_API_SolarisOS_PCM.c Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.desktop/unix/native/libjsound/PLATFORM_API_SolarisOS_PCM.c Wed Oct 26 20:13:29 2016 +0000
@@ -182,6 +182,10 @@
ERROR1(" DAUDIO_Open: invalid encoding %d\n", (int) encoding);
return NULL;
}
+ if (channels <= 0) {
+ ERROR1(" DAUDIO_Open: Invalid number of channels=%d!\n", channels);
+ return NULL;
+ }
info = (SolPcmInfo*) malloc(sizeof(SolPcmInfo));
if (!info) {
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WFramePeer.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WFramePeer.java Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2014, 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
@@ -153,6 +153,19 @@
@Override
public void setMenuBar(MenuBar mb) {
WMenuBarPeer mbPeer = (WMenuBarPeer) WToolkit.targetToPeer(mb);
+ if (mbPeer != null) {
+ if (mbPeer.framePeer != this) {
+ mb.removeNotify();
+ mb.addNotify();
+ mbPeer = (WMenuBarPeer) WToolkit.targetToPeer(mb);
+ if (mbPeer != null && mbPeer.framePeer != this) {
+ throw new IllegalStateException("Wrong parent peer");
+ }
+ }
+ if (mbPeer != null) {
+ addChildPeer(mbPeer);
+ }
+ }
setMenuBar0(mbPeer);
updateInsets(insets_);
}
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WMenuBarPeer.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WMenuBarPeer.java Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2014, 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
@@ -31,6 +31,8 @@
// MenuBarPeer implementation
+ final WFramePeer framePeer;
+
@Override
public native void addMenu(Menu m);
@Override
@@ -44,8 +46,11 @@
// Toolkit & peer internals
WMenuBarPeer(MenuBar target) {
this.target = target;
- WFramePeer framePeer = (WFramePeer)
+ framePeer = (WFramePeer)
WToolkit.targetToPeer(target.getParent());
+ if (framePeer != null) {
+ framePeer.addChildPeer(this);
+ }
create(framePeer);
// fix for 5088782: check if menu object is created successfully
checkMenuCreation();
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WMenuItemPeer.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WMenuItemPeer.java Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2013, 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
@@ -107,6 +107,7 @@
this.target = target;
this.parent = (WMenuPeer) WToolkit.targetToPeer(target.getParent());
this.isCheckbox = isCheckbox;
+ parent.addChildPeer(this);
create(parent);
// fix for 5088782: check if menu object is created successfully
checkMenuCreation();
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WMenuPeer.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WMenuPeer.java Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2014, 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
@@ -51,10 +51,12 @@
if (parent instanceof MenuBar) {
WMenuBarPeer mbPeer = (WMenuBarPeer) WToolkit.targetToPeer(parent);
this.parent = mbPeer;
+ mbPeer.addChildPeer(this);
createMenu(mbPeer);
}
else if (parent instanceof Menu) {
this.parent = (WMenuPeer) WToolkit.targetToPeer(parent);
+ this.parent.addChildPeer(this);
createSubMenu(this.parent);
}
else {
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WObjectPeer.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WObjectPeer.java Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2008, 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
@@ -24,6 +24,9 @@
*/
package sun.awt.windows;
+import java.util.Map;
+import java.util.WeakHashMap;
+
abstract class WObjectPeer {
static {
@@ -45,6 +48,8 @@
// used to synchronize the state of this peer
private final Object stateLock = new Object();
+ private volatile Map<WObjectPeer, WObjectPeer> childPeers;
+
public static WObjectPeer getPeerForTarget(Object t) {
WObjectPeer peer = (WObjectPeer) WToolkit.targetToPeer(t);
return peer;
@@ -77,6 +82,9 @@
}
if (call_disposeImpl) {
+ if (childPeers != null) {
+ disposeChildPeers();
+ }
disposeImpl();
}
}
@@ -88,4 +96,33 @@
* Initialize JNI field and method IDs
*/
private static native void initIDs();
+
+ // if a child peer existence depends on this peer, add it to this collection
+ final void addChildPeer(WObjectPeer child) {
+ synchronized (getStateLock()) {
+ if (childPeers == null) {
+ childPeers = new WeakHashMap<>();
+ }
+ if (isDisposed()) {
+ throw new IllegalStateException("Parent peer is disposed");
+ }
+ childPeers.put(child, this);
+ }
+ }
+
+ // called to dispose dependent child peers
+ private void disposeChildPeers() {
+ synchronized (getStateLock()) {
+ for (WObjectPeer child : childPeers.keySet()) {
+ if (child != null) {
+ try {
+ child.dispose();
+ }
+ catch (Exception e) {
+ // ignored
+ }
+ }
+ }
+ }
+ }
}
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPopupMenuPeer.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPopupMenuPeer.java Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2014, 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
@@ -58,6 +58,7 @@
parent = WToolkit.getNativeContainer((Component)parent);
parentPeer = (WComponentPeer) WToolkit.targetToPeer(parent);
}
+ parentPeer.addChildPeer(this);
createMenu(parentPeer);
// fix for 5088782: check if menu object is created successfully
checkMenuCreation();
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Font.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Font.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -640,7 +640,7 @@
int AwtFont::getFontDescriptorNumber(JNIEnv *env, jobject font,
jobject fontDescriptor)
{
- int i, num;
+ int i, num = 0;
jobject refFontDescriptor;
jobjectArray array;
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Frame.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Frame.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -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
@@ -1113,11 +1113,19 @@
void AwtFrame::SetMenuBar(AwtMenuBar* mb)
{
+ if (menuBar) {
+ menuBar->SetFrame(NULL);
+ }
menuBar = mb;
if (mb == NULL) {
// Remove existing menu bar, if any.
::SetMenu(GetHWnd(), NULL);
} else {
+ AwtFrame* oldFrame = menuBar->GetFrame();
+ if (oldFrame && oldFrame != this) {
+ oldFrame->SetMenuBar(NULL);
+ }
+ menuBar->SetFrame(this);
if (menuBar->GetHMenu() != NULL) {
::SetMenu(GetHWnd(), menuBar->GetHMenu());
}
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuBar.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuBar.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2014, 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
@@ -58,6 +58,9 @@
void AwtMenuBar::Dispose()
{
+ if (m_frame != NULL && m_frame->GetMenuBar() == this) {
+ m_frame->SetMenuBar(NULL);
+ }
m_frame = NULL;
AwtMenu::Dispose();
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuBar.h Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuBar.h Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2011, 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
@@ -63,6 +63,9 @@
virtual AwtMenuBar* GetMenuBar() { return this; }
INLINE AwtFrame* GetFrame() { return m_frame; }
+ INLINE void SetFrame(AwtFrame* frame) {
+ m_frame = frame;
+ }
virtual HWND GetOwnerHWnd();
virtual void RedrawMenuBar();
--- a/jdk/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -859,6 +859,10 @@
ERROR1("DAUDIO_Open: ERROR: cannot open the device with encoding=%d!\n", encoding);
return NULL;
}
+ if (channels <= 0) {
+ ERROR1("DAUDIO_Open: ERROR: Invalid number of channels=%d!\n", channels);
+ return NULL;
+ }
if (sampleSizeInBits > 8 &&
#ifdef _LITTLE_ENDIAN
isBigEndian
--- a/jdk/src/java.management/share/classes/com/sun/jmx/remote/util/ClassLoaderWithRepository.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.management/share/classes/com/sun/jmx/remote/util/ClassLoaderWithRepository.java Wed Oct 26 20:13:29 2016 +0000
@@ -39,8 +39,9 @@
}
protected Class<?> findClass(String name) throws ClassNotFoundException {
+ Class<?> cls;
try {
- return repository.loadClass(name);
+ cls = repository.loadClass(name);
} catch (ClassNotFoundException cne) {
if (cl2 != null) {
return cl2.loadClass(name);
@@ -48,6 +49,15 @@
throw cne;
}
}
+
+ if(!cls.getName().equals(name)){
+ if (cl2 != null) {
+ return cl2.loadClass(name);
+ } else {
+ throw new ClassNotFoundException(name);
+ }
+ }
+ return cls;
}
private ClassLoaderRepository repository;
--- a/jdk/src/java.scripting/share/classes/javax/script/ScriptContext.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.scripting/share/classes/javax/script/ScriptContext.java Wed Oct 26 20:13:29 2016 +0000
@@ -85,7 +85,8 @@
public Bindings getBindings(int scope);
/**
- * Sets the value of an attribute in a given scope.
+ * Sets the value of an attribute in a given scope. If the scope is <code>GLOBAL_SCOPE</code>
+ * and no Bindings is set for <code>GLOBAL_SCOPE</code>, then setAttribute call is a no-op.
*
* @param name The name of the attribute to set
* @param value The value of the attribute
--- a/jdk/src/java.scripting/share/classes/javax/script/ScriptEngineFactory.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.scripting/share/classes/javax/script/ScriptEngineFactory.java Wed Oct 26 20:13:29 2016 +0000
@@ -216,8 +216,9 @@
* @param statements The statements to be executed. May be return values of
* calls to the <code>getMethodCallSyntax</code> and <code>getOutputStatement</code> methods.
* @return The Program
+ *
+ * @throws NullPointerException if the <code>statements</code> array or any of its elements is null
*/
-
public String getProgram(String... statements);
/**
--- a/jdk/src/java.scripting/share/classes/javax/script/SimpleScriptContext.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.scripting/share/classes/javax/script/SimpleScriptContext.java Wed Oct 26 20:13:29 2016 +0000
@@ -213,7 +213,8 @@
}
/**
- * Sets the value of an attribute in a given scope.
+ * Sets the value of an attribute in a given scope. If the scope is <code>GLOBAL_SCOPE</code>
+ * and no Bindings is set for <code>GLOBAL_SCOPE</code>, then setAttribute call is a no-op.
*
* @param name The name of the attribute to set
* @param value The value of the attribute
--- a/jdk/src/java.security.jgss/share/classes/javax/security/auth/kerberos/KerberosTicket.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.security.jgss/share/classes/javax/security/auth/kerberos/KerberosTicket.java Wed Oct 26 20:13:29 2016 +0000
@@ -694,7 +694,7 @@
"Proxy Ticket " + flags[PROXY_TICKET_FLAG] + "\n" +
"Postdated Ticket " + flags[POSTDATED_TICKET_FLAG] + "\n" +
"Renewable Ticket " + flags[RENEWABLE_TICKET_FLAG] + "\n" +
- "Initial Ticket " + flags[RENEWABLE_TICKET_FLAG] + "\n" +
+ "Initial Ticket " + flags[INITIAL_TICKET_FLAG] + "\n" +
"Auth Time = " + String.valueOf(authTime) + "\n" +
"Start Time = " + String.valueOf(startTime) + "\n" +
"End Time = " + endTime.toString() + "\n" +
--- a/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/Base64.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/Base64.java Wed Oct 26 20:13:29 2016 +0000
@@ -376,14 +376,14 @@
return null;
}
- int lengthDataBits = binaryData.length * EIGHTBIT;
- if (lengthDataBits == 0) {
+ long lengthDataBits = ((long) binaryData.length) * ((long) EIGHTBIT);
+ if (lengthDataBits == 0L) {
return "";
}
- int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;
- int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP;
- int numberQuartet = fewerThan24bits != 0 ? numberTriplets + 1 : numberTriplets;
+ long fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;
+ int numberTriplets = (int) (lengthDataBits / TWENTYFOURBITGROUP);
+ int numberQuartet = fewerThan24bits != 0L ? numberTriplets + 1 : numberTriplets;
int quartesPerLine = length / 4;
int numberLines = (numberQuartet - 1) / quartesPerLine;
char encodedData[] = null;
--- a/jdk/src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -36,6 +36,7 @@
#include <BaseTsd.h>
#include <wincrypt.h>
#include <stdio.h>
+#include <memory>
#define OID_EKU_ANY "2.5.29.37.0"
@@ -48,6 +49,7 @@
#define KEYSTORE_EXCEPTION "java/security/KeyStoreException"
#define PROVIDER_EXCEPTION "java/security/ProviderException"
#define SIGNATURE_EXCEPTION "java/security/SignatureException"
+#define OUT_OF_MEMORY_ERROR "java/lang/OutOfMemoryError"
extern "C" {
@@ -57,10 +59,22 @@
DEF_STATIC_JNI_OnLoad
/*
+ * Throws an arbitrary Java exception with the given message.
+ */
+void ThrowExceptionWithMessage(JNIEnv *env, const char *exceptionName,
+ const char *szMessage)
+{
+ jclass exceptionClazz = env->FindClass(exceptionName);
+ if (exceptionClazz != NULL) {
+ env->ThrowNew(exceptionClazz, szMessage);
+ }
+}
+
+/*
* Throws an arbitrary Java exception.
* The exception message is a Windows system error message.
*/
-void ThrowException(JNIEnv *env, char *exceptionName, DWORD dwError)
+void ThrowException(JNIEnv *env, const char *exceptionName, DWORD dwError)
{
char szMessage[1024];
szMessage[0] = '\0';
@@ -71,12 +85,22 @@
strcpy(szMessage, "Unknown error");
}
- jclass exceptionClazz = env->FindClass(exceptionName);
- if (exceptionClazz != NULL) {
- env->ThrowNew(exceptionClazz, szMessage);
- }
+ ThrowExceptionWithMessage(env, exceptionName, szMessage);
}
+/*
+ * Overloaded 'operator new[]' variant, which will raise Java's
+ * OutOfMemoryError in the case of a failure.
+ */
+static void* operator new[](std::size_t size, JNIEnv *env)
+{
+ void* buf = ::operator new[](size, std::nothrow);
+ if (buf == NULL) {
+ ThrowExceptionWithMessage(env, OUT_OF_MEMORY_ERROR,
+ "Native memory allocation failed");
+ }
+ return buf;
+}
/*
* Maps the name of a hash algorithm to an algorithm identifier.
@@ -211,7 +235,10 @@
} else if (length > 0) {
- pbData = new BYTE[length];
+ pbData = new (env) BYTE[length];
+ if (pbData == NULL) {
+ __leave;
+ }
if (::CryptGenRandom(
hCryptProv,
@@ -441,7 +468,11 @@
NULL, 0)) > 1) {
// Found friendly name
- pszNameString = new char[cchNameString];
+ pszNameString = new (env) char[cchNameString];
+ if (pszNameString == NULL) {
+ __leave;
+ }
+
CertGetNameString(pc,
CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL,
pszNameString, cchNameString);
@@ -578,7 +609,10 @@
}
// Copy hash from Java to native buffer
- pHashBuffer = new jbyte[jHashSize];
+ pHashBuffer = new (env) jbyte[jHashSize];
+ if (pHashBuffer == NULL) {
+ __leave;
+ }
env->GetByteArrayRegion(jHash, 0, jHashSize, pHashBuffer);
// Set hash value in the hash object
@@ -616,7 +650,10 @@
__leave;
}
- pSignedHashBuffer = new jbyte[dwBufLen];
+ pSignedHashBuffer = new (env) jbyte[dwBufLen];
+ if (pSignedHashBuffer == NULL) {
+ __leave;
+ }
if (::CryptSignHash(hHash, dwKeySpec, NULL, dwFlags, (BYTE*)pSignedHashBuffer, &dwBufLen) == FALSE)
{
ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
@@ -704,9 +741,16 @@
}
// Copy hash and signedHash from Java to native buffer
- pHashBuffer = new jbyte[jHashSize];
+ pHashBuffer = new (env) jbyte[jHashSize];
+ if (pHashBuffer == NULL) {
+ __leave;
+ }
env->GetByteArrayRegion(jHash, 0, jHashSize, pHashBuffer);
- pSignedHashBuffer = new jbyte[jSignedHashSize];
+
+ pSignedHashBuffer = new (env) jbyte[jSignedHashSize];
+ if (pSignedHashBuffer == NULL) {
+ __leave;
+ }
env->GetByteArrayRegion(jSignedHash, 0, jSignedHashSize,
pSignedHashBuffer);
@@ -919,7 +963,10 @@
}
// Copy encoding from Java to native buffer
- pbCertEncoding = new jbyte[jCertEncodingSize];
+ pbCertEncoding = new (env) jbyte[jCertEncodingSize];
+ if (pbCertEncoding == NULL) {
+ __leave;
+ }
env->GetByteArrayRegion(jCertEncoding, 0, jCertEncodingSize, pbCertEncoding);
// Create a certificate context from the encoded cert
@@ -932,7 +979,10 @@
// Set the certificate's friendly name
int size = env->GetStringLength(jCertAliasName);
- pszCertAliasName = new WCHAR[size + 1];
+ pszCertAliasName = new (env) WCHAR[size + 1];
+ if (pszCertAliasName == NULL) {
+ __leave;
+ }
jCertAliasChars = env->GetStringChars(jCertAliasName, NULL);
memcpy(pszCertAliasName, jCertAliasChars, size * sizeof(WCHAR));
@@ -970,7 +1020,10 @@
__leave;
}
- pszContainerName = new char[dwDataLen];
+ pszContainerName = new (env) char[dwDataLen];
+ if (pszContainerName == NULL) {
+ __leave;
+ }
if (! ::CryptGetProvParam(
(HCRYPTPROV) hCryptProv,
@@ -984,7 +1037,10 @@
}
// Convert to a wide char string
- pwszContainerName = new WCHAR[dwDataLen];
+ pwszContainerName = new (env) WCHAR[dwDataLen];
+ if (pwszContainerName == NULL) {
+ __leave;
+ }
if (mbstowcs(pwszContainerName, pszContainerName, dwDataLen) == 0) {
ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
@@ -1007,7 +1063,10 @@
__leave;
}
- pszProviderName = new char[dwDataLen];
+ pszProviderName = new (env) char[dwDataLen];
+ if (pszProviderName == NULL) {
+ __leave;
+ }
if (! ::CryptGetProvParam(
(HCRYPTPROV) hCryptProv,
@@ -1021,7 +1080,10 @@
}
// Convert to a wide char string
- pwszProviderName = new WCHAR[dwDataLen];
+ pwszProviderName = new (env) WCHAR[dwDataLen];
+ if (pwszProviderName == NULL) {
+ __leave;
+ }
if (mbstowcs(pwszProviderName, pszProviderName, dwDataLen) == 0) {
ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
@@ -1161,7 +1223,10 @@
}
// Copy encoding from Java to native buffer
- pbCertEncoding = new jbyte[jCertEncodingSize];
+ pbCertEncoding = new (env) jbyte[jCertEncodingSize];
+ if (pbCertEncoding == NULL) {
+ __leave;
+ }
env->GetByteArrayRegion(jCertEncoding, 0, jCertEncodingSize, pbCertEncoding);
// Create a certificate context from the encoded cert
@@ -1184,7 +1249,10 @@
if ((cchNameString = ::CertGetNameString(pTBDCertContext,
CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, NULL, 0)) > 1) {
- pszNameString = new char[cchNameString];
+ pszNameString = new (env) char[cchNameString];
+ if (pszNameString == NULL) {
+ __leave;
+ }
::CertGetNameString(pTBDCertContext,
CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, pszNameString,
@@ -1334,7 +1402,10 @@
continue; // not found
}
- pszNameString = new char[cchNameString];
+ pszNameString = new (env) char[cchNameString];
+ if (pszNameString == NULL) {
+ __leave;
+ }
if (::CertGetNameString(pCertContext,
CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, pszNameString,
@@ -1510,7 +1581,10 @@
__try
{
// Copy data from Java buffer to native buffer
- pData = new jbyte[dwBufLen];
+ pData = new (env) jbyte[dwBufLen];
+ if (pData == NULL) {
+ __leave;
+ }
env->GetByteArrayRegion(jData, 0, dwBufLen, pData);
if (doEncrypt == JNI_TRUE) {
@@ -1584,7 +1658,10 @@
__leave;
}
- pbKeyBlob = new BYTE[dwBlobLen];
+ pbKeyBlob = new (env) BYTE[dwBlobLen];
+ if (pbKeyBlob == NULL) {
+ __leave;
+ }
// Generate key blob
if (! ::CryptExportKey((HCRYPTKEY) hCryptKey, 0, PUBLICKEYBLOB, 0,
@@ -1638,8 +1715,12 @@
RSAPUBKEY* pRsaPubKey =
(RSAPUBKEY *) (keyBlob + sizeof(PUBLICKEYSTRUC));
+
int len = sizeof(pRsaPubKey->pubexp);
- exponentBytes = new jbyte[len];
+ exponentBytes = new (env) jbyte[len];
+ if (exponentBytes == NULL) {
+ __leave;
+ }
// convert from little-endian while copying from blob
for (int i = 0, j = len - 1; i < len; i++, j--) {
@@ -1690,9 +1771,12 @@
RSAPUBKEY* pRsaPubKey =
(RSAPUBKEY *) (keyBlob + sizeof(PUBLICKEYSTRUC));
+
int len = pRsaPubKey->bitlen / 8;
-
- modulusBytes = new jbyte[len];
+ modulusBytes = new (env) jbyte[len];
+ if (modulusBytes == NULL) {
+ __leave;
+ }
BYTE * pbModulus =
(BYTE *) (keyBlob + sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY));
@@ -1813,12 +1897,16 @@
(jKeyBitLength / 8);
}
- jbyte* jBlobBytes = new jbyte[jBlobLength];
+ jbyte* jBlobBytes = NULL;
jbyte* jBlobElement;
jbyteArray jBlob = NULL;
jsize jElementLength;
__try {
+ jBlobBytes = new (env) jbyte[jBlobLength];
+ if (jBlobBytes == NULL) {
+ __leave;
+ }
BLOBHEADER *pBlobHeader = (BLOBHEADER *) jBlobBytes;
if (bGeneratePrivateKeyBlob) {
--- a/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/Config.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/Config.java Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -32,7 +32,6 @@
import java.security.*;
-import sun.security.action.GetPropertyAction;
import sun.security.util.PropertyExpander;
import sun.security.pkcs11.wrapper.*;
@@ -58,15 +57,30 @@
// will accept single threaded modules regardless of the setting in their
// config files.
private static final boolean staticAllowSingleThreadedModules;
+ private static final String osName;
+ private static final String osArch;
static {
- String p = "sun.security.pkcs11.allowSingleThreadedModules";
- String s = AccessController.doPrivileged(new GetPropertyAction(p));
- if ("false".equalsIgnoreCase(s)) {
+ List<String> props = AccessController.doPrivileged(
+ new PrivilegedAction<>() {
+ @Override
+ public List<String> run() {
+ return List.of(
+ System.getProperty(
+ "sun.security.pkcs11.allowSingleThreadedModules",
+ "true"),
+ System.getProperty("os.name"),
+ System.getProperty("os.arch"));
+ }
+ }
+ );
+ if ("false".equalsIgnoreCase(props.get(0))) {
staticAllowSingleThreadedModules = false;
} else {
staticAllowSingleThreadedModules = true;
}
+ osName = props.get(1);
+ osArch = props.get(2);
}
private final static boolean DEBUG = false;
@@ -650,8 +664,6 @@
// replace "/$ISA/" with "/sparcv9/" on 64-bit Solaris SPARC
// and with "/amd64/" on Solaris AMD64.
// On all other platforms, just turn it into a "/"
- String osName = System.getProperty("os.name", "");
- String osArch = System.getProperty("os.arch", "");
String prefix = lib.substring(0, i);
String suffix = lib.substring(i + 5);
if (osName.equals("SunOS") && osArch.equals("sparcv9")) {
--- a/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11Digest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11Digest.java Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -34,6 +34,8 @@
import sun.nio.ch.DirectBuffer;
+import sun.security.util.MessageDigestSpi2;
+
import sun.security.pkcs11.wrapper.*;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
@@ -49,7 +51,8 @@
* @author Andreas Sterbenz
* @since 1.5
*/
-final class P11Digest extends MessageDigestSpi implements Cloneable {
+final class P11Digest extends MessageDigestSpi implements Cloneable,
+ MessageDigestSpi2 {
/* fields initialized, no session acquired */
private final static int S_BLANK = 1;
@@ -233,10 +236,11 @@
}
// Called by SunJSSE via reflection during the SSL 3.0 handshake if
- // the master secret is sensitive. We may want to consider making this
- // method public in a future release.
- protected void implUpdate(SecretKey key) throws InvalidKeyException {
-
+ // the master secret is sensitive.
+ // Note: Change to protected after this method is moved from
+ // sun.security.util.MessageSpi2 interface to
+ // java.security.MessageDigestSpi class
+ public void engineUpdate(SecretKey key) throws InvalidKeyException {
// SunJSSE calls this method only if the key does not have a RAW
// encoding, i.e. if it is sensitive. Therefore, no point in calling
// SecretKeyFactory to try to convert it. Just verify it ourselves.
--- a/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/wrapper/Constants.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/wrapper/Constants.java Wed Oct 26 20:13:29 2016 +0000
@@ -58,7 +58,7 @@
*/
public class Constants {
- public static final String NEWLINE = System.getProperty("line.separator");
+ public static final String NEWLINE = System.lineSeparator();
public static final String INDENT = " ";
--- a/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoProvider.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoProvider.java Wed Oct 26 20:13:29 2016 +0000
@@ -50,12 +50,13 @@
try {
// cannot use LoadLibraryAction because that would make the native
// library available to the bootclassloader, but we run in the
- // extension classloader.
- String osname = System.getProperty("os.name");
- if (osname.startsWith("SunOS")) {
- provProp = AccessController.doPrivileged
- (new PrivilegedAction<HashMap<String, ServiceDesc>>() {
- public HashMap<String, ServiceDesc> run() {
+ // platform classloader.
+ provProp = AccessController.doPrivileged
+ (new PrivilegedAction<>() {
+ @Override
+ public HashMap<String, ServiceDesc> run() {
+ String osname = System.getProperty("os.name");
+ if (osname.startsWith("SunOS")) {
try {
DEBUG = Boolean.parseBoolean(System.getProperty("com.oracle.security.ucrypto.debug"));
String javaHome = System.getProperty("java.home");
@@ -66,14 +67,13 @@
return new HashMap<>();
} catch (Error err) {
if (DEBUG) err.printStackTrace();
- return null;
} catch (SecurityException se) {
if (DEBUG) se.printStackTrace();
- return null;
}
}
- });
- }
+ return null;
+ }
+ });
if (provProp != null) {
boolean[] result = loadLibraries();
if (result.length == 2) {
--- a/jdk/src/jdk.httpserver/share/classes/module-info.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/jdk.httpserver/share/classes/module-info.java Wed Oct 26 20:13:29 2016 +0000
@@ -24,7 +24,6 @@
*/
module jdk.httpserver {
- requires java.logging;
exports com.sun.net.httpserver;
exports com.sun.net.httpserver.spi;
--- a/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/ExchangeImpl.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/ExchangeImpl.java Wed Oct 26 20:13:29 2016 +0000
@@ -29,7 +29,8 @@
import java.net.*;
import javax.net.ssl.*;
import java.util.*;
-import java.util.logging.Logger;
+import java.lang.System.Logger;
+import java.lang.System.Logger.Level;
import java.text.*;
import com.sun.net.httpserver.*;
@@ -221,7 +222,7 @@
Logger logger = server.getLogger();
String msg = "sendResponseHeaders: rCode = "+ rCode
+ ": forcing contentLen = -1";
- logger.warning (msg);
+ logger.log (Level.WARNING, msg);
}
contentLen = -1;
}
@@ -234,7 +235,7 @@
final Logger logger = server.getLogger();
String msg =
"sendResponseHeaders: being invoked with a content length for a HEAD request";
- logger.warning (msg);
+ logger.log (Level.WARNING, msg);
}
noContentToSend = true;
contentLen = 0;
--- a/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/HttpConnection.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/HttpConnection.java Wed Oct 26 20:13:29 2016 +0000
@@ -28,7 +28,8 @@
import java.io.*;
import javax.net.ssl.*;
import java.nio.channels.*;
-import java.util.logging.Logger;
+import java.lang.System.Logger;
+import java.lang.System.Logger.Level;
import com.sun.net.httpserver.*;
import com.sun.net.httpserver.spi.*;
@@ -119,7 +120,7 @@
}
closed = true;
if (logger != null && chan != null) {
- logger.finest ("Closing connection: " + chan.toString());
+ logger.log (Level.TRACE, "Closing connection: " + chan.toString());
}
if (!chan.isOpen()) {
--- a/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/HttpContextImpl.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/HttpContextImpl.java Wed Oct 26 20:13:29 2016 +0000
@@ -26,7 +26,7 @@
package sun.net.httpserver;
import java.io.*;
import java.util.*;
-import java.util.logging.Logger;
+import java.lang.System.Logger;
import com.sun.net.httpserver.*;
import com.sun.net.httpserver.spi.*;
--- a/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/ServerConfig.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/ServerConfig.java Wed Oct 26 20:13:29 2016 +0000
@@ -25,7 +25,8 @@
package sun.net.httpserver;
-import java.util.logging.Logger;
+import java.lang.System.Logger;
+import java.lang.System.Logger.Level;
import java.security.PrivilegedAction;
/**
@@ -115,7 +116,8 @@
if (System.getProperty("sun.net.httpserver.readTimeout")
!=null)
{
- logger.warning ("sun.net.httpserver.readTimeout "+
+ logger.log (Level.WARNING,
+ "sun.net.httpserver.readTimeout "+
"property is no longer used. "+
"Use sun.net.httpserver.maxReqTime instead."
);
@@ -123,7 +125,8 @@
if (System.getProperty("sun.net.httpserver.writeTimeout")
!=null)
{
- logger.warning ("sun.net.httpserver.writeTimeout "+
+ logger.log (Level.WARNING,
+ "sun.net.httpserver.writeTimeout "+
"property is no longer used. Use "+
"sun.net.httpserver.maxRspTime instead."
);
@@ -131,7 +134,8 @@
if (System.getProperty("sun.net.httpserver.selCacheTimeout")
!=null)
{
- logger.warning ("sun.net.httpserver.selCacheTimeout "+
+ logger.log (Level.WARNING,
+ "sun.net.httpserver.selCacheTimeout "+
"property is no longer used."
);
}
--- a/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/ServerImpl.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/ServerImpl.java Wed Oct 26 20:13:29 2016 +0000
@@ -30,8 +30,8 @@
import java.nio.channels.*;
import java.util.*;
import java.util.concurrent.*;
-import java.util.logging.Logger;
-import java.util.logging.Level;
+import java.lang.System.Logger;
+import java.lang.System.Logger.Level;
import javax.net.ssl.*;
import com.sun.net.httpserver.*;
import java.security.AccessController;
@@ -81,7 +81,7 @@
final static boolean timer1Enabled = MAX_REQ_TIME != -1 || MAX_RSP_TIME != -1;
private Timer timer, timer1;
- private Logger logger;
+ private final Logger logger;
private Thread dispatcherThread;
ServerImpl (
@@ -90,7 +90,7 @@
this.protocol = protocol;
this.wrapper = wrapper;
- this.logger = Logger.getLogger ("com.sun.net.httpserver");
+ this.logger = System.getLogger ("com.sun.net.httpserver");
ServerConfig.checkLegacyProperties (logger);
https = protocol.equalsIgnoreCase ("https");
this.address = addr;
@@ -115,12 +115,12 @@
if (timer1Enabled) {
timer1 = new Timer ("server-timer1", true);
timer1.schedule (new ServerTimerTask1(),TIMER_MILLIS,TIMER_MILLIS);
- logger.config ("HttpServer timer1 enabled period in ms: "+TIMER_MILLIS);
- logger.config ("MAX_REQ_TIME: "+MAX_REQ_TIME);
- logger.config ("MAX_RSP_TIME: "+MAX_RSP_TIME);
+ logger.log (Level.DEBUG, "HttpServer timer1 enabled period in ms: ", TIMER_MILLIS);
+ logger.log (Level.DEBUG, "MAX_REQ_TIME: "+MAX_REQ_TIME);
+ logger.log (Level.DEBUG, "MAX_RSP_TIME: "+MAX_RSP_TIME);
}
events = new LinkedList<Event>();
- logger.config ("HttpServer created "+protocol+" "+ addr);
+ logger.log (Level.DEBUG, "HttpServer created "+protocol+" "+ addr);
}
public void bind (InetSocketAddress addr, int backlog) throws IOException {
@@ -211,7 +211,7 @@
dispatcherThread.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
- logger.log(Level.FINER, "ServerImpl.stop: ", e);
+ logger.log (Level.TRACE, "ServerImpl.stop: ", e);
}
}
}
@@ -224,7 +224,7 @@
}
HttpContextImpl context = new HttpContextImpl (protocol, path, handler, this);
contexts.add (context);
- logger.config ("context created: " + path);
+ logger.log (Level.DEBUG, "context created: " + path);
return context;
}
@@ -234,7 +234,7 @@
}
HttpContextImpl context = new HttpContextImpl (protocol, path, null, this);
contexts.add (context);
- logger.config ("context created: " + path);
+ logger.log (Level.DEBUG, "context created: " + path);
return context;
}
@@ -243,7 +243,7 @@
throw new NullPointerException ("null path parameter");
}
contexts.remove (protocol, path);
- logger.config ("context removed: " + path);
+ logger.log (Level.DEBUG, "context removed: " + path);
}
public synchronized void removeContext (HttpContext context) throws IllegalArgumentException {
@@ -251,7 +251,7 @@
throw new IllegalArgumentException ("wrong HttpContext type");
}
contexts.remove ((HttpContextImpl)context);
- logger.config ("context removed: " + context.getPath());
+ logger.log (Level.DEBUG, "context removed: " + context.getPath());
}
public InetSocketAddress getAddress() {
@@ -310,7 +310,7 @@
}
} catch (IOException e) {
logger.log (
- Level.FINER, "Dispatcher (1)", e
+ Level.TRACE, "Dispatcher (1)", e
);
c.close();
}
@@ -331,7 +331,7 @@
idleConnections.add (c);
} catch (IOException e) {
dprint(e);
- logger.log(Level.FINER, "Dispatcher(8)", e);
+ logger.log (Level.TRACE, "Dispatcher(8)", e);
c.close();
}
}
@@ -416,9 +416,9 @@
// call the selector just to process the cancelled keys
selector.selectNow();
} catch (IOException e) {
- logger.log (Level.FINER, "Dispatcher (4)", e);
+ logger.log (Level.TRACE, "Dispatcher (4)", e);
} catch (Exception e) {
- logger.log (Level.FINER, "Dispatcher (7)", e);
+ logger.log (Level.TRACE, "Dispatcher (7)", e);
}
}
try {selector.close(); } catch (Exception e) {}
@@ -427,7 +427,7 @@
private void handleException (SelectionKey key, Exception e) {
HttpConnection conn = (HttpConnection)key.attachment();
if (e != null) {
- logger.log (Level.FINER, "Dispatcher (2)", e);
+ logger.log (Level.TRACE, "Dispatcher (2)", e);
}
closeConnection(conn);
}
@@ -439,10 +439,10 @@
Exchange t = new Exchange (chan, protocol, conn);
executor.execute (t);
} catch (HttpError e1) {
- logger.log (Level.FINER, "Dispatcher (4)", e1);
+ logger.log (Level.TRACE, "Dispatcher (4)", e1);
closeConnection(conn);
} catch (IOException e) {
- logger.log (Level.FINER, "Dispatcher (5)", e);
+ logger.log (Level.TRACE, "Dispatcher (5)", e);
closeConnection(conn);
}
}
@@ -522,7 +522,8 @@
newconnection = true;
if (https) {
if (sslContext == null) {
- logger.warning ("SSL connection received. No https contxt created");
+ logger.log (Level.WARNING,
+ "SSL connection received. No https contxt created");
throw new HttpError ("No SSL context established");
}
sslStreams = new SSLStreams (ServerImpl.this, sslContext, chan);
@@ -657,7 +658,7 @@
}
} catch (IOException e1) {
- logger.log (Level.FINER, "ServerImpl.Exchange (1)", e1);
+ logger.log (Level.TRACE, "ServerImpl.Exchange (1)", e1);
closeConnection(connection);
} catch (NumberFormatException e3) {
reject (Code.HTTP_BAD_REQUEST,
@@ -666,7 +667,7 @@
reject (Code.HTTP_BAD_REQUEST,
requestLine, "URISyntaxException thrown");
} catch (Exception e4) {
- logger.log (Level.FINER, "ServerImpl.Exchange (2)", e4);
+ logger.log (Level.TRACE, "ServerImpl.Exchange (2)", e4);
closeConnection(connection);
}
}
@@ -722,7 +723,7 @@
closeConnection(connection);
}
} catch (IOException e) {
- logger.log (Level.FINER, "ServerImpl.sendReply", e);
+ logger.log (Level.TRACE, "ServerImpl.sendReply", e);
closeConnection(connection);
}
}
@@ -730,7 +731,7 @@
}
void logReply (int code, String requestStr, String text) {
- if (!logger.isLoggable(Level.FINE)) {
+ if (!logger.isLoggable(Level.DEBUG)) {
return;
}
if (text == null) {
@@ -744,7 +745,7 @@
}
String message = r + " [" + code + " " +
Code.msg(code) + "] ("+text+")";
- logger.fine (message);
+ logger.log (Level.DEBUG, message);
}
long getTicks() {
@@ -843,7 +844,7 @@
}
}
for (HttpConnection c : toClose) {
- logger.log (Level.FINE, "closing: no request: " + c);
+ logger.log (Level.DEBUG, "closing: no request: " + c);
reqConnections.remove (c);
allConnections.remove (c);
c.close();
@@ -859,7 +860,7 @@
}
}
for (HttpConnection c : toClose) {
- logger.log (Level.FINE, "closing: no response: " + c);
+ logger.log (Level.DEBUG, "closing: no response: " + c);
rspConnections.remove (c);
allConnections.remove (c);
c.close();
@@ -870,13 +871,13 @@
}
void logStackTrace (String s) {
- logger.finest (s);
+ logger.log (Level.TRACE, s);
StringBuilder b = new StringBuilder ();
StackTraceElement[] e = Thread.currentThread().getStackTrace();
for (int i=0; i<e.length; i++) {
b.append (e[i].toString()).append("\n");
}
- logger.finest (b.toString());
+ logger.log (Level.TRACE, b.toString());
}
static long getTimeMillis(long secs) {
--- a/jdk/src/jdk.internal.le/share/classes/jdk/internal/jline/console/ConsoleReader.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/jdk.internal.le/share/classes/jdk/internal/jline/console/ConsoleReader.java Wed Oct 26 20:13:29 2016 +0000
@@ -2339,7 +2339,7 @@
Stack<Character> pushBackChar = new Stack<Character>();
- if (terminal.isAnsiSupported()) {
+ if (terminal.isAnsiSupported() && System.console() != null) {
//detect the prompt length by reading the cursor position from the terminal
//the real prompt length could differ from the simple prompt length due to
//use of escape sequences:
--- a/jdk/src/jdk.jartool/share/classes/module-info.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/jdk.jartool/share/classes/module-info.java Wed Oct 26 20:13:29 2016 +0000
@@ -26,5 +26,7 @@
module jdk.jartool {
exports com.sun.jarsigner;
exports jdk.security.jarsigner;
+
+ provides java.util.spi.ToolProvider with sun.tools.jar.JarToolProvider;
}
--- a/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java Wed Oct 26 20:13:29 2016 +0000
@@ -50,6 +50,9 @@
import jdk.security.jarsigner.JarSigner;
import jdk.security.jarsigner.JarSignerException;
+import sun.security.pkcs.PKCS7;
+import sun.security.pkcs.SignerInfo;
+import sun.security.timestamp.TimestampToken;
import sun.security.tools.KeyStoreUtil;
import sun.security.x509.*;
import sun.security.util.*;
@@ -87,6 +90,15 @@
private static final long SIX_MONTHS = 180*24*60*60*1000L; //milliseconds
+ private static final DisabledAlgorithmConstraints DISABLED_CHECK =
+ new DisabledAlgorithmConstraints(
+ DisabledAlgorithmConstraints.PROPERTY_JAR_DISABLED_ALGS);
+
+ private static final Set<CryptoPrimitive> DIGEST_PRIMITIVE_SET = Collections
+ .unmodifiableSet(EnumSet.of(CryptoPrimitive.MESSAGE_DIGEST));
+ private static final Set<CryptoPrimitive> SIG_PRIMITIVE_SET = Collections
+ .unmodifiableSet(EnumSet.of(CryptoPrimitive.SIGNATURE));
+
// Attention:
// This is the entry that get launched by the security tool jarsigner.
public static void main(String args[]) throws Exception {
@@ -163,6 +175,8 @@
private Throwable chainNotValidatedReason = null;
+ private boolean seeWeak = false;
+
CertificateFactory certificateFactory;
CertPathValidator validator;
PKIXParameters pkixParameters;
@@ -628,6 +642,10 @@
{
boolean anySigned = false; // if there exists entry inside jar signed
JarFile jf = null;
+ Map<String,String> digestMap = new HashMap<>();
+ Map<String,PKCS7> sigMap = new HashMap<>();
+ Map<String,String> sigNameMap = new HashMap<>();
+ Map<String,String> unparsableSignatures = new HashMap<>();
try {
jf = new JarFile(jarName, true);
@@ -638,21 +656,50 @@
while (entries.hasMoreElements()) {
JarEntry je = entries.nextElement();
entriesVec.addElement(je);
- InputStream is = null;
- try {
- is = jf.getInputStream(je);
- while (is.read(buffer, 0, buffer.length) != -1) {
- // we just read. this will throw a SecurityException
- // if a signature/digest check fails.
- }
- } finally {
- if (is != null) {
- is.close();
+ try (InputStream is = jf.getInputStream(je)) {
+ String name = je.getName();
+ if (signatureRelated(name)
+ && SignatureFileVerifier.isBlockOrSF(name)) {
+ String alias = name.substring(name.lastIndexOf('/') + 1,
+ name.lastIndexOf('.'));
+ try {
+ if (name.endsWith(".SF")) {
+ Manifest sf = new Manifest(is);
+ boolean found = false;
+ for (Object obj : sf.getMainAttributes().keySet()) {
+ String key = obj.toString();
+ if (key.endsWith("-Digest-Manifest")) {
+ digestMap.put(alias,
+ key.substring(0, key.length() - 16));
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ unparsableSignatures.putIfAbsent(alias,
+ String.format(
+ rb.getString("history.unparsable"),
+ name));
+ }
+ } else {
+ sigNameMap.put(alias, name);
+ sigMap.put(alias, new PKCS7(is));
+ }
+ } catch (IOException ioe) {
+ unparsableSignatures.putIfAbsent(alias, String.format(
+ rb.getString("history.unparsable"), name));
+ }
+ } else {
+ while (is.read(buffer, 0, buffer.length) != -1) {
+ // we just read. this will throw a SecurityException
+ // if a signature/digest check fails.
+ }
}
}
}
Manifest man = jf.getManifest();
+ boolean hasSignature = false;
// The map to record display info, only used when -verbose provided
// key: signer info string
@@ -668,6 +715,10 @@
while (e.hasMoreElements()) {
JarEntry je = e.nextElement();
String name = je.getName();
+
+ hasSignature = hasSignature
+ || SignatureFileVerifier.isBlockOrSF(name);
+
CodeSigner[] signers = je.getCodeSigners();
boolean isSigned = (signers != null);
anySigned |= isSigned;
@@ -800,10 +851,11 @@
System.out.println(rb.getString(
".X.not.signed.by.specified.alias.es."));
}
- System.out.println();
}
- if (man == null)
+ if (man == null) {
+ System.out.println();
System.out.println(rb.getString("no.manifest."));
+ }
// If signer is a trusted cert or private entry in user's own
// keystore, it can be self-signed.
@@ -811,9 +863,103 @@
signerSelfSigned = false;
}
+ // Even if the verbose option is not specified, all out strings
+ // must be generated so seeWeak can be updated.
+ if (!digestMap.isEmpty()
+ || !sigMap.isEmpty()
+ || !unparsableSignatures.isEmpty()) {
+ if (verbose != null) {
+ System.out.println();
+ }
+ for (String s : sigMap.keySet()) {
+ if (!digestMap.containsKey(s)) {
+ unparsableSignatures.putIfAbsent(s, String.format(
+ rb.getString("history.nosf"), s));
+ }
+ }
+ for (String s : digestMap.keySet()) {
+ PKCS7 p7 = sigMap.get(s);
+ if (p7 != null) {
+ String history;
+ try {
+ SignerInfo si = p7.getSignerInfos()[0];
+ X509Certificate signer = si.getCertificate(p7);
+ String digestAlg = digestMap.get(s);
+ String sigAlg = AlgorithmId.makeSigAlg(
+ si.getDigestAlgorithmId().getName(),
+ si.getDigestEncryptionAlgorithmId().getName());
+ PublicKey key = signer.getPublicKey();
+ PKCS7 tsToken = si.getTsToken();
+ if (tsToken != null) {
+ SignerInfo tsSi = tsToken.getSignerInfos()[0];
+ X509Certificate tsSigner = tsSi.getCertificate(tsToken);
+ byte[] encTsTokenInfo = tsToken.getContentInfo().getData();
+ TimestampToken tsTokenInfo = new TimestampToken(encTsTokenInfo);
+ PublicKey tsKey = tsSigner.getPublicKey();
+ String tsDigestAlg = tsTokenInfo.getHashAlgorithm().getName();
+ String tsSigAlg = AlgorithmId.makeSigAlg(
+ tsSi.getDigestAlgorithmId().getName(),
+ tsSi.getDigestEncryptionAlgorithmId().getName());
+ Calendar c = Calendar.getInstance(
+ TimeZone.getTimeZone("UTC"),
+ Locale.getDefault(Locale.Category.FORMAT));
+ c.setTime(tsTokenInfo.getDate());
+ history = String.format(
+ rb.getString("history.with.ts"),
+ signer.getSubjectX500Principal(),
+ withWeak(digestAlg, DIGEST_PRIMITIVE_SET),
+ withWeak(sigAlg, SIG_PRIMITIVE_SET),
+ withWeak(key),
+ c,
+ tsSigner.getSubjectX500Principal(),
+ withWeak(tsDigestAlg, DIGEST_PRIMITIVE_SET),
+ withWeak(tsSigAlg, SIG_PRIMITIVE_SET),
+ withWeak(tsKey));
+ } else {
+ history = String.format(
+ rb.getString("history.without.ts"),
+ signer.getSubjectX500Principal(),
+ withWeak(digestAlg, DIGEST_PRIMITIVE_SET),
+ withWeak(sigAlg, SIG_PRIMITIVE_SET),
+ withWeak(key));
+ }
+ } catch (Exception e) {
+ // The only usage of sigNameMap, remember the name
+ // of the block file if it's invalid.
+ history = String.format(
+ rb.getString("history.unparsable"),
+ sigNameMap.get(s));
+ }
+ if (verbose != null) {
+ System.out.println(history);
+ }
+ } else {
+ unparsableSignatures.putIfAbsent(s, String.format(
+ rb.getString("history.nobk"), s));
+ }
+ }
+ if (verbose != null) {
+ for (String s : unparsableSignatures.keySet()) {
+ System.out.println(unparsableSignatures.get(s));
+ }
+ }
+ }
+ System.out.println();
if (!anySigned) {
- System.out.println(rb.getString(
- "jar.is.unsigned.signatures.missing.or.not.parsable."));
+ if (seeWeak) {
+ if (verbose != null) {
+ System.out.println(rb.getString("jar.treated.unsigned.see.weak.verbose"));
+ System.out.println("\n " +
+ DisabledAlgorithmConstraints.PROPERTY_JAR_DISABLED_ALGS +
+ "=" + Security.getProperty(DisabledAlgorithmConstraints.PROPERTY_JAR_DISABLED_ALGS));
+ } else {
+ System.out.println(rb.getString("jar.treated.unsigned.see.weak"));
+ }
+ } else if (hasSignature) {
+ System.out.println(rb.getString("jar.treated.unsigned"));
+ } else {
+ System.out.println(rb.getString("jar.is.unsigned"));
+ }
} else {
boolean warningAppeared = false;
boolean errorAppeared = false;
@@ -837,7 +983,9 @@
if (weakAlg != 0) {
// In fact, jarsigner verification did not catch this
// since it has not read the JarFile content itself.
- // Everything is done with JarFile API.
+ // Everything is done with JarFile API. The signing
+ // history (digestMap etc) will show these info and
+ // print out proper warnings.
}
if (badKeyUsage) {
@@ -928,6 +1076,26 @@
System.exit(1);
}
+ private String withWeak(String alg, Set<CryptoPrimitive> primitiveSet) {
+ if (DISABLED_CHECK.permits(primitiveSet, alg, null)) {
+ return alg;
+ } else {
+ seeWeak = true;
+ return String.format(rb.getString("with.weak"), alg);
+ }
+ }
+
+ private String withWeak(PublicKey key) {
+ if (DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) {
+ return String.format(
+ rb.getString("key.bit"), KeyUtil.getKeySize(key));
+ } else {
+ seeWeak = true;
+ return String.format(
+ rb.getString("key.bit.weak"), KeyUtil.getKeySize(key));
+ }
+ }
+
private static MessageFormat validityTimeForm = null;
private static MessageFormat notYetTimeForm = null;
private static MessageFormat expiredTimeForm = null;
@@ -1117,22 +1285,22 @@
void signJar(String jarName, String alias)
throws Exception {
- DisabledAlgorithmConstraints dac =
- new DisabledAlgorithmConstraints(
- DisabledAlgorithmConstraints.PROPERTY_CERTPATH_DISABLED_ALGS);
-
- if (digestalg != null && !dac.permits(
- Collections.singleton(CryptoPrimitive.MESSAGE_DIGEST), digestalg, null)) {
+ if (digestalg != null && !DISABLED_CHECK.permits(
+ DIGEST_PRIMITIVE_SET, digestalg, null)) {
weakAlg |= 1;
}
- if (tSADigestAlg != null && !dac.permits(
- Collections.singleton(CryptoPrimitive.MESSAGE_DIGEST), tSADigestAlg, null)) {
+ if (tSADigestAlg != null && !DISABLED_CHECK.permits(
+ DIGEST_PRIMITIVE_SET, tSADigestAlg, null)) {
weakAlg |= 4;
}
- if (sigalg != null && !dac.permits(
- Collections.singleton(CryptoPrimitive.SIGNATURE), sigalg, null)) {
+ if (sigalg != null && !DISABLED_CHECK.permits(
+ SIG_PRIMITIVE_SET , sigalg, null)) {
weakAlg |= 2;
}
+ if (!DISABLED_CHECK.permits(
+ SIG_PRIMITIVE_SET, privateKey)) {
+ weakAlg |= 8;
+ }
boolean aliasUsed = false;
X509Certificate tsaCert = null;
@@ -1377,6 +1545,11 @@
rb.getString("The.1.algorithm.specified.for.the.2.option.is.considered.a.security.risk."),
tSADigestAlg, "-tsadigestalg"));
}
+ if ((weakAlg & 8) == 8) {
+ System.out.println(String.format(
+ rb.getString("The.1.signing.key.has.a.keysize.of.2.which.is.considered.a.security.risk."),
+ privateKey.getAlgorithm(), KeyUtil.getKeySize(privateKey)));
+ }
} else {
System.out.println(rb.getString("jar.signed."));
}
--- a/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java Wed Oct 26 20:13:29 2016 +0000
@@ -142,12 +142,29 @@
{"no.manifest.", "no manifest."},
{".Signature.related.entries.","(Signature related entries)"},
{".Unsigned.entries.", "(Unsigned entries)"},
- {"jar.is.unsigned.signatures.missing.or.not.parsable.",
- "jar is unsigned. (signatures missing or not parsable)"},
+ {"jar.is.unsigned",
+ "jar is unsigned."},
+ {"jar.treated.unsigned",
+ "WARNING: Signature is either not parsable or not verifiable, and the jar will be treated as unsigned. For more information, re-run jarsigner with debug enabled (-J-Djava.security.debug=jar)."},
+ {"jar.treated.unsigned.see.weak",
+ "The jar will be treated as unsigned, because it is signed with a weak algorithm that is now disabled.\n\nRe-run jarsigner with the -verbose option for more details."},
+ {"jar.treated.unsigned.see.weak.verbose",
+ "WARNING: The jar will be treated as unsigned, because it is signed with a weak algorithm that is now disabled by the security property:"},
{"jar.signed.", "jar signed."},
{"jar.signed.with.signer.errors.", "jar signed, with signer errors."},
{"jar.verified.", "jar verified."},
{"jar.verified.with.signer.errors.", "jar verified, with signer errors."},
+
+ {"history.with.ts", "- Signed by \"%1$s\"\n Digest algorithm: %2$s\n Signature algorithm: %3$s, %4$s\n Timestamped by \"%6$s\" on %5$tc\n Timestamp digest algorithm: %7$s\n Timestamp signature algorithm: %8$s, %9$s"},
+ {"history.without.ts", "- Signed by \"%1$s\"\n Digest algorithm: %2$s\n Signature algorithm: %3$s, %4$s"},
+ {"history.unparsable", "- Unparsable signature-related file %s"},
+ {"history.nosf", "- Missing signature-related file META-INF/%s.SF"},
+ {"history.nobk", "- Missing block file for signature-related file META-INF/%s.SF"},
+
+ {"with.weak", "%s (weak)"},
+ {"key.bit", "%d-bit key"},
+ {"key.bit.weak", "%d-bit key (weak)"},
+
{"jarsigner.", "jarsigner: "},
{"signature.filename.must.consist.of.the.following.characters.A.Z.0.9.or.",
"signature filename must consist of the following characters: A-Z, 0-9, _ or -"},
@@ -246,6 +263,8 @@
"The signer's certificate is self-signed."},
{"The.1.algorithm.specified.for.the.2.option.is.considered.a.security.risk.",
"The %1$s algorithm specified for the %2$s option is considered a security risk."},
+ {"The.1.signing.key.has.a.keysize.of.2.which.is.considered.a.security.risk.",
+ "The %s signing key has a keysize of %d which is considered a security risk."},
{"This.jar.contains.entries.whose.certificate.chain.is.not.validated.reason.1",
"This jar contains entries whose certificate chain is not validated. Reason: %s"},
{"no.timestamp.signing",
--- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/GNUStyleOptions.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/GNUStyleOptions.java Wed Oct 26 20:13:29 2016 +0000
@@ -27,6 +27,7 @@
import java.io.File;
import java.io.PrintStream;
+import java.io.PrintWriter;
import java.lang.module.ModuleFinder;
import java.lang.module.ModuleDescriptor.Version;
import java.nio.file.Path;
@@ -253,7 +254,8 @@
// process options
for (; count < args.length; count++) {
- if (args[count].charAt(0) != '-' || args[count].equals("-C"))
+ if (args[count].charAt(0) != '-' || args[count].equals("-C")
+ || args[count].equals("--release"))
break;
String name = args[count];
@@ -289,7 +291,7 @@
throw new BadArgs("error.unrecognized.option", name).showUsage(true);
}
- static void printHelp(PrintStream out) {
+ static void printHelp(PrintWriter out) {
out.format("%s%n", Main.getMsg("main.help.preopt"));
for (OptionType type : OptionType.values()) {
boolean typeHeadingWritten = false;
@@ -312,16 +314,16 @@
out.format("%n%s%n%n", Main.getMsg("main.help.postopt"));
}
- static void printCompatHelp(PrintStream out) {
+ static void printCompatHelp(PrintWriter out) {
out.format("%s%n", Main.getMsg("usage.compat"));
}
- static void printUsageSummary(PrintStream out) {
+ static void printUsageSummary(PrintWriter out) {
out.format("%s%n", Main.getMsg("main.usage.summary"));
out.format("%s%n", Main.getMsg("main.usage.summary.try"));
}
- static void printVersion(PrintStream out) {
+ static void printVersion(PrintWriter out) {
out.format("%s %s%n", "jar", System.getProperty("java.version"));
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/JarToolProvider.java Wed Oct 26 20:13:29 2016 +0000
@@ -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. 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 sun.tools.jar;
+
+import java.io.PrintWriter;
+import java.util.spi.ToolProvider;
+
+public class JarToolProvider implements ToolProvider {
+ public String name() {
+ return "jar";
+ }
+
+ public int run(PrintWriter out, PrintWriter err, String... args) {
+ boolean ok = new Main(out, err, name()).run(args);
+ return ok ? 0 : 1;
+ }
+}
--- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/Main.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/Main.java Wed Oct 26 20:13:29 2016 +0000
@@ -76,7 +76,7 @@
public
class Main {
String program;
- PrintStream out, err;
+ PrintWriter out, err;
String fname, mname, ename;
String zname = "";
String rootjar = null;
@@ -189,9 +189,9 @@
USAGE_SUMMARY(GNUStyleOptions::printUsageSummary),
VERSION(GNUStyleOptions::printVersion);
- private Consumer<PrintStream> printFunction;
- Info(Consumer<PrintStream> f) { this.printFunction = f; }
- void print(PrintStream out) { printFunction.accept(out); }
+ private Consumer<PrintWriter> printFunction;
+ Info(Consumer<PrintWriter> f) { this.printFunction = f; }
+ void print(PrintWriter out) { printFunction.accept(out); }
};
Info info;
@@ -252,6 +252,12 @@
}
public Main(PrintStream out, PrintStream err, String program) {
+ this.out = new PrintWriter(out, true);
+ this.err = new PrintWriter(err, true);
+ this.program = program;
+ }
+
+ public Main(PrintWriter out, PrintWriter err, String program) {
this.out = out;
this.err = err;
this.program = program;
--- a/jdk/src/jdk.jdwp.agent/share/native/include/jdwpTransport.h Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/jdk.jdwp.agent/share/native/include/jdwpTransport.h Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -96,6 +96,11 @@
*/
enum {
+ /*
+ * If additional flags are added that apply to jdwpCmdPacket,
+ * then debugLoop.c: reader() will need to be updated to
+ * accept more than JDWPTRANSPORT_FLAGS_NONE.
+ */
JDWPTRANSPORT_FLAGS_NONE = 0x0,
JDWPTRANSPORT_FLAGS_REPLY = 0x80
};
--- a/jdk/src/jdk.jdwp.agent/share/native/libjdwp/debugLoop.c Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/jdk.jdwp.agent/share/native/libjdwp/debugLoop.c Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2014, 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
@@ -218,6 +218,20 @@
if (rc != 0 || (rc == 0 && packet.type.cmd.len == 0)) {
shouldListen = JNI_FALSE;
notifyTransportError();
+ } else if (packet.type.cmd.flags != JDWPTRANSPORT_FLAGS_NONE) {
+ /*
+ * Close the connection when we get a jdwpCmdPacket with an
+ * invalid flags field value. This is a protocol violation
+ * so we drop the connection. Also this could be a web
+ * browser generating an HTTP request that passes the JDWP
+ * handshake. HTTP requests requires that everything be in
+ * the ASCII printable range so a flags value of
+ * JDWPTRANSPORT_FLAGS_NONE(0) cannot be generated via HTTP.
+ */
+ ERROR_MESSAGE(("Received jdwpPacket with flags != 0x%d (actual=0x%x) when a jdwpCmdPacket was expected.",
+ JDWPTRANSPORT_FLAGS_NONE, packet.type.cmd.flags));
+ shouldListen = JNI_FALSE;
+ notifyTransportError();
} else {
cmd = &packet.type.cmd;
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/Jlink.java Wed Oct 26 15:46:13 2016 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,306 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. 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.tools.jlink;
-
-import java.lang.reflect.Layer;
-import java.nio.ByteOrder;
-import java.nio.file.Path;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import jdk.tools.jlink.internal.ExecutableImage;
-import jdk.tools.jlink.internal.JlinkTask;
-import jdk.tools.jlink.plugin.Plugin;
-import jdk.tools.jlink.plugin.PluginException;
-import jdk.tools.jlink.builder.ImageBuilder;
-import jdk.tools.jlink.internal.PluginRepository;
-
-/**
- * API to call jlink.
- */
-public final class Jlink {
-
- /**
- * Create a plugin.
- *
- * @param name Plugin name
- * @param configuration Plugin configuration.
- * @param pluginsLayer Plugins Layer. null means boot layer.
- * @return A new plugin or null if plugin is unknown.
- */
- public static Plugin newPlugin(String name,
- Map<String, String> configuration, Layer pluginsLayer) {
- Objects.requireNonNull(name);
- Objects.requireNonNull(configuration);
- pluginsLayer = pluginsLayer == null ? Layer.boot() : pluginsLayer;
- return PluginRepository.newPlugin(configuration, name, pluginsLayer);
- }
-
- /**
- * A complete plugin configuration. Instances of this class are used to
- * configure jlink.
- */
- public static final class PluginsConfiguration {
-
- private final List<Plugin> plugins;
- private final ImageBuilder imageBuilder;
- private final String lastSorterPluginName;
-
- /**
- * Empty plugins configuration.
- */
- public PluginsConfiguration() {
- this(Collections.emptyList());
- }
-
- /**
- * Plugins configuration.
- *
- * @param plugins List of plugins.
- */
- public PluginsConfiguration(List<Plugin> plugins) {
- this(plugins, null, null);
- }
-
- /**
- * Plugins configuration with a last sorter and an ImageBuilder. No
- * sorting can occur after the last sorter plugin. The ImageBuilder is
- * in charge to layout the image content on disk.
- *
- * @param plugins List of transformer plugins.
- * @param imageBuilder Image builder.
- * @param lastSorterPluginName Name of last sorter plugin, no sorting
- * can occur after it.
- */
- public PluginsConfiguration(List<Plugin> plugins,
- ImageBuilder imageBuilder, String lastSorterPluginName) {
- this.plugins = plugins == null ? Collections.emptyList()
- : plugins;
- this.imageBuilder = imageBuilder;
- this.lastSorterPluginName = lastSorterPluginName;
- }
-
- /**
- * @return the plugins
- */
- public List<Plugin> getPlugins() {
- return plugins;
- }
-
- /**
- * @return the imageBuilder
- */
- public ImageBuilder getImageBuilder() {
- return imageBuilder;
- }
-
- /**
- * @return the lastSorterPluginName
- */
- public String getLastSorterPluginName() {
- return lastSorterPluginName;
- }
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
- builder.append("imagebuilder=").append(imageBuilder).append("\n");
- StringBuilder pluginsBuilder = new StringBuilder();
- for (Plugin p : plugins) {
- pluginsBuilder.append(p).append(",");
- }
- builder.append("plugins=").append(pluginsBuilder).append("\n");
- builder.append("lastsorter=").append(lastSorterPluginName).append("\n");
-
- return builder.toString();
- }
- }
-
- /**
- * Jlink configuration. Instances of this class are used to configure jlink.
- */
- public static final class JlinkConfiguration {
-
- private final List<Path> modulepaths;
- private final Path output;
- private final Set<String> modules;
- private final Set<String> limitmods;
-
- private final ByteOrder endian;
-
- /**
- * jlink configuration,
- *
- * @param output Output directory, must not exist.
- * @param modulepaths Modules paths
- * @param modules Root modules to resolve
- * @param limitmods Limit the universe of observable modules
- * @param endian Jimage byte order. Native order by default
- */
- public JlinkConfiguration(Path output,
- List<Path> modulepaths,
- Set<String> modules,
- Set<String> limitmods,
- ByteOrder endian) {
- this.output = output;
- this.modulepaths = modulepaths == null ? Collections.emptyList() : modulepaths;
- this.modules = modules == null ? Collections.emptySet() : modules;
- this.limitmods = limitmods == null ? Collections.emptySet() : limitmods;
- this.endian = endian == null ? ByteOrder.nativeOrder() : endian;
- }
-
- /**
- * jlink configuration,
- *
- * @param output Output directory, must not exist.
- * @param modulepaths Modules paths
- * @param modules Root modules to resolve
- * @param limitmods Limit the universe of observable modules
- */
- public JlinkConfiguration(Path output,
- List<Path> modulepaths,
- Set<String> modules,
- Set<String> limitmods) {
- this(output, modulepaths, modules, limitmods,
- ByteOrder.nativeOrder());
- }
-
- /**
- * @return the modulepaths
- */
- public List<Path> getModulepaths() {
- return modulepaths;
- }
-
- /**
- * @return the byte ordering
- */
- public ByteOrder getByteOrder() {
- return endian;
- }
-
- /**
- * @return the output
- */
- public Path getOutput() {
- return output;
- }
-
- /**
- * @return the modules
- */
- public Set<String> getModules() {
- return modules;
- }
-
- /**
- * @return the limitmods
- */
- public Set<String> getLimitmods() {
- return limitmods;
- }
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
-
- builder.append("output=").append(output).append("\n");
- StringBuilder pathsBuilder = new StringBuilder();
- for (Path p : modulepaths) {
- pathsBuilder.append(p).append(",");
- }
- builder.append("modulepaths=").append(pathsBuilder).append("\n");
-
- StringBuilder modsBuilder = new StringBuilder();
- for (String p : modules) {
- modsBuilder.append(p).append(",");
- }
- builder.append("modules=").append(modsBuilder).append("\n");
-
- StringBuilder limitsBuilder = new StringBuilder();
- for (String p : limitmods) {
- limitsBuilder.append(p).append(",");
- }
- builder.append("limitmodules=").append(limitsBuilder).append("\n");
- builder.append("endian=").append(endian).append("\n");
- return builder.toString();
- }
- }
-
- /**
- * Jlink instance constructor, if a security manager is set, the jlink
- * permission is checked.
- */
- public Jlink() {
- if (System.getSecurityManager() != null) {
- System.getSecurityManager().
- checkPermission(new JlinkPermission("jlink"));
- }
- }
-
- /**
- * Build the image.
- *
- * @param config Jlink config, must not be null.
- * @throws PluginException
- */
- public void build(JlinkConfiguration config) {
- build(config, null);
- }
-
- /**
- * Build the image with a plugin configuration.
- *
- * @param config Jlink config, must not be null.
- * @param pluginsConfig Plugins config, can be null
- * @throws PluginException
- */
- public void build(JlinkConfiguration config, PluginsConfiguration pluginsConfig) {
- Objects.requireNonNull(config);
- try {
- JlinkTask.createImage(config, pluginsConfig);
- } catch (Exception ex) {
- throw new PluginException(ex);
- }
- }
-
- /**
- * Post process the image with a plugin configuration.
- *
- * @param image Existing image.
- * @param plugins Plugins cannot be null
- */
- public void postProcess(ExecutableImage image, List<Plugin> plugins) {
- Objects.requireNonNull(image);
- Objects.requireNonNull(plugins);
- try {
- JlinkTask.postProcessImage(image, plugins);
- } catch (Exception ex) {
- throw new PluginException(ex);
- }
- }
-}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/JlinkPermission.java Wed Oct 26 15:46:13 2016 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. 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.tools.jlink;
-
-import java.security.BasicPermission;
-
-/**
- * The permission required to use jlink API. The permission target_name is
- * "jlink". e.g.: permission jdk.tools.jlink.plugins.JlinkPermission "jlink";
- *
- */
-public final class JlinkPermission extends BasicPermission {
-
- private static final long serialVersionUID = -3687912306077727801L;
-
- public JlinkPermission(String name) {
- super(name);
- }
-
-}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java Wed Oct 26 20:13:29 2016 +0000
@@ -37,17 +37,17 @@
import java.io.UncheckedIOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
-import java.io.UncheckedIOException;
import java.io.Writer;
import java.lang.module.ModuleDescriptor;
import java.nio.charset.StandardCharsets;
+import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
-import java.nio.file.attribute.PosixFileAttributeView;
import java.nio.file.attribute.PosixFilePermission;
-import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -55,7 +55,8 @@
import java.util.Optional;
import java.util.Properties;
import java.util.Set;
-import java.util.stream.Collectors;
+import static java.util.stream.Collectors.*;
+
import jdk.tools.jlink.internal.BasicImageWriter;
import jdk.tools.jlink.internal.plugins.FileCopierPlugin.SymImageFile;
import jdk.tools.jlink.internal.ExecutableImage;
@@ -171,15 +172,36 @@
Properties release = releaseProperties(files);
Path bin = root.resolve("bin");
- files.entries().forEach(f -> {
- if (!f.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) {
+ // check any duplicated resource files
+ Map<Path, Set<String>> duplicates = new HashMap<>();
+ files.entries()
+ .filter(f -> f.type() != ResourcePoolEntry.Type.CLASS_OR_RESOURCE)
+ .collect(groupingBy(this::entryToImagePath,
+ mapping(ResourcePoolEntry::moduleName, toSet())))
+ .entrySet()
+ .stream()
+ .filter(e -> e.getValue().size() > 1)
+ .forEach(e -> duplicates.put(e.getKey(), e.getValue()));
+
+ // write non-classes resource files to the image
+ files.entries()
+ .filter(f -> f.type() != ResourcePoolEntry.Type.CLASS_OR_RESOURCE)
+ .forEach(f -> {
try {
accept(f);
+ } catch (FileAlreadyExistsException e) {
+ // error for duplicated entries
+ Path path = entryToImagePath(f);
+ UncheckedIOException x =
+ new UncheckedIOException(path + " duplicated in " +
+ duplicates.get(path), e);
+ x.addSuppressed(e);
+ throw x;
} catch (IOException ioExp) {
throw new UncheckedIOException(ioExp);
}
- }
- });
+ });
+
files.moduleView().modules().forEach(m -> {
// Only add modules that contain packages
if (!m.packages().isEmpty()) {
@@ -226,7 +248,7 @@
version().
stream().
map(Object::toString).
- collect(Collectors.joining("."));
+ collect(joining("."));
}
private static String quote(String str) {
@@ -344,28 +366,69 @@
}
}
+ /**
+ * Returns the file name of this entry
+ */
+ private String entryToFileName(ResourcePoolEntry entry) {
+ if (entry.type() == ResourcePoolEntry.Type.CLASS_OR_RESOURCE)
+ throw new IllegalArgumentException("invalid type: " + entry);
+
+ String module = "/" + entry.moduleName() + "/";
+ String filename = entry.path().substring(module.length());
+ // Remove radical native|config|...
+ return filename.substring(filename.indexOf('/') + 1);
+ }
+
+ /**
+ * Returns the path of the given entry to be written in the image
+ */
+ private Path entryToImagePath(ResourcePoolEntry entry) {
+ switch (entry.type()) {
+ case NATIVE_LIB:
+ String filename = entryToFileName(entry);
+ return Paths.get(nativeDir(filename), filename);
+ case NATIVE_CMD:
+ return Paths.get("bin", entryToFileName(entry));
+ case CONFIG:
+ return Paths.get("conf", entryToFileName(entry));
+ case HEADER_FILE:
+ return Paths.get("include", entryToFileName(entry));
+ case MAN_PAGE:
+ return Paths.get("man", entryToFileName(entry));
+ case TOP:
+ return Paths.get(entryToFileName(entry));
+ case OTHER:
+ return Paths.get("other", entryToFileName(entry));
+ default:
+ throw new IllegalArgumentException("invalid type: " + entry);
+ }
+ }
+
private void accept(ResourcePoolEntry file) throws IOException {
- String fullPath = file.path();
- String module = "/" + file.moduleName() + "/";
- String filename = fullPath.substring(module.length());
- // Remove radical native|config|...
- filename = filename.substring(filename.indexOf('/') + 1);
try (InputStream in = file.content()) {
switch (file.type()) {
case NATIVE_LIB:
- writeEntry(in, destFile(nativeDir(filename), filename));
+ Path dest = root.resolve(entryToImagePath(file));
+ writeEntry(in, dest);
break;
case NATIVE_CMD:
- Path path = destFile("bin", filename);
- writeEntry(in, path);
- path.toFile().setExecutable(true);
+ Path p = root.resolve(entryToImagePath(file));
+ writeEntry(in, p);
+ p.toFile().setExecutable(true);
break;
case CONFIG:
- writeEntry(in, destFile("conf", filename));
+ writeEntry(in, root.resolve(entryToImagePath(file)));
+ break;
+ case HEADER_FILE:
+ writeEntry(in, root.resolve(entryToImagePath(file)));
+ break;
+ case MAN_PAGE:
+ writeEntry(in, root.resolve(entryToImagePath(file)));
break;
case TOP:
break;
case OTHER:
+ String filename = entryToFileName(file);
if (file instanceof SymImageFile) {
SymImageFile sym = (SymImageFile) file;
Path target = root.resolve(sym.getTargetPath());
@@ -379,15 +442,11 @@
}
break;
default:
- throw new InternalError("unexpected entry: " + fullPath);
+ throw new InternalError("unexpected entry: " + file.path());
}
}
}
- private Path destFile(String dir, String filename) {
- return root.resolve(dir).resolve(filename);
- }
-
private void writeEntry(InputStream in, Path dstFile) throws IOException {
Objects.requireNonNull(in);
Objects.requireNonNull(dstFile);
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Archive.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Archive.java Wed Oct 26 20:13:29 2016 +0000
@@ -44,9 +44,11 @@
public static enum EntryType {
MODULE_NAME,
CLASS_OR_RESOURCE,
+ CONFIG,
NATIVE_LIB,
NATIVE_CMD,
- CONFIG,
+ HEADER_FILE,
+ MAN_PAGE,
SERVICE;
}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ArchiveEntryResourcePoolEntry.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ArchiveEntryResourcePoolEntry.java Wed Oct 26 20:13:29 2016 +0000
@@ -73,6 +73,10 @@
return ResourcePoolEntry.Type.NATIVE_CMD;
case NATIVE_LIB:
return ResourcePoolEntry.Type.NATIVE_LIB;
+ case HEADER_FILE:
+ return ResourcePoolEntry.Type.HEADER_FILE;
+ case MAN_PAGE:
+ return ResourcePoolEntry.Type.MAN_PAGE;
default:
return ResourcePoolEntry.Type.OTHER;
}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginConfiguration.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginConfiguration.java Wed Oct 26 20:13:29 2016 +0000
@@ -33,7 +33,6 @@
import java.util.Map;
import java.util.Map.Entry;
import jdk.tools.jlink.builder.ImageBuilder;
-import jdk.tools.jlink.Jlink;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.plugin.Plugin.Category;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Jlink.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,303 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. 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.tools.jlink.internal;
+
+import java.lang.reflect.Layer;
+import java.nio.ByteOrder;
+import java.nio.file.Path;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import jdk.tools.jlink.plugin.Plugin;
+import jdk.tools.jlink.plugin.PluginException;
+import jdk.tools.jlink.builder.ImageBuilder;
+
+/**
+ * API to call jlink.
+ */
+public final class Jlink {
+
+ /**
+ * Create a plugin.
+ *
+ * @param name Plugin name
+ * @param configuration Plugin configuration.
+ * @param pluginsLayer Plugins Layer. null means boot layer.
+ * @return A new plugin or null if plugin is unknown.
+ */
+ public static Plugin newPlugin(String name,
+ Map<String, String> configuration, Layer pluginsLayer) {
+ Objects.requireNonNull(name);
+ Objects.requireNonNull(configuration);
+ pluginsLayer = pluginsLayer == null ? Layer.boot() : pluginsLayer;
+ return PluginRepository.newPlugin(configuration, name, pluginsLayer);
+ }
+
+ /**
+ * A complete plugin configuration. Instances of this class are used to
+ * configure jlink.
+ */
+ public static final class PluginsConfiguration {
+
+ private final List<Plugin> plugins;
+ private final ImageBuilder imageBuilder;
+ private final String lastSorterPluginName;
+
+ /**
+ * Empty plugins configuration.
+ */
+ public PluginsConfiguration() {
+ this(Collections.emptyList());
+ }
+
+ /**
+ * Plugins configuration.
+ *
+ * @param plugins List of plugins.
+ */
+ public PluginsConfiguration(List<Plugin> plugins) {
+ this(plugins, null, null);
+ }
+
+ /**
+ * Plugins configuration with a last sorter and an ImageBuilder. No
+ * sorting can occur after the last sorter plugin. The ImageBuilder is
+ * in charge to layout the image content on disk.
+ *
+ * @param plugins List of transformer plugins.
+ * @param imageBuilder Image builder.
+ * @param lastSorterPluginName Name of last sorter plugin, no sorting
+ * can occur after it.
+ */
+ public PluginsConfiguration(List<Plugin> plugins,
+ ImageBuilder imageBuilder, String lastSorterPluginName) {
+ this.plugins = plugins == null ? Collections.emptyList()
+ : plugins;
+ this.imageBuilder = imageBuilder;
+ this.lastSorterPluginName = lastSorterPluginName;
+ }
+
+ /**
+ * @return the plugins
+ */
+ public List<Plugin> getPlugins() {
+ return plugins;
+ }
+
+ /**
+ * @return the imageBuilder
+ */
+ public ImageBuilder getImageBuilder() {
+ return imageBuilder;
+ }
+
+ /**
+ * @return the lastSorterPluginName
+ */
+ public String getLastSorterPluginName() {
+ return lastSorterPluginName;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("imagebuilder=").append(imageBuilder).append("\n");
+ StringBuilder pluginsBuilder = new StringBuilder();
+ for (Plugin p : plugins) {
+ pluginsBuilder.append(p).append(",");
+ }
+ builder.append("plugins=").append(pluginsBuilder).append("\n");
+ builder.append("lastsorter=").append(lastSorterPluginName).append("\n");
+
+ return builder.toString();
+ }
+ }
+
+ /**
+ * Jlink configuration. Instances of this class are used to configure jlink.
+ */
+ public static final class JlinkConfiguration {
+
+ private final List<Path> modulepaths;
+ private final Path output;
+ private final Set<String> modules;
+ private final Set<String> limitmods;
+
+ private final ByteOrder endian;
+
+ /**
+ * jlink configuration,
+ *
+ * @param output Output directory, must not exist.
+ * @param modulepaths Modules paths
+ * @param modules Root modules to resolve
+ * @param limitmods Limit the universe of observable modules
+ * @param endian Jimage byte order. Native order by default
+ */
+ public JlinkConfiguration(Path output,
+ List<Path> modulepaths,
+ Set<String> modules,
+ Set<String> limitmods,
+ ByteOrder endian) {
+ this.output = output;
+ this.modulepaths = modulepaths == null ? Collections.emptyList() : modulepaths;
+ this.modules = modules == null ? Collections.emptySet() : modules;
+ this.limitmods = limitmods == null ? Collections.emptySet() : limitmods;
+ this.endian = endian == null ? ByteOrder.nativeOrder() : endian;
+ }
+
+ /**
+ * jlink configuration,
+ *
+ * @param output Output directory, must not exist.
+ * @param modulepaths Modules paths
+ * @param modules Root modules to resolve
+ * @param limitmods Limit the universe of observable modules
+ */
+ public JlinkConfiguration(Path output,
+ List<Path> modulepaths,
+ Set<String> modules,
+ Set<String> limitmods) {
+ this(output, modulepaths, modules, limitmods,
+ ByteOrder.nativeOrder());
+ }
+
+ /**
+ * @return the modulepaths
+ */
+ public List<Path> getModulepaths() {
+ return modulepaths;
+ }
+
+ /**
+ * @return the byte ordering
+ */
+ public ByteOrder getByteOrder() {
+ return endian;
+ }
+
+ /**
+ * @return the output
+ */
+ public Path getOutput() {
+ return output;
+ }
+
+ /**
+ * @return the modules
+ */
+ public Set<String> getModules() {
+ return modules;
+ }
+
+ /**
+ * @return the limitmods
+ */
+ public Set<String> getLimitmods() {
+ return limitmods;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+
+ builder.append("output=").append(output).append("\n");
+ StringBuilder pathsBuilder = new StringBuilder();
+ for (Path p : modulepaths) {
+ pathsBuilder.append(p).append(",");
+ }
+ builder.append("modulepaths=").append(pathsBuilder).append("\n");
+
+ StringBuilder modsBuilder = new StringBuilder();
+ for (String p : modules) {
+ modsBuilder.append(p).append(",");
+ }
+ builder.append("modules=").append(modsBuilder).append("\n");
+
+ StringBuilder limitsBuilder = new StringBuilder();
+ for (String p : limitmods) {
+ limitsBuilder.append(p).append(",");
+ }
+ builder.append("limitmodules=").append(limitsBuilder).append("\n");
+ builder.append("endian=").append(endian).append("\n");
+ return builder.toString();
+ }
+ }
+
+ /**
+ * Jlink instance constructor, if a security manager is set, the jlink
+ * permission is checked.
+ */
+ public Jlink() {
+ if (System.getSecurityManager() != null) {
+ System.getSecurityManager().
+ checkPermission(new JlinkPermission("jlink"));
+ }
+ }
+
+ /**
+ * Build the image.
+ *
+ * @param config Jlink config, must not be null.
+ * @throws PluginException
+ */
+ public void build(JlinkConfiguration config) {
+ build(config, null);
+ }
+
+ /**
+ * Build the image with a plugin configuration.
+ *
+ * @param config Jlink config, must not be null.
+ * @param pluginsConfig Plugins config, can be null
+ * @throws PluginException
+ */
+ public void build(JlinkConfiguration config, PluginsConfiguration pluginsConfig) {
+ Objects.requireNonNull(config);
+ try {
+ JlinkTask.createImage(config, pluginsConfig);
+ } catch (Exception ex) {
+ throw new PluginException(ex);
+ }
+ }
+
+ /**
+ * Post process the image with a plugin configuration.
+ *
+ * @param image Existing image.
+ * @param plugins Plugins cannot be null
+ */
+ public void postProcess(ExecutableImage image, List<Plugin> plugins) {
+ Objects.requireNonNull(image);
+ Objects.requireNonNull(plugins);
+ try {
+ JlinkTask.postProcessImage(image, plugins);
+ } catch (Exception ex) {
+ throw new PluginException(ex);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkPermission.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. 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.tools.jlink.internal;
+
+import java.security.BasicPermission;
+
+/**
+ * The permission required to use jlink API. The permission target_name is
+ * "jlink". e.g.: permission jdk.tools.jlink.plugins.JlinkPermission "jlink";
+ *
+ */
+public final class JlinkPermission extends BasicPermission {
+
+ private static final long serialVersionUID = -3687912306077727801L;
+
+ public JlinkPermission(String name) {
+ super(name);
+ }
+
+}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java Wed Oct 26 20:13:29 2016 +0000
@@ -46,11 +46,11 @@
import jdk.internal.module.ConfigurableModuleFinder.Phase;
import jdk.tools.jlink.internal.TaskHelper.BadArgs;
import static jdk.tools.jlink.internal.TaskHelper.JLINK_BUNDLE;
+import jdk.tools.jlink.internal.Jlink.JlinkConfiguration;
+import jdk.tools.jlink.internal.Jlink.PluginsConfiguration;
import jdk.tools.jlink.internal.TaskHelper.Option;
import jdk.tools.jlink.internal.TaskHelper.OptionsHelper;
import jdk.tools.jlink.internal.ImagePluginStack.ImageProvider;
-import jdk.tools.jlink.Jlink.JlinkConfiguration;
-import jdk.tools.jlink.Jlink.PluginsConfiguration;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.builder.DefaultImageBuilder;
import jdk.tools.jlink.plugin.Plugin;
@@ -153,7 +153,7 @@
= taskHelper.newOptionsHelper(JlinkTask.class, recognizedOptions);
private PrintWriter log;
- void setLog(PrintWriter out) {
+ void setLog(PrintWriter out, PrintWriter err) {
log = out;
taskHelper.setLog(log);
}
@@ -182,7 +182,8 @@
int run(String[] args) {
if (log == null) {
- setLog(new PrintWriter(System.out, true));
+ setLog(new PrintWriter(System.out, true),
+ new PrintWriter(System.err, true));
}
try {
optionsHelper.handleOptions(this, args);
@@ -212,8 +213,8 @@
}
return EXIT_OK;
- } catch (UncheckedIOException | PluginException | IllegalArgumentException |
- IOException | ResolutionException e) {
+ } catch (PluginException | IllegalArgumentException |
+ UncheckedIOException |IOException | ResolutionException e) {
log.println(taskHelper.getMessage("error.prefix") + " " + e.getMessage());
if (DEBUG) {
e.printStackTrace(log);
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JmodArchive.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JmodArchive.java Wed Oct 26 20:13:29 2016 +0000
@@ -128,12 +128,16 @@
switch (section) {
case CLASSES:
return EntryType.CLASS_OR_RESOURCE;
+ case CONFIG:
+ return EntryType.CONFIG;
case NATIVE_LIBS:
return EntryType.NATIVE_LIB;
case NATIVE_CMDS:
return EntryType.NATIVE_CMD;
- case CONFIG:
- return EntryType.CONFIG;
+ case HEADER_FILES:
+ return EntryType.HEADER_FILE;
+ case MAN_PAGES:
+ return EntryType.MAN_PAGE;
default:
throw new InternalError("unexpected entry: " + section);
}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Main.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Main.java Wed Oct 26 20:13:29 2016 +0000
@@ -26,25 +26,41 @@
package jdk.tools.jlink.internal;
import java.io.*;
+import java.util.spi.ToolProvider;
public class Main {
public static void main(String... args) throws Exception {
- JlinkTask t = new JlinkTask();
- int rc = t.run(args);
- System.exit(rc);
+ System.exit(run(new PrintWriter(System.out, true),
+ new PrintWriter(System.err, true),
+ args));
}
-
/**
* Entry point that does <i>not</i> call System.exit.
*
+ * @param out output stream
+ * @param err error output stream
* @param args command line arguments
- * @param out output stream
* @return an exit code. 0 means success, non-zero means an error occurred.
*/
- public static int run(String[] args, PrintWriter out) {
+ public static int run(PrintWriter out, PrintWriter err, String... args) {
+ if (System.getSecurityManager() != null) {
+ System.getSecurityManager().
+ checkPermission(new JlinkPermission("jlink"));
+ }
+
JlinkTask t = new JlinkTask();
- t.setLog(out);
+ t.setLog(out, err);
return t.run(args);
}
+
+ public static class JlinkToolProvider implements ToolProvider {
+ public String name() {
+ return "jlink";
+ }
+
+ public int run(PrintWriter out, PrintWriter err, String... args) {
+ return Main.run(out, err, args);
+ }
+ }
}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/TaskHelper.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/TaskHelper.java Wed Oct 26 20:13:29 2016 +0000
@@ -49,13 +49,14 @@
import jdk.internal.module.ConfigurableModuleFinder;
import jdk.internal.module.ConfigurableModuleFinder.Phase;
-import jdk.tools.jlink.Jlink;
-import jdk.tools.jlink.Jlink.PluginsConfiguration;
+import jdk.tools.jlink.internal.plugins.ExcludeFilesPlugin;
+import jdk.tools.jlink.internal.plugins.ExcludeJmodSectionPlugin;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.Plugin.Category;
import jdk.tools.jlink.builder.DefaultImageBuilder;
import jdk.tools.jlink.builder.ImageBuilder;
import jdk.tools.jlink.plugin.PluginException;
+import jdk.tools.jlink.internal.Jlink.PluginsConfiguration;
import jdk.tools.jlink.internal.plugins.PluginsResourceBundle;
import jdk.tools.jlink.internal.plugins.DefaultCompressPlugin;
import jdk.tools.jlink.internal.plugins.StripDebugPlugin;
@@ -323,6 +324,20 @@
addArgumentMap(plugin);
}, "-G");
mainOptions.add(plugOption);
+ } else if (plugin instanceof ExcludeJmodSectionPlugin) {
+ plugOption = new PlugOption(false, (task, opt, arg) -> {
+ Map<String, String> m = addArgumentMap(plugin);
+ m.put(ExcludeJmodSectionPlugin.NAME,
+ ExcludeJmodSectionPlugin.MAN_PAGES);
+ }, "--no-man-pages");
+ mainOptions.add(plugOption);
+
+ plugOption = new PlugOption(false, (task, opt, arg) -> {
+ Map<String, String> m = addArgumentMap(plugin);
+ m.put(ExcludeJmodSectionPlugin.NAME,
+ ExcludeJmodSectionPlugin.INCLUDE_HEADER_FILES);
+ }, "--no-header-files");
+ mainOptions.add(plugOption);
}
}
}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/packager/AppRuntimeImageBuilder.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/packager/AppRuntimeImageBuilder.java Wed Oct 26 20:13:29 2016 +0000
@@ -26,8 +26,8 @@
package jdk.tools.jlink.internal.packager;
-import jdk.tools.jlink.Jlink;
import jdk.tools.jlink.builder.DefaultImageBuilder;
+import jdk.tools.jlink.internal.Jlink;
import jdk.tools.jlink.internal.JlinkTask;
import jdk.tools.jlink.plugin.Plugin;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeJmodSectionPlugin.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,104 @@
+/*
+ * 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.tools.jlink.internal.plugins;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import jdk.tools.jlink.plugin.Plugin;
+import jdk.tools.jlink.plugin.PluginException;
+import jdk.tools.jlink.plugin.ResourcePool;
+import jdk.tools.jlink.plugin.ResourcePoolBuilder;
+import jdk.tools.jlink.plugin.ResourcePoolEntry.Type;
+
+/**
+ *
+ * A plugin to exclude a JMOD section such as man pages or header files
+ */
+public final class ExcludeJmodSectionPlugin implements Plugin {
+
+ public static final String NAME = "exclude-jmod-section";
+ public static final String MAN_PAGES = "man";
+ public static final String INCLUDE_HEADER_FILES = "headers";
+
+ private final Set<Type> filters = new HashSet<>();
+
+ @Override
+ public String getName() {
+ return NAME;
+ }
+
+ @Override
+ public void configure(Map<String, String> config) {
+ String arg = config.get(NAME);
+ if (arg.isEmpty()) {
+ throw new PluginException("Section name must be specified");
+ }
+
+ switch (arg) {
+ case MAN_PAGES:
+ filters.add(Type.MAN_PAGE);
+ break;
+ case INCLUDE_HEADER_FILES:
+ filters.add(Type.HEADER_FILE);
+ break;
+ default:
+ throw new PluginException("Invalid section name: " + arg);
+ }
+ }
+
+ @Override
+ public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
+ in.transformAndCopy(entry -> {
+ // filter entries whose type corresponds to the specified JMOD section
+ if (filters.contains(entry.type())) {
+ entry = null;
+ }
+ return entry;
+ }, out);
+ return out.build();
+ }
+
+ @Override
+ public Category getType() {
+ return Category.FILTER;
+ }
+
+ @Override
+ public String getDescription() {
+ return PluginsResourceBundle.getDescription(NAME);
+ }
+
+ @Override
+ public boolean hasArguments() {
+ return true;
+ }
+
+ @Override
+ public String getArgumentsDescription() {
+ return PluginsResourceBundle.getArgument(NAME);
+ }
+}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ResourcePoolEntry.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ResourcePoolEntry.java Wed Oct 26 20:13:29 2016 +0000
@@ -24,13 +24,12 @@
*/
package jdk.tools.jlink.plugin;
-import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UncheckedIOException;
-import java.nio.file.Files;
import java.nio.file.Path;
+
import jdk.tools.jlink.internal.ResourcePoolEntryFactory;
/**
@@ -64,6 +63,8 @@
CONFIG,
NATIVE_CMD,
NATIVE_LIB,
+ HEADER_FILE,
+ MAN_PAGE,
TOP,
OTHER
}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins.properties Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins.properties Wed Oct 26 20:13:29 2016 +0000
@@ -68,6 +68,12 @@
exclude-resources.description=\
Specify resources to exclude. e.g.: **.jcov,glob:**/META-INF/**
+exclude-jmod-section.argument=<section-name>\n\
+where <section-name> is \"man\" or \"headers".
+
+exclude-jmod-section.description=\
+Specify a JMOD section to exclude
+
generate-jli-classes.argument=<none|@filename>
generate-jli-classes.description=\
@@ -145,6 +151,12 @@
plugin.opt.G=\
\ -G, --strip-debug Strip debug information
+plugin.opt.no-man-pages=\
+\ --no-man-pages Exclude man pages
+
+plugin.opt.no-header-files=\
+\ --no-header-files Exclude include header files
+
main.plugin.name=\
\Plugin Name
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java Wed Oct 26 20:13:29 2016 +0000
@@ -32,6 +32,7 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
+import java.io.PrintWriter;
import java.io.UncheckedIOException;
import java.lang.module.Configuration;
import java.lang.module.ModuleReader;
@@ -136,8 +137,8 @@
private static final String MODULE_INFO = "module-info.class";
private Options options;
- private PrintStream out = System.out;
- void setLog(PrintStream out) {
+ private PrintWriter out = new PrintWriter(System.out, true);
+ void setLog(PrintWriter out, PrintWriter err) {
this.out = out;
}
@@ -164,6 +165,8 @@
List<Path> cmds;
List<Path> configs;
List<Path> libs;
+ List<Path> headerFiles;
+ List<Path> manPages;
ModuleFinder moduleFinder;
Version moduleVersion;
String mainClass;
@@ -345,6 +348,9 @@
final List<Path> libs = options.libs;
final List<Path> configs = options.configs;
final List<Path> classpath = options.classpath;
+ final List<Path> headerFiles = options.headerFiles;
+ final List<Path> manPages = options.manPages;
+
final Version moduleVersion = options.moduleVersion;
final String mainClass = options.mainClass;
final String osName = options.osName;
@@ -368,6 +374,9 @@
processSection(out, Section.NATIVE_CMDS, cmds);
processSection(out, Section.NATIVE_LIBS, libs);
processSection(out, Section.CONFIG, configs);
+ processSection(out, Section.HEADER_FILES, headerFiles);
+ processSection(out, Section.MAN_PAGES, manPages);
+
}
/**
@@ -595,7 +604,7 @@
return "";
}
- void processClasses(JmodOutputStream zos, List<Path> classpaths)
+ void processClasses(JmodOutputStream out, List<Path> classpaths)
throws IOException
{
if (classpaths == null)
@@ -603,24 +612,24 @@
for (Path p : classpaths) {
if (Files.isDirectory(p)) {
- processSection(zos, Section.CLASSES, p);
+ processSection(out, Section.CLASSES, p);
} else if (Files.isRegularFile(p) && p.toString().endsWith(".jar")) {
try (JarFile jf = new JarFile(p.toFile())) {
- JarEntryConsumer jec = new JarEntryConsumer(zos, jf);
+ JarEntryConsumer jec = new JarEntryConsumer(out, jf);
jf.stream().filter(jec).forEach(jec);
}
}
}
}
- void processSection(JmodOutputStream zos, Section section, List<Path> paths)
+ void processSection(JmodOutputStream out, Section section, List<Path> paths)
throws IOException
{
if (paths == null)
return;
for (Path p : paths)
- processSection(zos, section, p);
+ processSection(out, section, p);
}
void processSection(JmodOutputStream out, Section section, Path top)
@@ -1194,6 +1203,12 @@
= parser.acceptsAll(Set.of("h", "help"), getMessage("main.opt.help"))
.forHelp();
+ OptionSpec<Path> headerFiles
+ = parser.accepts("header-files", getMessage("main.opt.header-files"))
+ .withRequiredArg()
+ .withValuesSeparatedBy(File.pathSeparatorChar)
+ .withValuesConvertedBy(DirPathConverter.INSTANCE);
+
OptionSpec<Path> libs
= parser.accepts("libs", getMessage("main.opt.libs"))
.withRequiredArg()
@@ -1205,6 +1220,12 @@
.withRequiredArg()
.describedAs(getMessage("main.opt.main-class.arg"));
+ OptionSpec<Path> manPages
+ = parser.accepts("man-pages", getMessage("main.opt.man-pages"))
+ .withRequiredArg()
+ .withValuesSeparatedBy(File.pathSeparatorChar)
+ .withValuesConvertedBy(DirPathConverter.INSTANCE);
+
OptionSpec<Path> modulePath
= parser.acceptsAll(Set.of("p", "module-path"),
getMessage("main.opt.module-path"))
@@ -1271,6 +1292,10 @@
options.excludes = opts.valuesOf(excludes);
if (opts.has(libs))
options.libs = opts.valuesOf(libs);
+ if (opts.has(headerFiles))
+ options.headerFiles = opts.valuesOf(headerFiles);
+ if (opts.has(manPages))
+ options.manPages = opts.valuesOf(manPages);
if (opts.has(modulePath)) {
Path[] dirs = opts.valuesOf(modulePath).toArray(new Path[0]);
options.moduleFinder = ModuleFinder.of(dirs);
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/Main.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/Main.java Wed Oct 26 20:13:29 2016 +0000
@@ -26,6 +26,7 @@
package jdk.tools.jmod;
import java.io.*;
+import java.util.spi.ToolProvider;
public class Main {
public static void main(String... args) throws Exception {
@@ -37,13 +38,24 @@
/**
* Entry point that does <i>not</i> call System.exit.
*
+ * @param out output stream
+ * @param err error output stream
* @param args command line arguments
- * @param out output stream
* @return an exit code. 0 means success, non-zero means an error occurred.
*/
- public static int run(String[] args, PrintStream out) {
+ public static int run(PrintWriter out, PrintWriter err, String... args) {
JmodTask t = new JmodTask();
- t.setLog(out);
+ t.setLog(out, err);
return t.run(args);
}
+
+ public static class JmodToolProvider implements ToolProvider {
+ public String name() {
+ return "jmod";
+ }
+
+ public int run(PrintWriter out, PrintWriter err, String... args) {
+ return Main.run(out, err, args);
+ }
+ }
}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/resources/jmod.properties Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/resources/jmod.properties Wed Oct 26 20:13:29 2016 +0000
@@ -54,9 +54,11 @@
main.opt.exclude=Exclude files matching the supplied comma separated pattern\
\ list, each element using one the following forms: <glob-pattern>,\
\ glob:<glob-pattern> or regex:<regex-pattern>
+main.opt.header-files=Location of header files
main.opt.module-version= Module version
main.opt.main-class=Main class
main.opt.main-class.arg=class-name
+main.opt.man-pages=Location of man pages
main.opt.os-name=Operating system name
main.opt.os-name.arg=os-name
main.opt.os-arch=Operating system architecture
--- a/jdk/src/jdk.jlink/share/classes/module-info.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/jdk.jlink/share/classes/module-info.java Wed Oct 26 20:13:29 2016 +0000
@@ -31,10 +31,14 @@
uses jdk.tools.jlink.plugin.Plugin;
+ provides java.util.spi.ToolProvider with jdk.tools.jmod.Main.JmodToolProvider;
+ provides java.util.spi.ToolProvider with jdk.tools.jlink.internal.Main.JlinkToolProvider;
+
provides jdk.tools.jlink.plugin.Plugin with jdk.tools.jlink.internal.plugins.FileCopierPlugin;
provides jdk.tools.jlink.plugin.Plugin with jdk.tools.jlink.internal.plugins.StripDebugPlugin;
provides jdk.tools.jlink.plugin.Plugin with jdk.tools.jlink.internal.plugins.ExcludePlugin;
provides jdk.tools.jlink.plugin.Plugin with jdk.tools.jlink.internal.plugins.ExcludeFilesPlugin;
+ provides jdk.tools.jlink.plugin.Plugin with jdk.tools.jlink.internal.plugins.ExcludeJmodSectionPlugin;
provides jdk.tools.jlink.plugin.Plugin with jdk.tools.jlink.internal.plugins.SystemModuleDescriptorPlugin;
provides jdk.tools.jlink.plugin.Plugin with jdk.tools.jlink.internal.plugins.StripNativeCommandsPlugin;
provides jdk.tools.jlink.plugin.Plugin with jdk.tools.jlink.internal.plugins.OrderResourcesPlugin;
--- a/jdk/src/jdk.pack200/share/native/common-unpack/unpack.cpp Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/jdk.pack200/share/native/common-unpack/unpack.cpp Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2014, 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
@@ -174,7 +174,10 @@
const char* utf8String() {
assert(tagMatches(CONSTANT_Utf8));
- assert(value.b.len == strlen((const char*)value.b.ptr));
+ if (value.b.len != strlen((const char*)value.b.ptr)) {
+ unpack_abort("bad utf8 encoding");
+ // and fall through
+ }
return (const char*)value.b.ptr;
}
@@ -1319,10 +1322,10 @@
CHECK;
int nc = 0;
- for ( const char* ncp = form.utf8String() ; *ncp; ncp++) {
- if (*ncp == 'L') nc++;
+ for (int j = 0; j < (int)form.value.b.len; j++) {
+ int c = form.value.b.ptr[j];
+ if (c == 'L') nc++;
}
-
ncTotal += nc;
e.refs = U_NEW(entry*, cpMap[i].nrefs = 1 + nc);
CHECK;
@@ -2830,6 +2833,7 @@
}
assert(!b.le_bci || prevBCI == (int)to_bci(prevBII));
+ CHECK;
switch (b.le_len) {
case 0: break;
case 1: putu1(x); break;
@@ -4026,6 +4030,10 @@
uint len = bcimap.length();
uint* map = (uint*) bcimap.base();
assert(len > 0); // must be initialized before using to_bci
+ if (len == 0) {
+ abort("bad bcimap");
+ return 0;
+ }
if (bii < len)
return map[bii];
// Else it's a fractional or out-of-range BCI.
@@ -4048,6 +4056,7 @@
break;
case 8: // (8) [PH]
putu2(to_bci(code_StackMapTable_P.getInt()));
+ CHECK;
break;
}
}
@@ -4095,6 +4104,7 @@
CHECK;
for (int curIP = 0; ; curIP++) {
+ CHECK;
int curPC = (int)(wpoffset() - codeBase);
bcimap.add(curPC);
ensure_put_space(10); // covers most instrs w/o further bounds check
@@ -4336,6 +4346,7 @@
int curIP = code_fixup_source.get(i);
int destIP = curIP + bc_label.getInt();
int span = to_bci(destIP) - to_bci(curIP);
+ CHECK;
switch (type) {
case 2: putu2_at(bp, (ushort)span); break;
case 4: putu4_at(bp, span); break;
@@ -4532,11 +4543,13 @@
if (tag <= 127) {
// (64-127) [(2)]
if (tag >= 64) put_stackmap_type();
+ CHECK_0;
} else if (tag <= 251) {
// (247) [(1)(2)]
// (248-251) [(1)]
if (tag >= 247) putu2(code_StackMapTable_offset.getInt());
if (tag == 247) put_stackmap_type();
+ CHECK_0;
} else if (tag <= 254) {
// (252) [(1)(2)]
// (253) [(1)(2)(2)]
@@ -4563,6 +4576,7 @@
putu2(count = code_LineNumberTable_N.getInt());
for (j = 0; j < count; j++) {
putu2(to_bci(code_LineNumberTable_bci_P.getInt()));
+ CHECK_0;
putu2(code_LineNumberTable_line.getInt());
}
break;
@@ -4573,9 +4587,11 @@
for (j = 0; j < count; j++) {
int bii = code_LocalVariableTable_bci_P.getInt();
int bci = to_bci(bii);
+ CHECK_0;
putu2(bci);
bii += code_LocalVariableTable_span_O.getInt();
putu2(to_bci(bii) - bci);
+ CHECK_0;
putref(code_LocalVariableTable_name_RU.getRefN());
CHECK_0;
putref(code_LocalVariableTable_type_RS.getRefN());
@@ -4590,9 +4606,11 @@
for (j = 0; j < count; j++) {
int bii = code_LocalVariableTypeTable_bci_P.getInt();
int bci = to_bci(bii);
+ CHECK_0;
putu2(bci);
bii += code_LocalVariableTypeTable_span_O.getInt();
putu2(to_bci(bii) - bci);
+ CHECK_0;
putref(code_LocalVariableTypeTable_name_RU.getRefN());
CHECK_0;
putref(code_LocalVariableTypeTable_type_RS.getRefN());
@@ -5036,6 +5054,7 @@
entry* e = file_name.getRef();
CHECK_0;
cur_file.name = e->utf8String();
+ CHECK_0;
bool haveLongSize = (testBit(archive_options, AO_HAVE_FILE_SIZE_HI));
cur_file.size = file_size_hi.getLong(file_size_lo, haveLongSize);
if (testBit(archive_options, AO_HAVE_FILE_MODTIME))
--- a/jdk/src/jdk.unsupported/share/classes/sun/reflect/ReflectionFactory.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/src/jdk.unsupported/share/classes/sun/reflect/ReflectionFactory.java Wed Oct 26 20:13:29 2016 +0000
@@ -25,24 +25,34 @@
package sun.reflect;
+import java.io.OptionalDataException;
+import java.lang.invoke.MethodHandle;
import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
import java.security.AccessController;
import java.security.Permission;
import java.security.PrivilegedAction;
+/**
+ * ReflectionFactory supports custom serialization.
+ * Its methods support the creation of uninitialized objects, invoking serialization
+ * private methods for readObject, writeObject, readResolve, and writeReplace.
+ * <p>
+ * ReflectionFactory access is restricted, if a security manager is active,
+ * unless the permission {@code RuntimePermission("reflectionFactoryAccess")}
+ * is granted.
+ */
public class ReflectionFactory {
private static final ReflectionFactory soleInstance = new ReflectionFactory();
- private final jdk.internal.reflect.ReflectionFactory delegate;
-
- private ReflectionFactory() {
- delegate = AccessController.doPrivileged(
+ private static final jdk.internal.reflect.ReflectionFactory delegate = AccessController.doPrivileged(
new PrivilegedAction<jdk.internal.reflect.ReflectionFactory>() {
public jdk.internal.reflect.ReflectionFactory run() {
return jdk.internal.reflect.ReflectionFactory.getReflectionFactory();
}
- });
- }
+ });
+
+ private ReflectionFactory() {}
private static final Permission REFLECTION_FACTORY_ACCESS_PERM
= new RuntimePermission("reflectionFactoryAccess");
@@ -53,7 +63,7 @@
*
* <p> First, if there is a security manager, its {@code checkPermission}
* method is called with a {@link java.lang.RuntimePermission} with target
- * {@code "reflectionFactoryAccess"}. This may result in a securit
+ * {@code "reflectionFactoryAccess"}. This may result in a security
* exception.
*
* <p> The returned {@code ReflectionFactory} object should be carefully
@@ -61,6 +71,7 @@
* data and invoke private methods, as well as to load unverified bytecodes.
* It must never be passed to untrusted code.
*
+ * @return the ReflectionFactory
* @throws SecurityException if a security manager exists and its
* {@code checkPermission} method doesn't allow access to
* the RuntimePermission "reflectionFactoryAccess".
@@ -73,11 +84,129 @@
return soleInstance;
}
- public Constructor<?> newConstructorForSerialization(Class<?> classToInstantiate,
- Constructor<?> constructorToCall)
+ /**
+ * Returns an accessible no-arg constructor for a class.
+ * The no-arg constructor is found searching the class and its supertypes.
+ *
+ * @param cl the class to instantiate
+ * @return a no-arg constructor for the class or {@code null} if
+ * the class or supertypes do not have a suitable no-arg constructor
+ */
+ public final Constructor<?> newConstructorForSerialization(Class<?> cl)
{
- return delegate.newConstructorForSerialization(classToInstantiate,
- constructorToCall);
+ return delegate.newConstructorForSerialization(cl);
+ }
+
+ /**
+ * Returns an accessible no-arg constructor for an externalizable class to be
+ * initialized using a public no-argument constructor.
+ *
+ * @param cl the class to instantiate
+ * @return A no-arg constructor for the class; returns {@code null} if
+ * the class does not implement {@link java.io.Externalizable}
+ */
+ public final Constructor<?> newConstructorForExternalization(Class<?> cl) {
+ return delegate.newConstructorForExternalization(cl);
+ }
+
+ /**
+ * Returns a direct MethodHandle for the {@code readObject} method on
+ * a Serializable class.
+ * The first argument of {@link MethodHandle#invoke} is the serializable
+ * object and the second argument is the {@code ObjectInputStream} passed to
+ * {@code readObject}.
+ *
+ * @param cl a Serializable class
+ * @return a direct MethodHandle for the {@code readObject} method of the class or
+ * {@code null} if the class does not have a {@code readObject} method
+ */
+ public final MethodHandle readObjectForSerialization(Class<?> cl) {
+ return delegate.readObjectForSerialization(cl);
+ }
+
+ /**
+ * Returns a direct MethodHandle for the {@code readObjectNoData} method on
+ * a Serializable class.
+ * The first argument of {@link MethodHandle#invoke} is the serializable
+ * object and the second argument is the {@code ObjectInputStream} passed to
+ * {@code readObjectNoData}.
+ *
+ * @param cl a Serializable class
+ * @return a direct MethodHandle for the {@code readObjectNoData} method
+ * of the class or {@code null} if the class does not have a
+ * {@code readObjectNoData} method
+ */
+ public final MethodHandle readObjectNoDataForSerialization(Class<?> cl) {
+ return delegate.readObjectNoDataForSerialization(cl);
+ }
+
+ /**
+ * Returns a direct MethodHandle for the {@code writeObject} method on
+ * a Serializable class.
+ * The first argument of {@link MethodHandle#invoke} is the serializable
+ * object and the second argument is the {@code ObjectOutputStream} passed to
+ * {@code writeObject}.
+ *
+ * @param cl a Serializable class
+ * @return a direct MethodHandle for the {@code writeObject} method of the class or
+ * {@code null} if the class does not have a {@code writeObject} method
+ */
+ public final MethodHandle writeObjectForSerialization(Class<?> cl) {
+ return delegate.writeObjectForSerialization(cl);
+ }
+
+ /**
+ * Returns a direct MethodHandle for the {@code readResolve} method on
+ * a serializable class.
+ * The single argument of {@link MethodHandle#invoke} is the serializable
+ * object.
+ *
+ * @param cl the Serializable class
+ * @return a direct MethodHandle for the {@code readResolve} method of the class or
+ * {@code null} if the class does not have a {@code readResolve} method
+ */
+ public final MethodHandle readResolveForSerialization(Class<?> cl) {
+ return delegate.readResolveForSerialization(cl);
+ }
+
+ /**
+ * Returns a direct MethodHandle for the {@code writeReplace} method on
+ * a serializable class.
+ * The single argument of {@link MethodHandle#invoke} is the serializable
+ * object.
+ *
+ * @param cl the Serializable class
+ * @return a direct MethodHandle for the {@code writeReplace} method of the class or
+ * {@code null} if the class does not have a {@code writeReplace} method
+ */
+ public final MethodHandle writeReplaceForSerialization(Class<?> cl) {
+ return delegate.writeReplaceForSerialization(cl);
+ }
+
+ /**
+ * Returns true if the class has a static initializer.
+ * The presence of a static initializer is used to compute the serialVersionUID.
+ * @param cl a serializable class
+ * @return {@code true} if the class has a static initializer,
+ * otherwise {@code false}
+ */
+ public final boolean hasStaticInitializerForSerialization(Class<?> cl) {
+ return delegate.hasStaticInitializerForSerialization(cl);
+ }
+
+ /**
+ * Returns a new OptionalDataException with {@code eof} set to {@code true}
+ * or {@code false}.
+ * @param bool the value of {@code eof} in the created OptionalDataException
+ * @return a new OptionalDataException
+ */
+ public final OptionalDataException newOptionalDataExceptionForSerialization(boolean bool) {
+ Constructor<OptionalDataException> cons = delegate.newOptionalDataExceptionForSerialization();
+ try {
+ return cons.newInstance(bool);
+ } catch (InstantiationException|IllegalAccessException|InvocationTargetException ex) {
+ throw new InternalError("unable to create OptionalDataException", ex);
+ }
}
}
--- a/jdk/test/com/oracle/security/ucrypto/TestAES.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/com/oracle/security/ucrypto/TestAES.java Wed Oct 26 20:13:29 2016 +0000
@@ -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
@@ -23,9 +23,11 @@
/*
* @test
- * @bug 7088989 8014374
+ * @bug 7088989 8014374 8167512
* @summary Ensure the AES ciphers of OracleUcrypto provider works correctly
* @key randomness
+ * @run main TestAES
+ * @run main/othervm/java.security.policy==empty.policy TestAES
*/
import java.io.*;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/corba/serialization/ObjectStreamTest$_Echo_Stub.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,91 @@
+/*
+ * 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.
+ */
+
+import java.rmi.UnexpectedException;
+
+import javax.rmi.CORBA.Stub;
+import javax.rmi.CORBA.Util;
+
+import org.omg.CORBA.SystemException;
+import org.omg.CORBA.portable.ApplicationException;
+import org.omg.CORBA.portable.OutputStream;
+import org.omg.CORBA.portable.RemarshalException;
+import org.omg.CORBA.portable.ServantObject;
+
+
+/**
+ * ObjectStreamTest$Echo Stub class generated by rmic, do not edit.
+ */
+public class ObjectStreamTest$_Echo_Stub extends Stub implements ObjectStreamTest.Echo {
+
+ private static final String[] _type_ids = {
+ "RMI:ObjectStreamTest\\U0024Echo:0000000000000000"
+ };
+
+ private static final long serialVersionUID = 5217577841494640354L;
+
+ public String[] _ids() {
+ return _type_ids.clone();
+ }
+
+ public Object echo(Object arg0) throws java.rmi.RemoteException {
+ if (!Util.isLocal(this)) {
+ try {
+ org.omg.CORBA.portable.InputStream in = null;
+ try {
+ OutputStream out = _request("echo", true);
+ Util.writeAny(out,arg0);
+ in = _invoke(out);
+ return Util.readAny(in);
+ } catch (ApplicationException ex) {
+ in = ex.getInputStream();
+ String $_id = in.read_string();
+ throw new UnexpectedException($_id);
+ } catch (RemarshalException ex) {
+ return echo(arg0);
+ } finally {
+ _releaseReply(in);
+ }
+ } catch (SystemException ex) {
+ throw Util.mapSystemException(ex);
+ }
+ } else {
+ ServantObject so = _servant_preinvoke("echo",ObjectStreamTest.Echo.class);
+ if (so == null) {
+ return echo(arg0);
+ }
+ try {
+ Object arg0Copy = Util.copyObject(arg0,_orb());
+ Object result = ((ObjectStreamTest.Echo)so.servant).echo(arg0Copy);
+ return Util.copyObject(result,_orb());
+ } catch (Throwable ex) {
+ Throwable exCopy = (Throwable)Util.copyObject(ex,_orb());
+ throw Util.wrapException(exCopy);
+ } finally {
+ _servant_postinvoke(so);
+ }
+ }
+ }
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/corba/serialization/ObjectStreamTest$_Server_Tie.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,103 @@
+/*
+ * 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.
+ */
+import java.rmi.Remote;
+
+import javax.rmi.CORBA.Tie;
+import javax.rmi.CORBA.Util;
+
+import org.omg.CORBA.BAD_OPERATION;
+import org.omg.CORBA.ORB;
+import org.omg.CORBA.SystemException;
+import org.omg.CORBA.portable.InputStream;
+import org.omg.CORBA.portable.OutputStream;
+import org.omg.CORBA.portable.ResponseHandler;
+import org.omg.CORBA.portable.UnknownException;
+import org.omg.CORBA_2_3.portable.ObjectImpl;
+
+
+/**
+ * ObjectStreamClass$Echo server tie class generated by rmic, do not edit.
+ */
+public class ObjectStreamTest$_Server_Tie extends ObjectImpl implements Tie {
+
+ volatile private ObjectStreamTest.Server target = null;
+
+ private static final String[] _type_ids = {
+ "RMI:ObjectStreamTest\\U0024Echo:0000000000000000"
+ };
+
+ public void setTarget(Remote target) {
+ this.target = (ObjectStreamTest.Server) target;
+ }
+
+ public Remote getTarget() {
+ return target;
+ }
+
+ public org.omg.CORBA.Object thisObject() {
+ return this;
+ }
+
+ public void deactivate() {
+ _orb().disconnect(this);
+ _set_delegate(null);
+ target = null;
+ }
+
+ public ORB orb() {
+ return _orb();
+ }
+
+ public void orb(ORB orb) {
+ orb.connect(this);
+ }
+
+ public String[] _ids() {
+ return _type_ids.clone();
+ }
+
+ public OutputStream _invoke(String method, InputStream _in, ResponseHandler reply) throws SystemException {
+ try {
+ ObjectStreamTest.Server target = this.target;
+ if (target == null) {
+ throw new java.io.IOException();
+ }
+ org.omg.CORBA_2_3.portable.InputStream in =
+ (org.omg.CORBA_2_3.portable.InputStream) _in;
+ if (method.equals("echo")) {
+ Object arg0 = Util.readAny(in);
+ Object result = target.echo(arg0);
+ OutputStream out = reply.createReply();
+ Util.writeAny(out,result);
+ return out;
+ }
+ throw new BAD_OPERATION();
+ } catch (SystemException ex) {
+ throw ex;
+ } catch (Throwable ex) {
+ throw new UnknownException(ex);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/corba/serialization/ObjectStreamTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,433 @@
+/*
+ * 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.
+ */
+
+import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.time.LocalTime;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.HashMap;
+import java.util.Objects;
+import java.util.PropertyPermission;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.LongAdder;
+
+import javax.naming.CommunicationException;
+import javax.naming.InitialContext;
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.rmi.CORBA.Util;
+import javax.rmi.PortableRemoteObject;
+
+import org.omg.CORBA_2_3.ORB;
+import org.omg.CORBA_2_3.portable.OutputStream;
+import org.omg.CORBA_2_3.portable.InputStream;
+
+import jdk.test.lib.JDKToolFinder;
+import jdk.test.lib.JDKToolLauncher;
+
+import org.testng.Assert;
+import org.testng.annotations.AfterSuite;
+import org.testng.annotations.Test;
+import org.testng.annotations.DataProvider;
+import org.testng.TestNG;
+
+/*
+ * @test
+ * @library /test/lib
+ * @build jdk.test.lib.*
+ * @compile ObjectStreamTest.java ObjectStreamTest$_Echo_Stub.java ObjectStreamTest$_Server_Tie.java
+ * @modules java.corba/com.sun.corba.se.impl.io java.base/java.io java.corba/com.sun.corba.se.impl.activation
+ * @summary Tests of ReflectionFactory use in IIOP Serialization
+ * @run testng/othervm
+ * -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory
+ * -Djava.naming.provider.url=iiop://localhost:1050 ObjectStreamTest
+ * @run testng/othervm/policy=security.policy
+ * -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory
+ * -Djava.naming.provider.url=iiop://localhost:1050 ObjectStreamTest
+ */
+
+@Test
+public class ObjectStreamTest {
+
+ enum Colors {RED, GREEN, YELLOW}
+
+ static Set<Colors> colorSet = new HashSet<>();
+
+ static {
+ colorSet.add(Colors.RED);
+ colorSet.add(Colors.GREEN);
+ }
+
+ /**
+ * The process spawned to run orbd.
+ */
+ static Process orbdProcess;
+ static Thread orbThread;
+
+ @DataProvider(name = "Objects")
+ static Object[][] patterns() {
+ BigInteger bigInteger = new BigInteger("8943892002309239");
+ InetAddress inetAddr;
+ try {
+ inetAddr = java.net.InetAddress.getByAddress(new byte[]{127, 0, 0, 1});
+ } catch (UnknownHostException ignored) {
+ inetAddr = null;
+ // ignored
+ }
+ HashMap<String, Object> hashMap = new HashMap<>();
+ hashMap.put("BigInteger", bigInteger);
+ hashMap.put("InetAddress", inetAddr);
+ hashMap.put("String", "bString");
+ Object[][] patterns = new Object[][]{
+ {"aString"},
+ {Integer.valueOf(5)},
+ {new SimpleObject(4, 4.0f)},
+ {Arrays.asList("a", "b", "c")},
+ {new String[]{"x", "y", "z"}},
+ {new ArrayList<Object>(1)}, // uses readObject/writeObject
+ {new StringBuffer("abc")}, // Has serialPersistentFields
+ {new StringBuilder("abc")},
+ {Colors.RED},
+ {inetAddr},
+ {LocalTime.MIDNIGHT}, // uses writeReplace/readResolve
+ {new LongAdder()}, // uses writeReplace/readResolve
+ {EnumSet.allOf(Colors.class)}, // used writeReplace/readResolve
+ {bigInteger},
+ {new BigDecimal(bigInteger)},
+ {hashMap},
+ {new PropertyPermission("abc", "read")}, // has serialPersistentFields
+ };
+ return patterns;
+ }
+
+
+ /**
+ * Check ObjectStreamClass facts match between core serialization and CORBA.
+ *
+ * @param value
+ */
+ @Test(dataProvider = "Objects")
+ static void factCheck(Serializable value) {
+ Class<?> clazz = value.getClass();
+ java.io.ObjectStreamClass sOSC = java.io.ObjectStreamClass.lookup(clazz);
+ java.io.ObjectStreamField[] sFields = sOSC.getFields();
+ com.sun.corba.se.impl.io.ObjectStreamClass cOSC = corbaLookup(clazz);
+ com.sun.corba.se.impl.io.ObjectStreamField[] cFields = cOSC.getFields();
+
+ Assert.assertEquals(sFields.length, cFields.length, "Different number of fields");
+ for (int i = 0; i < sFields.length; i++) {
+ Assert.assertEquals(sFields[i].getName(), cFields[i].getName(), "different field names " + cFields[i].getName());
+ Assert.assertEquals(sFields[i].getType(), cFields[i].getType(), "different field types " + cFields[i].getName());
+ Assert.assertEquals(sFields[i].getTypeString(), cFields[i].getTypeString(), "different field typestrings " + cFields[i].getName());
+ }
+
+ Assert.assertEquals(baseMethod("hasReadObjectMethod", sOSC, (Class<?>[]) null),
+ corbaMethod("hasReadObject", cOSC, (Class<?>[]) null), "hasReadObject: " + value.getClass());
+
+ Assert.assertEquals(baseMethod("hasWriteObjectMethod", sOSC, (Class<?>[]) null),
+ corbaMethod("hasWriteObject", cOSC, (Class<?>[]) null), "hasWriteObject: " + value.getClass());
+
+ Assert.assertEquals(baseMethod("hasWriteReplaceMethod", sOSC, (Class<?>[]) null),
+ corbaMethod("hasWriteReplaceMethod", cOSC, (Class<?>[]) null), "hasWriteReplace: " + value.getClass());
+
+ Assert.assertEquals(baseMethod("hasReadResolveMethod", sOSC, (Class<?>[]) null),
+ corbaMethod("hasReadResolveMethod", cOSC, (Class<?>[]) null), "hasReadResolve: " + value.getClass());
+
+ Assert.assertEquals(baseMethod("getSerialVersionUID", sOSC, (Class<?>[]) null),
+ corbaMethod("getSerialVersionUID", cOSC, (Class<?>[]) null), "getSerialVersionUID: " + value.getClass());
+
+ }
+
+
+ /**
+ * Test that objects written using Util.writeAny can be serialized
+ * and deserialized using Util.readAny to equivalent objects.
+ */
+ @Test(dataProvider = "Objects", enabled = true, dependsOnMethods = {"factCheck"})
+ static void WriteValueObjectStreamTest01(Serializable value) throws Exception {
+ ORB orb = (ORB) ORB.init(new String[0], null);
+
+ OutputStream out = (OutputStream) orb.create_output_stream();
+ Util.writeAny(out, value);
+
+ InputStream in = (InputStream) out.create_input_stream();
+ Object actual = Util.readAny(in);
+
+ checkEquals(actual, value);
+ }
+
+ /**
+ * Test that objects can be echoed to a server and come back equivalent.
+ */
+ @Test(dataProvider = "Objects", enabled = false, dependsOnMethods = {"factCheck"})
+ static void echoObjects(Serializable value) throws Exception {
+ Context initialNamingContext = Server.init();
+ Echo echo = (Echo) PortableRemoteObject.narrow(
+ initialNamingContext.lookup(Server.serverID), Echo.class);
+ Object actual = echo.echo(value);
+ checkEquals(actual, value);
+ }
+
+ /**
+ * Check if the value and result are equals, with some tests depending on the type.
+ * @param expected the expected value
+ * @param actual the actual value
+ */
+ static void checkEquals(Object actual, Object expected) {
+ Class<?> cl = expected.getClass();
+ Assert.assertEquals(actual.getClass(), cl, "type of value not equal to class of result");
+ try {
+ if (cl.isArray() || !(cl.getDeclaredMethod("equals", cl) == null)) {
+ Assert.assertEquals(actual, expected, "echo'd object not equal");
+ } else {
+ Assert.assertEquals(toString(actual), toString(expected), "toString values not equal");
+ }
+ } catch (NoSuchMethodException ex) {
+ Assert.assertEquals(toString(actual), toString(expected), "toString values not equal");
+ }
+ }
+
+ /**
+ * Convert an object to a String, and correctly for arrays.
+ * @param obj an object
+ * @return the tostring for the object.
+ */
+ static String toString(Object obj) {
+ return obj.getClass().isArray()
+ ? Arrays.toString((Object[]) obj)
+ : Objects.toString(obj);
+ }
+
+ /**
+ * SimpleObject to test round trip.
+ */
+ static class SimpleObject implements Serializable {
+ private static final long serialVersionUID = 5217577841494640354L;
+
+ private int i = 0;
+ private float f = 0.0f;
+
+ SimpleObject(int i, float f) {
+ this.i = i;
+ this.f = f;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ SimpleObject that = (SimpleObject) o;
+
+ if (i != that.i) return false;
+ return Float.compare(that.f, f) == 0;
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = i;
+ result = 31 * result + (f != +0.0f ? Float.floatToIntBits(f) : 0);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "SimpleObject{" +
+ "i=" + i +
+ ", f=" + f +
+ '}';
+ }
+ }
+
+
+ /**
+ * Lookup the CORBA ObjectStreamClass instance for a class.
+ * @param clazz the class
+ * @return the CORBA ObjectStreamClass instance for the class
+ */
+ static com.sun.corba.se.impl.io.ObjectStreamClass corbaLookup(Class<?> clazz) {
+ Class<?> oscClass = com.sun.corba.se.impl.io.ObjectStreamClass.class;
+
+ try {
+ Method meth = oscClass.getDeclaredMethod("lookup", Class.class);
+ meth.setAccessible(true);
+ return (com.sun.corba.se.impl.io.ObjectStreamClass) meth.invoke(null, clazz);
+ } catch (NoSuchMethodException noMeth) {
+ throw new RuntimeException("missing method", noMeth);
+ } catch (IllegalAccessException | InvocationTargetException rex) {
+ throw new RuntimeException("invocation failed", rex);
+ }
+ }
+
+ /**
+ * Lookup aand invoke method on a serializable object via the CORBA ObjectStreamClass.
+ * @param methodName method name
+ * @param osc CORBA ObjectStreamClass
+ * @param argClasses method arguments
+ * @return the value returned from invoking the method
+ */
+ static Object corbaMethod(String methodName, com.sun.corba.se.impl.io.ObjectStreamClass osc, Class<?>... argClasses) {
+ Class<?> oscClass = com.sun.corba.se.impl.io.ObjectStreamClass.class;
+
+ try {
+ Method meth = oscClass.getDeclaredMethod(methodName, argClasses);
+ meth.setAccessible(true);
+ return meth.invoke(osc);
+
+ } catch (NoSuchMethodException noMeth) {
+ throw new RuntimeException("missing method" + osc.getName()
+ + "::" + methodName, noMeth);
+ } catch (IllegalAccessException | InvocationTargetException rex) {
+ throw new RuntimeException("invocation failed", rex);
+ }
+ }
+
+
+ /**
+ * Lookup aand invoke method on a serializable object via java.io.ObjectStreamClass.
+ * @param methodName method name
+ * @param osc java.io.ObjectStreamClass
+ * @param argClasses method arguments
+ * @return the value returned from invoking the method
+ */
+ static Object baseMethod(String methodName, java.io.ObjectStreamClass osc, Class<?>... argClasses) {
+ Class<?> oscClass = java.io.ObjectStreamClass.class;
+
+ try {
+ Method meth = oscClass.getDeclaredMethod(methodName, argClasses);
+ meth.setAccessible(true);
+ return meth.invoke(osc);
+
+ } catch (NoSuchMethodException noMeth) {
+ throw new RuntimeException("missing method: " + osc.getName()
+ + "::" + methodName, noMeth);
+ } catch (IllegalAccessException | InvocationTargetException rex) {
+ throw new RuntimeException("invocation failed", rex);
+ }
+ }
+
+ /**
+ * Simple echo interface to check serialization/deserialization.
+ */
+ interface Echo extends Remote {
+ Object echo(Object obj) throws RemoteException;
+ }
+
+ static class Server extends PortableRemoteObject implements Echo {
+
+ public static final String serverID = "ObjectStreamTestServer";
+
+ private static Context initialNamingContext;
+
+ private static Server server;
+
+ public Server() throws RemoteException {
+ super();
+ }
+
+ public Object echo(Object obj) {
+ return obj;
+ }
+
+
+ public static Context init() {
+ if (initialNamingContext == null) {
+ try {
+ startOrbd();
+ Thread.sleep(5000L); // Give it 5 seconds
+ } catch (Exception eex) {
+ throw new RuntimeException("Orbd", eex);
+ }
+ for (int i = 0; i < 1; i++) {
+ try {
+ Thread.sleep(1L);
+ initialNamingContext = new InitialContext();
+ server = new Server();
+ initialNamingContext.rebind(serverID, server);
+ } catch (CommunicationException | InterruptedException cex) {
+ System.out.printf("retry #%d sec: ex: %s%n", i, cex);
+ } catch (NamingException ex) {
+ throw new RuntimeException("can't initialize naming context", ex);
+ } catch (RemoteException rex) {
+ throw new RuntimeException("can't initialize server", rex);
+ }
+ }
+ }
+ if (initialNamingContext == null) {
+ Assert.fail("Can't initialize the Orb, no naming context");
+ }
+ return initialNamingContext;
+ }
+ }
+
+ static void startOrbd() throws Exception {
+ System.out.println("\nStarting orbd with NS port 1050 ");
+ JDKToolLauncher orbdLauncher = JDKToolLauncher.create("orbd")
+ .addToolArg("-ORBInitialHost").addToolArg("localhost")
+ .addToolArg("-ORBInitialPort").addToolArg("1050");
+
+ System.out.println("ObjectStreamTest: Executing: " + Arrays.asList(orbdLauncher.getCommand()));
+ ProcessBuilder pb = new ProcessBuilder(orbdLauncher.getCommand());
+
+ pb.redirectError(ProcessBuilder.Redirect.INHERIT);
+ orbdProcess = pb.start();
+ }
+
+ @AfterSuite
+ static void killOrbd() throws Exception {
+ if (orbdProcess != null) {
+ orbdProcess.destroyForcibly();
+ orbdProcess.waitFor();
+ System.out.printf("destroyed orbd, pid: %d, exitValue: %d%n",
+ orbdProcess.getPid(), orbdProcess.exitValue());
+ }
+ }
+
+
+
+ // Main can be used to run the tests from the command line with only testng.jar.
+ @SuppressWarnings("raw_types")
+ @Test(enabled = false)
+ public static void main(String[] args) {
+ Class<?>[] testclass = {ObjectStreamTest.class};
+ TestNG testng = new TestNG();
+ testng.setTestClasses(testclass);
+ testng.run();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/corba/serialization/security.policy Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,15 @@
+// Individual Permissions for ObjectStreamTest
+grant {
+ // Permissions needed to run the test
+ permission java.util.PropertyPermission "*", "read";
+ permission java.io.FilePermission "<<ALL FILES>>", "read,write,delete,execute";
+ permission java.net.SocketPermission "*", "resolve,connect,listen,accept";
+
+ // Permissions to allow ObjectTest to use IIOP ObjectStreamClass
+ permission java.lang.RuntimePermission "accessClassInPackage.com.sun.corba.se.impl.io";
+ permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
+ permission java.lang.RuntimePermission "accessDeclaredMembers";
+ permission java.lang.RuntimePermission "accessClassInPackage.sun.reflect";
+ permission java.lang.RuntimePermission "accessClassInPackage.sun.misc";
+ permission java.io.SerializablePermission "enableSubclassImplementation";
+};
--- a/jdk/test/java/io/Serializable/serialFilter/FilterWithSecurityManagerTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/java/io/Serializable/serialFilter/FilterWithSecurityManagerTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -28,6 +28,7 @@
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
+import org.testng.Assert;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
@@ -65,20 +66,21 @@
*/
@Test
public void testGlobalFilter() throws Exception {
- if (ObjectInputFilter.Config.getSerialFilter() == null) {
- return;
- }
- try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
- ObjectInputStream ois = new ObjectInputStream(bais)) {
+ ObjectInputFilter global = ObjectInputFilter.Config.getSerialFilter();
+
+ try {
ObjectInputFilter.Config.setSerialFilter(filter);
assertFalse(setSecurityManager,
"When SecurityManager exists, without "
- + "java.security.SerializablePermission(serialFilter) Exception should be thrown");
- Object o = ois.readObject();
+ + "java.io.SerializablePermission(serialFilter) "
+ + "IllegalStateException should be thrown");
} catch (AccessControlException ex) {
assertTrue(setSecurityManager);
assertTrue(ex.getMessage().contains("java.io.SerializablePermission"));
assertTrue(ex.getMessage().contains("serialFilter"));
+ } catch (IllegalStateException ise) {
+ // ISE should occur only if global filter already set
+ Assert.assertNotNull(global, "Global filter should be non-null");
}
}
--- a/jdk/test/java/io/Serializable/serialFilter/GlobalFilterTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/java/io/Serializable/serialFilter/GlobalFilterTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -126,9 +126,7 @@
ObjectInputFilter.Config.setSerialFilter(filter);
Assert.fail("set only once process-wide filter");
} catch (IllegalStateException ise) {
- if (sm != null) {
- Assert.fail("wrong exception when security manager is set", ise);
- }
+ // Normal, once set can never be re-set even if no security manager
} catch (SecurityException se) {
if (sm == null) {
Assert.fail("wrong exception when security manager is not set", se);
--- a/jdk/test/java/io/Serializable/serialFilter/security.policy Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/java/io/Serializable/serialFilter/security.policy Wed Oct 26 20:13:29 2016 +0000
@@ -1,7 +1,8 @@
-// Individual Permissions to for GlobalFilterTest
+// Individual Permissions to for GlobalFilterTest and FilterWithSecurityManager
grant {
// Specific permission under test
- permission java.security.SerializablePermission "serialFilter";
+ permission java.io.SerializablePermission "serialFilter";
+
// Permissions needed to run the test
permission java.util.PropertyPermission "*", "read";
permission java.io.FilePermission "<<ALL FILES>>", "read,write,delete";
--- a/jdk/test/java/lang/StackWalker/CallerSensitiveMethod/Main.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/java/lang/StackWalker/CallerSensitiveMethod/Main.java Wed Oct 26 20:13:29 2016 +0000
@@ -26,6 +26,7 @@
* @bug 8157464
* @summary Basic test for StackWalker.getCallerClass()
* @library src
+ * @modules java.base/jdk.internal.reflect
* @build java.base/java.util.CSM csm/*
* @run main/othervm csm/jdk.test.CallerSensitiveTest
* @run main/othervm csm/jdk.test.CallerSensitiveTest sm
--- a/jdk/test/java/lang/module/ModuleReader/ModuleReaderTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/java/lang/module/ModuleReader/ModuleReaderTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -25,8 +25,8 @@
* @test
* @library /lib/testlibrary
* @modules java.base/jdk.internal.module
- * jdk.jlink/jdk.tools.jmod
* jdk.compiler
+ * jdk.jlink
* @build ModuleReaderTest CompilerUtils JarUtils
* @run testng ModuleReaderTest
* @summary Basic tests for java.lang.module.ModuleReader
@@ -48,6 +48,7 @@
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Optional;
+import java.util.spi.ToolProvider;
import jdk.internal.module.ConfigurableModuleFinder;
import jdk.internal.module.ConfigurableModuleFinder.Phase;
@@ -196,8 +197,11 @@
String cp = MODS_DIR.resolve(TEST_MODULE).toString();
String jmod = dir.resolve("m.jmod").toString();
String[] args = { "create", "--class-path", cp, jmod };
- jdk.tools.jmod.JmodTask task = new jdk.tools.jmod.JmodTask();
- assertEquals(task.run(args), 0);
+ ToolProvider jmodTool = ToolProvider.findFirst("jmod")
+ .orElseThrow(() ->
+ new RuntimeException("jmod tool not found")
+ );
+ assertEquals(jmodTool.run(System.out, System.out, args), 0);
test(dir);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/AccessControl/AccessControlTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,454 @@
+/*
+ * 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 util.ClassSupplier;
+import util.MemberFactory;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Stream;
+
+import static java.util.stream.Collectors.groupingBy;
+import static java.util.stream.Collectors.joining;
+import static java.util.stream.Collectors.mapping;
+import static java.util.stream.Collectors.toCollection;
+import static util.MemberFactory.*;
+import static util.MemberFactory.Group.*;
+import static util.ClassSupplier.*;
+
+/**
+ * @test
+ * @summary An exhaustive test of reflective access controls
+ * @bug 6378384
+ * @build a.PublicSuper a.Package b.PublicSub b.Package
+ * util.MemberFactory util.ClassSupplier
+ * @run main AccessControlTest
+ */
+public class AccessControlTest {
+
+ public static void main(String[] args) throws Exception {
+ boolean ok = true;
+
+ ok &= new Test()
+ .current(PACKAGE_CLASS_IN_PKG_A)
+ .member (PACKAGE_CLASS_IN_PKG_A).target(PACKAGE_CLASS_IN_PKG_A)
+ .allowed(ALL)
+ .perform();
+
+ ok &= new Test()
+ .current(PACKAGE_CLASS_IN_PKG_A)
+ .member (PUBLIC_SUPERCLASS_IN_PKG_A).target(PUBLIC_SUPERCLASS_IN_PKG_A)
+ .allowed(PACKAGE_MEMBERS, PROTECTED_MEMBERS, PUBLIC_MEMBERS)
+ .denied (PRIVATE_MEMBERS)
+ .perform();
+
+ ok &= new Test()
+ .current(PACKAGE_CLASS_IN_PKG_A)
+ .member (PUBLIC_SUPERCLASS_IN_PKG_A).target(PUBLIC_SUBCLASS_IN_PKG_B)
+ .allowed(PACKAGE_MEMBERS, PROTECTED_MEMBERS, PUBLIC_MEMBERS)
+ .denied (PRIVATE_MEMBERS)
+ .perform();
+
+ ok &= new Test()
+ .current(PACKAGE_CLASS_IN_PKG_A)
+ .member (PACKAGE_CLASS_IN_PKG_B).target(PACKAGE_CLASS_IN_PKG_B)
+ .denied (ALL)
+ .perform();
+
+ ok &= new Test()
+ .current(PACKAGE_CLASS_IN_PKG_A)
+ .member (PUBLIC_SUBCLASS_IN_PKG_B).target(PUBLIC_SUBCLASS_IN_PKG_B)
+ .allowed(PUBLIC_MEMBERS)
+ .denied (PRIVATE_MEMBERS, PACKAGE_MEMBERS, PROTECTED_MEMBERS)
+ .perform();
+
+ ok &= new Test()
+ .current(PUBLIC_SUPERCLASS_IN_PKG_A)
+ .member (PACKAGE_CLASS_IN_PKG_A).target(PACKAGE_CLASS_IN_PKG_A)
+ .allowed(PACKAGE_MEMBERS, PROTECTED_MEMBERS, PUBLIC_MEMBERS)
+ .denied (PRIVATE_MEMBERS)
+ .perform();
+
+ ok &= new Test()
+ .current(PUBLIC_SUPERCLASS_IN_PKG_A)
+ .member (PUBLIC_SUPERCLASS_IN_PKG_A).target(PUBLIC_SUPERCLASS_IN_PKG_A)
+ .allowed(ALL)
+ .perform();
+
+ ok &= new Test()
+ .current(PUBLIC_SUPERCLASS_IN_PKG_A)
+ .member (PUBLIC_SUPERCLASS_IN_PKG_A).target(PUBLIC_SUBCLASS_IN_PKG_B)
+ .allowed(ALL)
+ .perform();
+
+ ok &= new Test()
+ .current(PUBLIC_SUPERCLASS_IN_PKG_A)
+ .member (PACKAGE_CLASS_IN_PKG_B).target(PACKAGE_CLASS_IN_PKG_B)
+ .denied (ALL)
+ .perform();
+
+ ok &= new Test()
+ .current(PUBLIC_SUPERCLASS_IN_PKG_A)
+ .member (PUBLIC_SUBCLASS_IN_PKG_B).target(PUBLIC_SUBCLASS_IN_PKG_B)
+ .allowed(PUBLIC_MEMBERS)
+ .denied (PRIVATE_MEMBERS, PACKAGE_MEMBERS, PROTECTED_MEMBERS)
+ .perform();
+
+ ok &= new Test()
+ .current(PACKAGE_CLASS_IN_PKG_B)
+ .member (PACKAGE_CLASS_IN_PKG_A).target(PACKAGE_CLASS_IN_PKG_A)
+ .denied (ALL)
+ .perform();
+
+ ok &= new Test()
+ .current(PACKAGE_CLASS_IN_PKG_B)
+ .member (PUBLIC_SUPERCLASS_IN_PKG_A).target(PUBLIC_SUPERCLASS_IN_PKG_A)
+ .allowed(PUBLIC_MEMBERS)
+ .denied (PRIVATE_MEMBERS, PACKAGE_MEMBERS, PROTECTED_MEMBERS)
+ .perform();
+
+ ok &= new Test()
+ .current(PACKAGE_CLASS_IN_PKG_B)
+ .member (PUBLIC_SUPERCLASS_IN_PKG_A).target(PUBLIC_SUBCLASS_IN_PKG_B)
+ .allowed(PUBLIC_MEMBERS)
+ .denied (PRIVATE_MEMBERS, PACKAGE_MEMBERS, PROTECTED_MEMBERS)
+ .perform();
+
+ ok &= new Test()
+ .current(PACKAGE_CLASS_IN_PKG_B)
+ .member (PACKAGE_CLASS_IN_PKG_B).target(PACKAGE_CLASS_IN_PKG_B)
+ .allowed(ALL)
+ .perform();
+
+ ok &= new Test()
+ .current(PACKAGE_CLASS_IN_PKG_B)
+ .member (PUBLIC_SUBCLASS_IN_PKG_B).target(PUBLIC_SUBCLASS_IN_PKG_B)
+ .allowed(PACKAGE_MEMBERS, PROTECTED_MEMBERS, PUBLIC_MEMBERS)
+ .denied (PRIVATE_MEMBERS)
+ .perform();
+
+ ok &= new Test()
+ .current(PUBLIC_SUBCLASS_IN_PKG_B)
+ .member (PACKAGE_CLASS_IN_PKG_A).target(PACKAGE_CLASS_IN_PKG_A)
+ .denied (ALL)
+ .perform();
+
+ ok &= new Test()
+ .current(PUBLIC_SUBCLASS_IN_PKG_B)
+ .member (PUBLIC_SUPERCLASS_IN_PKG_A).target(PUBLIC_SUPERCLASS_IN_PKG_A)
+ .allowed(PUBLIC_MEMBERS, PROTECTED_STATIC_F_M)
+ .denied (PRIVATE_MEMBERS, PACKAGE_MEMBERS, PROTECTED_INSTANCE_F_M,
+ PROTECTED_C)
+ .perform();
+
+ ok &= new Test()
+ .current(PUBLIC_SUBCLASS_IN_PKG_B)
+ .member (PUBLIC_SUPERCLASS_IN_PKG_A).target(PUBLIC_SUBCLASS_IN_PKG_B)
+ .allowed(PUBLIC_MEMBERS, PROTECTED_INSTANCE_F_M, PROTECTED_STATIC_F_M)
+ .denied (PRIVATE_MEMBERS, PACKAGE_MEMBERS, PROTECTED_C)
+ .perform();
+
+ ok &= new Test()
+ .current(PUBLIC_SUBCLASS_IN_PKG_B)
+ .member (PACKAGE_CLASS_IN_PKG_B).target(PACKAGE_CLASS_IN_PKG_B)
+ .allowed(PACKAGE_MEMBERS, PROTECTED_MEMBERS, PUBLIC_MEMBERS)
+ .denied (PRIVATE_MEMBERS)
+ .perform();
+
+ ok &= new Test()
+ .current(PUBLIC_SUBCLASS_IN_PKG_B)
+ .member (PUBLIC_SUBCLASS_IN_PKG_B).target(PUBLIC_SUBCLASS_IN_PKG_B)
+ .allowed(ALL)
+ .perform();
+
+ if (ok) {
+ System.out.println("\nAll cases passed.");
+ } else {
+ throw new RuntimeException("Some cases failed - see log.");
+ }
+ }
+
+ // use this for generating an exhaustive set of test cases on stdout
+ public static class Generate {
+ public static void main(String[] args) {
+ for (ClassSupplier current : ClassSupplier.values()) {
+ for (ClassSupplier member : ClassSupplier.values()) {
+ for (ClassSupplier target : ClassSupplier.values()) {
+ if (member.get().isAssignableFrom(target.get())) {
+ new Test()
+ .current(current).member(member).target(target)
+ .allowed(ALL)
+ .perform(true);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ static class Test {
+
+ ClassSupplier currentClassSupplier, memberClassSupplier, targetClassSupplier;
+ EnumSet<MemberFactory> expectAllowedMembers = EnumSet.noneOf(MemberFactory.class);
+ EnumSet<MemberFactory> expectDeniedMembers = EnumSet.noneOf(MemberFactory.class);
+
+ Test current(ClassSupplier current) {
+ currentClassSupplier = current;
+ return this;
+ }
+
+ Test member(ClassSupplier member) {
+ memberClassSupplier = member;
+ return this;
+ }
+
+ Test target(ClassSupplier target) {
+ targetClassSupplier = target;
+ return this;
+ }
+
+ Test allowed(MemberFactory... allowed) {
+ expectAllowedMembers = MemberFactory.asSet(allowed);
+ return this;
+ }
+
+ Test allowed(MemberFactory.Group... allowedGroups) {
+ expectAllowedMembers = MemberFactory.groupsToMembers(
+ MemberFactory.Group.asSet(allowedGroups));
+ return this;
+ }
+
+ Test denied(MemberFactory... denied) {
+ expectDeniedMembers = MemberFactory.asSet(denied);
+ return this;
+ }
+
+ Test denied(MemberFactory.Group... deniedGroups) {
+ expectDeniedMembers = MemberFactory.groupsToMembers(
+ MemberFactory.Group.asSet(deniedGroups));
+ return this;
+ }
+
+ boolean perform() {
+ return perform(false);
+ }
+
+ boolean perform(boolean generateCases) {
+
+ // some validation 1st
+ EnumSet<MemberFactory> intersection = EnumSet.copyOf(expectAllowedMembers);
+ intersection.retainAll(expectDeniedMembers);
+ if (!intersection.isEmpty()) {
+ throw new IllegalArgumentException(
+ "Expected allowed and denied MemberFactories have non-empty intersection: " +
+ intersection);
+ }
+
+ EnumSet<MemberFactory> missing = EnumSet.allOf(MemberFactory.class);
+ missing.removeAll(expectAllowedMembers);
+ missing.removeAll(expectDeniedMembers);
+ if (!missing.isEmpty()) {
+ throw new IllegalArgumentException(
+ "Union of expected allowed and denied MemberFactories is missing elements: " +
+ missing);
+ }
+
+ // retrieve method that will perform reflective access
+ Method checkAccessMethod;
+ try {
+ checkAccessMethod = currentClassSupplier.get().getDeclaredMethod(
+ "checkAccess", AccessibleObject.class, Object.class);
+ // in case of inaccessible currentClass
+ checkAccessMethod.setAccessible(true);
+ } catch (NoSuchMethodException e) {
+ throw new RuntimeException(e);
+ }
+
+ // construct a target object (for instance field/method)
+ Object target;
+ Constructor<?> targetConstructor =
+ (Constructor<?>) PUBLIC_CONSTRUCTOR.apply(targetClassSupplier.get());
+ // in case of inaccessible targetClass
+ targetConstructor.setAccessible(true);
+ try {
+ target = targetConstructor.newInstance(
+ new Object[targetConstructor.getParameterCount()]);
+ } catch (ReflectiveOperationException e) {
+ throw new RuntimeException(e);
+ }
+
+ Class<?> memberClass = memberClassSupplier.get();
+
+ Map<Boolean, EnumSet<MemberFactory>> actualMembers = Stream.concat(
+
+ expectAllowedMembers.stream().map(member -> new Trial(member, true)),
+ expectDeniedMembers.stream().map(member -> new Trial(member, false))
+
+ ).map(trial -> {
+
+ // obtain AccessibleObject to be used to perform reflective access
+ AccessibleObject accessibleObject = trial.member.apply(memberClass);
+
+ // only need target 'obj' for instance fields and methods
+ Object obj =
+ (accessibleObject instanceof Field &&
+ !Modifier.isStatic(((Field) accessibleObject).getModifiers())
+ ||
+ accessibleObject instanceof Method &&
+ !Modifier.isStatic(((Method) accessibleObject).getModifiers())
+ )
+ ? target : null;
+
+ // invoke checkAccess method and let it perform the reflective access
+ try {
+ checkAccessMethod.invoke(null, accessibleObject, obj);
+ trial.actualAllowed = true;
+ } catch (IllegalAccessException e) {
+ // should not happen as checkAccessMethod.isAccessible()
+ throw new RuntimeException(e);
+ } catch (InvocationTargetException e) {
+ if (e.getTargetException() instanceof IllegalAccessException) {
+ trial.actualAllowed = false;
+ } else {
+ // any other Exception is a fault in test or infrastructure - fail fast
+ throw new RuntimeException(e.getTargetException());
+ }
+ }
+
+ if (!generateCases) {
+ System.out.printf(
+ "%-26s accessing %26s's %-25s %-43s - expected %s, actual %s: %s\n",
+ currentClassSupplier, memberClassSupplier, trial.member.name(),
+ (obj == null ? "" : "with instance of " + targetClassSupplier),
+ (trial.expectAllowed ? "allowed" : "denied "),
+ (trial.actualAllowed ? "allowed" : "denied "),
+ (trial.expectAllowed == trial.actualAllowed ? "OK" : "FAILURE")
+ );
+ }
+
+ return trial;
+
+ }).collect(
+ groupingBy(
+ Trial::isActualAllowed,
+ mapping(
+ Trial::getMember,
+ toCollection(() -> EnumSet.noneOf(MemberFactory.class))))
+ );
+
+ EnumSet<MemberFactory> actualAllowedMembers =
+ Optional.ofNullable(actualMembers.get(true))
+ .orElse(EnumSet.noneOf(MemberFactory.class));
+ EnumSet<MemberFactory> actualDeniedMembers =
+ Optional.ofNullable(actualMembers.get(false))
+ .orElse(EnumSet.noneOf(MemberFactory.class));
+
+ if (generateCases) {
+ System.out.printf(
+ " ok &= new Test()\n" +
+ " .current(%s)\n" +
+ " .member (%s).target(%s)\n",
+ currentClassSupplier,
+ memberClassSupplier, targetClassSupplier
+ );
+
+ if (!actualAllowedMembers.isEmpty()) {
+ EnumSet<? extends Enum> actualAllowed =
+ MemberFactory.membersToGroupsOrNull(actualAllowedMembers);
+ if (actualAllowed == null)
+ actualAllowed = actualAllowedMembers;
+ System.out.print(
+ chunkBy(3, actualAllowed.stream().map(Enum::name))
+ .map(chunk -> chunk.collect(joining(", ")))
+ .collect(joining(",\n" +
+ " ",
+ " .allowed(",
+ ")\n"))
+ );
+ }
+
+ if (!actualDeniedMembers.isEmpty()) {
+ EnumSet<? extends Enum> actualDenied =
+ MemberFactory.membersToGroupsOrNull(actualDeniedMembers);
+ if (actualDenied == null)
+ actualDenied = actualAllowedMembers;
+ System.out.print(
+ chunkBy(3, actualDenied.stream().map(Enum::name))
+ .map(chunk -> chunk.collect(joining(", ")))
+ .collect(joining(",\n" +
+ " ",
+ " .denied (",
+ ")\n"))
+ );
+ }
+
+ System.out.print(
+ " .perform();\n"
+ );
+ }
+
+ return expectAllowedMembers.equals(actualAllowedMembers) &&
+ expectDeniedMembers.equals(actualDeniedMembers);
+ }
+ }
+
+ private static <T> Stream<Stream<T>> chunkBy(int chunkSize, Stream<T> stream) {
+ Iterator<T> elements = stream.iterator();
+ Stream.Builder<Stream<T>> b1 = Stream.builder();
+ while (elements.hasNext()) {
+ Stream.Builder<T> b2 = Stream.builder();
+ for (int i = 0; i < chunkSize && elements.hasNext(); i++) {
+ b2.accept(elements.next());
+ }
+ b1.accept(b2.build());
+ }
+ return b1.build();
+ }
+
+ private static class Trial {
+ final MemberFactory member;
+ final boolean expectAllowed;
+ boolean actualAllowed;
+
+ Trial(MemberFactory member, boolean expectAllowed) {
+ this.member = member;
+ this.expectAllowed = expectAllowed;
+ }
+
+ MemberFactory getMember() {
+ return member;
+ }
+
+ boolean isActualAllowed() {
+ return actualAllowed;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/AccessControl/a/Package.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,82 @@
+/*
+ * 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 a;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * A package-private class in a.
+ */
+class Package {
+
+ // fields
+ private static int privateStatic;
+ private int privateInstance;
+ static int packageStatic;
+ int packageInstance;
+ protected static int protectedStatic;
+ protected int protectedInstance;
+ public static int publicStatic;
+ public int publicInstance;
+
+ // methods
+ private static int privateStatic() { return 42; }
+ private int privateInstance() { return 42; }
+ static int packageStatic() { return 42; }
+ int packageInstance() { return 42; }
+ protected static int protectedStatic() { return 42; }
+ protected int protectedInstance() { return 42; }
+ public static int publicStatic() { return 42; }
+ public int publicInstance() { return 42; }
+
+ // constructors
+ private Package(Void _1, Void _2, Void _3) {}
+ Package(Void _1, Void _2) {}
+ protected Package(Void _1) {}
+ public Package() {}
+
+
+ // testing method
+ public static void checkAccess(AccessibleObject accessibleObject, Object obj)
+ throws IllegalAccessException,
+ InvocationTargetException,
+ InstantiationException
+ {
+ if (accessibleObject instanceof Field) {
+ Field field = (Field) accessibleObject;
+ field.set(obj, 42);
+ field.get(obj);
+ } else if (accessibleObject instanceof Method) {
+ Method method = (Method) accessibleObject;
+ method.invoke(obj);
+ } else if (accessibleObject instanceof Constructor) {
+ Constructor<?> constructor = (Constructor<?>) accessibleObject;
+ Object[] params = new Object[constructor.getParameterCount()];
+ constructor.newInstance(params);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/AccessControl/a/PublicSuper.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,82 @@
+/*
+ * 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 a;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * A public class in a which is a superclass of public class in b.
+ */
+public class PublicSuper {
+
+ // fields
+ private static int privateStatic;
+ private int privateInstance;
+ static int packageStatic;
+ int packageInstance;
+ protected static int protectedStatic;
+ protected int protectedInstance;
+ public static int publicStatic;
+ public int publicInstance;
+
+ // methods
+ private static int privateStatic() { return 42; }
+ private int privateInstance() { return 42; }
+ static int packageStatic() { return 42; }
+ int packageInstance() { return 42; }
+ protected static int protectedStatic() { return 42; }
+ protected int protectedInstance() { return 42; }
+ public static int publicStatic() { return 42; }
+ public int publicInstance() { return 42; }
+
+ // constructors
+ private PublicSuper(Void _1, Void _2, Void _3) {}
+ PublicSuper(Void _1, Void _2) {}
+ protected PublicSuper(Void _1) {}
+ public PublicSuper() {}
+
+
+ // testing method
+ public static void checkAccess(AccessibleObject accessibleObject, Object obj)
+ throws IllegalAccessException,
+ InvocationTargetException,
+ InstantiationException
+ {
+ if (accessibleObject instanceof Field) {
+ Field field = (Field) accessibleObject;
+ field.set(obj, 42);
+ field.get(obj);
+ } else if (accessibleObject instanceof Method) {
+ Method method = (Method) accessibleObject;
+ method.invoke(obj);
+ } else if (accessibleObject instanceof Constructor) {
+ Constructor<?> constructor = (Constructor<?>) accessibleObject;
+ Object[] params = new Object[constructor.getParameterCount()];
+ constructor.newInstance(params);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/AccessControl/b/Package.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,82 @@
+/*
+ * 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 b;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * A package-private class in b.
+ */
+class Package {
+
+ // fields
+ private static int privateStatic;
+ private int privateInstance;
+ static int packageStatic;
+ int packageInstance;
+ protected static int protectedStatic;
+ protected int protectedInstance;
+ public static int publicStatic;
+ public int publicInstance;
+
+ // methods
+ private static int privateStatic() { return 42; }
+ private int privateInstance() { return 42; }
+ static int packageStatic() { return 42; }
+ int packageInstance() { return 42; }
+ protected static int protectedStatic() { return 42; }
+ protected int protectedInstance() { return 42; }
+ public static int publicStatic() { return 42; }
+ public int publicInstance() { return 42; }
+
+ // constructors
+ private Package(Void _1, Void _2, Void _3) {}
+ Package(Void _1, Void _2) {}
+ protected Package(Void _1) {}
+ public Package() {}
+
+
+ // testing method
+ public static void checkAccess(AccessibleObject accessibleObject, Object obj)
+ throws IllegalAccessException,
+ InvocationTargetException,
+ InstantiationException
+ {
+ if (accessibleObject instanceof Field) {
+ Field field = (Field) accessibleObject;
+ field.set(obj, 42);
+ field.get(obj);
+ } else if (accessibleObject instanceof Method) {
+ Method method = (Method) accessibleObject;
+ method.invoke(obj);
+ } else if (accessibleObject instanceof Constructor) {
+ Constructor<?> constructor = (Constructor<?>) accessibleObject;
+ Object[] params = new Object[constructor.getParameterCount()];
+ constructor.newInstance(params);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/AccessControl/b/PublicSub.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,82 @@
+/*
+ * 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 b;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * A public class in b which is a subclass of public class in a.
+ */
+public class PublicSub extends a.PublicSuper {
+
+ // fields
+ private static int privateStatic;
+ private int privateInstance;
+ static int packageStatic;
+ int packageInstance;
+ protected static int protectedStatic;
+ protected int protectedInstance;
+ public static int publicStatic;
+ public int publicInstance;
+
+ // methods
+ private static int privateStatic() { return 42; }
+ private int privateInstance() { return 42; }
+ static int packageStatic() { return 42; }
+ int packageInstance() { return 42; }
+ protected static int protectedStatic() { return 42; }
+ protected int protectedInstance() { return 42; }
+ public static int publicStatic() { return 42; }
+ public int publicInstance() { return 42; }
+
+ // constructors
+ private PublicSub(Void _1, Void _2, Void _3) {}
+ PublicSub(Void _1, Void _2) {}
+ protected PublicSub(Void _1) {}
+ public PublicSub() {}
+
+
+ // testing method
+ public static void checkAccess(AccessibleObject accessibleObject, Object obj)
+ throws IllegalAccessException,
+ InvocationTargetException,
+ InstantiationException
+ {
+ if (accessibleObject instanceof Field) {
+ Field field = (Field) accessibleObject;
+ field.set(obj, 42);
+ field.get(obj);
+ } else if (accessibleObject instanceof Method) {
+ Method method = (Method) accessibleObject;
+ method.invoke(obj);
+ } else if (accessibleObject instanceof Constructor) {
+ Constructor<?> constructor = (Constructor<?>) accessibleObject;
+ Object[] params = new Object[constructor.getParameterCount()];
+ constructor.newInstance(params);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/AccessControl/util/ClassSupplier.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,50 @@
+/*
+ * 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 util;
+
+import java.util.function.Supplier;
+
+/**
+ * An enumeration of suppliers of test classes.
+ */
+public enum ClassSupplier implements Supplier<Class<?>> {
+ PACKAGE_CLASS_IN_PKG_A("a.Package"),
+ PUBLIC_SUPERCLASS_IN_PKG_A("a.PublicSuper"),
+ PACKAGE_CLASS_IN_PKG_B("b.Package"),
+ PUBLIC_SUBCLASS_IN_PKG_B("b.PublicSub");
+
+ private final String className;
+
+ ClassSupplier(String className) {
+ this.className = className;
+ }
+
+ @Override
+ public Class<?> get() {
+ try {
+ return Class.forName(className);
+ } catch (ClassNotFoundException e) {
+ throw (Error) new NoClassDefFoundError(className).initCause(e);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/AccessControl/util/MemberFactory.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,220 @@
+/*
+ * 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 util;
+
+import java.lang.reflect.AccessibleObject;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
+import static util.MemberFactory.Kind.CONSTRUCTOR;
+import static util.MemberFactory.Kind.FIELD;
+import static util.MemberFactory.Kind.METHOD;
+
+/**
+ * Enumeration of:
+ * <p>
+ * {private, package, protected, public} x {instance, static} x {field, method}
+ * <p>
+ * and:
+ * <p>
+ * {private, package, protected, public} x {constructor},
+ * <p>
+ * with each element acting as a factory of AccessibleObject(s)
+ * declared by given declaringClass(es).
+ */
+public enum MemberFactory implements Function<Class<?>, AccessibleObject> {
+ // instance fields
+ PRIVATE_INSTANCE_FIELD(FIELD, "privateInstance"),
+ PACKAGE_INSTANCE_FIELD(FIELD, "packageInstance"),
+ PROTECTED_INSTANCE_FIELD(FIELD, "protectedInstance"),
+ PUBLIC_INSTANCE_FIELD(FIELD, "publicInstance"),
+ // instance methods
+ PRIVATE_INSTANCE_METHOD(METHOD, "privateInstance"),
+ PACKAGE_INSTANCE_METHOD(METHOD, "packageInstance"),
+ PROTECTED_INSTANCE_METHOD(METHOD, "protectedInstance"),
+ PUBLIC_INSTANCE_METHOD(METHOD, "publicInstance"),
+ // static fields
+ PRIVATE_STATIC_FIELD(FIELD, "privateStatic"),
+ PACKAGE_STATIC_FIELD(FIELD, "packageStatic"),
+ PROTECTED_STATIC_FIELD(FIELD, "protectedStatic"),
+ PUBLIC_STATIC_FIELD(FIELD, "publicStatic"),
+ // static methods
+ PRIVATE_STATIC_METHOD(METHOD, "privateStatic"),
+ PACKAGE_STATIC_METHOD(METHOD, "packageStatic"),
+ PROTECTED_STATIC_METHOD(METHOD, "protectedStatic"),
+ PUBLIC_STATIC_METHOD(METHOD, "publicStatic"),
+ // constructors
+ PRIVATE_CONSTRUCTOR(CONSTRUCTOR, null, Void.class, Void.class, Void.class),
+ PACKAGE_CONSTRUCTOR(CONSTRUCTOR, null, Void.class, Void.class),
+ PROTECTED_CONSTRUCTOR(CONSTRUCTOR, null, Void.class),
+ PUBLIC_CONSTRUCTOR(CONSTRUCTOR, null),;
+
+ final Kind kind;
+ final String name;
+ final Class<?>[] parameterTypes;
+
+ MemberFactory(Kind kind, String name, Class<?>... parameterTypes) {
+ this.kind = kind;
+ this.name = name;
+ this.parameterTypes = parameterTypes;
+ }
+
+ @Override
+ public AccessibleObject apply(Class<?> declaringClass) {
+ return kind.apply(declaringClass, this);
+ }
+
+ public static EnumSet<MemberFactory> asSet(MemberFactory... members) {
+ return members.length == 0 ? EnumSet.noneOf(MemberFactory.class)
+ : EnumSet.copyOf(Arrays.asList(members));
+ }
+
+ /**
+ * @param members the set of MemberFactory(s) to convert to set of
+ * MemberFactory.Group(s).
+ * @return a set of groups that cover all elements of the members set if
+ * such set of groups exists or null if it doesn't.
+ */
+ public static EnumSet<Group> membersToGroupsOrNull(EnumSet<MemberFactory> members) {
+ EnumSet<MemberFactory> mSet = members.clone();
+ EnumSet<Group> gSet = EnumSet.allOf(Group.class);
+ Iterator<Group> gIter = gSet.iterator();
+ while (gIter.hasNext()) {
+ Group g = gIter.next();
+ if (mSet.containsAll(g.members)) {
+ mSet.removeAll(g.members);
+ } else {
+ gIter.remove();
+ }
+ }
+ return mSet.isEmpty() ? gSet : null;
+ }
+
+ /**
+ * @param groups the set of MemberFactory.Group(s) to convert to set of
+ * MemberFactory(s).
+ * @return a set of members as a union of members of all groups.
+ */
+ public static EnumSet<MemberFactory> groupsToMembers(EnumSet<Group> groups) {
+ EnumSet<MemberFactory> mSet = EnumSet.noneOf(MemberFactory.class);
+ for (Group g : groups) {
+ mSet.addAll(g.members);
+ }
+ return mSet;
+ }
+
+ enum Kind implements BiFunction<Class<?>, MemberFactory, AccessibleObject> {
+ FIELD {
+ @Override
+ public AccessibleObject apply(Class<?> declaringClass, MemberFactory factory) {
+ assert factory.kind == this;
+ try {
+ return declaringClass.getDeclaredField(factory.name);
+ } catch (NoSuchFieldException e) {
+ // a fault in test - fail fast
+ throw new RuntimeException(e.getMessage());
+ }
+ }
+ },
+ METHOD {
+ @Override
+ public AccessibleObject apply(Class<?> declaringClass, MemberFactory factory) {
+ assert factory.kind == this;
+ try {
+ return declaringClass.getDeclaredMethod(factory.name, factory.parameterTypes);
+ } catch (NoSuchMethodException e) {
+ // a fault in test - fail fast
+ throw new RuntimeException(e.getMessage());
+ }
+ }
+ },
+ CONSTRUCTOR {
+ @Override
+ public AccessibleObject apply(Class<?> declaringClass, MemberFactory factory) {
+ assert factory.kind == this;
+ try {
+ return declaringClass.getDeclaredConstructor(factory.parameterTypes);
+ } catch (NoSuchMethodException e) {
+ // a fault in test - fail fast
+ throw new RuntimeException(e.getMessage());
+ }
+ }
+ }
+ }
+
+ /**
+ * We define groups of MemberFactory(s) for members that commonly
+ * exhibit same access restrictions in various cases in order to allow
+ * specifying groups instead of individual members in the test cases,
+ * making them less verbose.
+ */
+ public enum Group {
+ // all members
+ ALL(MemberFactory.values()),
+ // all private members
+ PRIVATE_MEMBERS(PRIVATE_INSTANCE_FIELD, PRIVATE_INSTANCE_METHOD,
+ PRIVATE_STATIC_FIELD, PRIVATE_STATIC_METHOD,
+ PRIVATE_CONSTRUCTOR),
+ // all package members
+ PACKAGE_MEMBERS(PACKAGE_INSTANCE_FIELD, PACKAGE_INSTANCE_METHOD,
+ PACKAGE_STATIC_FIELD, PACKAGE_STATIC_METHOD,
+ PACKAGE_CONSTRUCTOR),
+ // all protected members
+ PROTECTED_MEMBERS(PROTECTED_INSTANCE_FIELD, PROTECTED_INSTANCE_METHOD,
+ PROTECTED_STATIC_FIELD, PROTECTED_STATIC_METHOD,
+ PROTECTED_CONSTRUCTOR),
+ // all public members
+ PUBLIC_MEMBERS(PUBLIC_INSTANCE_FIELD, PUBLIC_INSTANCE_METHOD,
+ PUBLIC_STATIC_FIELD, PUBLIC_STATIC_METHOD,
+ PUBLIC_CONSTRUCTOR),
+ // instance field and method pairs
+ PRIVATE_INSTANCE_F_M(PRIVATE_INSTANCE_FIELD, PRIVATE_INSTANCE_METHOD),
+ PACKAGE_INSTANCE_F_M(PACKAGE_INSTANCE_FIELD, PACKAGE_INSTANCE_METHOD),
+ PROTECTED_INSTANCE_F_M(PROTECTED_INSTANCE_FIELD, PROTECTED_INSTANCE_METHOD),
+ PUBLIC_INSTANCE_F_M(PUBLIC_INSTANCE_FIELD, PUBLIC_INSTANCE_METHOD),
+ // static field and method pairs
+ PRIVATE_STATIC_F_M(PRIVATE_STATIC_FIELD, PRIVATE_STATIC_METHOD),
+ PACKAGE_STATIC_F_M(PACKAGE_STATIC_FIELD, PACKAGE_STATIC_METHOD),
+ PROTECTED_STATIC_F_M(PROTECTED_STATIC_FIELD, PROTECTED_STATIC_METHOD),
+ PUBLIC_STATIC_F_M(PUBLIC_STATIC_FIELD, PUBLIC_STATIC_METHOD),
+ // constructor singles
+ PRIVATE_C(PRIVATE_CONSTRUCTOR),
+ PACKAGE_C(PACKAGE_CONSTRUCTOR),
+ PROTECTED_C(PROTECTED_CONSTRUCTOR),
+ PUBLIC_C(PUBLIC_CONSTRUCTOR);
+
+ final EnumSet<MemberFactory> members;
+
+ Group(MemberFactory... members) {
+ this.members = EnumSet.copyOf(Arrays.asList(members));
+ }
+
+ public static EnumSet<Group> asSet(Group... groups) {
+ return groups.length == 0 ? EnumSet.noneOf(Group.class)
+ : EnumSet.copyOf(Arrays.asList(groups));
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/rmi/server/UnicastRemoteObject/serialFilter/FilterUROTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,194 @@
+/*
+ * 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.io.InvalidClassException;
+import java.io.ObjectInputFilter;
+import java.io.Serializable;
+
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.rmi.UnmarshalException;
+import java.rmi.server.UnicastRemoteObject;
+
+import java.util.Objects;
+
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+/*
+ * @test
+ * @run testng/othervm FilterUROTest
+ * @summary Check that objects are exported with ObjectInputFilters via UnicastRemoteObject
+ */
+public class FilterUROTest {
+
+ /**
+ * Data to test serialFilter call counts.
+ * - name
+ * - Object
+ * - expected count of calls to checkInput.
+ *
+ * @return array of test data
+ */
+ @DataProvider(name = "bindData")
+ static Object[][] bindObjects() {
+ Object[][] data = {
+ {"SimpleString", "SimpleString", 0},
+ {"String", new XX("now is the time"), 1},
+ {"String[]", new XX(new String[3]), 3},
+ {"Long[4]", new XX(new Long[4]), 3},
+ {"RejectME", new XX(new RejectME()), -1},
+ };
+ return data;
+ }
+
+ /*
+ * Test exporting an object with a serialFilter using exportObject().
+ * Send some objects and check the number of calls to the serialFilter.
+ */
+ @Test(dataProvider = "bindData")
+ public void useExportObject(String name, Object obj, int expectedFilterCount) throws RemoteException {
+ try {
+ RemoteImpl impl = RemoteImpl.create();
+ Echo client = (Echo) UnicastRemoteObject
+ .exportObject(impl, 0, impl.checker);
+ int count = client.filterCount(obj);
+ System.out.printf("count: %d, obj: %s%n", count, obj);
+ Assert.assertEquals(count, expectedFilterCount, "wrong number of filter calls");
+ } catch (RemoteException rex) {
+ if (expectedFilterCount == -1 &&
+ UnmarshalException.class.equals(rex.getCause().getClass()) &&
+ InvalidClassException.class.equals(rex.getCause().getCause().getClass())) {
+ return; // normal expected exception
+ }
+ rex.printStackTrace();
+ Assert.fail("unexpected remote exception", rex);
+ } catch (Exception rex) {
+ Assert.fail("unexpected exception", rex);
+ }
+ }
+
+ /*
+ * Test exporting an object with a serialFilter using exportObject()
+ * with explicit (but null) SocketFactories.
+ * Send some objects and check the number of calls to the serialFilter.
+ */
+ @Test(dataProvider = "bindData")
+ public void useExportObject2(String name, Object obj, int expectedFilterCount) throws RemoteException {
+ try {
+ RemoteImpl impl = RemoteImpl.create();
+ Echo client = (Echo) UnicastRemoteObject
+ .exportObject(impl, 0, null, null, impl.checker);
+ int count = client.filterCount(obj);
+ System.out.printf("count: %d, obj: %s%n", count, obj);
+ Assert.assertEquals(count, expectedFilterCount, "wrong number of filter calls");
+ } catch (RemoteException rex) {
+ if (expectedFilterCount == -1 &&
+ UnmarshalException.class.equals(rex.getCause().getClass()) &&
+ InvalidClassException.class.equals(rex.getCause().getCause().getClass())) {
+ return; // normal expected exception
+ }
+ rex.printStackTrace();
+ Assert.fail("unexpected remote exception", rex);
+ } catch (Exception rex) {
+ Assert.fail("unexpected exception", rex);
+ }
+ }
+
+ /**
+ * A simple Serializable holding an object that is passed by value.
+ * It and its contents are checked by the filter.
+ */
+ static class XX implements Serializable {
+ private static final long serialVersionUID = 362498820763181265L;
+
+ final Object obj;
+
+ XX(Object obj) {
+ this.obj = obj;
+ }
+
+ public String toString() {
+ return super.toString() + "//" + Objects.toString(obj);
+ }
+ }
+
+ interface Echo extends Remote {
+ int filterCount(Object obj) throws RemoteException;
+ }
+
+ /**
+ * This remote object just counts the calls to the serialFilter
+ * and returns it. The caller can check the number against
+ * what was expected for the object passed as an argument.
+ * A new RemoteImpl is used for each test so the count starts at zero again.
+ */
+ static class RemoteImpl implements Echo {
+
+ private static final long serialVersionUID = -6999613679881262446L;
+
+ transient Checker checker;
+
+ static RemoteImpl create() throws RemoteException {
+ RemoteImpl impl = new RemoteImpl(new Checker());
+ return impl;
+ }
+
+ private RemoteImpl(Checker checker) throws RemoteException {
+ this.checker = checker;
+ }
+
+ public int filterCount(Object obj) throws RemoteException {
+ return checker.count();
+ }
+
+ }
+
+ /**
+ * A ObjectInputFilter that just counts when it is called.
+ */
+ static class Checker implements ObjectInputFilter {
+ int count;
+
+ @Override
+ public Status checkInput(FilterInfo filterInfo) {
+ if (filterInfo.serialClass() == RejectME.class) {
+ return Status.REJECTED;
+ }
+ count++;
+ return Status.UNDECIDED;
+ }
+
+ public int count() {
+ return count;
+ }
+ }
+
+ /**
+ * A class to be rejected by the filter.
+ */
+ static class RejectME implements Serializable {
+ private static final long serialVersionUID = 2L;
+ }
+}
--- a/jdk/test/java/security/KeyStore/TestKeyStoreBasic.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/java/security/KeyStore/TestKeyStoreBasic.java Wed Oct 26 20:13:29 2016 +0000
@@ -40,7 +40,7 @@
/*
* @test
- * @bug 8048621 8133090
+ * @bug 8048621 8133090 8167371
* @summary Test basic operations with keystores (jks, jceks, pkcs12)
* @author Yu-Ching Valerie PENG
*/
@@ -116,6 +116,8 @@
};
private static final String ALIAS_HEAD = "test";
+ private static final String CRYPTO_ALG = "PBEWithHmacSHA256AndAES_128";
+
public static void main(String args[]) throws Exception {
TestKeyStoreBasic jstest = new TestKeyStoreBasic();
jstest.run();
@@ -125,7 +127,7 @@
for (String provider : PROVIDERS) {
try {
runTest(provider);
- System.out.println("Test with provider " + provider + "passed");
+ System.out.println("Test with provider " + provider + " passed");
} catch (java.security.KeyStoreException e) {
if (provider.equals("SunPKCS11-Solaris")) {
System.out.println("KeyStoreException is expected: "
@@ -236,6 +238,44 @@
// compare the creation date of the 2 key stores for all aliases
compareCreationDate(ks, ks2, numEntries);
+ // check setEntry/getEntry with a password protection algorithm
+ if ("PKCS12".equalsIgnoreCase(ks.getType())) {
+ System.out.println(
+ "Skipping the setEntry/getEntry check for PKCS12 keystore...");
+ return;
+ }
+ String alias = ALIAS_HEAD + ALIAS_HEAD;
+ KeyStore.PasswordProtection pw =
+ new KeyStore.PasswordProtection(PASSWD2, CRYPTO_ALG, null);
+ KeyStore.PrivateKeyEntry entry =
+ new KeyStore.PrivateKeyEntry(privateKey, new Certificate[]{ cert });
+ checkSetEntry(ks, alias, pw, entry);
+ ks.setEntry(alias, entry, new KeyStore.PasswordProtection(PASSWD2));
+ checkGetEntry(ks, alias, pw);
+ }
+
+ // check setEntry with a password protection algorithm
+ private void checkSetEntry(KeyStore ks, String alias,
+ KeyStore.PasswordProtection pw, KeyStore.Entry entry) throws Exception {
+ try {
+ ks.setEntry(alias, entry, pw);
+ throw new Exception(
+ "ERROR: expected KeyStore.setEntry to throw an exception");
+ } catch (KeyStoreException e) {
+ // ignore the expected exception
+ }
+ }
+
+ // check getEntry with a password protection algorithm
+ private void checkGetEntry(KeyStore ks, String alias,
+ KeyStore.PasswordProtection pw) throws Exception {
+ try {
+ ks.getEntry(alias, pw);
+ throw new Exception(
+ "ERROR: expected KeyStore.getEntry to throw an exception");
+ } catch (KeyStoreException e) {
+ // ignore the expected exception
+ }
}
// check key store type
--- a/jdk/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java Wed Oct 26 20:13:29 2016 +0000
@@ -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
@@ -624,7 +624,7 @@
@Test
public void test_chronoFields() {
ChronoLocalDate hdate = HijrahChronology.INSTANCE.date(1434, 6, 28);
- assertEquals(hdate.get(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH), 3);
+ assertEquals(hdate.get(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH), 7);
assertEquals(hdate.get(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR), 7);
assertEquals(hdate.get(ChronoField.ALIGNED_WEEK_OF_MONTH), 4);
assertEquals(hdate.get(ChronoField.ALIGNED_WEEK_OF_YEAR), 25);
@@ -785,4 +785,32 @@
public void test_hijrahToJapanese(HijrahDate hijrah, String japanese) {
assertEquals(JapaneseChronology.INSTANCE.date(hijrah).toString(), japanese);
}
+
+ @DataProvider(name="alignedDayOfWeekInMonthTestDates")
+ Object[][] data_alignedDayOfWeekInMonth() {
+ return new Object[][] {
+ {1437, 9, 1, 1, 1},
+ {1437, 10, 1, 1, 1},
+ {1437, 10, 11, 2, 4},
+ {1437, 10, 29, 5, 1},
+ };
+ }
+
+ //-----------------------------------------------------------------------
+ // Test for aligned-week-of-month calculation based on the day-of-month
+ //-----------------------------------------------------------------------
+ @Test(dataProvider="alignedDayOfWeekInMonthTestDates")
+ public void test_alignedWeekOfMonth(int year, int month, int dom, int wom, int dowm) {
+ HijrahDate date = HijrahChronology.INSTANCE.date(year, month, dom);
+ assertEquals(date.getLong(ChronoField.ALIGNED_WEEK_OF_MONTH), wom);
+ }
+
+ //-----------------------------------------------------------------------
+ // Test for aligned-day-of-week calculation based on the day-of-month
+ //-----------------------------------------------------------------------
+ @Test(dataProvider="alignedDayOfWeekInMonthTestDates")
+ public void test_alignedDayOfWeekInMonth(int year, int month, int dom, int wom, int dowm) {
+ HijrahDate date = HijrahChronology.INSTANCE.date(year, month, dom);
+ assertEquals(date.getLong(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH), dowm);
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/time/test/java/time/format/TestNarrowMonthNamesAndDayNames.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,127 @@
+/*
+ * 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 test.java.time.format;
+
+/*
+ * @test
+ * @bug 8146750
+ * @summary Test Narrow and NarrowStandalone month names are retrieved correctly.
+ */
+import static org.testng.Assert.assertEquals;
+
+import java.time.DayOfWeek;
+import java.time.Month;
+import java.time.format.TextStyle;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class TestNarrowMonthNamesAndDayNames {
+
+ static {
+ System.setProperty("java.locale.providers", "COMPAT");
+ }
+
+ private static final List<Month> MONTHVALUES = Arrays.asList(Month.values());
+ private static final List<DayOfWeek> DAYVALUES = Arrays.asList(DayOfWeek.values());
+ private static final List<TextStyle> TEXTSTYLELIST = Arrays.asList(TextStyle.NARROW,
+ TextStyle.NARROW_STANDALONE);
+ private static final List<Locale> LOCARR = Arrays.asList(Locale.US,
+ Locale.GERMANY,
+ Locale.FRANCE,
+ new Locale("no", "NO"));
+
+ /**
+ * Locale en_US, de_DE, fr_FR, no_NO will have same Narrow and
+ * Narrow_Standalone month Names for COMPAT Provider.
+ */
+ @DataProvider(name = "MonthNarrows")
+ public Object[][] monthNameData() {
+ return new Object[][]{{new String[]{
+ "J",
+ "F",
+ "M",
+ "A",
+ "M",
+ "J",
+ "J",
+ "A",
+ "S",
+ "O",
+ "N",
+ "D"
+ }},};
+ }
+
+ //-----------------------------------------------------------------------
+ // Check Narrow and Narrow_standalone month name values
+ //-----------------------------------------------------------------------
+ @Test(dataProvider = "MonthNarrows")
+ public void compareMonthNarrowValues(String[] monthNarrowExpected) {
+ LOCARR.forEach((loc) -> {
+ TEXTSTYLELIST.forEach((style) -> {
+ MONTHVALUES.forEach((value) -> {
+ String result = value.getDisplayName(style, loc);
+ int index = value.ordinal();
+ assertEquals(result, monthNarrowExpected[index], "Test failed"
+ + " for COMPAT Provider for locale "
+ + loc + " for style " + style.name()
+ + " with Month value " + value.name());
+ });
+ });
+ });
+ }
+
+ /**
+ * Locale en_US, de_DE, fr_FR, no_NO will have different Narrow and
+ * Narrow_Standalone Day Names for COMPAT Provider.
+ */
+ @DataProvider(name = "DayNarrows")
+ public Object[][] dayNameData() {
+ return new Object[][]{
+ {Locale.US, new String[]{"M", "T", "W", "T", "F", "S", "S"}},
+ {Locale.GERMANY, new String[]{"M", "D", "M", "D", "F", "S", "S"}},
+ {Locale.FRANCE, new String[]{"L", "M", "M", "J", "V", "S", "D"}},
+ {new Locale("no", "NO"), new String[]{"M", "T", "O", "T", "F", "L", "S"}},};
+ }
+
+ //-----------------------------------------------------------------------
+ // Check Narrow and Narrow_standalone Day name values
+ //-----------------------------------------------------------------------
+ @Test(dataProvider = "DayNarrows")
+ public void compareDayNarrowValues(Locale locale, String[] dayNarrowExpected) {
+ TEXTSTYLELIST.forEach((style) -> {
+ DAYVALUES.forEach((value) -> {
+ String result = value.getDisplayName(style, locale);
+ int index = value.ordinal();
+ assertEquals(result, dayNarrowExpected[index], "Test failed"
+ + " for COMPAT Provider for locale "
+ + locale + " for style " + style.name()
+ + " with Day value " + value.name());
+ });
+ });
+ }
+}
--- a/jdk/test/javax/crypto/SecretKeyFactory/FailOverTest.sh Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/javax/crypto/SecretKeyFactory/FailOverTest.sh Wed Oct 26 20:13:29 2016 +0000
@@ -88,6 +88,7 @@
${TESTJAVA}${FS}bin${FS}java \
${TESTVMOPTS} \
+ -Djava.security.properties=${TESTSRC}${FS}security.properties \
-classpath "${TESTSRC}${FS}P1.jar${PS}${TESTSRC}${FS}P2.jar${PS}." \
FailOverTest
result=$?
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/crypto/SecretKeyFactory/security.properties Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,6 @@
+# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+# ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+
+jdk.security.provider.preferred=
+jdk.jar.disabledAlgorithms=
+
--- a/jdk/test/javax/net/ssl/templates/SSLTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/javax/net/ssl/templates/SSLTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -94,12 +94,22 @@
/*
* Is the server ready to serve?
*/
- private final CountDownLatch serverCondition = new CountDownLatch(1);
+ private final CountDownLatch serverReadyCondition = new CountDownLatch(1);
/*
* Is the client ready to handshake?
*/
- private final CountDownLatch clientCondition = new CountDownLatch(1);
+ private final CountDownLatch clientReadyCondition = new CountDownLatch(1);
+
+ /*
+ * Is the server done?
+ */
+ private final CountDownLatch serverDoneCondition = new CountDownLatch(1);
+
+ /*
+ * Is the client done?
+ */
+ private final CountDownLatch clientDoneCondition = new CountDownLatch(1);
/*
* Public API.
@@ -162,6 +172,25 @@
return keystore;
}
+ // Try to accept a connection in 30 seconds.
+ public static SSLSocket accept(SSLServerSocket sslServerSocket)
+ throws IOException {
+
+ return accept(sslServerSocket, SERVER_TIMEOUT);
+ }
+
+ public static SSLSocket accept(SSLServerSocket sslServerSocket, int timeout)
+ throws IOException {
+
+ try {
+ sslServerSocket.setSoTimeout(timeout);
+ return (SSLSocket) sslServerSocket.accept();
+ } catch (SocketTimeoutException ste) {
+ sslServerSocket.close();
+ return null;
+ }
+ }
+
public SSLTest setSeparateServerThread(boolean separateServerThread) {
this.separateServerThread = separateServerThread;
return this;
@@ -202,33 +231,61 @@
}
public void signalServerReady() {
- serverCondition.countDown();
+ serverReadyCondition.countDown();
+ }
+
+ public void signalServerDone() {
+ serverDoneCondition.countDown();
}
public boolean waitForClientSignal(long timeout, TimeUnit unit)
throws InterruptedException {
- return clientCondition.await(timeout, unit);
+ return clientReadyCondition.await(timeout, unit);
}
public boolean waitForClientSignal() throws InterruptedException {
return waitForClientSignal(CLIENT_SIGNAL_TIMEOUT, TimeUnit.SECONDS);
}
+ public boolean waitForClientDone(long timeout, TimeUnit unit)
+ throws InterruptedException {
+
+ return clientDoneCondition.await(timeout, unit);
+ }
+
+ public boolean waitForClientDone() throws InterruptedException {
+ return waitForClientDone(CLIENT_SIGNAL_TIMEOUT, TimeUnit.SECONDS);
+ }
+
public void signalClientReady() {
- clientCondition.countDown();
+ clientReadyCondition.countDown();
+ }
+
+ public void signalClientDone() {
+ clientDoneCondition.countDown();
}
public boolean waitForServerSignal(long timeout, TimeUnit unit)
throws InterruptedException {
- return serverCondition.await(timeout, unit);
+ return serverReadyCondition.await(timeout, unit);
}
public boolean waitForServerSignal() throws InterruptedException {
return waitForServerSignal(SERVER_SIGNAL_TIMEOUT, TimeUnit.SECONDS);
}
+ public boolean waitForServerDone(long timeout, TimeUnit unit)
+ throws InterruptedException {
+
+ return serverDoneCondition.await(timeout, unit);
+ }
+
+ public boolean waitForServerDone() throws InterruptedException {
+ return waitForServerDone(SERVER_SIGNAL_TIMEOUT, TimeUnit.SECONDS);
+ }
+
public SSLTest setServerPeer(Peer serverPeer) {
this.serverPeer = serverPeer;
return this;
@@ -310,19 +367,14 @@
test.signalServerReady();
// Try to accept a connection in 30 seconds.
- SSLSocket sslSocket;
- try {
- sslServerSocket.setSoTimeout(SERVER_TIMEOUT);
- sslSocket = (SSLSocket) sslServerSocket.accept();
- print("Server accepted connection");
- } catch (SocketTimeoutException ste) {
- sslServerSocket.close();
-
+ SSLSocket sslSocket = accept(sslServerSocket);
+ if (sslSocket == null) {
// Ignore the test case if no connection within 30 seconds.
print("No incoming client connection in 30 seconds. "
- + "Ignore in server side.", ste);
+ + "Ignore in server side.");
return;
}
+ print("Server accepted connection");
// handle the connection
try {
@@ -353,6 +405,8 @@
sslSocket.close();
sslServerSocket.close();
}
+
+ test.signalServerDone();
}
/*
@@ -419,6 +473,8 @@
print("Run client application");
test.getClientApplication().run(sslSocket, test);
}
+
+ test.signalClientDone();
}
/*
--- a/jdk/test/javax/script/DummyScriptEngineFactory.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/javax/script/DummyScriptEngineFactory.java Wed Oct 26 20:13:29 2016 +0000
@@ -91,9 +91,10 @@
}
public String getProgram(String... statements) {
+ Objects.requireNonNull(statements);
StringBuffer buf = new StringBuffer();
- for (int i = 0; i < statements.length; i++) {
- buf.append(statements[i]);
+ for (String stat : statements) {
+ buf.append(Objects.requireNonNull(stat));
}
return buf.toString();
}
--- a/jdk/test/jdk/internal/util/jar/TestVersionedStream.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/jdk/internal/util/jar/TestVersionedStream.java Wed Oct 26 20:13:29 2016 +0000
@@ -25,13 +25,14 @@
* @test
* @bug 8163798
* @summary basic tests for multi-release jar versioned streams
+ * @library /lib/testlibrary
* @modules jdk.jartool/sun.tools.jar java.base/jdk.internal.util.jar
+ * @build jdk.testlibrary.FileUtils
* @run testng TestVersionedStream
*/
import org.testng.Assert;
import org.testng.annotations.AfterClass;
-import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
@@ -40,29 +41,31 @@
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.net.URI;
-import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
-import java.nio.file.SimpleFileVisitor;
-import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.zip.ZipFile;
-public class TestVersionedStream {
- private String userdir;
+import jdk.testlibrary.FileUtils;
- @BeforeClass
- public void initialize() {
- userdir = System.getProperty("user.dir", ".");
+public class TestVersionedStream {
+ private final Path userdir;
+ private final Set<String> unversionedEntryNames;
+
+ public TestVersionedStream() throws IOException {
+ userdir = Paths.get(System.getProperty("user.dir", "."));
// These are not real class files even though they end with .class.
// They are resource files so jar tool validation won't reject them.
@@ -70,91 +73,103 @@
// could be in a concealed package if this was a modular multi-release
// jar.
createFiles(
+ "base/p/Bar.class",
"base/p/Foo.class",
"base/p/Main.class",
"v9/p/Foo.class",
"v10/p/Foo.class",
"v10/q/Bar.class",
+ "v11/p/Bar.class",
"v11/p/Foo.class"
);
- jar("cf mmr.jar -C base . --release 9 -C v9 . --release 10 -C v10 . --release 11 -C v11 .");
+ jar("cf mmr.jar -C base . --release 9 -C v9 . " +
+ "--release 10 -C v10 . --release 11 -C v11 .");
System.out.println("Contents of mmr.jar\n=======");
- jar("tf mmr.jar");
+
+ try(JarFile jf = new JarFile("mmr.jar")) {
+ unversionedEntryNames = jf.stream()
+ .map(je -> je.getName())
+ .peek(System.out::println)
+ .map(nm -> nm.startsWith("META-INF/versions/")
+ ? nm.replaceFirst("META-INF/versions/\\d+/", "")
+ : nm)
+ .collect(Collectors.toCollection(LinkedHashSet::new));
+ }
+
System.out.println("=======");
}
@AfterClass
public void close() throws IOException {
- Path root = Paths.get(userdir);
- Files.walkFileTree(root, new SimpleFileVisitor<>() {
- @Override
- public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
- Files.delete(file);
- return FileVisitResult.CONTINUE;
- }
-
- @Override
- public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
- if (!dir.equals(root)) {
- Files.delete(dir);
- }
- return FileVisitResult.CONTINUE;
- }
- });
+ Files.walk(userdir, 1)
+ .filter(p -> !p.equals(userdir))
+ .forEach(p -> {
+ try {
+ if (Files.isDirectory(p)) {
+ FileUtils.deleteFileTreeWithRetry(p);
+ } else {
+ FileUtils.deleteFileIfExistsWithRetry(p);
+ }
+ } catch (IOException x) {
+ throw new UncheckedIOException(x);
+ }
+ });
}
@DataProvider
public Object[][] data() {
- List<String> p = List.of(
- "META-INF/",
- "META-INF/MANIFEST.MF",
- "p/",
- "p/Foo.class",
- "p/Main.class"
- );
- List<String> q = List.of(
- "META-INF/",
- "META-INF/MANIFEST.MF",
- "p/",
- "p/Foo.class",
- "p/Main.class",
- "q/",
- "q/Bar.class"
- );
- Runtime.Version rt = JarFile.runtimeVersion();
return new Object[][] {
- {Runtime.Version.parse("8"), p},
- {Runtime.Version.parse("9"), p},
- {Runtime.Version.parse("10"), q},
- {Runtime.Version.parse("11"), q},
- {JarFile.baseVersion(), p},
- {rt, rt.major() > 9 ? q : p}
+ {Runtime.Version.parse("8")},
+ {Runtime.Version.parse("9")},
+ {Runtime.Version.parse("10")},
+ {Runtime.Version.parse("11")},
+ {JarFile.baseVersion()},
+ {JarFile.runtimeVersion()}
};
}
@Test(dataProvider="data")
- public void test(Runtime.Version version, List<String> names) throws Exception {
+ public void test(Runtime.Version version) throws Exception {
try (JarFile jf = new JarFile(new File("mmr.jar"), false, ZipFile.OPEN_READ, version);
- Stream<JarEntry> jes = jdk.internal.util.jar.VersionedStream.stream(jf))
+ Stream<JarEntry> jes = jdk.internal.util.jar.VersionedStream.stream(jf))
{
Assert.assertNotNull(jes);
- List<JarEntry> entries = jes.collect(Collectors.toList());
+ // put versioned entries in list so we can reuse them
+ List<JarEntry> versionedEntries = jes.collect(Collectors.toList());
+
+ Assert.assertTrue(versionedEntries.size() > 0);
+
+ // also keep the names
+ List<String> versionedNames = new ArrayList<>(versionedEntries.size());
+
+ // verify the correct order while building enames
+ Iterator<String> allIt = unversionedEntryNames.iterator();
+ Iterator<JarEntry> verIt = versionedEntries.iterator();
+ boolean match = false;
- // verify the correct order
- List<String> enames = entries.stream()
- .map(je -> je.getName())
- .collect(Collectors.toList());
- Assert.assertEquals(enames, names);
+ while (verIt.hasNext()) {
+ match = false;
+ if (!allIt.hasNext()) break;
+ String name = verIt.next().getName();
+ versionedNames.add(name);
+ while (allIt.hasNext()) {
+ if (name.equals(allIt.next())) {
+ match = true;
+ break;
+ }
+ }
+ }
+ if (!match) {
+ Assert.fail("versioned entries not in same order as unversioned entries");
+ }
// verify the contents
Map<String,String> contents = new HashMap<>();
+ contents.put("p/Bar.class", "base/p/Bar.class\n");
contents.put("p/Main.class", "base/p/Main.class\n");
- if (version.major() > 9) {
- contents.put("q/Bar.class", "v10/q/Bar.class\n");
- }
switch (version.major()) {
case 8:
contents.put("p/Foo.class", "base/p/Foo.class\n");
@@ -164,9 +179,12 @@
break;
case 10:
contents.put("p/Foo.class", "v10/p/Foo.class\n");
+ contents.put("q/Bar.class", "v10/q/Bar.class\n");
break;
case 11:
+ contents.put("p/Bar.class", "v11/p/Bar.class\n");
contents.put("p/Foo.class", "v11/p/Foo.class\n");
+ contents.put("q/Bar.class", "v10/q/Bar.class\n");
break;
default:
Assert.fail("Test out of date, please add more cases");
@@ -174,9 +192,9 @@
contents.entrySet().stream().forEach(e -> {
String name = e.getKey();
- int i = enames.indexOf(name);
+ int i = versionedNames.indexOf(name);
Assert.assertTrue(i != -1, name + " not in enames");
- JarEntry je = entries.get(i);
+ JarEntry je = versionedEntries.get(i);
try (InputStream is = jf.getInputStream(je)) {
String s = new String(is.readAllBytes());
Assert.assertTrue(s.endsWith(e.getValue()), s);
@@ -210,5 +228,4 @@
new sun.tools.jar.Main(System.out, System.err, "jar")
.run(args.split(" +"));
}
-
}
--- a/jdk/test/lib/testlibrary/jdk/testlibrary/JarUtils.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/JarUtils.java Wed Oct 26 20:13:29 2016 +0000
@@ -24,6 +24,7 @@
package jdk.testlibrary;
import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
@@ -40,7 +41,8 @@
public final class JarUtils {
/**
- * Create jar file with specified files.
+ * Create jar file with specified files. If a specified file does not exist,
+ * a new jar entry will be created with the file name itself as the content.
*/
public static void createJar(String dest, String... files)
throws IOException {
@@ -54,6 +56,8 @@
jos.putNextEntry(new JarEntry(file));
try (FileInputStream fis = new FileInputStream(file)) {
fis.transferTo(jos);
+ } catch (FileNotFoundException e) {
+ jos.write(file.getBytes());
}
}
}
@@ -61,7 +65,17 @@
}
/**
- * Add specified files to existing jar file.
+ * Add or remove specified files to existing jar file. If a specified file
+ * to be updated or added does not exist, the jar entry will be created
+ * with the file name itself as the content.
+ *
+ * @param src the original jar file name
+ * @param dest the new jar file name
+ * @param files the files to update. The list is broken into 2 groups
+ * by a "-" string. The files before in the 1st group will
+ * be either updated or added. The files in the 2nd group
+ * will be removed. If no "-" exists, all files belong to
+ * the 1st group.
*/
public static void updateJar(String src, String dest, String... files)
throws IOException {
@@ -77,8 +91,11 @@
JarEntry entry = entries.nextElement();
String name = entry.getName();
boolean found = false;
+ boolean update = true;
for (String file : files) {
- if (name.equals(file)) {
+ if (file.equals("-")) {
+ update = false;
+ } else if (name.equals(file)) {
updatedFiles.add(file);
found = true;
break;
@@ -86,11 +103,18 @@
}
if (found) {
- System.out.println(String.format("Updating %s with %s",
- dest, name));
- jos.putNextEntry(new JarEntry(name));
- try (FileInputStream fis = new FileInputStream(name)) {
- fis.transferTo(jos);
+ if (update) {
+ System.out.println(String.format("Updating %s with %s",
+ dest, name));
+ jos.putNextEntry(new JarEntry(name));
+ try (FileInputStream fis = new FileInputStream(name)) {
+ fis.transferTo(jos);
+ } catch (FileNotFoundException e) {
+ jos.write(name.getBytes());
+ }
+ } else {
+ System.out.println(String.format("Removing %s from %s",
+ name, dest));
}
} else {
System.out.println(String.format("Copying %s to %s",
@@ -103,12 +127,17 @@
// append new files
for (String file : files) {
+ if (file.equals("-")) {
+ break;
+ }
if (!updatedFiles.contains(file)) {
System.out.println(String.format("Adding %s with %s",
dest, file));
jos.putNextEntry(new JarEntry(file));
try (FileInputStream fis = new FileInputStream(file)) {
fis.transferTo(jos);
+ } catch (FileNotFoundException e) {
+ jos.write(file.getBytes());
}
}
}
--- a/jdk/test/sun/net/www/protocol/https/HttpsClient/OriginServer.java Wed Oct 26 15:46:13 2016 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,148 +0,0 @@
-/*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- *
- * This is a HTTP test server used by the regression test
- * for the bug fixes: 4323990, 4413069
- */
-
-import java.io.*;
-import java.net.*;
-import javax.net.*;
-
-/*
- * OriginServer.java -- a simple server that can serve
- * Http get request in both clear and secure channel
- */
-
-public abstract class OriginServer implements Runnable {
-
- private ServerSocket server = null;
- Exception serverException = null;
- /**
- * Constructs a OriginServer based on ss and
- * obtains a response data's bytecodes using the method
- * getBytes.
- */
- protected OriginServer(ServerSocket ss) throws Exception
- {
- server = ss;
- newListener();
- if (serverException != null)
- throw serverException;
- }
-
- /**
- * Returns an array of bytes containing the bytes for
- * the data sent in the response.
- *
- * @return the bytes for the information that is being sent
- */
- public abstract byte[] getBytes();
-
- /**
- * The "listen" thread that accepts a connection to the
- * server, parses the header and sends back the response
- */
- public void run()
- {
- Socket socket;
-
- // accept a connection
- try {
- socket = server.accept();
- } catch (IOException e) {
- System.out.println("Class Server died: " + e.getMessage());
- serverException = e;
- return;
- }
- try {
- DataOutputStream out =
- new DataOutputStream(socket.getOutputStream());
- try {
- BufferedReader in =
- new BufferedReader(new InputStreamReader(
- socket.getInputStream()));
- // read the request
- readRequest(in);
- // retrieve bytecodes
- byte[] bytecodes = getBytes();
- // send bytecodes in response (assumes HTTP/1.0 or later)
- try {
- out.writeBytes("HTTP/1.0 200 OK\r\n");
- out.writeBytes("Content-Length: " + bytecodes.length +
- "\r\n");
- out.writeBytes("Content-Type: text/html\r\n\r\n");
- out.write(bytecodes);
- out.flush();
- } catch (IOException ie) {
- serverException = ie;
- return;
- }
-
- } catch (Exception e) {
- // write out error response
- out.writeBytes("HTTP/1.0 400 " + e.getMessage() + "\r\n");
- out.writeBytes("Content-Type: text/html\r\n\r\n");
- out.flush();
- }
-
- } catch (IOException ex) {
- System.out.println("error writing response: " + ex.getMessage());
- serverException = ex;
-
- } finally {
- try {
- socket.close();
- } catch (IOException e) {
- serverException = e;
- }
- }
- }
-
- /**
- * Create a new thread to listen.
- */
- private void newListener()
- {
- (new Thread(this)).start();
- }
-
- /**
- * read the response, don't care for the syntax of the request-line
- * for this testing
- */
- private static void readRequest(BufferedReader in)
- throws IOException
- {
- String line = null;
- System.out.println("Server received: ");
- do {
- if (line != null)
- System.out.println(line);
- line = in.readLine();
- } while ((line.length() != 0) &&
- (line.charAt(0) != '\r') && (line.charAt(0) != '\n'));
- }
-}
--- a/jdk/test/sun/net/www/protocol/https/HttpsClient/ProxyAuthTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/sun/net/www/protocol/https/HttpsClient/ProxyAuthTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -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
@@ -23,22 +23,38 @@
/*
* @test
- * @bug 4323990 4413069
+ * @bug 4323990 4413069 8160838
* @summary HttpsURLConnection doesn't send Proxy-Authorization on CONNECT
* Incorrect checking of proxy server response
* @modules java.base/sun.net.www
- * @run main/othervm ProxyAuthTest
- *
- * No way to reserve and restore java.lang.Authenticator, need to run this
- * test in othervm mode.
+ * @library /javax/net/ssl/templates
+ * @run main/othervm ProxyAuthTest fail
+ * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=Basic ProxyAuthTest fail
+ * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=Basic, ProxyAuthTest fail
+ * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=BAsIc ProxyAuthTest fail
+ * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=Basic,Digest ProxyAuthTest fail
+ * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=Unknown,bAsIc ProxyAuthTest fail
+ * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes= ProxyAuthTest succeed
+ * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=Digest,NTLM,Negotiate ProxyAuthTest succeed
+ * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=UNKNOWN,notKnown ProxyAuthTest succeed
*/
-import java.io.*;
-import java.net.*;
-import java.security.KeyStore;
-import javax.net.*;
-import javax.net.ssl.*;
-import java.security.cert.*;
+// No way to reserve and restore java.lang.Authenticator, as well as read-once
+// system properties, so this tests needs to run in othervm mode.
+
+import java.io.BufferedReader;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.Authenticator;
+import java.net.InetSocketAddress;
+import java.net.PasswordAuthentication;
+import java.net.Proxy;
+import java.net.URL;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLSession;
+import static java.nio.charset.StandardCharsets.US_ASCII;
/*
* ProxyAuthTest.java -- includes a simple server that can serve
@@ -56,132 +72,167 @@
static String trustStoreFile = "truststore";
static String passwd = "passphrase";
- volatile private static int serverPort = 0;
-
- /*
- * The TestServer implements a OriginServer that
- * processes HTTP requests and responses.
+ /**
+ * read the response, don't care for the syntax of the request-line
+ * for this testing
*/
- static class TestServer extends OriginServer {
- public TestServer(ServerSocket ss) throws Exception {
- super(ss);
- }
-
- /*
- * Returns an array of bytes containing the bytes for
- * the data sent in the response.
- *
- * @return bytes for the data in the response
- */
- public byte[] getBytes() {
- return "Proxy authentication for tunneling succeeded ..".
- getBytes();
- }
+ private static void readRequest(BufferedReader in) throws IOException {
+ String line = null;
+ System.out.println("Server received: ");
+ do {
+ if (line != null) {
+ System.out.println(line);
+ }
+ line = in.readLine();
+ } while ((line.length() != 0) &&
+ (line.charAt(0) != '\r') && (line.charAt(0) != '\n'));
}
/*
* Main method to create the server and the client
*/
public static void main(String args[]) throws Exception {
+ boolean expectSuccess;
+ expectSuccess = args[0].equals("succeed");
+
String keyFilename =
- System.getProperty("test.src", "./") + "/" + pathToStores +
- "/" + keyStoreFile;
+ SSLTest.TEST_SRC + "/" + pathToStores + "/" + keyStoreFile;
String trustFilename =
- System.getProperty("test.src", "./") + "/" + pathToStores +
- "/" + trustStoreFile;
+ SSLTest.TEST_SRC + "/" + pathToStores + "/" + trustStoreFile;
+
+ SSLTest.setup(keyFilename, trustFilename, passwd);
+
+ new SSLTest()
+ .setServerApplication((socket, test) -> {
+ DataOutputStream out = new DataOutputStream(
+ socket.getOutputStream());
- System.setProperty("javax.net.ssl.keyStore", keyFilename);
- System.setProperty("javax.net.ssl.keyStorePassword", passwd);
- System.setProperty("javax.net.ssl.trustStore", trustFilename);
- System.setProperty("javax.net.ssl.trustStorePassword", passwd);
+ try {
+ BufferedReader in = new BufferedReader(
+ new InputStreamReader(socket.getInputStream()));
+
+ // read the request
+ readRequest(in);
+
+ // retrieve bytecodes
+ byte[] bytecodes =
+ "Proxy authentication for tunneling succeeded .."
+ .getBytes(US_ASCII);
- boolean useSSL = true;
- /*
- * setup the server
- */
- try {
- ServerSocketFactory ssf =
- ProxyAuthTest.getServerSocketFactory(useSSL);
- ServerSocket ss = ssf.createServerSocket(serverPort);
- serverPort = ss.getLocalPort();
- new TestServer(ss);
- } catch (Exception e) {
- System.out.println("Server side failed:" +
- e.getMessage());
- throw e;
- }
- // trigger the client
- try {
- doClientSide();
- } catch (Exception e) {
- System.out.println("Client side failed: " + e.getMessage());
- throw e;
- }
+ // send bytecodes in response (assumes HTTP/1.0 or later)
+ out.writeBytes("HTTP/1.0 200 OK\r\n");
+ out.writeBytes("Content-Length: " + bytecodes.length +
+ "\r\n");
+ out.writeBytes("Content-Type: text/html\r\n\r\n");
+ out.write(bytecodes);
+ out.flush();
+ } catch (IOException e) {
+ // write out error response
+ out.writeBytes("HTTP/1.0 400 " + e.getMessage() + "\r\n");
+ out.writeBytes("Content-Type: text/html\r\n\r\n");
+ out.flush();
+ }
+ })
+ .setClientPeer(test -> {
+ try {
+ doClientSide(test);
+ if (!expectSuccess) {
+ throw new RuntimeException("Expected exception/failure "
+ + "to connect, but succeeded.");
+ }
+ } catch (IOException e) {
+ if (expectSuccess) {
+ System.out.println("Client side failed: "
+ + e.getMessage());
+ throw e;
+ }
+
+ if (! (e.getMessage().contains(
+ "Unable to tunnel through proxy") &&
+ e.getMessage().contains("407")) ) {
+
+ throw new RuntimeException(
+ "Expected exception about cannot tunnel, "
+ + "407, etc, but got", e);
+ } else {
+ // Informative
+ System.out.println("Caught expected exception: "
+ + e.getMessage());
+ }
+ }
+ })
+ .runTest();
}
- private static ServerSocketFactory getServerSocketFactory
- (boolean useSSL) throws Exception {
- if (useSSL) {
- SSLServerSocketFactory ssf = null;
- // set up key manager to do server authentication
- SSLContext ctx;
- KeyManagerFactory kmf;
- KeyStore ks;
- char[] passphrase = passwd.toCharArray();
-
- ctx = SSLContext.getInstance("TLS");
- kmf = KeyManagerFactory.getInstance("SunX509");
- ks = KeyStore.getInstance("JKS");
+ static void doClientSide(SSLTest test) throws IOException {
- ks.load(new FileInputStream(System.getProperty(
- "javax.net.ssl.keyStore")), passphrase);
- kmf.init(ks, passphrase);
- ctx.init(kmf.getKeyManagers(), null, null);
+ // Wait for server to get started.
+ //
+ // The server side takes care of the issue if the server cannot
+ // get started in 90 seconds. The client side would just ignore
+ // the test case if the serer is not ready.
+ try {
+ if (!test.waitForServerSignal()) {
+ System.out.print("The server is not ready yet in 90 seconds. "
+ + "Ignore in client side.");
+ return;
+ }
+ } catch (InterruptedException e) {
+ System.out.print("InterruptedException occured. "
+ + "Ignore in client side.");
+ return;
+ }
- ssf = ctx.getServerSocketFactory();
- return ssf;
- } else {
- return ServerSocketFactory.getDefault();
- }
- }
-
- static void doClientSide() throws Exception {
/*
* setup up a proxy with authentication information
*/
- setupProxy();
+ ProxyTunnelServer ps = setupProxy();
/*
* we want to avoid URLspoofCheck failures in cases where the cert
* DN name does not match the hostname in the URL.
*/
- HttpsURLConnection.setDefaultHostnameVerifier(
- new NameVerifier());
- URL url = new URL("https://" + "localhost:" + serverPort
- + "/index.html");
- BufferedReader in = null;
- try {
- in = new BufferedReader(new InputStreamReader(
- url.openStream()));
+ HttpsURLConnection.setDefaultHostnameVerifier(new NameVerifier());
+
+ InetSocketAddress paddr = new InetSocketAddress(
+ "localhost", ps.getPort());
+ Proxy proxy = new Proxy(Proxy.Type.HTTP, paddr);
+
+ URL url = new URL("https://" + "localhost:" + test.getServerPort()
+ + "/index.html");
+
+ // Signal the server, the client is ready to communicate.
+ test.signalClientReady();
+
+ HttpsURLConnection uc = (HttpsURLConnection) url.openConnection(proxy);
+ try (BufferedReader in = new BufferedReader(
+ new InputStreamReader(uc.getInputStream()))) {
+
String inputLine;
System.out.print("Client recieved from the server: ");
- while ((inputLine = in.readLine()) != null)
+ while ((inputLine = in.readLine()) != null) {
System.out.println(inputLine);
- in.close();
- } catch (SSLException e) {
- if (in != null)
- in.close();
+ }
+ } catch (IOException e) {
+ // Assert that the error stream is not accessible from the failed
+ // tunnel setup.
+ if (uc.getErrorStream() != null) {
+ throw new RuntimeException("Unexpected error stream.");
+ }
+
throw e;
}
}
static class NameVerifier implements HostnameVerifier {
+
+ @Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
}
- static void setupProxy() throws IOException {
+ static ProxyTunnelServer setupProxy() throws IOException {
ProxyTunnelServer pserver = new ProxyTunnelServer();
/*
* register a system wide authenticator and setup the proxy for
@@ -194,16 +245,14 @@
pserver.setUserAuth("Test", "test123");
pserver.start();
- System.setProperty("https.proxyHost", "localhost");
- System.setProperty("https.proxyPort", String.valueOf(
- pserver.getPort()));
+ return pserver;
}
public static class TestAuthenticator extends Authenticator {
+ @Override
public PasswordAuthentication getPasswordAuthentication() {
- return new PasswordAuthentication("Test",
- "test123".toCharArray());
+ return new PasswordAuthentication("Test", "test123".toCharArray());
}
}
}
--- a/jdk/test/sun/net/www/protocol/https/HttpsClient/ProxyTunnelServer.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/sun/net/www/protocol/https/HttpsClient/ProxyTunnelServer.java Wed Oct 26 20:13:29 2016 +0000
@@ -65,6 +65,7 @@
ss = (ServerSocket) ServerSocketFactory.getDefault().
createServerSocket(0);
}
+ setDaemon(true);
}
public void needUserAuth(boolean auth) {
@@ -211,6 +212,7 @@
this.sockOut = sockOut;
input = sockIn.getInputStream();
output = sockOut.getOutputStream();
+ setDaemon(true);
}
public void run() {
--- a/jdk/test/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.sh Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.sh Wed Oct 26 20:13:29 2016 +0000
@@ -57,5 +57,6 @@
${TESTSRC}${FS}ProxyTunnelServer.java \
${TESTSRC}${FS}PostThruProxyWithAuth.java
${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} ${EXTRAOPTS} \
+ -Djdk.http.auth.tunneling.disabledSchemes= \
PostThruProxyWithAuth ${HOSTNAME} ${TESTSRC}
exit
--- a/jdk/test/sun/net/www/protocol/jar/B4957695.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/sun/net/www/protocol/jar/B4957695.java Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -24,6 +24,7 @@
/**
* @test
* @bug 4957695
+ * @run main/othervm -Djava.io.tmpdir=. B4957695
* @summary URLJarFile.retrieve does not delete tmpFile on IOException
*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/nio/cs/TestHKSCS.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,49 @@
+/*
+ * 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 8166258
+ * @summary Some corner cases for hkscs charsets
+ * @modules jdk.charsets
+ * @run main TestHKSCS
+ */
+
+import java.util.Arrays;
+
+public class TestHKSCS {
+ public static void main(String args[]) throws Exception {
+ String[] charsets = { "x-MS950-HKSCS-XP",
+ "x-MS950-HKSCS",
+ "Big5-HKSCS",
+ "x-Big5-HKSCS-2001"
+ };
+ String s = "\ufffd\ud87f\udffd";
+ byte[] bytes = new byte[] { 0x3f, 0x3f };
+ for (String cs : charsets) {
+ if (!Arrays.equals(bytes, s.getBytes(cs))) {
+ throw new RuntimeException(cs + " failed to decode u+fffd");
+ }
+ }
+ }
+}
--- a/jdk/test/sun/reflect/ReflectionFactory/NewConstructorForSerialization.java Wed Oct 26 15:46:13 2016 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +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.
- */
-
-/*
- * @test
- * @bug 8137058
- * @summary Basic test for the unsupported newConstructorForSerialization
- * @modules jdk.unsupported
- */
-
-import java.lang.reflect.Constructor;
-import sun.reflect.ReflectionFactory;
-
-public class NewConstructorForSerialization {
-
- private static Constructor<?> getConstructor(Class<?> type)
- throws NoSuchMethodException
- {
- ReflectionFactory factory = ReflectionFactory.getReflectionFactory();
- Constructor<?> objectConstructor = type.getConstructor((Class[]) null);
-
- @SuppressWarnings("unchecked")
- Constructor<?> c = (Constructor<?>) factory
- .newConstructorForSerialization(type, objectConstructor);
- return c;
- }
-
- public static void main(String[] args) throws Exception {
- System.out.println(getConstructor(Object.class).newInstance());
- System.out.println(getConstructor(Foo.class).newInstance());
- System.out.println(getConstructor(Bar.class).newInstance());
- }
-
- static class Foo {
- public Foo() { }
- }
-
- static class Bar extends Foo {
- public Bar() { }
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/reflect/ReflectionFactory/ReflectionFactoryTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,289 @@
+/*
+ * 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.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutput;
+import java.io.ObjectOutputStream;
+import java.io.OptionalDataException;
+import java.io.Serializable;
+import java.lang.invoke.MethodHandle;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+import sun.reflect.ReflectionFactory;
+
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+import org.testng.annotations.DataProvider;
+import org.testng.TestNG;
+
+/*
+ * @test
+ * @bug 8137058 8164908
+ * @run testng ReflectionFactoryTest
+ * @run testng/othervm/policy=security.policy ReflectionFactoryTest
+ * @summary Basic test for the unsupported ReflectionFactory
+ * @modules jdk.unsupported
+ */
+
+public class ReflectionFactoryTest {
+
+ // Initialized by init()
+ static ReflectionFactory factory;
+
+ @DataProvider(name = "ClassConstructors")
+ static Object[][] classConstructors() {
+ return new Object[][] {
+ {Object.class},
+ {Foo.class},
+ {Bar.class},
+ };
+ }
+
+ @BeforeClass
+ static void init() {
+ factory = ReflectionFactory.getReflectionFactory();
+ }
+
+ /**
+ * Test that the correct Constructor is selected and run.
+ * @param type type of object to create
+ * @throws NoSuchMethodException - error
+ * @throws InstantiationException - error
+ * @throws IllegalAccessException - error
+ * @throws InvocationTargetException - error
+ */
+ @Test(dataProvider="ClassConstructors")
+ static void testConstructor(Class<?> type)
+ throws NoSuchMethodException, InstantiationException,
+ IllegalAccessException, InvocationTargetException
+ {
+ @SuppressWarnings("unchecked")
+ Constructor<?> c = factory.newConstructorForSerialization(type);
+
+ Object o = c.newInstance();
+ Assert.assertEquals(o.getClass(), type, "Instance is wrong type");
+ if (o instanceof Foo) {
+ Foo foo = (Foo)o;
+ foo.check();
+ }
+ }
+
+ static class Foo {
+ private int foo;
+ public Foo() {
+ this.foo = 1;
+ }
+
+ public String toString() {
+ return "foo: " + foo;
+ }
+
+ public void check() {
+ int expectedFoo = 1;
+ Assert.assertEquals(foo, expectedFoo, "foo() constructor not run");
+ }
+ }
+
+ static class Bar extends Foo implements Serializable {
+ private int bar;
+ public Bar() {
+ this.bar = 1;
+ }
+
+ public String toString() {
+ return super.toString() + ", bar: " + bar;
+ }
+
+ public void check() {
+ super.check();
+ int expectedBar = 0;
+ Assert.assertEquals(bar, expectedBar, "bar() constructor not run");
+ }
+ }
+
+ /**
+ * Test newConstructorForExternalization returns the constructor and it can be called.
+ * @throws NoSuchMethodException - error
+ * @throws InstantiationException - error
+ * @throws IllegalAccessException - error
+ * @throws InvocationTargetException - error
+ */
+ @Test
+ static void newConstructorForExternalization()
+ throws NoSuchMethodException, InstantiationException,
+ IllegalAccessException, InvocationTargetException {
+ Constructor<?> cons = factory.newConstructorForExternalization(Ext.class);
+ Ext ext = (Ext)cons.newInstance();
+ Assert.assertEquals(ext.ext, 1, "Constructor not run");
+ }
+
+ static class Ext implements Externalizable {
+ private static final long serialVersionUID = 1L;
+
+ int ext;
+
+ public Ext() {
+ ext = 1;
+ }
+
+ @Override
+ public void writeExternal(ObjectOutput out) throws IOException {}
+
+ @Override
+ public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {}
+ }
+
+ @Test
+ static void testReadWriteObjectForSerialization() throws Throwable {
+ MethodHandle readObjectMethod = factory.readObjectForSerialization(Ser.class);
+ Assert.assertNotNull(readObjectMethod, "readObjectMethod not found");
+
+ MethodHandle readObjectNoDataMethod = factory.readObjectNoDataForSerialization(Ser.class);
+ Assert.assertNotNull(readObjectNoDataMethod, "readObjectNoDataMethod not found");
+
+ MethodHandle writeObjectMethod = factory.writeObjectForSerialization(Ser.class);
+ Assert.assertNotNull(writeObjectMethod, "writeObjectMethod not found");
+
+ MethodHandle readResolveMethod = factory.readResolveForSerialization(Ser.class);
+ Assert.assertNotNull(readResolveMethod, "readResolveMethod not found");
+
+ MethodHandle writeReplaceMethod = factory.writeReplaceForSerialization(Ser.class);
+ Assert.assertNotNull(writeReplaceMethod, "writeReplaceMethod not found");
+
+ byte[] data = null;
+ try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(baos)) {
+ Ser ser = new Ser();
+
+ writeReplaceMethod.invoke(ser);
+ Assert.assertTrue(ser.writeReplaceCalled, "writeReplace not called");
+ Assert.assertFalse(ser.writeObjectCalled, "writeObject should not have been called");
+
+ writeObjectMethod.invoke(ser, oos);
+ Assert.assertTrue(ser.writeReplaceCalled, "writeReplace should have been called");
+ Assert.assertTrue(ser.writeObjectCalled, "writeObject not called");
+ oos.flush();
+ data = baos.toByteArray();
+ }
+
+ try (ByteArrayInputStream bais = new ByteArrayInputStream(data);
+ ObjectInputStream ois = new ObjectInputStream(bais)) {
+ Ser ser2 = new Ser();
+
+ readObjectMethod.invoke(ser2, ois);
+ Assert.assertTrue(ser2.readObjectCalled, "readObject not called");
+ Assert.assertFalse(ser2.readObjectNoDataCalled, "readObjectNoData should not be called");
+ Assert.assertFalse(ser2.readResolveCalled, "readResolve should not be called");
+
+ readObjectNoDataMethod.invoke(ser2, ois);
+ Assert.assertTrue(ser2.readObjectCalled, "readObject should have been called");
+ Assert.assertTrue(ser2.readObjectNoDataCalled, "readObjectNoData not called");
+ Assert.assertFalse(ser2.readResolveCalled, "readResolve should not be called");
+
+ readResolveMethod.invoke(ser2);
+ Assert.assertTrue(ser2.readObjectCalled, "readObject should have been called");
+ Assert.assertTrue(ser2.readObjectNoDataCalled, "readObjectNoData not called");
+ Assert.assertTrue(ser2.readResolveCalled, "readResolve not called");
+ }
+ }
+
+ @Test
+ static void hasStaticInitializer() {
+ boolean actual = factory.hasStaticInitializerForSerialization(Ser.class);
+ Assert.assertTrue(actual, "hasStaticInitializerForSerialization is wrong");
+ }
+
+ static class Ser implements Serializable {
+ private static final long serialVersionUID = 2L;
+ static {
+ // Define a static class initialization method
+ }
+
+ boolean readObjectCalled = false;
+ boolean readObjectNoDataCalled = false;
+ boolean writeObjectCalled = false;
+ boolean readResolveCalled = false;
+ boolean writeReplaceCalled = false;
+
+ public Ser() {}
+
+ private void readObject(ObjectInputStream ois) throws IOException {
+ Assert.assertFalse(writeObjectCalled, "readObject called too many times");
+ readObjectCalled = ois.readBoolean();
+ }
+
+ private void readObjectNoData(ObjectInputStream ois) throws IOException {
+ Assert.assertFalse(readObjectNoDataCalled, "readObjectNoData called too many times");
+ readObjectNoDataCalled = true;
+ }
+
+ private void writeObject(ObjectOutputStream oos) throws IOException {
+ Assert.assertFalse(writeObjectCalled, "writeObject called too many times");
+ writeObjectCalled = true;
+ oos.writeBoolean(writeObjectCalled);
+ }
+
+ private Object writeReplace() {
+ Assert.assertFalse(writeReplaceCalled, "writeReplace called too many times");
+ writeReplaceCalled = true;
+ return this;
+ }
+
+ private Object readResolve() {
+ Assert.assertFalse(readResolveCalled, "readResolve called too many times");
+ readResolveCalled = true;
+ return this;
+ }
+ }
+
+ /**
+ * Test the constructor of OptionalDataExceptions.
+ */
+ @Test
+ static void newOptionalDataException() {
+ OptionalDataException ode = factory.newOptionalDataExceptionForSerialization(true);
+ Assert.assertTrue(ode.eof, "eof wrong");
+ ode = factory.newOptionalDataExceptionForSerialization(false);
+ Assert.assertFalse(ode.eof, "eof wrong");
+
+ }
+
+
+
+ // Main can be used to run the tests from the command line with only testng.jar.
+ @SuppressWarnings("raw_types")
+ @Test(enabled = false)
+ public static void main(String[] args) {
+ Class<?>[] testclass = {ReflectionFactoryTest.class};
+ TestNG testng = new TestNG();
+ testng.setTestClasses(testclass);
+ testng.run();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/reflect/ReflectionFactory/security.policy Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,11 @@
+// Individual Permissions for ReflectionFactoryTest
+grant {
+ // Permissions needed to run the test
+ permission java.util.PropertyPermission "*", "read";
+ permission java.io.FilePermission "<<ALL FILES>>", "read,write,delete,execute";
+
+ permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
+ permission java.lang.RuntimePermission "accessDeclaredMembers";
+ permission java.lang.RuntimePermission "accessClassInPackage.sun.reflect";
+ permission java.lang.RuntimePermission "reflectionFactoryAccess";
+};
--- a/jdk/test/sun/security/ec/TestEC.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/sun/security/ec/TestEC.java Wed Oct 26 20:13:29 2016 +0000
@@ -28,7 +28,7 @@
/**
* @test
- * @bug 6840752
+ * @bug 6840752 8168078
* @summary Provide out-of-the-box support for ECC algorithms
* @library ../pkcs11
* @library ../pkcs11/ec
@@ -37,6 +37,7 @@
* @modules jdk.crypto.pkcs11/sun.security.pkcs11.wrapper
* @compile -XDignore.symbol.file TestEC.java
* @run main/othervm -Djdk.tls.namedGroups="secp256r1,sect193r1" TestEC
+ * @run main/othervm/java.security.policy=TestEC.policy -Djdk.tls.namedGroups="secp256r1,sect193r1" TestEC
*/
import java.security.NoSuchProviderException;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/ec/TestEC.policy Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,3 @@
+grant codebase "file:${test.classes}/*" {
+ permission java.security.AllPermission;
+};
--- a/jdk/test/sun/security/pkcs/pkcs7/PKCS7VerifyTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/sun/security/pkcs/pkcs7/PKCS7VerifyTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -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
@@ -27,8 +27,8 @@
* @summary Read signed data in one or more PKCS7 objects from individual files,
* verify SignerInfos and certificate chain.
* @modules java.base/sun.security.pkcs
- * @run main PKCS7VerifyTest PKCS7TEST.DSA.base64
- * @run main PKCS7VerifyTest PKCS7TEST.DSA.base64 PKCS7TEST.SF
+ * @run main/othervm PKCS7VerifyTest PKCS7TEST.DSA.base64
+ * @run main/othervm PKCS7VerifyTest PKCS7TEST.DSA.base64 PKCS7TEST.SF
*/
import java.io.ByteArrayInputStream;
import java.io.File;
@@ -36,6 +36,7 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.security.Security;
import java.security.cert.X509Certificate;
import java.util.Base64;
import java.util.HashMap;
@@ -55,6 +56,8 @@
throw new RuntimeException("usage: java JarVerify <file1> <file2>");
}
+ Security.setProperty("jdk.jar.disabledAlgorithms", "");
+
// The command " java PKCS7VerifyTest file1 [file2] "
// treats file1 as containing the DER encoding of a PKCS7 signed data
// object. If file2 is absent, the program verifies that some signature
--- a/jdk/test/sun/security/pkcs11/PKCS11Test.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/sun/security/pkcs11/PKCS11Test.java Wed Oct 26 20:13:29 2016 +0000
@@ -47,6 +47,7 @@
import java.util.List;
import java.util.Map;
import java.util.Properties;
+import java.util.ServiceConfigurationError;
import java.util.ServiceLoader;
import java.util.Set;
@@ -112,7 +113,7 @@
found = true;
break;
}
- } catch (Exception e) {
+ } catch (Exception | ServiceConfigurationError e) {
// ignore and move on to the next one
}
}
@@ -299,11 +300,12 @@
+ props.getProperty("os.arch") + "-" + props.getProperty("sun.arch.data.model");
String[] nssLibDirs = osMap.get(osid);
if (nssLibDirs == null) {
- System.out.println("Unsupported OS, skipping: " + osid);
+ System.out.println("Warning: unsupported OS: " + osid
+ + ", please initialize NSS librarys location firstly, skipping test");
return null;
}
if (nssLibDirs.length == 0) {
- System.out.println("NSS not supported on this platform, skipping test");
+ System.out.println("Warning: NSS not supported on this platform, skipping test");
return null;
}
String nssLibDir = null;
@@ -315,6 +317,10 @@
break;
}
}
+ if (nssLibDir == null) {
+ System.out.println("Warning: can't find NSS librarys on this machine, skipping test");
+ return null;
+ }
return nssLibDir;
}
@@ -624,6 +630,11 @@
PKCS11_BASE + "/nss/lib/windows-amd64/".replace('/', SEP)});
osMap.put("MacOSX-x86_64-64", new String[]{
PKCS11_BASE + "/nss/lib/macosx-x86_64/"});
+ osMap.put("Linux-arm-32", new String[]{
+ "/usr/lib/arm-linux-gnueabi/nss/",
+ "/usr/lib/arm-linux-gnueabihf/nss/"});
+ osMap.put("Linux-aarch64-64", new String[]{
+ "/usr/lib/aarch64-linux-gnu/nss/"});
}
private final static char[] hexDigits = "0123456789abcdef".toCharArray();
--- a/jdk/test/sun/security/tools/jarsigner/JarSigningNonAscii.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/sun/security/tools/jarsigner/JarSigningNonAscii.java Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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,10 +26,12 @@
* @bug 4924188
* @summary sign a JAR file that has entry names with non-ASCII characters.
* @modules jdk.jartool/sun.security.tools.jarsigner
+ * @run main/othervm JarSigningNonAscii
*/
import sun.security.tools.*;
import java.io.*;
+import java.security.Security;
import java.util.*;
import java.util.jar.*;
import java.security.cert.Certificate;
@@ -40,6 +42,7 @@
private static String keystore;
public static void main(String[] args) throws Exception {
+ Security.setProperty("jdk.jar.disabledAlgorithms", "");
String srcDir = System.getProperty("test.src", ".");
String destDir = System.getProperty("test.classes", ".");
--- a/jdk/test/sun/security/tools/jarsigner/TimestampCheck.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/sun/security/tools/jarsigner/TimestampCheck.java Wed Oct 26 20:13:29 2016 +0000
@@ -22,25 +22,29 @@
*/
import com.sun.net.httpserver.*;
-import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
-import java.io.FileInputStream;
+import java.io.File;
import java.io.IOException;
import java.io.InputStream;
-import java.io.InputStreamReader;
import java.io.OutputStream;
import java.math.BigInteger;
import java.net.InetSocketAddress;
+import java.nio.file.Files;
+import java.nio.file.Paths;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Calendar;
+import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
-import java.util.Locale;
+import jdk.testlibrary.*;
+import jdk.testlibrary.JarUtils;
import sun.security.pkcs.ContentInfo;
import sun.security.pkcs.PKCS7;
import sun.security.pkcs.PKCS9Attribute;
@@ -52,11 +56,22 @@
import sun.security.x509.AlgorithmId;
import sun.security.x509.X500Name;
+/*
+ * @test
+ * @bug 6543842 6543440 6939248 8009636 8024302 8163304
+ * @summary checking response of timestamp
+ * @modules java.base/sun.security.pkcs
+ * java.base/sun.security.timestamp
+ * java.base/sun.security.x509
+ * java.base/sun.security.util
+ * java.base/sun.security.tools.keytool
+ * @library /lib/testlibrary
+ * @run main/timeout=600 TimestampCheck
+ */
public class TimestampCheck {
- static final String TSKS = "tsks";
- static final String JAR = "old.jar";
- static final String defaultPolicyId = "2.3.4.5";
+ static final String defaultPolicyId = "2.3.4";
+ static String host = null;
static class Handler implements HttpHandler, AutoCloseable {
@@ -75,11 +90,7 @@
t.getRequestBody().read(input);
try {
- int path = 0;
- if (t.getRequestURI().getPath().length() > 1) {
- path = Integer.parseInt(
- t.getRequestURI().getPath().substring(1));
- }
+ String path = t.getRequestURI().getPath().substring(1);
byte[] output = sign(input, path);
Headers out = t.getResponseHeaders();
out.set("Content-Type", "application/timestamp-reply");
@@ -97,24 +108,10 @@
/**
* @param input The data to sign
* @param path different cases to simulate, impl on URL path
- * 0: normal
- * 1: Missing nonce
- * 2: Different nonce
- * 3: Bad digets octets in messageImprint
- * 4: Different algorithmId in messageImprint
- * 5: whole chain in cert set
- * 6: extension is missing
- * 7: extension is non-critical
- * 8: extension does not have timestamping
- * 9: no cert in response
- * 10: normal
- * 11: always return default policy id
- * 12: normal
- * otherwise: normal
* @returns the signed
*/
- byte[] sign(byte[] input, int path) throws Exception {
- // Read TSRequest
+ byte[] sign(byte[] input, String path) throws Exception {
+
DerValue value = new DerValue(input);
System.err.println("\nIncoming Request\n===================");
System.err.println("Version: " + value.data.getInteger());
@@ -138,36 +135,33 @@
}
}
- // Write TSResponse
System.err.println("\nResponse\n===================");
- KeyStore ks = KeyStore.getInstance("JKS");
- try (FileInputStream fis = new FileInputStream(keystore)) {
- ks.load(fis, "changeit".toCharArray());
+ KeyStore ks = KeyStore.getInstance(
+ new File(keystore), "changeit".toCharArray());
+
+ String alias = "ts";
+ if (path.startsWith("bad") || path.equals("weak")) {
+ alias = "ts" + path;
}
- String alias = "ts";
- if (path == 6) alias = "tsbad1";
- if (path == 7) alias = "tsbad2";
- if (path == 8) alias = "tsbad3";
-
- if (path == 11) {
+ if (path.equals("diffpolicy")) {
policyId = new ObjectIdentifier(defaultPolicyId);
}
DerOutputStream statusInfo = new DerOutputStream();
statusInfo.putInteger(0);
- DerOutputStream token = new DerOutputStream();
AlgorithmId[] algorithms = {aid};
Certificate[] chain = ks.getCertificateChain(alias);
- X509Certificate[] signerCertificateChain = null;
+ X509Certificate[] signerCertificateChain;
X509Certificate signer = (X509Certificate)chain[0];
- if (path == 5) { // Only case 5 uses full chain
+
+ if (path.equals("fullchain")) { // Only case 5 uses full chain
signerCertificateChain = new X509Certificate[chain.length];
for (int i=0; i<chain.length; i++) {
signerCertificateChain[i] = (X509Certificate)chain[i];
}
- } else if (path == 9) {
+ } else if (path.equals("nocert")) {
signerCertificateChain = new X509Certificate[0];
} else {
signerCertificateChain = new X509Certificate[1];
@@ -179,11 +173,11 @@
tst.putInteger(1);
tst.putOID(policyId);
- if (path != 3 && path != 4) {
+ if (!path.equals("baddigest") && !path.equals("diffalg")) {
tst.putDerValue(messageImprint);
} else {
byte[] data = messageImprint.toByteArray();
- if (path == 4) {
+ if (path.equals("diffalg")) {
data[6] = (byte)0x01;
} else {
data[data.length-1] = (byte)0x01;
@@ -198,10 +192,10 @@
Calendar cal = Calendar.getInstance();
tst.putGeneralizedTime(cal.getTime());
- if (path == 2) {
+ if (path.equals("diffnonce")) {
tst.putInteger(1234);
- } else if (path == 1) {
- // do nothing
+ } else if (path.equals("nononce")) {
+ // no noce
} else {
tst.putInteger(nonce);
}
@@ -212,6 +206,8 @@
DerOutputStream tstInfo2 = new DerOutputStream();
tstInfo2.putOctetString(tstInfo.toByteArray());
+ // Always use the same algorithm at timestamp signing
+ // so it is different from the hash algorithm.
Signature sig = Signature.getInstance("SHA1withRSA");
sig.initSign((PrivateKey)(ks.getKey(
alias, "changeit".toCharArray())));
@@ -229,12 +225,11 @@
SignerInfo signerInfo = new SignerInfo(
new X500Name(signer.getIssuerX500Principal().getName()),
signer.getSerialNumber(),
- aid, AlgorithmId.get("RSA"), sig.sign());
+ AlgorithmId.get("SHA-1"), AlgorithmId.get("RSA"), sig.sign());
SignerInfo[] signerInfos = {signerInfo};
- PKCS7 p7 =
- new PKCS7(algorithms, contentInfo, signerCertificateChain,
- signerInfos);
+ PKCS7 p7 = new PKCS7(algorithms, contentInfo,
+ signerCertificateChain, signerInfos);
ByteArrayOutputStream p7out = new ByteArrayOutputStream();
p7.encodeSignedData(p7out);
@@ -294,44 +289,68 @@
}
}
- public static void main(String[] args) throws Exception {
- try (Handler tsa = Handler.init(0, TSKS);) {
+ public static void main(String[] args) throws Throwable {
+
+ prepare();
+
+ try (Handler tsa = Handler.init(0, "tsks");) {
tsa.start();
int port = tsa.getPort();
-
- String cmd;
- // Use -J-Djava.security.egd=file:/dev/./urandom to speed up
- // nonce generation in timestamping request. Not avaibale on
- // Windows and defaults to thread seed generator, not too bad.
- if (System.getProperty("java.home").endsWith("jre")) {
- cmd = System.getProperty("java.home") + "/../bin/jarsigner";
- } else {
- cmd = System.getProperty("java.home") + "/bin/jarsigner";
- }
-
- cmd += " " + System.getProperty("test.tool.vm.opts")
- + " -J-Djava.security.egd=file:/dev/./urandom"
- + " -J-Duser.language=en -J-Duser.country=US"
- + " -debug -keystore " + TSKS + " -storepass changeit"
- + " -tsa http://localhost:" + port + "/%d"
- + " -signedjar new_%d.jar " + JAR + " old";
+ host = "http://localhost:" + port + "/";
if (args.length == 0) { // Run this test
- jarsigner(cmd, 0, true); // Success, normal call
- jarsigner(cmd, 1, false); // These 4 should fail
- jarsigner(cmd, 2, false);
- jarsigner(cmd, 3, false);
- jarsigner(cmd, 4, false);
- jarsigner(cmd, 5, true); // Success, 6543440 solved.
- jarsigner(cmd, 6, false); // tsbad1
- jarsigner(cmd, 7, false); // tsbad2
- jarsigner(cmd, 8, false); // tsbad3
- jarsigner(cmd, 9, false); // no cert in timestamp
- jarsigner(cmd + " -tsapolicyid 1.2.3.4", 10, true);
- checkTimestamp("new_10.jar", "1.2.3.4", "SHA-256");
- jarsigner(cmd + " -tsapolicyid 1.2.3.5", 11, false);
- jarsigner(cmd + " -tsadigestalg SHA", 12, true);
- checkTimestamp("new_12.jar", defaultPolicyId, "SHA-1");
+ sign("none")
+ .shouldContain("is not timestamped")
+ .shouldHaveExitValue(0);
+
+ sign("badku")
+ .shouldHaveExitValue(0);
+ checkBadKU("badku.jar");
+
+ sign("normal")
+ .shouldNotContain("is not timestamped")
+ .shouldHaveExitValue(0);
+
+ sign("nononce")
+ .shouldHaveExitValue(1);
+ sign("diffnonce")
+ .shouldHaveExitValue(1);
+ sign("baddigest")
+ .shouldHaveExitValue(1);
+ sign("diffalg")
+ .shouldHaveExitValue(1);
+ sign("fullchain")
+ .shouldHaveExitValue(0); // Success, 6543440 solved.
+ sign("bad1")
+ .shouldHaveExitValue(1);
+ sign("bad2")
+ .shouldHaveExitValue(1);
+ sign("bad3")
+ .shouldHaveExitValue(1);
+ sign("nocert")
+ .shouldHaveExitValue(1);
+
+ sign("policy", "-tsapolicyid", "1.2.3")
+ .shouldHaveExitValue(0);
+ checkTimestamp("policy.jar", "1.2.3", "SHA-256");
+
+ sign("diffpolicy", "-tsapolicyid", "1.2.3")
+ .shouldHaveExitValue(1);
+
+ sign("tsaalg", "-tsadigestalg", "SHA")
+ .shouldHaveExitValue(0);
+ checkTimestamp("tsaalg.jar", defaultPolicyId, "SHA-1");
+
+ sign("weak", "-digestalg", "MD5",
+ "-sigalg", "MD5withRSA", "-tsadigestalg", "MD5")
+ .shouldHaveExitValue(0)
+ .shouldMatch("MD5.*-digestalg.*risk")
+ .shouldMatch("MD5.*-tsadigestalg.*risk")
+ .shouldMatch("MD5withRSA.*-sigalg.*risk");
+ checkWeak("weak.jar");
+
+ // When .SF or .RSA is missing or invalid
+ checkMissingOrInvalidFiles("normal.jar");
} else { // Run as a standalone server
System.err.println("Press Enter to quit server");
System.in.read();
@@ -339,6 +358,95 @@
}
}
+ private static void checkMissingOrInvalidFiles(String s)
+ throws Throwable {
+ JarUtils.updateJar(s, "1.jar", "-", "META-INF/OLD.SF");
+ verify("1.jar", "-verbose")
+ .shouldHaveExitValue(0)
+ .shouldContain("treated as unsigned")
+ .shouldContain("Missing signature-related file META-INF/OLD.SF");
+ JarUtils.updateJar(s, "2.jar", "-", "META-INF/OLD.RSA");
+ verify("2.jar", "-verbose")
+ .shouldHaveExitValue(0)
+ .shouldContain("treated as unsigned")
+ .shouldContain("Missing block file for signature-related file META-INF/OLD.SF");
+ JarUtils.updateJar(s, "3.jar", "META-INF/OLD.SF");
+ verify("3.jar", "-verbose")
+ .shouldHaveExitValue(0)
+ .shouldContain("treated as unsigned")
+ .shouldContain("Unparsable signature-related file META-INF/OLD.SF");
+ JarUtils.updateJar(s, "4.jar", "META-INF/OLD.RSA");
+ verify("4.jar", "-verbose")
+ .shouldHaveExitValue(0)
+ .shouldContain("treated as unsigned")
+ .shouldContain("Unparsable signature-related file META-INF/OLD.RSA");
+ }
+
+ static OutputAnalyzer jarsigner(List<String> extra)
+ throws Throwable {
+ JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jarsigner")
+ .addVMArg("-Duser.language=en")
+ .addVMArg("-Duser.country=US")
+ .addToolArg("-keystore")
+ .addToolArg("tsks")
+ .addToolArg("-storepass")
+ .addToolArg("changeit");
+ for (String s : extra) {
+ if (s.startsWith("-J")) {
+ launcher.addVMArg(s.substring(2));
+ } else {
+ launcher.addToolArg(s);
+ }
+ }
+ return ProcessTools.executeCommand(launcher.getCommand());
+ }
+
+ static OutputAnalyzer verify(String file, String... extra)
+ throws Throwable {
+ List<String> args = new ArrayList<>();
+ args.add("-verify");
+ args.add(file);
+ args.addAll(Arrays.asList(extra));
+ return jarsigner(args);
+ }
+
+ static void checkBadKU(String file) throws Throwable {
+ verify(file)
+ .shouldHaveExitValue(0)
+ .shouldContain("treated as unsigned")
+ .shouldContain("re-run jarsigner with debug enabled");
+ verify(file, "-verbose")
+ .shouldHaveExitValue(0)
+ .shouldContain("Signed by")
+ .shouldContain("treated as unsigned")
+ .shouldContain("re-run jarsigner with debug enabled");
+ verify(file, "-J-Djava.security.debug=jar")
+ .shouldHaveExitValue(0)
+ .shouldContain("SignatureException: Key usage restricted")
+ .shouldContain("treated as unsigned")
+ .shouldContain("re-run jarsigner with debug enabled");
+ }
+
+ static void checkWeak(String file) throws Throwable {
+ verify(file)
+ .shouldHaveExitValue(0)
+ .shouldContain("treated as unsigned")
+ .shouldMatch("weak algorithm that is now disabled.")
+ .shouldMatch("Re-run jarsigner with the -verbose option for more details");
+ verify(file, "-verbose")
+ .shouldHaveExitValue(0)
+ .shouldContain("treated as unsigned")
+ .shouldMatch("weak algorithm that is now disabled by")
+ .shouldMatch("Digest algorithm: .*weak")
+ .shouldMatch("Signature algorithm: .*weak")
+ .shouldMatch("Timestamp digest algorithm: .*weak")
+ .shouldNotMatch("Timestamp signature algorithm: .*weak.*weak")
+ .shouldMatch("Timestamp signature algorithm: .*key.*weak");
+ verify(file, "-J-Djava.security.debug=jar")
+ .shouldHaveExitValue(0)
+ .shouldMatch("SignatureException:.*Disabled");
+ }
+
static void checkTimestamp(String file, String policyId, String digestAlg)
throws Exception {
try (JarFile jf = new JarFile(file)) {
@@ -365,41 +473,62 @@
}
}
+ static int which = 0;
+
/**
- * @param cmd the command line (with a hole to plug in)
- * @param path the path in the URL, i.e, http://localhost/path
- * @param expected if this command should succeed
+ * @param extra more args given to jarsigner
*/
- static void jarsigner(String cmd, int path, boolean expected)
- throws Exception {
- System.err.println("Test " + path);
- Process p = Runtime.getRuntime().exec(String.format(Locale.ROOT,cmd, path, path));
- BufferedReader reader = new BufferedReader(
- new InputStreamReader(p.getErrorStream()));
- while (true) {
- String s = reader.readLine();
- if (s == null) break;
- System.err.println(s);
+ static OutputAnalyzer sign(String path, String... extra)
+ throws Throwable {
+ which++;
+ System.err.println("\n>> Test #" + which + ": " + Arrays.toString(extra));
+ List<String> args = List.of("-J-Djava.security.egd=file:/dev/./urandom",
+ "-debug", "-signedjar", path + ".jar", "old.jar",
+ path.equals("badku") ? "badku" : "old");
+ args = new ArrayList<>(args);
+ if (!path.equals("none") && !path.equals("badku")) {
+ args.add("-tsa");
+ args.add(host + path);
}
+ args.addAll(Arrays.asList(extra));
+ return jarsigner(args);
+ }
- // Will not see noTimestamp warning
- boolean seeWarning = false;
- reader = new BufferedReader(
- new InputStreamReader(p.getInputStream()));
- while (true) {
- String s = reader.readLine();
- if (s == null) break;
- System.err.println(s);
- if (s.indexOf("Warning:") >= 0) {
- seeWarning = true;
- }
+ static void prepare() throws Exception {
+ jdk.testlibrary.JarUtils.createJar("old.jar", "A");
+ Files.deleteIfExists(Paths.get("tsks"));
+ keytool("-alias ca -genkeypair -ext bc -dname CN=CA");
+ keytool("-alias old -genkeypair -dname CN=old");
+ keytool("-alias badku -genkeypair -dname CN=badku");
+ keytool("-alias ts -genkeypair -dname CN=ts");
+ keytool("-alias tsweak -genkeypair -keysize 512 -dname CN=tsbad1");
+ keytool("-alias tsbad1 -genkeypair -dname CN=tsbad1");
+ keytool("-alias tsbad2 -genkeypair -dname CN=tsbad2");
+ keytool("-alias tsbad3 -genkeypair -dname CN=tsbad3");
+
+ gencert("old");
+ gencert("badku", "-ext ku:critical=keyAgreement");
+ gencert("ts", "-ext eku:critical=ts");
+ gencert("tsweak", "-ext eku:critical=ts");
+ gencert("tsbad1");
+ gencert("tsbad2", "-ext eku=ts");
+ gencert("tsbad3", "-ext eku:critical=cs");
+ }
+
+ static void gencert(String alias, String... extra) throws Exception {
+ keytool("-alias " + alias + " -certreq -file " + alias + ".req");
+ String genCmd = "-gencert -alias ca -infile " +
+ alias + ".req -outfile " + alias + ".cert";
+ for (String s : extra) {
+ genCmd += " " + s;
}
- int result = p.waitFor();
- if (expected && result != 0 || !expected && result == 0) {
- throw new Exception("Failed");
- }
- if (seeWarning) {
- throw new Exception("See warning");
- }
+ keytool(genCmd);
+ keytool("-alias " + alias + " -importcert -file " + alias + ".cert");
+ }
+
+ static void keytool(String cmd) throws Exception {
+ cmd = "-keystore tsks -storepass changeit -keypass changeit " +
+ "-keyalg rsa -validity 200 " + cmd;
+ sun.security.tools.keytool.Main.main(cmd.split(" "));
}
}
--- a/jdk/test/sun/security/tools/jarsigner/TsacertOptionTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/sun/security/tools/jarsigner/TsacertOptionTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -31,6 +31,7 @@
* @library /lib/testlibrary warnings
* @modules java.base/sun.security.pkcs
* java.base/sun.security.timestamp
+ * java.base/sun.security.tools.keytool
* java.base/sun.security.util
* java.base/sun.security.x509
* java.management
--- a/jdk/test/sun/security/tools/jarsigner/ts.sh Wed Oct 26 15:46:13 2016 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-#
-# Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-# @test
-# @bug 6543842 6543440 6939248 8009636 8024302
-# @summary checking response of timestamp
-# @modules java.base/sun.security.pkcs
-# java.base/sun.security.timestamp
-# java.base/sun.security.x509
-# java.base/sun.security.util
-#
-# @run shell/timeout=600 ts.sh
-
-# Run for a long time because jarsigner with timestamp needs to create a
-# 64-bit random number and it might be extremely slow on a machine with
-# not enough entropy pool
-
-# set platform-dependent variables
-OS=`uname -s`
-case "$OS" in
- Windows_* )
- FS="\\"
- ;;
- * )
- FS="/"
- ;;
-esac
-
-if [ "${TESTSRC}" = "" ] ; then
- TESTSRC="."
-fi
-if [ "${TESTJAVA}" = "" ] ; then
- JAVAC_CMD=`which javac`
- TESTJAVA=`dirname $JAVAC_CMD`/..
-fi
-
-JAR="${TESTJAVA}${FS}bin${FS}jar ${TESTTOOLVMOPTS}"
-JAVA="${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS}"
-JAVAC="${TESTJAVA}${FS}bin${FS}javac ${TESTTOOLVMOPTS} ${TESTJAVACOPTS}"
-KT="${TESTJAVA}${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -keystore tsks -storepass changeit -keypass changeit -keyalg rsa -validity 200"
-
-rm tsks
-echo Nothing > A
-rm old.jar
-$JAR cvf old.jar A
-
-# ca is CA
-# old is signer for code
-# ts is signer for timestamp
-# tsbad1 has no extendedKeyUsage
-# tsbad2's extendedKeyUsage is non-critical
-# tsbad3's extendedKeyUsage has no timestamping
-
-$KT -alias ca -genkeypair -ext bc -dname CN=CA
-$KT -alias old -genkeypair -dname CN=old
-$KT -alias ts -genkeypair -dname CN=ts
-$KT -alias tsbad1 -genkeypair -dname CN=tsbad1
-$KT -alias tsbad2 -genkeypair -dname CN=tsbad2
-$KT -alias tsbad3 -genkeypair -dname CN=tsbad3
-
-$KT -alias old -certreq | \
- $KT -alias ca -gencert | \
- $KT -alias old -importcert
-$KT -alias ts -certreq | \
- $KT -alias ca -gencert -ext eku:critical=ts | \
- $KT -alias ts -importcert
-$KT -alias tsbad1 -certreq | \
- $KT -alias ca -gencert | \
- $KT -alias tsbad1 -importcert
-$KT -alias tsbad2 -certreq | \
- $KT -alias ca -gencert -ext eku=ts | \
- $KT -alias tsbad2 -importcert
-$KT -alias tsbad3 -certreq | \
- $KT -alias ca -gencert -ext eku:critical=cs | \
- $KT -alias tsbad3 -importcert
-
-EXTRAOPTS="--add-exports java.base/sun.security.pkcs=ALL-UNNAMED \
- --add-exports java.base/sun.security.timestamp=ALL-UNNAMED \
- --add-exports java.base/sun.security.x509=ALL-UNNAMED \
- --add-exports java.base/sun.security.util=ALL-UNNAMED"
-$JAVAC ${EXTRAOPTS} -d . ${TESTSRC}/TimestampCheck.java
-$JAVA ${TESTVMOPTS} ${EXTRAOPTS} "-Dtest.tool.vm.opts=${TESTTOOLVMOPTS}" TimestampCheck
-
--- a/jdk/test/sun/tools/jrunscript/jrunscript-DTest.sh Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/sun/tools/jrunscript/jrunscript-DTest.sh Wed Oct 26 20:13:29 2016 +0000
@@ -33,7 +33,7 @@
. ${TESTSRC-.}/common.sh
setup
-${JAVA} -cp ${TESTCLASSES} CheckEngine
+${JAVA} ${TESTVMOPTS} ${TESTJAVAOPTS} -cp ${TESTCLASSES} CheckEngine
if [ $? -eq 2 ]; then
echo "No js engine found and engine not required; test vacuously passes."
exit 0
--- a/jdk/test/sun/tools/jrunscript/jrunscript-argsTest.sh Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/sun/tools/jrunscript/jrunscript-argsTest.sh Wed Oct 26 20:13:29 2016 +0000
@@ -33,7 +33,7 @@
. ${TESTSRC-.}/common.sh
setup
-${JAVA} -cp ${TESTCLASSES} CheckEngine
+${JAVA} ${TESTVMOPTS} ${TESTJAVAOPTS} -cp ${TESTCLASSES} CheckEngine
if [ $? -eq 2 ]; then
echo "No js engine found and engine not required; test vacuously passes."
exit 0
--- a/jdk/test/sun/tools/jrunscript/jrunscript-cpTest.sh Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/sun/tools/jrunscript/jrunscript-cpTest.sh Wed Oct 26 20:13:29 2016 +0000
@@ -33,14 +33,14 @@
. ${TESTSRC-.}/common.sh
setup
-${JAVA} -cp ${TESTCLASSES} CheckEngine
+${JAVA} ${TESTVMOPTS} ${TESTJAVAOPTS} -cp ${TESTCLASSES} CheckEngine
if [ $? -eq 2 ]; then
echo "No js engine found and engine not required; test vacuously passes."
exit 0
fi
rm -f Hello.class
-${JAVAC} ${TESTSRC}/Hello.java -d .
+${JAVAC} ${TESTTOOLVMOPTS} ${TESTJAVACOPTS} ${TESTSRC}/Hello.java -d .
# we check whether classpath setting for app classes
# work with jrunscript. Script should be able to
--- a/jdk/test/sun/tools/jrunscript/jrunscript-eTest.sh Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/sun/tools/jrunscript/jrunscript-eTest.sh Wed Oct 26 20:13:29 2016 +0000
@@ -33,7 +33,7 @@
. ${TESTSRC-.}/common.sh
setup
-${JAVA} -cp ${TESTCLASSES} CheckEngine
+${JAVA} ${TESTVMOPTS} ${TESTJAVAOPTS} -cp ${TESTCLASSES} CheckEngine
if [ $? -eq 2 ]; then
echo "No js engine found and engine not required; test vacuously passes."
exit 0
--- a/jdk/test/sun/tools/jrunscript/jrunscript-fTest.sh Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/sun/tools/jrunscript/jrunscript-fTest.sh Wed Oct 26 20:13:29 2016 +0000
@@ -33,7 +33,7 @@
. ${TESTSRC-.}/common.sh
setup
-${JAVA} -cp ${TESTCLASSES} CheckEngine
+${JAVA} ${TESTVMOPTS} ${TESTJAVAOPTS} -cp ${TESTCLASSES} CheckEngine
if [ $? -eq 2 ]; then
echo "No js engine found and engine not required; test vacuously passes."
exit 0
--- a/jdk/test/sun/tools/jrunscript/jrunscriptTest.sh Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/sun/tools/jrunscript/jrunscriptTest.sh Wed Oct 26 20:13:29 2016 +0000
@@ -33,7 +33,7 @@
. ${TESTSRC-.}/common.sh
setup
-${JAVA} -cp ${TESTCLASSES} CheckEngine
+${JAVA} ${TESTVMOPTS} ${TESTJAVAOPTS} -cp ${TESTCLASSES} CheckEngine
if [ $? -eq 2 ]; then
echo "No js engine found and engine not required; test vacuously passes."
exit 0
--- a/jdk/test/tools/jar/ChangeDir.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/tools/jar/ChangeDir.java Wed Oct 26 20:13:29 2016 +0000
@@ -24,7 +24,7 @@
/**
* @test
* @bug 4806786 8023113
- * @modules jdk.jartool/sun.tools.jar
+ * @modules jdk.jartool
* @summary jar -C doesn't ignore multiple // in path
*/
@@ -32,10 +32,15 @@
import java.nio.file.*;
import java.util.*;
import java.util.jar.*;
+import java.util.spi.ToolProvider;
import java.util.stream.Stream;
-import sun.tools.jar.Main;
public class ChangeDir {
+ private static final ToolProvider JAR_TOOL = ToolProvider.findFirst("jar")
+ .orElseThrow(() ->
+ new RuntimeException("jar tool not found")
+ );
+
private final static String jarName = "test.jar";
private final static String fileName = "hello.txt";
@@ -88,8 +93,9 @@
argList.add(topDir.toString() + sep + "a" + sep + sep + "b"); // Note double 'sep' is intentional
argList.add(fileName);
- Main jarTool = new Main(System.out, System.err, "jar");
- if (!jarTool.run(argList.toArray(new String[argList.size()]))) {
+ int rc = JAR_TOOL.run(System.out, System.err,
+ argList.toArray(new String[argList.size()]));
+ if (rc != 0) {
fail("Could not create jar file.");
}
--- a/jdk/test/tools/jar/InputFilesTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/tools/jar/InputFilesTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -29,7 +29,7 @@
* duplicates that sometimes cause exceptions and other times do not,
* demonstrating identical behavior to JDK 8 jar tool.
* @library /lib/testlibrary
- * @modules jdk.jartool/sun.tools.jar
+ * @modules jdk.jartool
* @build jdk.testlibrary.FileUtils
* @run testng InputFilesTest
*/
@@ -47,12 +47,18 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
+import java.util.spi.ToolProvider;
import java.util.stream.Stream;
import java.util.zip.ZipException;
import jdk.testlibrary.FileUtils;
public class InputFilesTest {
+ private static final ToolProvider JAR_TOOL = ToolProvider.findFirst("jar")
+ .orElseThrow(() ->
+ new RuntimeException("jar tool not found")
+ );
+
private final String nl = System.lineSeparator();
private final ByteArrayOutputStream baos = new ByteArrayOutputStream();
private final PrintStream out = new PrintStream(baos);
@@ -195,9 +201,9 @@
PrintStream err = new PrintStream(baes);
PrintStream saveErr = System.err;
System.setErr(err);
- boolean ok = new sun.tools.jar.Main(out, err, "jar").run(cmdline.split(" +"));
+ int rc = JAR_TOOL.run(out, err, cmdline.split(" +"));
System.setErr(saveErr);
- if (!ok) {
+ if (rc != 0) {
String s = baes.toString();
if (s.startsWith("java.util.zip.ZipException: duplicate entry: ")) {
throw new ZipException(s);
--- a/jdk/test/tools/jar/JarBackSlash.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/tools/jar/JarBackSlash.java Wed Oct 26 20:13:29 2016 +0000
@@ -28,7 +28,7 @@
/*
* @test
* @bug 7201156
- * @modules jdk.jartool/sun.tools.jar
+ * @modules jdk.jartool
* @summary jar tool fails to convert file separation characters for list and extract
* @author Sean Chou
*/
@@ -43,10 +43,13 @@
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
-
-import sun.tools.jar.Main;
+import java.util.spi.ToolProvider;
public class JarBackSlash {
+ private static final ToolProvider JAR_TOOL = ToolProvider.findFirst("jar")
+ .orElseThrow(() ->
+ new RuntimeException("jar tool not found")
+ );
// used construct an entry JarBackSlash/dir/file.txt
private static String JARBACKSLASH = "JarBackSlash";
@@ -78,8 +81,8 @@
PipedInputStream pipedInput = new PipedInputStream(pipedOutput);
PrintStream out = new PrintStream(pipedOutput);
- Main jarTool = new Main(out, System.err, "jar");
- if (!jarTool.run(jarArgs)) {
+ int rc = JAR_TOOL.run(out, System.err, jarArgs);
+ if (rc != 0) {
fail("Could not list jar file.");
}
@@ -101,8 +104,8 @@
PipedInputStream pipedInput = new PipedInputStream(pipedOutput);
PrintStream out = new PrintStream(pipedOutput);
- Main jarTool = new Main(out, System.err, "jar");
- if (!jarTool.run(jarArgs)) {
+ int rc = JAR_TOOL.run(out, System.err, jarArgs);
+ if (rc != 0) {
fail("Could not list jar file.");
}
--- a/jdk/test/tools/jar/JarEntryTime.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/tools/jar/JarEntryTime.java Wed Oct 26 20:13:29 2016 +0000
@@ -24,7 +24,7 @@
/**
* @test
* @bug 4225317 6969651
- * @modules jdk.jartool/sun.tools.jar
+ * @modules jdk.jartool
* @summary Check extracted files have date as per those in the .jar file
*/
@@ -33,9 +33,14 @@
import java.nio.file.attribute.FileTime;
import java.util.Date;
import java.util.TimeZone;
-import sun.tools.jar.Main;
+import java.util.spi.ToolProvider;
public class JarEntryTime {
+ static final ToolProvider JAR_TOOL = ToolProvider.findFirst("jar")
+ .orElseThrow(() ->
+ new RuntimeException("jar tool not found")
+ );
+
// ZipEntry's mod date has 2 seconds precision: give extra time to
// allow for e.g. rounding/truncation and networked/samba drives.
@@ -114,10 +119,8 @@
check(fileInner.setLastModified(earlier));
// Make a jar file from that directory structure
- Main jartool = new Main(System.out, System.err, "jar");
- check(jartool.run(new String[] {
- "cf",
- jarFile.getName(), dirOuter.getName() } ));
+ check(JAR_TOOL.run(System.out, System.err,
+ "cf", jarFile.getName(), dirOuter.getName()) == 0);
check(jarFile.exists());
check(cleanup(dirInner));
@@ -142,7 +145,6 @@
final long start = testFile.lastModified();
// Extract and check the last modified values are the current times.
- // See sun.tools.jar.Main
extractJar(jarFile, true);
try (PrintWriter pw = new PrintWriter(testFile)) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/ReleaseBeforeFiles.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,165 @@
+/*
+ * 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 8167237
+ * @summary test that both old style command line options and new gnu style
+ * command line options work with the --release option whether or
+ * not the --release option is preceded by a file name.
+ * @library /lib/testlibrary
+ * @modules jdk.jartool/sun.tools.jar
+ * @build jdk.testlibrary.FileUtils
+ * @run testng ReleaseBeforeFiles
+ */
+
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.stream.Stream;
+
+import jdk.testlibrary.FileUtils;
+
+public class ReleaseBeforeFiles {
+ private Runnable onCompletion;
+
+ @BeforeMethod
+ public void reset() {
+ onCompletion = null;
+ }
+
+ @AfterMethod
+ public void run() {
+ if (onCompletion != null) {
+ onCompletion.run();
+ }
+ }
+
+ @Test // passes before bug fix
+ public void test1() throws IOException {
+ mkdir("test1");
+ touch("test1/testfile1");
+ jar("cf test.jar --release 9 test1");
+ jar("tf test.jar");
+ rm("test.jar test1");
+ }
+
+ @Test // fails before bug fix
+ public void test2() throws IOException {
+ System.out.println("=====");
+ mkdir("test1");
+ touch("test1/testfile1");
+ onCompletion = () -> rm("test.jar test1");
+ jar("--create --file=test.jar --release 9 test1");
+ jar("tf test.jar");
+ }
+
+ @Test // passes before bug fix
+ public void test3() throws IOException {
+ System.out.println("=====");
+ mkdir("test1");
+ touch("test1/testfile1");
+ jar("-cf test.jar -C test1 .");
+ jar("-uf test.jar --release 9 -C test1 .");
+ jar("tf test.jar");
+ rm("test.jar test1");
+ }
+
+ @Test // fails before bug fix
+ public void test4() throws IOException {
+ System.out.println("=====");
+ mkdir("test1");
+ touch("test1/testfile1");
+ onCompletion = () -> rm("test.jar test1");
+ jar("--create --file=test.jar -C test1 .");
+ jar("--update --file=test.jar --release 9 -C test1 .");
+ jar("tf test.jar");
+ }
+
+ @Test // passes before bug fix since test2 precedes --release 9
+ public void test5() throws IOException {
+ System.out.println("=====");
+ mkdir("test1 test2");
+ touch("test1/testfile1 test2/testfile2");
+ jar("--create --file=test.jar -C test1 .");
+ jar("--update --file=test.jar test2 --release 9 -C test1 .");
+ jar("tf test.jar");
+ rm("test.jar test1 test2");
+ }
+
+ private Stream<Path> mkpath(String... args) {
+ return Arrays.stream(args).map(d -> Paths.get(".", d.split("/")));
+ }
+
+ private void mkdir(String cmdline) {
+ System.out.println("mkdir -p " + cmdline);
+ mkpath(cmdline.split(" +")).forEach(p -> {
+ try {
+ Files.createDirectories(p);
+ } catch (IOException x) {
+ throw new UncheckedIOException(x);
+ }
+ });
+ }
+
+ private void touch(String cmdline) {
+ System.out.println("touch " + cmdline);
+ mkpath(cmdline.split(" +")).forEach(p -> {
+ try {
+ Files.createFile(p);
+ } catch (IOException x) {
+ throw new UncheckedIOException(x);
+ }
+ });
+ }
+
+ private void rm(String cmdline) {
+ System.out.println("rm -rf " + cmdline);
+ mkpath(cmdline.split(" +")).forEach(p -> {
+ try {
+ if (Files.isDirectory(p)) {
+ FileUtils.deleteFileTreeWithRetry(p);
+ } else {
+ FileUtils.deleteFileIfExistsWithRetry(p);
+ }
+ } catch (IOException x) {
+ throw new UncheckedIOException(x);
+ }
+ });
+ }
+
+ private void jar(String cmdline) throws IOException {
+ System.out.println("jar " + cmdline);
+ boolean ok = new sun.tools.jar.Main(System.out, System.err, "jar")
+ .run(cmdline.split(" +"));
+ Assert.assertTrue(ok);
+ }
+}
--- a/jdk/test/tools/jar/UpdateJar.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/tools/jar/UpdateJar.java Wed Oct 26 20:13:29 2016 +0000
@@ -24,7 +24,7 @@
/**
* @test
* @bug 7175845
- * @modules jdk.jartool/sun.tools.jar
+ * @modules jdk.jartool
* @summary jar -uf should not change file permission
*/
@@ -32,9 +32,13 @@
import java.nio.file.*;
import java.nio.file.attribute.*;
import java.util.Set;
-import sun.tools.jar.Main;
+import java.util.spi.ToolProvider;
public class UpdateJar {
+ private static final ToolProvider JAR_TOOL = ToolProvider.findFirst("jar")
+ .orElseThrow(() ->
+ new RuntimeException("jar tool not found")
+ );
private static void cleanup(String... fnames) throws Throwable {
for (String fname : fnames) {
@@ -55,12 +59,12 @@
fos1.write(0);
}
String[] jarArgs = new String[] {"cfM0", jar, e0};
- if (!new Main(System.out, System.err, "jar").run(jarArgs)) {
+ if (JAR_TOOL.run(System.out, System.err, jarArgs) != 0) {
fail("Could not create jar file.");
}
Set<PosixFilePermission> pm = Files.getPosixFilePermissions(Paths.get(jar));
jarArgs = new String[] {"uf", jar, e1};
- if (!new Main(System.out, System.err, "jar").run(jarArgs)) {
+ if (JAR_TOOL.run(System.out, System.err, jarArgs) != 0) {
fail("Could not create jar file.");
}
equal(pm, Files.getPosixFilePermissions(Paths.get(jar)));
--- a/jdk/test/tools/jar/UpdateManifest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/tools/jar/UpdateManifest.java Wed Oct 26 20:13:29 2016 +0000
@@ -24,7 +24,7 @@
/**
* @test
* @bug 6434207 6442687 6984046
- * @modules jdk.jartool/sun.tools.jar
+ * @modules jdk.jartool
* @summary Ensure that jar ufm actually updates the
* existing jar file's manifest with contents of the
* manifest file.
@@ -32,14 +32,19 @@
import java.io.*;
import java.util.logging.*;
+import java.util.spi.ToolProvider;
import java.util.zip.*;
-import sun.tools.jar.Main;
public class UpdateManifest {
static PrintStream out = System.out;
static PrintStream err = System.err;
static boolean debug = true;
+ static final ToolProvider JAR_TOOL = ToolProvider.findFirst("jar")
+ .orElseThrow(() ->
+ new RuntimeException("jar tool not found")
+ );
+
static final Logger JAR_LOGGER = Logger.getLogger("java.util.jar");
public static void realMain(String[] args) throws Throwable {
@@ -64,17 +69,14 @@
// Create a jar file, specifying a Main-Class
final String jarFileName = "um-existence.jar";
new File(jarFileName).delete(); // remove pre-existing first!
- Main jartool = new Main(out, err, "jar");
- boolean status = jartool.run(
- new String[] { "cfe", jarFileName, "Hello", existence.getPath() });
- check(status);
+ int status = JAR_TOOL.run(out, err, "cfe", jarFileName,
+ "Hello", existence.getPath());
+ check(status == 0);
checkManifest(jarFileName, "Hello");
// Update that jar file by changing the Main-Class
- jartool = new Main(out, err, "jar");
- status = jartool.run(
- new String[] { "ufe", jarFileName, "Bye" });
- check(status);
+ status = JAR_TOOL.run(out, err, "ufe", jarFileName, "Bye");
+ check(status == 0);
checkManifest(jarFileName, "Bye");
}
@@ -101,11 +103,9 @@
// Create a jar file
final String jarFileName = "um-test.jar";
new File(jarFileName).delete(); // remove pre-existing first!
- Main jartool = new Main(out, err, "jar");
- boolean status = jartool.run(
- new String[] {"cfm", jarFileName,
- manifestOrig.getPath(), hello.getPath() });
- check(status);
+ int status = JAR_TOOL.run(out, err, "cfm", jarFileName,
+ manifestOrig.getPath(), hello.getPath());
+ check(status == 0);
// Create a new manifest, to use in updating the jar file.
File manifestUpdate = File.createTempFile("manifestUpdate", ".txt");
@@ -122,10 +122,9 @@
pw.close();
// Update jar file with manifest
- jartool = new Main(out, err, "jar");
- status = jartool.run(
- new String[] { "ufm", jarFileName, manifestUpdate.getPath() });
- check(status);
+ status = JAR_TOOL.run(out, err, "ufm",
+ jarFileName, manifestUpdate.getPath());
+ check(status == 0);
// Extract jar, and verify contents of manifest file
File f = new File(jarFileName);
--- a/jdk/test/tools/jar/index/MetaInf.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/tools/jar/index/MetaInf.java Wed Oct 26 20:13:29 2016 +0000
@@ -24,17 +24,21 @@
/*
* @test
* @bug 4408526 6854795
- * @modules jdk.jartool/sun.tools.jar
+ * @modules jdk.jartool
* @summary Index the non-meta files in META-INF, such as META-INF/services.
*/
import java.io.*;
import java.util.Arrays;
import java.util.jar.*;
-import sun.tools.jar.Main;
+import java.util.spi.ToolProvider;
import java.util.zip.ZipFile;
public class MetaInf {
+ static final ToolProvider JAR_TOOL = ToolProvider.findFirst("jar")
+ .orElseThrow(() ->
+ new RuntimeException("jar tool not found")
+ );
static String jarName = "a.jar";
static String INDEX = "META-INF/INDEX.LIST";
@@ -43,7 +47,7 @@
System.getProperty("test.src") + File.separatorChar + "jarcontents";
static void run(String ... args) {
- if (! new Main(System.out, System.err, "jar").run(args))
+ if (JAR_TOOL.run(System.out, System.err, args) != 0)
throw new Error("jar failed: args=" + Arrays.toString(args));
}
--- a/jdk/test/tools/jlink/IntegrationTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/tools/jlink/IntegrationTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -37,14 +37,14 @@
import java.util.Properties;
import java.util.Set;
import java.util.function.Function;
-import jdk.tools.jlink.Jlink;
-import jdk.tools.jlink.Jlink.JlinkConfiguration;
-import jdk.tools.jlink.Jlink.PluginsConfiguration;
+import jdk.tools.jlink.internal.Jlink;
import jdk.tools.jlink.builder.DefaultImageBuilder;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.internal.ExecutableImage;
+import jdk.tools.jlink.internal.Jlink.JlinkConfiguration;
+import jdk.tools.jlink.internal.Jlink.PluginsConfiguration;
import jdk.tools.jlink.internal.PostProcessor;
import jdk.tools.jlink.internal.plugins.DefaultCompressPlugin;
import jdk.tools.jlink.internal.plugins.StripDebugPlugin;
--- a/jdk/test/tools/jlink/JLinkTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/tools/jlink/JLinkTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -32,13 +32,13 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.spi.ToolProvider;
import java.util.stream.Stream;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.internal.PluginRepository;
import tests.Helper;
import tests.JImageGenerator;
-import tests.JImageGenerator.InMemoryFile;
/*
* @test
@@ -48,13 +48,17 @@
* @modules java.base/jdk.internal.jimage
* jdk.jdeps/com.sun.tools.classfile
* jdk.jlink/jdk.tools.jlink.internal
- * jdk.jlink/jdk.tools.jmod
* jdk.jlink/jdk.tools.jimage
* jdk.compiler
* @build tests.*
* @run main/othervm -Xmx1g JLinkTest
*/
public class JLinkTest {
+ static final ToolProvider JLINK_TOOL = ToolProvider.findFirst("jlink")
+ .orElseThrow(() ->
+ new RuntimeException("jlink tool not found")
+ );
+
// number of built-in plugins from jdk.jlink module
private static int getNumJlinkPlugins() {
ModuleDescriptor desc = Plugin.class.getModule().getDescriptor();
@@ -180,7 +184,8 @@
{
// Help
StringWriter writer = new StringWriter();
- jdk.tools.jlink.internal.Main.run(new String[]{"--help"}, new PrintWriter(writer));
+ PrintWriter pw = new PrintWriter(writer);
+ JLINK_TOOL.run(pw, pw, "--help");
String output = writer.toString();
if (output.split("\n").length < 10) {
System.err.println(output);
@@ -202,7 +207,9 @@
{
// List plugins
StringWriter writer = new StringWriter();
- jdk.tools.jlink.internal.Main.run(new String[]{"--list-plugins"}, new PrintWriter(writer));
+ PrintWriter pw = new PrintWriter(writer);
+
+ JLINK_TOOL.run(pw, pw, "--list-plugins");
String output = writer.toString();
long number = Stream.of(output.split("\\R"))
.filter((s) -> s.matches("Plugin Name:.*"))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jlink/JLinkToolProviderTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,58 @@
+/*
+ * 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.io.PrintWriter;
+import java.io.StringWriter;
+import java.security.AccessControlException;
+import java.util.spi.ToolProvider;
+
+/*
+ * @test
+ * @build JLinkToolProviderTest
+ * @run main/othervm/java.security.policy=toolprovider.policy JLinkToolProviderTest
+ */
+public class JLinkToolProviderTest {
+ static final ToolProvider JLINK_TOOL = ToolProvider.findFirst("jlink")
+ .orElseThrow(() ->
+ new RuntimeException("jlink tool not found")
+ );
+
+ private static void checkJlinkOptions(String... options) {
+ StringWriter writer = new StringWriter();
+ PrintWriter pw = new PrintWriter(writer);
+
+ try {
+ JLINK_TOOL.run(pw, pw, options);
+ throw new AssertionError("SecurityException should have been thrown!");
+ } catch (AccessControlException ace) {
+ if (! ace.getPermission().getClass().getName().contains("JlinkPermission")) {
+ throw new AssertionError("expected JlinkPermission check failure");
+ }
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ checkJlinkOptions("--help");
+ checkJlinkOptions("--list-plugins");
+ }
+}
--- a/jdk/test/tools/jlink/SecurityTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/tools/jlink/SecurityTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -25,12 +25,12 @@
* @test
* @summary Test JlinkPermission
* @author Jean-Francois Denise
- * @modules jdk.jlink/jdk.tools.jlink
+ * @modules jdk.jlink/jdk.tools.jlink.internal
* @run main/othervm SecurityTest
*/
import java.security.AccessControlException;
-import jdk.tools.jlink.Jlink;
+import jdk.tools.jlink.internal.Jlink;
public class SecurityTest {
--- a/jdk/test/tools/jlink/basic/BasicTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/tools/jlink/basic/BasicTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -27,8 +27,7 @@
* @author Andrei Eremeev
* @library /lib/testlibrary
* @modules java.base/jdk.internal.module
- * jdk.jlink/jdk.tools.jlink.internal
- * jdk.jlink/jdk.tools.jmod
+ * jdk.jlink
* jdk.compiler
* @build jdk.testlibrary.ProcessTools
* jdk.testlibrary.OutputAnalyzer
@@ -44,11 +43,21 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.spi.ToolProvider;
import jdk.testlibrary.OutputAnalyzer;
import jdk.testlibrary.ProcessTools;
public class BasicTest {
+ static final ToolProvider JMOD_TOOL = ToolProvider.findFirst("jmod")
+ .orElseThrow(() ->
+ new RuntimeException("jmod tool not found")
+ );
+
+ static final ToolProvider JLINK_TOOL = ToolProvider.findFirst("jlink")
+ .orElseThrow(() ->
+ new RuntimeException("jlink tool not found")
+ );
private final Path jdkHome = Paths.get(System.getProperty("test.jdk"));
private final Path jdkMods = jdkHome.resolve("jmods");
@@ -110,20 +119,22 @@
"--add-modules", modName,
"--output", image.toString());
Collections.addAll(args, options);
- int rc = jdk.tools.jlink.internal.Main.run(args.toArray(new String[args.size()]), new PrintWriter(System.out));
+
+ PrintWriter pw = new PrintWriter(System.out);
+ int rc = JLINK_TOOL.run(pw, pw, args.toArray(new String[args.size()]));
if (rc != 0) {
throw new AssertionError("Jlink failed: rc = " + rc);
}
}
private void runJmod(String cp, String modName) {
- int rc = jdk.tools.jmod.Main.run(new String[] {
+ int rc = JMOD_TOOL.run(System.out, System.out, new String[] {
"create",
"--class-path", cp,
"--module-version", "1.0",
"--main-class", "jdk.test.Test",
jmods.resolve(modName + ".jmod").toString(),
- }, System.out);
+ });
if (rc != 0) {
throw new AssertionError("Jmod failed: rc = " + rc);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jlink/plugins/ExcludeJmodSectionPluginTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,340 @@
+/**
+ * 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 Test --no-man-pages and --no-header-files
+ * @library /lib/testlibrary
+ * @modules jdk.compiler
+ * jdk.jlink
+ * @build CompilerUtils
+ * @run testng ExcludeJmodSectionPluginTest
+ */
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.spi.ToolProvider;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.*;
+
+public class ExcludeJmodSectionPluginTest {
+ static final ToolProvider JMOD_TOOL = ToolProvider.findFirst("jmod")
+ .orElseThrow(() ->
+ new RuntimeException("jmod tool not found")
+ );
+
+ static final ToolProvider JLINK_TOOL = ToolProvider.findFirst("jlink")
+ .orElseThrow(() ->
+ new RuntimeException("jlink tool not found")
+ );
+
+ static final Path MODULE_PATH = Paths.get(System.getProperty("java.home"), "jmods");
+ static final Path SRC_DIR = Paths.get("src");
+ static final Path MODS_DIR = Paths.get("mods");
+ static final Path JMODS_DIR = Paths.get("jmods");
+ static final Path MAN_DIR = Paths.get("man");
+ static final Path INCLUDE_DIR = Paths.get("include");
+ static final Path IMAGES_DIR = Paths.get("images");
+
+ @BeforeTest
+ private void setup() throws Exception {
+ // build jmod files
+ JmodFileBuilder m1 = new JmodFileBuilder("m1");
+ m1.headerFile("m1a.h");
+ m1.headerFile("m1b.h");
+ m1.build();
+
+ JmodFileBuilder m2 = new JmodFileBuilder("m2");
+ m2.headerFile("m2.h");
+ m2.manPage("tool2.1");
+ m2.build();
+
+ JmodFileBuilder m3 = new JmodFileBuilder("m3");
+ m3.manPage("tool3.1");
+ m3.build();
+ }
+
+ private String imageDir(String dir) {
+ return IMAGES_DIR.resolve(dir).toString();
+ }
+
+
+ @DataProvider(name = "jlinkoptions")
+ public Object[][] jlinkoptions() {
+ // options and expected header files & man pages
+ return new Object[][] {
+ { new String [] {
+ "test1",
+ "--exclude-files=/java.base/include/**,/java.base/man/**",
+ },
+ List.of("include/m1a.h",
+ "include/m1b.h",
+ "include/m2.h",
+ "man/tool2.1",
+ "man/tool3.1")
+ },
+
+ { new String [] {
+ "test2",
+ "--no-man-pages",
+ "--no-header-files",
+ },
+ List.of()
+ },
+
+ { new String[] {
+ "test3",
+ "--no-header-files",
+ "--exclude-files=/java.base/man/**"
+ },
+ List.of("man/tool2.1",
+ "man/tool3.1") },
+
+ { new String [] {
+ "test4",
+ "--no-man-pages",
+ "--exclude-files=/java.base/include/**,/m2/include/**",
+ },
+ List.of("include/m1a.h",
+ "include/m1b.h")
+ },
+
+ { new String [] {
+ "test5",
+ "--no-header-files",
+ "--exclude-files=/java.base/man/**,/m2/man/**"
+ },
+ List.of("man/tool3.1")
+ },
+ };
+ }
+
+ @Test(dataProvider = "jlinkoptions")
+ public void test(String[] opts, List<String> expectedFiles) throws Exception {
+ if (Files.notExists(MODULE_PATH)) {
+ // exploded image
+ return;
+ }
+
+ String dir = opts[0];
+ List<String> options = new ArrayList<>();
+ for (int i = 1; i < opts.length; i++) {
+ options.add(opts[i]);
+ }
+
+ String mpath = MODULE_PATH.toString() + File.pathSeparator +
+ JMODS_DIR.toString();
+ Stream.of("--module-path", mpath,
+ "--add-modules", "m1,m2,m3",
+ "--output", imageDir(dir))
+ .forEach(options::add);
+
+ Path image = createImage(dir, options, expectedFiles);
+
+ // check if any unexpected header file or man page
+ Set<Path> extraFiles = Files.walk(image, Integer.MAX_VALUE)
+ .filter(p -> Files.isRegularFile(p))
+ .filter(p -> p.getParent().endsWith("include") ||
+ p.getParent().endsWith("man"))
+ .filter(p -> {
+ String fn = String.format("%s/%s",
+ p.getParent().getFileName().toString(),
+ p.getFileName().toString());
+ return !expectedFiles.contains(fn);
+ })
+ .collect(Collectors.toSet());
+
+ if (extraFiles.size() > 0) {
+ System.out.println("Unexpected files: " + extraFiles.toString());
+ assertTrue(extraFiles.isEmpty());
+ }
+ }
+
+ /**
+ * Test java.base's include header files
+ */
+ @Test
+ public void testJavaBase() {
+ if (Files.notExists(MODULE_PATH)) {
+ // exploded image
+ return;
+ }
+ List<String> options = List.of("--module-path",
+ MODULE_PATH.toString(),
+ "--add-modules", "java.base",
+ "--output", imageDir("base"));
+ createImage("base", options,
+ List.of("include/jni.h", "include/jvmti.h"));
+
+ }
+
+ private Path createImage(String outputDir, List<String> options,
+ List<String> expectedFiles) {
+ System.out.println("jlink " + options.toString());
+ int rc = JLINK_TOOL.run(System.out, System.out,
+ options.toArray(new String[0]));
+ assertTrue(rc == 0);
+
+ Path d = IMAGES_DIR.resolve(outputDir);
+ for (String fn : expectedFiles) {
+ Path path = d.resolve(fn);
+ if (Files.notExists(path)) {
+ throw new RuntimeException(path + " not found");
+ }
+ }
+ return d;
+ }
+
+ private void deleteDirectory(Path dir) throws IOException {
+ Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+ throws IOException
+ {
+ Files.delete(file);
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult postVisitDirectory(Path dir, IOException exc)
+ throws IOException
+ {
+ Files.delete(dir);
+ return FileVisitResult.CONTINUE;
+ }
+ });
+ }
+
+ /**
+ * Builder to create JMOD file
+ */
+ class JmodFileBuilder {
+
+ final String name;
+ final Set<String> manPages = new HashSet<>();
+ final Set<String> headerFiles = new HashSet<>();
+
+ JmodFileBuilder(String name) throws IOException {
+ this.name = name;
+
+ Path msrc = SRC_DIR.resolve(name);
+ if (Files.exists(msrc)) {
+ deleteDirectory(msrc);
+ }
+ }
+
+ JmodFileBuilder manPage(String filename) {
+ manPages.add(filename);
+ return this;
+ }
+
+ JmodFileBuilder headerFile(String filename) {
+ headerFiles.add(filename);
+ return this;
+ }
+
+ Path build() throws IOException {
+ compileModule();
+ // create man pages
+ Path mdir = MAN_DIR.resolve(name);
+ for (String filename : manPages) {
+ Files.createDirectories(mdir);
+ Files.createFile(mdir.resolve(filename));
+ }
+ // create header files
+ mdir = INCLUDE_DIR.resolve(name);
+ for (String filename : headerFiles) {
+ Files.createDirectories(mdir);
+ Files.createFile(mdir.resolve(filename));
+ }
+ return createJmodFile();
+ }
+
+ void compileModule() throws IOException {
+ Path msrc = SRC_DIR.resolve(name);
+ Files.createDirectories(msrc);
+ Path minfo = msrc.resolve("module-info.java");
+ try (BufferedWriter bw = Files.newBufferedWriter(minfo);
+ PrintWriter writer = new PrintWriter(bw)) {
+ writer.format("module %s { }%n", name);
+ }
+
+ assertTrue(CompilerUtils.compile(msrc, MODS_DIR,
+ "--module-source-path",
+ SRC_DIR.toString()));
+ }
+
+ Path createJmodFile() throws IOException {
+ Path mclasses = MODS_DIR.resolve(name);
+ Files.createDirectories(JMODS_DIR);
+ Path outfile = JMODS_DIR.resolve(name + ".jmod");
+ List<String> args = new ArrayList<>();
+ args.add("create");
+ // add classes
+ args.add("--class-path");
+ args.add(mclasses.toString());
+ // man pages
+ if (manPages.size() > 0) {
+ args.add("--man-pages");
+ args.add(MAN_DIR.resolve(name).toString());
+ }
+ // header files
+ if (headerFiles.size() > 0) {
+ args.add("--header-files");
+ args.add(INCLUDE_DIR.resolve(name).toString());
+ }
+ args.add(outfile.toString());
+
+ if (Files.exists(outfile))
+ Files.delete(outfile);
+
+ System.out.println("jmod " +
+ args.stream().collect(Collectors.joining(" ")));
+
+ int rc = JMOD_TOOL.run(System.out, System.out,
+ args.toArray(new String[args.size()]));
+ if (rc != 0) {
+ throw new AssertionError("jmod failed: rc = " + rc);
+ }
+ return outfile;
+ }
+ }
+}
--- a/jdk/test/tools/jlink/plugins/LastSorterTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/tools/jlink/plugins/LastSorterTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -37,11 +37,11 @@
import java.util.Map;
import jdk.tools.jlink.internal.ImagePluginConfiguration;
+import jdk.tools.jlink.internal.ImagePluginStack;
+import jdk.tools.jlink.internal.Jlink;
+import jdk.tools.jlink.internal.Jlink.PluginsConfiguration;
import jdk.tools.jlink.internal.PluginRepository;
-import jdk.tools.jlink.internal.ImagePluginStack;
import jdk.tools.jlink.internal.ResourcePoolManager;
-import jdk.tools.jlink.Jlink;
-import jdk.tools.jlink.Jlink.PluginsConfiguration;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
--- a/jdk/test/tools/jlink/plugins/PluginsNegativeTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/tools/jlink/plugins/PluginsNegativeTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -36,11 +36,11 @@
import java.util.Map;
import jdk.tools.jlink.internal.ImagePluginConfiguration;
+import jdk.tools.jlink.internal.Jlink;
+import jdk.tools.jlink.internal.Jlink.PluginsConfiguration;
import jdk.tools.jlink.internal.PluginRepository;
import jdk.tools.jlink.internal.ImagePluginStack;
import jdk.tools.jlink.internal.ResourcePoolManager;
-import jdk.tools.jlink.Jlink;
-import jdk.tools.jlink.Jlink.PluginsConfiguration;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
--- a/jdk/test/tools/jlink/plugins/PrevisitorTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/tools/jlink/plugins/PrevisitorTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -40,13 +40,13 @@
import java.util.stream.Collectors;
import jdk.tools.jlink.internal.ImagePluginConfiguration;
+import jdk.tools.jlink.internal.Jlink;
import jdk.tools.jlink.internal.PluginRepository;
import jdk.tools.jlink.internal.ImagePluginStack;
import jdk.tools.jlink.internal.ResourcePoolManager;
import jdk.tools.jlink.internal.ResourcePoolManager.ResourcePoolImpl;
import jdk.tools.jlink.internal.ResourcePrevisitor;
import jdk.tools.jlink.internal.StringTable;
-import jdk.tools.jlink.Jlink;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jlink/toolprovider.policy Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,2 @@
+grant {
+};
--- a/jdk/test/tools/jmod/JmodNegativeTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/tools/jmod/JmodNegativeTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -24,8 +24,8 @@
/*
* @test
* @library /lib/testlibrary
- * @modules jdk.jlink/jdk.tools.jmod
- * jdk.compiler
+ * @modules jdk.compiler
+ * jdk.jlink
* @build jdk.testlibrary.FileUtils CompilerUtils
* @run testng JmodNegativeTest
* @summary Negative tests for jmod
@@ -39,6 +39,7 @@
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Supplier;
+import java.util.spi.ToolProvider;
import java.util.zip.ZipOutputStream;
import jdk.testlibrary.FileUtils;
import org.testng.annotations.BeforeTest;
@@ -51,6 +52,11 @@
public class JmodNegativeTest {
+ static final ToolProvider JMOD_TOOL = ToolProvider.findFirst("jmod")
+ .orElseThrow(() ->
+ new RuntimeException("jmod tool not found")
+ );
+
static final String TEST_SRC = System.getProperty("test.src", ".");
static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
static final Path EXPLODED_DIR = Paths.get("build");
@@ -515,7 +521,7 @@
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(baos);
System.out.println("jmod " + Arrays.asList(args));
- int ec = jdk.tools.jmod.Main.run(args, ps);
+ int ec = JMOD_TOOL.run(ps, ps, args);
return new JmodResult(ec, new String(baos.toByteArray(), UTF_8));
}
--- a/jdk/test/tools/jmod/JmodTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/tools/jmod/JmodTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -24,8 +24,8 @@
/*
* @test
* @library /lib/testlibrary
- * @modules jdk.jlink/jdk.tools.jmod
- * jdk.compiler
+ * @modules jdk.compiler
+ * jdk.jlink
* @build jdk.testlibrary.FileUtils CompilerUtils
* @run testng JmodTest
* @summary Basic test for jmod
@@ -38,6 +38,7 @@
import java.util.*;
import java.util.function.Consumer;
import java.util.regex.Pattern;
+import java.util.spi.ToolProvider;
import java.util.stream.Stream;
import jdk.testlibrary.FileUtils;
import org.testng.annotations.BeforeTest;
@@ -51,6 +52,11 @@
public class JmodTest {
+ static final ToolProvider JMOD_TOOL = ToolProvider.findFirst("jmod")
+ .orElseThrow(() ->
+ new RuntimeException("jmod tool not found")
+ );
+
static final String TEST_SRC = System.getProperty("test.src", ".");
static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
static final Path EXPLODED_DIR = Paths.get("build");
@@ -479,7 +485,7 @@
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(baos);
System.out.println("jmod " + Arrays.asList(args));
- int ec = jdk.tools.jmod.Main.run(args, ps);
+ int ec = JMOD_TOOL.run(ps, ps, args);
return new JmodResult(ec, new String(baos.toByteArray(), UTF_8));
}
--- a/jdk/test/tools/jmod/hashes/HashesTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/tools/jmod/hashes/HashesTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -27,8 +27,7 @@
* @author Andrei Eremeev
* @library /lib/testlibrary
* @modules java.base/jdk.internal.module
- * jdk.jlink/jdk.tools.jlink.internal
- * jdk.jlink/jdk.tools.jmod
+ * jdk.jlink
* jdk.compiler
* @build CompilerUtils
* @run testng HashesTest
@@ -53,6 +52,7 @@
import java.util.List;
import java.util.Optional;
import java.util.Set;
+import java.util.spi.ToolProvider;
import java.util.stream.Collectors;
import jdk.internal.module.ConfigurableModuleFinder;
@@ -63,6 +63,10 @@
import static org.testng.Assert.*;
public class HashesTest {
+ static final ToolProvider JMOD_TOOL = ToolProvider.findFirst("jmod")
+ .orElseThrow(() ->
+ new RuntimeException("jmod tool not found")
+ );
private final Path testSrc = Paths.get(System.getProperty("test.src"));
private final Path modSrc = testSrc.resolve("src");
@@ -204,7 +208,7 @@
}
private void runJmod(List<String> args) {
- int rc = jdk.tools.jmod.Main.run(args.toArray(new String[args.size()]), System.out);
+ int rc = JMOD_TOOL.run(System.out, System.out, args.toArray(new String[args.size()]));
System.out.println("jmod options: " + args.stream().collect(Collectors.joining(" ")));
if (rc != 0) {
throw new AssertionError("Jmod failed: rc = " + rc);
--- a/jdk/test/tools/launcher/modules/basic/BasicTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/tools/launcher/modules/basic/BasicTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -24,9 +24,9 @@
/**
* @test
* @library /lib/testlibrary
- * @modules jdk.jartool/sun.tools.jar
- * jdk.jlink/jdk.tools.jmod
- * jdk.compiler
+ * @modules jdk.compiler
+ * jdk.jartool
+ * jdk.jlink
* @build BasicTest CompilerUtils jdk.testlibrary.*
* @run testng BasicTest
* @summary Basic test of starting an application as a module
@@ -36,6 +36,7 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.util.spi.ToolProvider;
import jdk.testlibrary.ProcessTools;
@@ -46,6 +47,14 @@
@Test
public class BasicTest {
+ private static final ToolProvider JAR_TOOL = ToolProvider.findFirst("jar")
+ .orElseThrow(() ->
+ new RuntimeException("jar tool not found")
+ );
+ private static final ToolProvider JMOD_TOOL = ToolProvider.findFirst("jmod")
+ .orElseThrow(() ->
+ new RuntimeException("jmod tool not found")
+ );
private static final Path USER_DIR = Paths.get(System.getProperty("user.dir"));
@@ -132,10 +141,8 @@
"--main-class=" + MAIN_CLASS,
"-C", classes, "."
};
- boolean success
- = new sun.tools.jar.Main(System.out, System.out, "jar")
- .run(args);
- assertTrue(success);
+ int rc = JAR_TOOL.run(System.out, System.out, args);
+ assertTrue(rc == 0);
// java --module-path mlib -module $TESTMODULE
int exitValue = exec("--module-path", dir.toString(),
@@ -164,8 +171,8 @@
"--main-class", MAIN_CLASS,
jmod
};
- jdk.tools.jmod.JmodTask task = new jdk.tools.jmod.JmodTask();
- assertEquals(task.run(args), 0);
+
+ assertEquals(JMOD_TOOL.run(System.out, System.out, args), 0);
// java --module-path mods --module $TESTMODULE
int exitValue = exec("--module-path", dir.toString(),
@@ -229,10 +236,8 @@
"--file=" + jar,
"-C", classes, "."
};
- boolean success
- = new sun.tools.jar.Main(System.out, System.out, "jar")
- .run(args);
- assertTrue(success);
+ int rc = JAR_TOOL.run(System.out, System.out, args);
+ assertTrue(rc == 0);
// java --module-path mods -m $TESTMODULE
int exitValue = exec("--module-path", dir.toString(), "-m", TEST_MODULE);
--- a/jdk/test/tools/launcher/modules/dryrun/DryRunTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/tools/launcher/modules/dryrun/DryRunTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -26,7 +26,7 @@
* @bug 8159596
* @library /lib/testlibrary
* @modules jdk.compiler
- * jdk.jartool/sun.tools.jar
+ * jdk.jartool
* @build DryRunTest CompilerUtils jdk.testlibrary.ProcessTools
* @run testng DryRunTest
* @summary Test java --dry-run
@@ -37,6 +37,7 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.util.spi.ToolProvider;
import jdk.testlibrary.ProcessTools;
@@ -78,8 +79,8 @@
Files.createDirectories(LIBS_DIR);
// create JAR files with no module-info.class
- assertTrue(jar(M_MODULE, "p/Lib.class"));
- assertTrue(jar(TEST_MODULE, "jdk/test/Main.class"));
+ assertTrue(jar(M_MODULE, "p/Lib.class") == 0);
+ assertTrue(jar(TEST_MODULE, "jdk/test/Main.class") == 0);
}
/**
@@ -197,7 +198,12 @@
assertTrue(exitValue != 0);
}
- private static boolean jar(String name, String entries) throws IOException {
+ private static final ToolProvider JAR_TOOL = ToolProvider.findFirst("jar")
+ .orElseThrow(() ->
+ new RuntimeException("jar tool not found")
+ );
+
+ private static int jar(String name, String entries) throws IOException {
Path jar = LIBS_DIR.resolve(name + ".jar");
// jar --create ...
@@ -207,8 +213,6 @@
"--file=" + jar,
"-C", classes, entries
};
- boolean success
- = new sun.tools.jar.Main(System.out, System.out, "jar").run(args);
- return success;
+ return JAR_TOOL.run(System.out, System.out, args);
}
}
--- a/jdk/test/tools/lib/tests/JImageGenerator.java Wed Oct 26 15:46:13 2016 -0400
+++ b/jdk/test/tools/lib/tests/JImageGenerator.java Wed Oct 26 20:13:29 2016 +0000
@@ -338,6 +338,10 @@
}
public static class JModTask {
+ static final java.util.spi.ToolProvider JMOD_TOOL =
+ java.util.spi.ToolProvider.findFirst("jmod").orElseThrow(() ->
+ new RuntimeException("jmod tool not found")
+ );
private final List<Path> classpath = new ArrayList<>();
private final List<Path> libs = new ArrayList<>();
@@ -477,7 +481,8 @@
String[] args = optionsJMod(cmd);
System.err.println("jmod options: " + optionsPrettyPrint(args));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
- int exitCode = jdk.tools.jmod.Main.run(args, new PrintStream(baos));
+ PrintStream ps = new PrintStream(baos);
+ int exitCode = JMOD_TOOL.run(ps, ps, args);
String msg = new String(baos.toByteArray());
return new Result(exitCode, msg, output);
}
@@ -556,6 +561,10 @@
}
public static class JLinkTask {
+ static final java.util.spi.ToolProvider JLINK_TOOL =
+ java.util.spi.ToolProvider.findFirst("jlink").orElseThrow(() ->
+ new RuntimeException("jlink tool not found")
+ );
private final List<Path> jars = new ArrayList<>();
private final List<Path> jmods = new ArrayList<>();
@@ -691,7 +700,8 @@
String[] args = optionsJLink();
System.err.println("jlink options: " + optionsPrettyPrint(args));
StringWriter writer = new StringWriter();
- int exitCode = jdk.tools.jlink.internal.Main.run(args, new PrintWriter(writer));
+ PrintWriter pw = new PrintWriter(writer);
+ int exitCode = JLINK_TOOL.run(pw, pw, args);
return new Result(exitCode, writer.toString(), output);
}
@@ -699,7 +709,8 @@
String[] args = optionsPostProcessJLink();
System.err.println("jlink options: " + optionsPrettyPrint(args));
StringWriter writer = new StringWriter();
- int exitCode = jdk.tools.jlink.internal.Main.run(args, new PrintWriter(writer));
+ PrintWriter pw = new PrintWriter(writer);
+ int exitCode = JLINK_TOOL.run(pw, pw, args);
return new Result(exitCode, writer.toString(), output);
}
}
--- a/langtools/.hgtags Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/.hgtags Wed Oct 26 20:13:29 2016 +0000
@@ -382,3 +382,5 @@
dd56c243c199a540c9f1fbff4855f0934b32a9d0 jdk-9+137
90dd93e668a521642382561c47abe96ee2e065b7 jdk-9+138
17a82cb0e4b480e97021691d39917f15e3f7b653 jdk-9+139
+6842e63d6c3971172214b411f29965852ca175d1 jdk-9+140
+296c875051187918f8f3f87e9432036d13013d39 jdk-9+141
--- a/langtools/make/build.properties Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/make/build.properties Wed Oct 26 20:13:29 2016 +0000
@@ -24,11 +24,12 @@
#
#javac configuration for "normal build" (these will be passed to the bootstrap compiler):
-javac.opts = -XDignore.symbol.file=true -Xlint:all,-deprecation,-options -Werror -g:source,lines,vars
+javac.opts = -XDignore.symbol.file=true -Xlint:all,-deprecation,-options,-exports -Werror -g:source,lines,vars
javac.source = 9
javac.target = 9
#version used to compile build tools
+javac.build.opts = -XDignore.symbol.file=true -Xlint:all,-deprecation,-options -Werror -g:source,lines,vars
javac.build.source = 8
javac.build.target = 8
--- a/langtools/make/build.xml Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/make/build.xml Wed Oct 26 20:13:29 2016 +0000
@@ -275,7 +275,7 @@
classpath="${ant.core.lib}"
bootclasspath="${langtools.jdk.home}/jre/lib/rt.jar"
includeantruntime="false">
- <compilerarg line="${javac.opts} -XDstringConcat=inline"/>
+ <compilerarg line="${javac.build.opts} -XDstringConcat=inline"/>
</javac>
<taskdef name="pparse"
classname="anttasks.PropertiesParserTask"
@@ -291,7 +291,7 @@
destdir="${build.dir}/toolclasses/"
classpath="${ant.core.lib}"
includeantruntime="false">
- <compilerarg line="${javac.opts} -XDstringConcat=inline"/>
+ <compilerarg line="${javac.build.opts} -XDstringConcat=inline"/>
</javac>
<taskdef name="pcompile"
classname="anttasks.CompilePropertiesTask"
--- a/langtools/make/gensrc/GensrcCommon.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/make/gensrc/GensrcCommon.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2014, 2015, 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
--- a/langtools/make/intellij/misc.xml Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/make/intellij/misc.xml Wed Oct 26 20:13:29 2016 +0000
@@ -4,14 +4,17 @@
<entry_points version="2.0" />
</component>
<component name="JTRegService">
- <option name="JTRegDir" value="@IDEA_JTREG_HOME@" />
- <option name="JTRegOptions" value='@XPATCH@' />
- <option name="alternativeJrePath" value="@IDEA_TARGET_JDK@" />
- <option name="alternativeJrePathEnabled" value="true" />
- <option name="workDir" value="build" />
+ <path>@IDEA_JTREG_HOME@</path>
+ <workDir>build</workDir>
+ <jre alt="true" value="@IDEA_TARGET_JDK@" />
+ <options>@XPATCH@</options>
+ <ant>
+ <target file="file://$PROJECT_DIR$/.idea/build.xml" name="build-all-classes" />
+ </ant>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/.idea/out" />
</component>
</project>
+
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -113,7 +113,7 @@
* Internal compiler flags (no bits in the lower 16).
*****************************************/
- /** Flag is set if symbol is deprecated.
+ /** Flag is set if symbol is deprecated. See also DEPRECATED_REMOVAL.
*/
public static final int DEPRECATED = 1<<17;
@@ -293,6 +293,11 @@
*/
public static final long SYSTEM_MODULE = 1L<<53;
+ /**
+ * Flag to indicate the given symbol has been deprecated and marked for removal.
+ */
+ public static final long DEPRECATED_REMOVAL = 1L<<54;
+
/** Modifier masks.
*/
public static final int
@@ -402,7 +407,8 @@
THROWS(Flags.THROWS),
LAMBDA_METHOD(Flags.LAMBDA_METHOD),
TYPE_TRANSLATED(Flags.TYPE_TRANSLATED),
- MODULE(Flags.MODULE);
+ MODULE(Flags.MODULE),
+ DEPRECATED_REMOVAL(Flags.DEPRECATED_REMOVAL);
Flag(long flag) {
this.value = flag;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java Wed Oct 26 20:13:29 2016 +0000
@@ -25,11 +25,13 @@
package com.sun.tools.javac.code;
+import java.util.Arrays;
import java.util.EnumSet;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.sun.tools.javac.code.Symbol.*;
+import com.sun.tools.javac.main.Option;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.Options;
@@ -81,12 +83,13 @@
}
/**
- * Returns a new Lint that has the given LintCategory suppressed.
+ * Returns a new Lint that has the given LintCategorys suppressed.
+ * @param lc one or more categories to be suppressed
*/
- public Lint suppress(LintCategory lc) {
+ public Lint suppress(LintCategory... lc) {
Lint l = new Lint(this);
- l.values.remove(lc);
- l.suppressedValues.add(lc);
+ l.values.removeAll(Arrays.asList(lc));
+ l.suppressedValues.addAll(Arrays.asList(lc));
return l;
}
@@ -100,10 +103,31 @@
protected Lint(Context context) {
// initialize values according to the lint options
Options options = Options.instance(context);
- values = EnumSet.noneOf(LintCategory.class);
- for (Map.Entry<String, LintCategory> e: map.entrySet()) {
- if (options.lint(e.getKey()))
- values.add(e.getValue());
+
+ if (options.isSet(Option.XLINT) || options.isSet(Option.XLINT_CUSTOM, "all")) {
+ // If -Xlint or -Xlint:all is given, enable all categories by default
+ values = EnumSet.allOf(LintCategory.class);
+ } else if (options.isSet(Option.XLINT_CUSTOM, "none")) {
+ // if -Xlint:none is given, disable all categories by default
+ values = EnumSet.noneOf(LintCategory.class);
+ } else {
+ // otherwise, enable on-by-default categories
+ values = EnumSet.noneOf(LintCategory.class);
+
+ Source source = Source.instance(context);
+ if (source.compareTo(Source.JDK1_9) >= 0) {
+ values.add(LintCategory.DEP_ANN);
+ }
+ values.add(LintCategory.REMOVAL);
+ }
+
+ // Look for specific overrides
+ for (LintCategory lc : LintCategory.values()) {
+ if (options.isSet(Option.XLINT_CUSTOM, lc.option)) {
+ values.add(lc);
+ } else if (options.isSet(Option.XLINT_CUSTOM, "-" + lc.option)) {
+ values.remove(lc);
+ }
}
suppressedValues = EnumSet.noneOf(LintCategory.class);
@@ -213,6 +237,11 @@
RAW("rawtypes"),
/**
+ * Warn about use of deprecated-for-removal items.
+ */
+ REMOVAL("removal"),
+
+ /**
* Warn about Serializable classes that do not provide a serial version ID.
*/
SERIAL("serial"),
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java Wed Oct 26 20:13:29 2016 +0000
@@ -359,6 +359,10 @@
return (flags_field & DEPRECATED) != 0;
}
+ public boolean isDeprecatedForRemoval() {
+ return (flags_field & DEPRECATED_REMOVAL) != 0;
+ }
+
public boolean isDeprecatableViaAnnotation() {
switch (getKind()) {
case LOCAL_VARIABLE:
@@ -949,6 +953,7 @@
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public java.util.List<Directive> getDirectives() {
+ complete();
completeUsesProvides();
return Collections.unmodifiableList(directives);
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java Wed Oct 26 20:13:29 2016 +0000
@@ -30,6 +30,7 @@
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
+import java.util.Optional;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.function.BiPredicate;
@@ -468,89 +469,14 @@
* and return-type substitutable with each method in the original list.
*/
private FunctionDescriptor mergeDescriptors(TypeSymbol origin, List<Symbol> methodSyms) {
- //pick argument types - simply take the signature that is a
- //subsignature of all other signatures in the list (as per JLS 8.4.2)
- List<Symbol> mostSpecific = List.nil();
- outer: for (Symbol msym1 : methodSyms) {
- Type mt1 = memberType(origin.type, msym1);
- for (Symbol msym2 : methodSyms) {
- Type mt2 = memberType(origin.type, msym2);
- if (!isSubSignature(mt1, mt2)) {
- continue outer;
- }
- }
- mostSpecific = mostSpecific.prepend(msym1);
- }
- if (mostSpecific.isEmpty()) {
- return null;
- }
-
-
- //pick return types - this is done in two phases: (i) first, the most
- //specific return type is chosen using strict subtyping; if this fails,
- //a second attempt is made using return type substitutability (see JLS 8.4.5)
- boolean phase2 = false;
- Symbol bestSoFar = null;
- while (bestSoFar == null) {
- outer: for (Symbol msym1 : mostSpecific) {
- Type mt1 = memberType(origin.type, msym1);
- for (Symbol msym2 : methodSyms) {
- Type mt2 = memberType(origin.type, msym2);
- if (phase2 ?
- !returnTypeSubstitutable(mt1, mt2) :
- !isSubtypeInternal(mt1.getReturnType(), mt2.getReturnType())) {
- continue outer;
+ return mergeAbstracts(methodSyms, origin.type, false)
+ .map(bestSoFar -> new FunctionDescriptor(bestSoFar.baseSymbol()) {
+ @Override
+ public Type getType(Type origin) {
+ Type mt = memberType(origin, getSymbol());
+ return createMethodTypeWithThrown(mt, bestSoFar.type.getThrownTypes());
}
- }
- bestSoFar = msym1;
- }
- if (phase2) {
- break;
- } else {
- phase2 = true;
- }
- }
- if (bestSoFar == null) return null;
-
- //merge thrown types - form the intersection of all the thrown types in
- //all the signatures in the list
- List<Type> thrown = null;
- Type mt1 = memberType(origin.type, bestSoFar);
- boolean toErase = !mt1.hasTag(FORALL);
- for (Symbol msym2 : methodSyms) {
- Type mt2 = memberType(origin.type, msym2);
- List<Type> thrown_mt2 = mt2.getThrownTypes();
- if (toErase) {
- thrown_mt2 = erasure(thrown_mt2);
- } else {
- /* If bestSoFar is generic then all the methods are generic.
- * The opposite is not true: a non generic method can override
- * a generic method (raw override) so it's safe to cast mt1 and
- * mt2 to ForAll.
- */
- ForAll fa1 = (ForAll)mt1;
- ForAll fa2 = (ForAll)mt2;
- thrown_mt2 = subst(thrown_mt2, fa2.tvars, fa1.tvars);
- }
- thrown = (thrown == null) ?
- thrown_mt2 :
- chk.intersect(thrown_mt2, thrown);
- }
-
- final List<Type> thrown1 = thrown;
- return new FunctionDescriptor(bestSoFar) {
- @Override
- public Type getType(Type origin) {
- Type mt = memberType(origin, getSymbol());
- return createMethodTypeWithThrown(mt, thrown1);
- }
- };
- }
-
- boolean isSubtypeInternal(Type s, Type t) {
- return (s.isPrimitive() && t.isPrimitive()) ?
- isSameType(t, s) :
- isSubtype(s, t);
+ }).orElse(null);
}
FunctionDescriptorLookupError failure(String msg, Object... args) {
@@ -2604,6 +2530,106 @@
return false;
}
+ /**
+ * This enum defines the strategy for implementing most specific return type check
+ * during the most specific and functional interface checks.
+ */
+ public enum MostSpecificReturnCheck {
+ /**
+ * Return r1 is more specific than r2 if {@code r1 <: r2}. Extra care required for (i) handling
+ * method type variables (if either method is generic) and (ii) subtyping should be replaced
+ * by type-equivalence for primitives. This is essentially an inlined version of
+ * {@link Types#resultSubtype(Type, Type, Warner)}, where the assignability check has been
+ * replaced with a strict subtyping check.
+ */
+ BASIC() {
+ @Override
+ public boolean test(Type mt1, Type mt2, Types types) {
+ List<Type> tvars = mt1.getTypeArguments();
+ List<Type> svars = mt2.getTypeArguments();
+ Type t = mt1.getReturnType();
+ Type s = types.subst(mt2.getReturnType(), svars, tvars);
+ return types.isSameType(t, s) ||
+ !t.isPrimitive() &&
+ !s.isPrimitive() &&
+ types.isSubtype(t, s);
+ }
+ },
+ /**
+ * Return r1 is more specific than r2 if r1 is return-type-substitutable for r2.
+ */
+ RTS() {
+ @Override
+ public boolean test(Type mt1, Type mt2, Types types) {
+ return types.returnTypeSubstitutable(mt1, mt2);
+ }
+ };
+
+ public abstract boolean test(Type mt1, Type mt2, Types types);
+ }
+
+ /**
+ * Merge multiple abstract methods. The preferred method is a method that is a subsignature
+ * of all the other signatures and whose return type is more specific {@see MostSpecificReturnCheck}.
+ * The resulting preferred method has a thrown clause that is the intersection of the merged
+ * methods' clauses.
+ */
+ public Optional<Symbol> mergeAbstracts(List<Symbol> ambiguousInOrder, Type site, boolean sigCheck) {
+ //first check for preconditions
+ boolean shouldErase = false;
+ List<Type> erasedParams = ambiguousInOrder.head.erasure(this).getParameterTypes();
+ for (Symbol s : ambiguousInOrder) {
+ if ((s.flags() & ABSTRACT) == 0 ||
+ (sigCheck && !isSameTypes(erasedParams, s.erasure(this).getParameterTypes()))) {
+ return Optional.empty();
+ } else if (s.type.hasTag(FORALL)) {
+ shouldErase = true;
+ }
+ }
+ //then merge abstracts
+ for (MostSpecificReturnCheck mostSpecificReturnCheck : MostSpecificReturnCheck.values()) {
+ outer: for (Symbol s : ambiguousInOrder) {
+ Type mt = memberType(site, s);
+ List<Type> allThrown = mt.getThrownTypes();
+ for (Symbol s2 : ambiguousInOrder) {
+ if (s != s2) {
+ Type mt2 = memberType(site, s2);
+ if (!isSubSignature(mt, mt2) ||
+ !mostSpecificReturnCheck.test(mt, mt2, this)) {
+ //ambiguity cannot be resolved
+ continue outer;
+ } else {
+ List<Type> thrownTypes2 = mt2.getThrownTypes();
+ if (!mt.hasTag(FORALL) && shouldErase) {
+ thrownTypes2 = erasure(thrownTypes2);
+ } else if (mt.hasTag(FORALL)) {
+ //subsignature implies that if most specific is generic, then all other
+ //methods are too
+ Assert.check(mt2.hasTag(FORALL));
+ // if both are generic methods, adjust thrown types ahead of intersection computation
+ thrownTypes2 = subst(thrownTypes2, mt2.getTypeArguments(), mt.getTypeArguments());
+ }
+ allThrown = chk.intersect(allThrown, thrownTypes2);
+ }
+ }
+ }
+ return (allThrown == mt.getThrownTypes()) ?
+ Optional.of(s) :
+ Optional.of(new MethodSymbol(
+ s.flags(),
+ s.name,
+ createMethodTypeWithThrown(s.type, allThrown),
+ s.owner) {
+ @Override
+ public Symbol baseSymbol() {
+ return s;
+ }
+ });
+ }
+ }
+ return Optional.empty();
+ }
+
// <editor-fold defaultstate="collapsed" desc="Determining method implementation in given site">
class ImplementationCache {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -340,6 +340,13 @@
&& toAnnotate.owner.kind != MTH
&& types.isSameType(c.type, syms.deprecatedType)) {
toAnnotate.flags_field |= Flags.DEPRECATED;
+ Attribute fr = c.member(names.forRemoval);
+ if (fr instanceof Attribute.Constant) {
+ Attribute.Constant v = (Attribute.Constant) fr;
+ if (v.type == syms.booleanType && ((Integer) v.value) != 0) {
+ toAnnotate.flags_field |= Flags.DEPRECATED_REMOVAL;
+ }
+ }
}
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Wed Oct 26 20:13:29 2016 +0000
@@ -2398,6 +2398,7 @@
try {
if (needsRecovery && isSerializable(pt())) {
localEnv.info.isSerializable = true;
+ localEnv.info.isLambda = true;
}
List<Type> explicitParamTypes = null;
if (that.paramKind == JCLambda.ParameterKind.EXPLICIT) {
@@ -2969,7 +2970,7 @@
}
if (isTargetSerializable) {
- chk.checkElemAccessFromSerializableLambda(that);
+ chk.checkAccessFromSerializableElement(that, true);
}
}
@@ -3364,7 +3365,7 @@
}
if (env.info.isSerializable) {
- chk.checkElemAccessFromSerializableLambda(tree);
+ chk.checkAccessFromSerializableElement(tree, env.info.isLambda);
}
result = checkId(tree, env1.enclClass.sym.type, sym, env, resultInfo);
@@ -3507,7 +3508,7 @@
}
if (env.info.isSerializable) {
- chk.checkElemAccessFromSerializableLambda(tree);
+ chk.checkAccessFromSerializableElement(tree, env.info.isLambda);
}
env.info.selectSuper = selectSuperPrev;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrContext.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrContext.java Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -56,10 +56,15 @@
*/
boolean selectSuper = false;
- /** Is the current target of lambda expression or method reference serializable?
+ /** Is the current target of lambda expression or method reference serializable or is this a
+ * serializable class?
*/
boolean isSerializable = false;
+ /** Is this a lambda environment?
+ */
+ boolean isLambda = false;
+
/** Is this a speculative attribution environment?
*/
boolean isSpeculative = false;
@@ -117,6 +122,7 @@
info.returnResult = returnResult;
info.defaultSuperCallSite = defaultSuperCallSite;
info.isSerializable = isSerializable;
+ info.isLambda = isLambda;
info.isSpeculative = isSpeculative;
info.isAnonymousDiamond = isAnonymousDiamond;
info.isNewClass = isNewClass;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java Wed Oct 26 20:13:29 2016 +0000
@@ -87,7 +87,7 @@
private final JavaFileManager fileManager;
private final Source source;
private final Profile profile;
- private final boolean warnOnAccessToSensitiveMembers;
+ private final boolean warnOnAnyAccessToMembers;
// The set of lint options currently in effect. It is initialized
// from the context, and then is set/reset as needed by Attr as it
@@ -131,7 +131,7 @@
allowStrictMethodClashCheck = source.allowStrictMethodClashCheck();
allowPrivateSafeVarargs = source.allowPrivateSafeVarargs();
allowDiamondWithAnonymousClassCreation = source.allowDiamondWithAnonymousClassCreation();
- warnOnAccessToSensitiveMembers = options.isSet("warnOnAccessToSensitiveMembers");
+ warnOnAnyAccessToMembers = options.isSet("warnOnAccessToMembers");
Target target = Target.instance(context);
syntheticNameChar = target.syntheticNameChar();
@@ -139,11 +139,14 @@
profile = Profile.instance(context);
boolean verboseDeprecated = lint.isEnabled(LintCategory.DEPRECATION);
+ boolean verboseRemoval = lint.isEnabled(LintCategory.REMOVAL);
boolean verboseUnchecked = lint.isEnabled(LintCategory.UNCHECKED);
boolean enforceMandatoryWarnings = true;
deprecationHandler = new MandatoryWarningHandler(log, verboseDeprecated,
enforceMandatoryWarnings, "deprecated", LintCategory.DEPRECATION);
+ removalHandler = new MandatoryWarningHandler(log, verboseRemoval,
+ enforceMandatoryWarnings, "removal", LintCategory.REMOVAL);
uncheckedHandler = new MandatoryWarningHandler(log, verboseUnchecked,
enforceMandatoryWarnings, "unchecked", LintCategory.UNCHECKED);
sunApiHandler = new MandatoryWarningHandler(log, false,
@@ -185,6 +188,10 @@
*/
private MandatoryWarningHandler deprecationHandler;
+ /** A handler for messages about deprecated-for-removal usage.
+ */
+ private MandatoryWarningHandler removalHandler;
+
/** A handler for messages about unchecked or unsafe usage.
*/
private MandatoryWarningHandler uncheckedHandler;
@@ -218,8 +225,13 @@
* @param sym The deprecated symbol.
*/
void warnDeprecated(DiagnosticPosition pos, Symbol sym) {
- if (!lint.isSuppressed(LintCategory.DEPRECATION))
+ if (sym.isDeprecatedForRemoval()) {
+ if (!lint.isSuppressed(LintCategory.REMOVAL)) {
+ removalHandler.report(pos, "has.been.deprecated.for.removal", sym, sym.location());
+ }
+ } else if (!lint.isSuppressed(LintCategory.DEPRECATION)) {
deprecationHandler.report(pos, "has.been.deprecated", sym, sym.location());
+ }
}
/** Warn about unchecked operation.
@@ -257,6 +269,7 @@
*/
public void reportDeferredDiagnostics() {
deprecationHandler.reportDeferredDiagnostic();
+ removalHandler.reportDeferredDiagnostic();
uncheckedHandler.reportDeferredDiagnostic();
sunApiHandler.reportDeferredDiagnostic();
}
@@ -2605,8 +2618,11 @@
}
}
- void checkElemAccessFromSerializableLambda(final JCTree tree) {
- if (warnOnAccessToSensitiveMembers) {
+ void checkAccessFromSerializableElement(final JCTree tree, boolean isLambda) {
+ if (warnOnAnyAccessToMembers ||
+ (lint.isEnabled(LintCategory.SERIAL) &&
+ !lint.isSuppressed(LintCategory.SERIAL) &&
+ isLambda)) {
Symbol sym = TreeInfo.symbol(tree);
if (!sym.kind.matches(KindSelector.VAL_MTH)) {
return;
@@ -2622,9 +2638,16 @@
}
if (!types.isSubtype(sym.owner.type, syms.serializableType) &&
- isEffectivelyNonPublic(sym)) {
- log.warning(tree.pos(),
- "access.to.sensitive.member.from.serializable.element", sym);
+ isEffectivelyNonPublic(sym)) {
+ if (isLambda) {
+ if (belongsToRestrictedPackage(sym)) {
+ log.warning(LintCategory.SERIAL, tree.pos(),
+ "access.to.member.from.serializable.lambda", sym);
+ }
+ } else {
+ log.warning(tree.pos(),
+ "access.to.member.from.serializable.element", sym);
+ }
}
}
}
@@ -2643,6 +2666,14 @@
return false;
}
+ private boolean belongsToRestrictedPackage(Symbol sym) {
+ String fullName = sym.packge().fullname.toString();
+ return fullName.startsWith("java.") ||
+ fullName.startsWith("javax.") ||
+ fullName.startsWith("sun.") ||
+ fullName.contains(".internal.");
+ }
+
/** Report a conflict between a user symbol and a synthetic symbol.
*/
private void syntheticError(DiagnosticPosition pos, Symbol sym) {
@@ -3212,9 +3243,9 @@
}
void checkDeprecated(final DiagnosticPosition pos, final Symbol other, final Symbol s) {
- if ((s.flags() & DEPRECATED) != 0 &&
- (other.flags() & DEPRECATED) == 0 &&
- s.outermostClass() != other.outermostClass()) {
+ if ( (s.isDeprecatedForRemoval()
+ || s.isDeprecated() && !other.isDeprecated())
+ && s.outermostClass() != other.outermostClass()) {
deferredLintHandler.report(new DeferredLintHandler.LintLogger() {
@Override
public void report() {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java Wed Oct 26 20:13:29 2016 +0000
@@ -29,6 +29,7 @@
import java.util.HashMap;
+import com.sun.source.tree.LambdaExpressionTree.BodyKind;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Scope.WriteableScope;
import com.sun.tools.javac.tree.*;
@@ -224,7 +225,7 @@
diagHandler = new Log.DiscardDiagnosticHandler(log);
}
try {
- new AliveAnalyzer().analyzeTree(env, that, make);
+ new LambdaAliveAnalyzer().analyzeTree(env, that, make);
} finally {
if (!speculative) {
log.popDiagnosticHandler(diagHandler);
@@ -241,19 +242,7 @@
//related errors, which will allow for more errors to be detected
Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log);
try {
- new AssignAnalyzer() {
- WriteableScope enclosedSymbols = WriteableScope.create(env.enclClass.sym);
- @Override
- public void visitVarDef(JCVariableDecl tree) {
- enclosedSymbols.enter(tree.sym);
- super.visitVarDef(tree);
- }
- @Override
- protected boolean trackable(VarSymbol sym) {
- return enclosedSymbols.includes(sym) &&
- sym.owner.kind == MTH;
- }
- }.analyzeTree(env, that);
+ new LambdaAssignAnalyzer(env).analyzeTree(env, that);
LambdaFlowAnalyzer flowAnalyzer = new LambdaFlowAnalyzer();
flowAnalyzer.analyzeTree(env, that, make);
return flowAnalyzer.inferredThrownTypes;
@@ -1341,6 +1330,79 @@
}
/**
+ * Specialized pass that performs reachability analysis on a lambda
+ */
+ class LambdaAliveAnalyzer extends AliveAnalyzer {
+
+ boolean inLambda;
+
+ @Override
+ public void visitReturn(JCReturn tree) {
+ //ignore lambda return expression (which might not even be attributed)
+ recordExit(new PendingExit(tree));
+ }
+
+ @Override
+ public void visitLambda(JCLambda tree) {
+ if (inLambda || tree.getBodyKind() == BodyKind.EXPRESSION) {
+ return;
+ }
+ inLambda = true;
+ try {
+ super.visitLambda(tree);
+ } finally {
+ inLambda = false;
+ }
+ }
+
+ @Override
+ public void visitClassDef(JCClassDecl tree) {
+ //skip
+ }
+ }
+
+ /**
+ * Specialized pass that performs DA/DU on a lambda
+ */
+ class LambdaAssignAnalyzer extends AssignAnalyzer {
+ WriteableScope enclosedSymbols;
+ boolean inLambda;
+
+ LambdaAssignAnalyzer(Env<AttrContext> env) {
+ enclosedSymbols = WriteableScope.create(env.enclClass.sym);
+ }
+
+ @Override
+ public void visitLambda(JCLambda tree) {
+ if (inLambda) {
+ return;
+ }
+ inLambda = true;
+ try {
+ super.visitLambda(tree);
+ } finally {
+ inLambda = false;
+ }
+ }
+
+ @Override
+ public void visitVarDef(JCVariableDecl tree) {
+ enclosedSymbols.enter(tree.sym);
+ super.visitVarDef(tree);
+ }
+ @Override
+ protected boolean trackable(VarSymbol sym) {
+ return enclosedSymbols.includes(sym) &&
+ sym.owner.kind == MTH;
+ }
+
+ @Override
+ public void visitClassDef(JCClassDecl tree) {
+ //skip
+ }
+ }
+
+ /**
* Specialized pass that performs inference of thrown types for lambdas.
*/
class LambdaFlowAnalyzer extends FlowAnalyzer {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Wed Oct 26 20:13:29 2016 +0000
@@ -1691,28 +1691,6 @@
}
}
//where
- Type mostSpecificReturnType(Type mt1, Type mt2) {
- Type rt1 = mt1.getReturnType();
- Type rt2 = mt2.getReturnType();
-
- if (mt1.hasTag(FORALL) && mt2.hasTag(FORALL)) {
- //if both are generic methods, adjust return type ahead of subtyping check
- rt1 = types.subst(rt1, mt1.getTypeArguments(), mt2.getTypeArguments());
- }
- //first use subtyping, then return type substitutability
- if (types.isSubtype(rt1, rt2)) {
- return mt1;
- } else if (types.isSubtype(rt2, rt1)) {
- return mt2;
- } else if (types.returnTypeSubstitutable(mt1, mt2)) {
- return mt1;
- } else if (types.returnTypeSubstitutable(mt2, mt1)) {
- return mt2;
- } else {
- return null;
- }
- }
- //where
Symbol ambiguityError(Symbol m1, Symbol m2) {
if (((m1.flags() | m2.flags()) & CLASH) != 0) {
return (m1.flags() & CLASH) == 0 ? m1 : m2;
@@ -4112,43 +4090,7 @@
*/
Symbol mergeAbstracts(Type site) {
List<Symbol> ambiguousInOrder = ambiguousSyms.reverse();
- for (Symbol s : ambiguousInOrder) {
- Type mt = types.memberType(site, s);
- boolean found = true;
- List<Type> allThrown = mt.getThrownTypes();
- for (Symbol s2 : ambiguousInOrder) {
- Type mt2 = types.memberType(site, s2);
- if ((s2.flags() & ABSTRACT) == 0 ||
- !types.overrideEquivalent(mt, mt2) ||
- !types.isSameTypes(s.erasure(types).getParameterTypes(),
- s2.erasure(types).getParameterTypes())) {
- //ambiguity cannot be resolved
- return this;
- }
- Type mst = mostSpecificReturnType(mt, mt2);
- if (mst == null || mst != mt) {
- found = false;
- break;
- }
- List<Type> thrownTypes2 = mt2.getThrownTypes();
- if (mt.hasTag(FORALL) && mt2.hasTag(FORALL)) {
- // if both are generic methods, adjust thrown types ahead of intersection computation
- thrownTypes2 = types.subst(thrownTypes2, mt2.getTypeArguments(), mt.getTypeArguments());
- }
- allThrown = chk.intersect(allThrown, thrownTypes2);
- }
- if (found) {
- //all ambiguous methods were abstract and one method had
- //most specific return type then others
- return (allThrown == mt.getThrownTypes()) ?
- s : new MethodSymbol(
- s.flags(),
- s.name,
- types.createMethodTypeWithThrown(s.type, allThrown),
- s.owner);
- }
- }
- return this;
+ return types.mergeAbstracts(ambiguousInOrder, site, true).orElse(this);
}
@Override
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -103,7 +103,6 @@
private final TypeAnnotations typeAnnotations;
private final Types types;
private final JCDiagnostic.Factory diags;
- private final Source source;
private final DeferredLintHandler deferredLintHandler;
private final Lint lint;
private final TypeEnvs typeEnvs;
@@ -131,7 +130,6 @@
typeAnnotations = TypeAnnotations.instance(context);
types = Types.instance(context);
diags = JCDiagnostic.Factory.instance(context);
- source = Source.instance(context);
deferredLintHandler = DeferredLintHandler.instance(context);
lint = Lint.instance(context);
typeEnvs = TypeEnvs.instance(context);
@@ -178,6 +176,7 @@
/** Complete entering a class.
* @param sym The symbol of the class to be completed.
*/
+ @Override
public void complete(Symbol sym) throws CompletionFailure {
// Suppress some (recursive) MemberEnter invocations
if (!completionEnabled) {
@@ -414,7 +413,7 @@
Type attribImportType(JCTree tree, Env<AttrContext> env) {
Assert.check(completionEnabled);
Lint prevLint = chk.setLint(allowDeprecationOnImport ?
- lint : lint.suppress(LintCategory.DEPRECATION));
+ lint : lint.suppress(LintCategory.DEPRECATION, LintCategory.REMOVAL));
try {
// To prevent deep recursion, suppress completion of some
// types.
@@ -751,12 +750,12 @@
// can attribute the annotation types and then check to see if the
// @Deprecated annotation is present.
attr.attribAnnotationTypes(tree.mods.annotations, baseEnv);
- if (hasDeprecatedAnnotation(tree.mods.annotations))
- sym.flags_field |= DEPRECATED;
+ handleDeprecatedAnnotation(tree.mods.annotations, sym);
chk.checkNonCyclicDecl(tree);
}
//where:
+ @Override
protected JCExpression clearTypeParams(JCExpression superType) {
switch (superType.getTag()) {
case TYPEAPPLY:
@@ -767,16 +766,29 @@
}
/**
- * Check if a list of annotations contains a reference to
- * java.lang.Deprecated.
+ * If a list of annotations contains a reference to java.lang.Deprecated,
+ * set the DEPRECATED flag.
+ * If the annotation is marked forRemoval=true, also set DEPRECATED_REMOVAL.
**/
- private boolean hasDeprecatedAnnotation(List<JCAnnotation> annotations) {
+ private void handleDeprecatedAnnotation(List<JCAnnotation> annotations, Symbol sym) {
for (List<JCAnnotation> al = annotations; !al.isEmpty(); al = al.tail) {
JCAnnotation a = al.head;
- if (a.annotationType.type == syms.deprecatedType && a.args.isEmpty())
- return true;
+ if (a.annotationType.type == syms.deprecatedType) {
+ sym.flags_field |= Flags.DEPRECATED;
+ a.args.stream()
+ .filter(e -> e.hasTag(ASSIGN))
+ .map(e -> (JCAssign) e)
+ .filter(assign -> TreeInfo.name(assign.lhs) == names.forRemoval)
+ .findFirst()
+ .ifPresent(assign -> {
+ JCExpression rhs = TreeInfo.skipParens(assign.rhs);
+ if (rhs.hasTag(LITERAL)
+ && Boolean.TRUE.equals(((JCLiteral) rhs).getValue())) {
+ sym.flags_field |= DEPRECATED_REMOVAL;
+ }
+ });
+ }
}
- return false;
}
@Override
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/BaseFileManager.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/BaseFileManager.java Wed Oct 26 20:13:29 2016 +0000
@@ -52,8 +52,6 @@
import javax.tools.JavaFileObject;
import javax.tools.JavaFileObject.Kind;
-import com.sun.tools.javac.code.Lint;
-import com.sun.tools.javac.code.Source;
import com.sun.tools.javac.main.Option;
import com.sun.tools.javac.main.OptionHelper;
import com.sun.tools.javac.main.OptionHelper.GrumpyHelper;
@@ -85,7 +83,10 @@
log = Log.instance(context);
options = Options.instance(context);
classLoaderClass = options.get("procloader");
- locations.update(log, Lint.instance(context), FSInfo.instance(context));
+
+ // Avoid initializing Lint
+ boolean warn = options.isLintSet("path");
+ locations.update(log, warn, FSInfo.instance(context));
// Setting this option is an indication that close() should defer actually closing
// the file manager until after a specified period of inactivity.
@@ -171,14 +172,6 @@
private long lastUsedTime = System.currentTimeMillis();
protected long deferredCloseTimeout = 0;
- protected Source getSource() {
- String sourceName = options.get(Option.SOURCE);
- Source source = null;
- if (sourceName != null)
- source = Source.lookup(sourceName);
- return (source != null ? source : Source.DEFAULT);
- }
-
protected ClassLoader getClassLoader(URL[] urls) {
ClassLoader thisClassLoader = getClass().getClassLoader();
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java Wed Oct 26 20:13:29 2016 +0000
@@ -42,7 +42,6 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.ProviderNotFoundException;
-import java.nio.file.spi.FileSystemProvider;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -63,7 +62,6 @@
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
-import java.util.zip.ZipFile;
import javax.lang.model.SourceVersion;
import javax.tools.JavaFileManager;
@@ -159,10 +157,9 @@
}
}
- // could replace Lint by "boolean warn"
- void update(Log log, Lint lint, FSInfo fsInfo) {
+ void update(Log log, boolean warn, FSInfo fsInfo) {
this.log = log;
- warn = lint.isEnabled(Lint.LintCategory.PATH);
+ this.warn = warn;
this.fsInfo = fsInfo;
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java Wed Oct 26 20:13:29 2016 +0000
@@ -1460,7 +1460,6 @@
ListBuffer<CompoundAnnotationProxy> proxies = new ListBuffer<>();
for (int i = 0; i<numAttributes; i++) {
CompoundAnnotationProxy proxy = readCompoundAnnotation();
-
if (proxy.type.tsym == syms.proprietaryType.tsym)
sym.flags_field |= PROPRIETARY;
else if (proxy.type.tsym == syms.profileType.tsym) {
@@ -1479,6 +1478,16 @@
target = proxy;
} else if (proxy.type.tsym == syms.repeatableType.tsym) {
repeatable = proxy;
+ } else if (proxy.type.tsym == syms.deprecatedType.tsym) {
+ sym.flags_field |= DEPRECATED;
+ for (Pair<Name, Attribute> v : proxy.values) {
+ if (v.fst == names.forRemoval && v.snd instanceof Attribute.Constant) {
+ Attribute.Constant c = (Attribute.Constant) v.snd;
+ if (c.type == syms.booleanType && ((Integer) c.value) != 0) {
+ sym.flags_field |= DEPRECATED_REMOVAL;
+ }
+ }
+ }
}
proxies.append(proxy);
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java Wed Oct 26 20:13:29 2016 +0000
@@ -37,6 +37,7 @@
import java.util.EnumSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
import java.util.Locale;
import java.util.Map;
import java.util.ServiceLoader;
@@ -111,7 +112,6 @@
"all",
log.localize(PrefixKind.JAVAC, "opt.Xlint.all")));
for (LintCategory lc : LintCategory.values()) {
- if (lc.hidden) continue;
log.printRawLines(WriterKind.STDOUT,
String.format(LINT_KEY_FORMAT,
lc.option,
@@ -801,8 +801,8 @@
/** The kind of choices for this option, if any. */
private final ChoiceKind choiceKind;
- /** The choices for this option, if any, and whether or not the choices are hidden. */
- private final Map<String,Boolean> choices;
+ /** The choices for this option, if any. */
+ private final Set<String> choices;
/**
* Looks up the first option matching the given argument in the full set of options.
@@ -815,7 +815,8 @@
/**
* Looks up the first option matching the given argument within a set of options.
- * @param arg the argument to be matches
+ * @param arg the argument to be matched
+ * @param options the set of possible options
* @return the first option that matches, or null if none.
*/
public static Option lookup(String arg, Set<Option> options) {
@@ -867,7 +868,7 @@
}
Option(String text, String argsNameKey, String descrKey, OptionKind kind, OptionGroup group,
- ChoiceKind choiceKind, Map<String,Boolean> choices) {
+ ChoiceKind choiceKind, Set<String> choices) {
this(text, argsNameKey, descrKey, kind, group, choiceKind, choices, ArgKind.REQUIRED);
}
@@ -875,19 +876,12 @@
OptionKind kind, OptionGroup group,
ChoiceKind choiceKind, String... choices) {
this(text, null, descrKey, kind, group, choiceKind,
- createChoices(choices), ArgKind.REQUIRED);
+ new LinkedHashSet<>(Arrays.asList(choices)), ArgKind.REQUIRED);
}
- // where
- private static Map<String,Boolean> createChoices(String... choices) {
- Map<String,Boolean> map = new LinkedHashMap<>();
- for (String c: choices)
- map.put(c, false);
- return map;
- }
private Option(String text, String argsNameKey, String descrKey,
OptionKind kind, OptionGroup group,
- ChoiceKind choiceKind, Map<String,Boolean> choices,
+ ChoiceKind choiceKind, Set<String> choices,
ArgKind argKind) {
this.names = text.trim().split("\\s+");
Assert.check(names.length >= 1);
@@ -943,10 +937,10 @@
if (choices != null) {
String arg = option.substring(name.length());
if (choiceKind == ChoiceKind.ONEOF)
- return choices.keySet().contains(arg);
+ return choices.contains(arg);
else {
for (String a: arg.split(",+")) {
- if (!choices.keySet().contains(a))
+ if (!choices.contains(a))
return false;
}
}
@@ -1016,7 +1010,7 @@
if (choices != null) {
if (choiceKind == ChoiceKind.ONEOF) {
// some clients like to see just one of option+choice set
- for (String s: choices.keySet())
+ for (String s : choices)
helper.remove(primaryName + s);
String opt = primaryName + arg;
helper.put(opt, opt);
@@ -1113,12 +1107,10 @@
if (argsNameKey == null) {
if (choices != null) {
String sep = "{";
- for (Map.Entry<String,Boolean> e: choices.entrySet()) {
- if (!e.getValue()) {
- sb.append(sep);
- sb.append(e.getKey());
- sep = ",";
- }
+ for (String choice : choices) {
+ sb.append(sep);
+ sb.append(choices);
+ sep = ",";
}
sb.append("}");
}
@@ -1163,14 +1155,14 @@
}
}
- private static Map<String,Boolean> getXLintChoices() {
- Map<String,Boolean> choices = new LinkedHashMap<>();
- choices.put("all", false);
- for (Lint.LintCategory c : Lint.LintCategory.values())
- choices.put(c.option, c.hidden);
- for (Lint.LintCategory c : Lint.LintCategory.values())
- choices.put("-" + c.option, c.hidden);
- choices.put("none", false);
+ private static Set<String> getXLintChoices() {
+ Set<String> choices = new LinkedHashSet<>();
+ choices.add("all");
+ for (Lint.LintCategory c : Lint.LintCategory.values()) {
+ choices.add(c.option);
+ choices.add("-" + c.option);
+ }
+ choices.add("none");
return choices;
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Wed Oct 26 20:13:29 2016 +0000
@@ -1321,14 +1321,31 @@
Some input files additionally use or override a deprecated API.
# 0: file name
+compiler.note.removal.filename=\
+ {0} uses or overrides a deprecated API that is marked for removal.
+
+compiler.note.removal.plural=\
+ Some input files use or override a deprecated API that is marked for removal.
+
+# The following string may appear after one of the above removal messages.
+compiler.note.removal.recompile=\
+ Recompile with -Xlint:removal for details.
+
+# 0: file name
+compiler.note.removal.filename.additional=\
+ {0} has additional uses or overrides of a deprecated API that is marked for removal.
+
+compiler.note.removal.plural.additional=\
+ Some input files additionally use or override a deprecated API that is marked for removal.
+
+# 0: file name
compiler.note.unchecked.filename=\
{0} uses unchecked or unsafe operations.
compiler.note.unchecked.plural=\
Some input files use unchecked or unsafe operations.
-# The following string may appear after one of the above deprecation
-# messages.
+# The following string may appear after one of the above unchecked messages.
compiler.note.unchecked.recompile=\
Recompile with -Xlint:unchecked for details.
@@ -1441,6 +1458,10 @@
compiler.warn.has.been.deprecated=\
{0} in {1} has been deprecated
+# 0: symbol, 1: symbol
+compiler.warn.has.been.deprecated.for.removal=\
+ {0} in {1} has been deprecated and marked for removal
+
# 0: symbol
compiler.warn.sun.proprietary=\
{0} is internal proprietary API and may be removed in a future release
@@ -1712,8 +1733,12 @@
Redundant {0} annotation. {1}
# 0: symbol
-compiler.warn.access.to.sensitive.member.from.serializable.element=\
- access to sensitive member {0} from serializable element can be publicly accessible to untrusted code
+compiler.warn.access.to.member.from.serializable.element=\
+ access to member {0} from serializable element can be publicly accessible to untrusted code
+
+# 0: symbol
+compiler.warn.access.to.member.from.serializable.lambda=\
+ access to member {0} from serializable lambda can be publicly accessible to untrusted code
#####
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties Wed Oct 26 20:13:29 2016 +0000
@@ -219,8 +219,12 @@
javac.opt.Xlint.desc.rawtypes=\
Warn about use of raw types.
+javac.opt.Xlint.desc.removal=\
+ Warn about use of API that has been marked for removal.
+
javac.opt.Xlint.desc.serial=\
- Warn about Serializable classes that do not provide a serial version ID.
+ Warn about Serializable classes that do not provide a serial version ID. \n\
+\ Also warn about access to non-public members from a serializable element.
javac.opt.Xlint.desc.static=\
Warn about accessing a static member using an instance.
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Names.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Names.java Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -87,6 +87,7 @@
public final Name family;
public final Name finalize;
public final Name forName;
+ public final Name forRemoval;
public final Name getClass;
public final Name getClassLoader;
public final Name getComponentType;
@@ -242,6 +243,7 @@
family = fromString("family");
finalize = fromString("finalize");
forName = fromString("forName");
+ forRemoval = fromString("forRemoval");
getClass = fromString("getClass");
getClassLoader = fromString("getClassLoader");
getComponentType = fromString("getComponentType");
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Options.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Options.java Wed Oct 26 20:13:29 2016 +0000
@@ -27,7 +27,6 @@
import java.util.*;
-import com.sun.tools.javac.code.Source;
import com.sun.tools.javac.main.Option;
import static com.sun.tools.javac.main.Option.*;
@@ -113,6 +112,18 @@
return (values.get(option.primaryName + value) != null);
}
+ /** Check if the value for a lint option has been explicitly set, either with -Xlint:opt
+ * or if all lint options have enabled and this one not disabled with -Xlint:-opt.
+ */
+ public boolean isLintSet(String s) {
+ // return true if either the specific option is enabled, or
+ // they are all enabled without the specific one being
+ // disabled
+ return
+ isSet(XLINT_CUSTOM, s) ||
+ (isSet(XLINT) || isSet(XLINT_CUSTOM, "all")) && isUnset(XLINT_CUSTOM, "-" + s);
+ }
+
/**
* Check if the value for an undocumented option has not been set.
*/
@@ -170,25 +181,4 @@
for (Runnable r: listeners)
r.run();
}
-
- /** Check for a lint suboption. */
- public boolean lint(String s) {
- // return true if either the specific option is enabled, or
- // they are all enabled without the specific one being
- // disabled
- return
- isSet(XLINT_CUSTOM, s) ||
- (isSet(XLINT) || isSet(XLINT_CUSTOM, "all") || (s.equals("dep-ann") && depAnnOnByDefault())) &&
- isUnset(XLINT_CUSTOM, "-" + s);
- }
- // where
- private boolean depAnnOnByDefault() {
- String sourceName = get(Option.SOURCE);
- Source source = null;
- if (sourceName != null)
- source = Source.lookup(sourceName);
- if (source == null)
- source = Source.DEFAULT;
- return source.compareTo(Source.JDK1_9) >= 0;
- }
}
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java Wed Oct 26 20:13:29 2016 +0000
@@ -353,11 +353,12 @@
protected Content getFramesJavaScript() {
HtmlTree script = HtmlTree.SCRIPT();
String scriptCode = DocletConstants.NL +
- " targetPage = \"\" + window.location.search;" + DocletConstants.NL +
- " if (targetPage != \"\" && targetPage != \"undefined\")" + DocletConstants.NL +
- " targetPage = targetPage.substring(1);" + DocletConstants.NL +
- " if (targetPage.indexOf(\":\") != -1 || (targetPage != \"\" && !validURL(targetPage)))" + DocletConstants.NL +
- " targetPage = \"undefined\";" + DocletConstants.NL +
+ " tmpTargetPage = \"\" + window.location.search;" + DocletConstants.NL +
+ " if (tmpTargetPage != \"\" && tmpTargetPage != \"undefined\")" + DocletConstants.NL +
+ " tmpTargetPage = tmpTargetPage.substring(1);" + DocletConstants.NL +
+ " if (tmpTargetPage.indexOf(\":\") != -1 || (tmpTargetPage != \"\" && !validURL(tmpTargetPage)))" + DocletConstants.NL +
+ " tmpTargetPage = \"undefined\";" + DocletConstants.NL +
+ " targetPage = tmpTargetPage;" + DocletConstants.NL +
" function validURL(url) {" + DocletConstants.NL +
" try {" + DocletConstants.NL +
" url = decodeURIComponent(url);" + DocletConstants.NL +
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlWriter.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlWriter.java Wed Oct 26 20:13:29 2016 +0000
@@ -234,11 +234,12 @@
protected Content getFramesJavaScript() {
HtmlTree scriptTree = HtmlTree.SCRIPT();
String scriptCode = "\n" +
- " targetPage = \"\" + window.location.search;\n" +
- " if (targetPage != \"\" && targetPage != \"undefined\")\n" +
- " targetPage = targetPage.substring(1);\n" +
- " if (targetPage.indexOf(\":\") != -1 || (targetPage != \"\" && !validURL(targetPage)))\n" +
- " targetPage = \"undefined\";\n" +
+ " tmpTargetPage = \"\" + window.location.search;\n" +
+ " if (tmpTargetPage != \"\" && tmpTargetPage != \"undefined\")\n" +
+ " tmpTargetPage = tmpTargetPage.substring(1);\n" +
+ " if (tmpTargetPage.indexOf(\":\") != -1 || (tmpTargetPage != \"\" && !validURL(tmpTargetPage)))\n" +
+ " tmpTargetPage = \"undefined\";\n" +
+ " targetPage = tmpTargetPage;\n" +
" function validURL(url) {\n" +
" try {\n" +
" url = decodeURIComponent(url);\n" +
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/search.js Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/search.js Wed Oct 26 20:13:29 2016 +0000
@@ -30,6 +30,9 @@
var catTypes = "Types";
var catMembers = "Members";
var catSearchTags = "SearchTags";
+var highlight = "<span class=\"resultHighlight\">$&</span>";
+var camelCaseRegexp = "";
+var secondaryMatcher = "";
function getName(name) {
var anchor = "";
var ch = '';
@@ -65,27 +68,35 @@
}
return anchor;
}
+function getHighlightedText(item) {
+ var ccMatcher = new RegExp(camelCaseRegexp);
+ var label = item.replace(ccMatcher, highlight);
+ if (label === item) {
+ label = item.replace(secondaryMatcher, highlight);
+ }
+ return label;
+}
var watermark = 'Search';
$(function() {
$("#search").prop("disabled", false);
$("#reset").prop("disabled", false);
$("#search").val(watermark).addClass('watermark');
- $("#search").blur(function(){
+ $("#search").blur(function() {
if ($(this).val().length == 0) {
$(this).val(watermark).addClass('watermark');
}
});
- $("#search").keydown(function(){
- if ($(this).val() == watermark) {
+ $("#search").keydown(function() {
+ if ($(this).val() == watermark) {
$(this).val('').removeClass('watermark');
}
});
- $("#reset").click(function(){
- $("#search").val('');
- $("#search").focus();
+ $("#reset").click(function() {
+ $("#search").val('');
+ $("#search").focus();
});
$("#search").focus();
- $("#search")[0].setSelectionRange(0,0);
+ $("#search")[0].setSelectionRange(0, 0);
});
$.widget("custom.catcomplete", $.ui.autocomplete, {
_create: function() {
@@ -112,22 +123,19 @@
});
},
_renderItem: function(ul, item) {
- var result = this.element.val();
- var regexp = new RegExp($.ui.autocomplete.escapeRegex(result), "i");
- highlight = "<span class=\"resultHighlight\">$&</span>";
var label = "";
if (item.category === catModules) {
- label = item.l.replace(regexp, highlight);
+ label = getHighlightedText(item.l);
} else if (item.category === catPackages) {
label = (item.m)
- ? (item.m + "/" + item.l).replace(regexp, highlight)
- : item.l.replace(regexp, highlight);
+ ? getHighlightedText(item.m + "/" + item.l)
+ : getHighlightedText(item.l);
} else if (item.category === catTypes) {
- label += (item.p + "." + item.l).replace(regexp, highlight);
+ label = getHighlightedText(item.p + "." + item.l);
} else if (item.category === catMembers) {
- label += item.p + "." + (item.c + "." + item.l).replace(regexp, highlight);
+ label = getHighlightedText(item.p + "." + (item.c + "." + item.l));
} else if (item.category === catSearchTags) {
- label = item.l.replace(regexp, highlight);
+ label = getHighlightedText(item.l);
} else {
label = item.l;
}
@@ -163,7 +171,9 @@
var tgresult = new Array();
var displayCount = 0;
var exactMatcher = new RegExp("^" + $.ui.autocomplete.escapeRegex(request.term) + "$", "i");
- var secondaryMatcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
+ camelCaseRegexp = ($.ui.autocomplete.escapeRegex(request.term)).split(/(?=[A-Z])/).join("([a-z0-9_$]*?)");
+ var camelCaseMatcher = new RegExp("^" + camelCaseRegexp);
+ secondaryMatcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
if (moduleSearchIndex) {
var mdleCount = 0;
$.each(moduleSearchIndex, function(index, item) {
@@ -171,6 +181,8 @@
if (exactMatcher.test(item.l)) {
result.unshift(item);
mdleCount++;
+ } else if (camelCaseMatcher.test(item.l)) {
+ result.unshift(item);
} else if (secondaryMatcher.test(item.l)) {
result.push(item);
}
@@ -188,6 +200,8 @@
if (exactMatcher.test(item.l)) {
presult.unshift(item);
pCount++;
+ } else if (camelCaseMatcher.test(pkg)) {
+ presult.unshift(item);
} else if (secondaryMatcher.test(pkg)) {
presult.push(item);
}
@@ -202,6 +216,8 @@
if (exactMatcher.test(item.l)) {
tresult.unshift(item);
tCount++;
+ } else if (camelCaseMatcher.test(item.l)) {
+ tresult.unshift(item);
} else if (secondaryMatcher.test(item.p + "." + item.l)) {
tresult.push(item);
}
@@ -216,6 +232,8 @@
if (exactMatcher.test(item.l)) {
mresult.unshift(item);
mCount++;
+ } else if (camelCaseMatcher.test(item.l)) {
+ mresult.unshift(item);
} else if (secondaryMatcher.test(item.c + "." + item.l)) {
mresult.push(item);
}
@@ -294,4 +312,4 @@
}
}
});
-});
+});
\ No newline at end of file
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Configuration.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Configuration.java Wed Oct 26 20:13:29 2016 +0000
@@ -308,9 +308,7 @@
public CommentUtils cmtUtils;
/**
- * A sorted set of packages specified on the command-line merged with a
- * collection of packages that contain the classes specified on the
- * command-line.
+ * A sorted set of included packages.
*/
public SortedSet<PackageElement> packages = null;
@@ -399,10 +397,8 @@
private void initPackages() {
packages = new TreeSet<>(utils.makePackageComparator());
- packages.addAll(getSpecifiedPackages());
- for (TypeElement aClass : getSpecifiedClasses()) {
- packages.add(utils.containingPackage(aClass));
- }
+ // add all the included packages
+ packages.addAll(docEnv.getIncludedPackageElements());
}
public Set<Doclet.Option> getSupportedOptions() {
@@ -647,7 +643,7 @@
if (docencoding == null) {
docencoding = encoding;
}
- typeElementCatalog = new TypeElementCatalog(getSpecifiedClasses(), this);
+ typeElementCatalog = new TypeElementCatalog(docEnv.getIncludedTypeElements(), this);
initTagletManager(customTagStrs);
groups.stream().forEach((grp) -> {
group.checkPackageGroups(grp.value1, grp.value2);
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java Wed Oct 26 20:13:29 2016 +0000
@@ -587,18 +587,28 @@
}
private Set<PackageElement> computeModulePackages() throws ToolException {
- final AccessKind accessValue = accessFilter.getAccessValue(ElementKind.PACKAGE);
+ AccessKind accessValue = accessFilter.getAccessValue(ElementKind.PACKAGE);
final boolean documentAllModulePackages = (accessValue == AccessKind.PACKAGE ||
accessValue == AccessKind.PRIVATE);
+ accessValue = accessFilter.getAccessValue(ElementKind.MODULE);
+ final boolean moduleDetailedMode = (accessValue == AccessKind.PACKAGE ||
+ accessValue == AccessKind.PRIVATE);
Set<PackageElement> expandedModulePackages = new LinkedHashSet<>();
for (ModuleElement mdle : specifiedModuleElements) {
- // add all exported packages belonging to a specified module
- if (specifiedModuleElements.contains(mdle)) {
+ if (documentAllModulePackages) { // include all packages
+ List<PackageElement> packages = ElementFilter.packagesIn(mdle.getEnclosedElements());
+ expandedModulePackages.addAll(packages);
+ expandedModulePackages.addAll(getAllModulePackages(mdle));
+ } else { // selectively include required packages
List<ExportsDirective> exports = ElementFilter.exportsIn(mdle.getDirectives());
for (ExportsDirective export : exports) {
- expandedModulePackages.add(export.getPackage());
+ // add if fully exported or add qualified exports only if desired
+ if (export.getTargetModules() == null
+ || documentAllModulePackages || moduleDetailedMode) {
+ expandedModulePackages.add(export.getPackage());
+ }
}
}
@@ -613,27 +623,6 @@
}
}
}
-
- if (!documentAllModulePackages) {
- List<ExportsDirective> exports = ElementFilter.exportsIn(mdle.getDirectives());
- // check exported packages
- for (ExportsDirective export : exports) {
- List<? extends ModuleElement> targetModules = export.getTargetModules();
- if (targetModules == null) { // no qualified exports, add 'em all
- expandedModulePackages.add(export.getPackage());
- } else { // qualified export, add only if target module is being considered
- for (ModuleElement target : targetModules) {
- if (specifiedModuleElements.contains(target)) {
- expandedModulePackages.add(export.getPackage());
- }
- }
- }
- }
- } else { // add all exported and module private packages
- List<PackageElement> packages = ElementFilter.packagesIn(mdle.getEnclosedElements());
- expandedModulePackages.addAll(packages);
- expandedModulePackages.addAll(getAllModulePackages(mdle));
- }
}
return expandedModulePackages;
}
@@ -668,8 +657,7 @@
if (!mdle.isUnnamed())
imodules.add(mdle);
PackageElement pkg = toolEnv.elements.getPackageOf(klass);
- if (!pkg.isUnnamed())
- ipackages.add(pkg);
+ ipackages.add(pkg);
addAllClasses(iclasses, klass, true);
});
--- a/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/Main.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/Main.java Wed Oct 26 20:13:29 2016 +0000
@@ -384,14 +384,14 @@
.collect(toList()));
} else {
// TODO: kind of a hack...
- // Create a throwaway compilation task with options "-release N"
+ // Create a throwaway compilation task with options "--release N"
// which has the side effect of setting the file manager's
// PLATFORM_CLASS_PATH to the right value.
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fm =
compiler.getStandardFileManager(this, null, StandardCharsets.UTF_8);
JavaCompiler.CompilationTask task =
- compiler.getTask(null, fm, this, List.of("-release", release), null, null);
+ compiler.getTask(null, fm, this, List.of("--release", release), null, null);
List<Path> paths = new ArrayList<>();
for (Path p : fm.getLocationAsPaths(StandardLocation.PLATFORM_CLASS_PATH)) {
try (Stream<Path> str = Files.walk(p)) {
--- a/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsTask.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsTask.java Wed Oct 26 20:13:29 2016 +0000
@@ -680,20 +680,21 @@
private boolean genModuleInfo(JdepsConfiguration config) throws IOException {
// check if any JAR file contains unnamed package
for (String arg : inputArgs) {
- Optional<String> classInUnnamedPackage =
- ClassFileReader.newInstance(Paths.get(arg))
- .entries().stream()
- .filter(n -> n.endsWith(".class"))
- .filter(cn -> toPackageName(cn).isEmpty())
- .findFirst();
+ try (ClassFileReader reader = ClassFileReader.newInstance(Paths.get(arg))) {
+ Optional<String> classInUnnamedPackage =
+ reader.entries().stream()
+ .filter(n -> n.endsWith(".class"))
+ .filter(cn -> toPackageName(cn).isEmpty())
+ .findFirst();
- if (classInUnnamedPackage.isPresent()) {
- if (classInUnnamedPackage.get().equals("module-info.class")) {
- reportError("err.genmoduleinfo.not.jarfile", arg);
- } else {
- reportError("err.genmoduleinfo.unnamed.package", arg);
+ if (classInUnnamedPackage.isPresent()) {
+ if (classInUnnamedPackage.get().equals("module-info.class")) {
+ reportError("err.genmoduleinfo.not.jarfile", arg);
+ } else {
+ reportError("err.genmoduleinfo.unnamed.package", arg);
+ }
+ return false;
}
- return false;
}
}
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ArgTokenizer.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ArgTokenizer.java Wed Oct 26 20:13:29 2016 +0000
@@ -30,7 +30,6 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.stream.Stream;
import static java.util.stream.Collectors.toList;
/**
@@ -78,7 +77,12 @@
while (true) {
nextToken();
if (sval != null && !isQuoted() && sval.startsWith("-")) {
- foundOption(sval);
+ // allow POSIX getopt() option format,
+ // to be consistent with command-line
+ String opt = sval.startsWith("--")
+ ? sval.substring(1)
+ : sval;
+ foundOption(opt);
} else {
break;
}
@@ -104,28 +108,13 @@
}
}
- String[] next(String... strings) {
- return next(Arrays.stream(strings));
- }
-
- String[] next(Stream<String> stream) {
- next();
- if (sval == null) {
- return null;
- }
- String[] matches = stream
- .filter(s -> s.startsWith(sval))
- .toArray(size -> new String[size]);
- return matches;
- }
-
/**
* Set the allowed options. Must be called before any options would be read
* and before calling any of the option functionality below.
*/
void allowedOptions(String... opts) {
for (String opt : opts) {
- options.put(opt, false);
+ options.putIfAbsent(opt, false);
}
}
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java Wed Oct 26 20:13:29 2016 +0000
@@ -31,6 +31,7 @@
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.InputStream;
+import java.io.InterruptedIOException;
import java.io.PrintStream;
import java.io.UncheckedIOException;
import java.lang.reflect.Method;
@@ -61,6 +62,8 @@
import jdk.internal.jline.console.history.MemoryHistory;
import jdk.internal.jline.extra.EditingHistory;
import jdk.internal.jshell.tool.StopDetectingInputStream.State;
+import jdk.internal.misc.Signal;
+import jdk.internal.misc.Signal.Handler;
class ConsoleIOContext extends IOContext {
@@ -170,6 +173,21 @@
bind(shortcuts + computer.shortcut, (ActionListener) evt -> fixes(computer));
}
}
+ try {
+ Signal.handle(new Signal("CONT"), new Handler() {
+ @Override public void handle(Signal sig) {
+ try {
+ in.getTerminal().reset();
+ in.redrawLine();
+ in.flush();
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+ });
+ } catch (IllegalArgumentException ignored) {
+ //the CONT signal does not exist on this platform
+ }
}
@Override
@@ -390,7 +408,7 @@
private int inputBytesPointer;
@Override
- public synchronized int readUserInput() {
+ public synchronized int readUserInput() throws IOException {
while (inputBytes == null || inputBytes.length <= inputBytesPointer) {
boolean prevHandleUserInterrupt = in.getHandleUserInterrupt();
History prevHistory = in.getHistory();
@@ -401,12 +419,8 @@
in.setHistory(userInputHistory);
inputBytes = (in.readLine("") + System.getProperty("line.separator")).getBytes();
inputBytesPointer = 0;
- } catch (IOException ex) {
- ex.printStackTrace();
- return -1;
} catch (UserInterruptException ex) {
- repl.state.stop();
- return -1;
+ throw new InterruptedIOException();
} finally {
in.setHistory(prevHistory);
in.setHandleUserInterrupt(prevHandleUserInterrupt);
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ExternalEditor.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ExternalEditor.java Wed Oct 26 20:13:29 2016 +0000
@@ -80,7 +80,7 @@
private void setupWatch(String initialText) throws IOException {
this.watcher = FileSystems.getDefault().newWatchService();
this.dir = Files.createTempDirectory("jshelltemp");
- this.tmpfile = Files.createTempFile(dir, null, ".edit");
+ this.tmpfile = Files.createTempFile(dir, null, ".java");
Files.write(tmpfile, initialText.getBytes(Charset.forName("UTF-8")));
dir.register(watcher,
ENTRY_CREATE,
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/Feedback.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/Feedback.java Wed Oct 26 20:13:29 2016 +0000
@@ -28,16 +28,26 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.Objects;
+import java.util.Set;
+import java.util.StringJoiner;
+import java.util.function.BiConsumer;
+import java.util.function.BinaryOperator;
+import java.util.function.Consumer;
import java.util.function.Function;
+import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import java.util.stream.Collector;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toMap;
import static jdk.internal.jshell.tool.ContinuousCompletionProvider.PERFECT_MATCHER;
@@ -114,8 +124,8 @@
return mode.getContinuationPrompt(nextId);
}
- public boolean setFeedback(MessageHandler messageHandler, ArgTokenizer at) {
- return new Setter(messageHandler, at).setFeedback();
+ public boolean setFeedback(MessageHandler messageHandler, ArgTokenizer at, Consumer<String> retainer) {
+ return new Setter(messageHandler, at).setFeedback(retainer);
}
public boolean setFormat(MessageHandler messageHandler, ArgTokenizer at) {
@@ -126,22 +136,14 @@
return new Setter(messageHandler, at).setTruncation();
}
- public boolean setMode(MessageHandler messageHandler, ArgTokenizer at) {
- return new Setter(messageHandler, at).setMode();
+ public boolean setMode(MessageHandler messageHandler, ArgTokenizer at, Consumer<String> retainer) {
+ return new Setter(messageHandler, at).setMode(retainer);
}
public boolean setPrompt(MessageHandler messageHandler, ArgTokenizer at) {
return new Setter(messageHandler, at).setPrompt();
}
- public String retainFeedback(MessageHandler messageHandler, ArgTokenizer at) {
- return new Setter(messageHandler, at).retainFeedback();
- }
-
- public String retainMode(MessageHandler messageHandler, ArgTokenizer at) {
- return new Setter(messageHandler, at).retainMode();
- }
-
public boolean restoreEncodedModes(MessageHandler messageHandler, String encoded) {
return new Setter(messageHandler, new ArgTokenizer("<init>", "")).restoreEncodedModes(encoded);
}
@@ -177,6 +179,15 @@
selectorMap.put(e.name().toLowerCase(Locale.US), e);
}
+ private static class SelectorSets {
+ Set<FormatCase> cc;
+ Set<FormatAction> ca;
+ Set<FormatWhen> cw;
+ Set<FormatResolve> cr;
+ Set<FormatUnresolved> cu;
+ Set<FormatErrors> ce;
+ }
+
/**
* Holds all the context of a mode mode
*/
@@ -197,12 +208,32 @@
String continuationPrompt = ">> ";
static class Setting {
+
final long enumBits;
final String format;
+
Setting(long enumBits, String format) {
this.enumBits = enumBits;
this.format = format;
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof Setting) {
+ Setting ing = (Setting) o;
+ return enumBits == ing.enumBits && format.equals(ing.format);
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 67 * hash + (int) (this.enumBits ^ (this.enumBits >>> 32));
+ hash = 67 * hash + Objects.hashCode(this.format);
+ return hash;
+ }
}
/**
@@ -274,6 +305,25 @@
}
}
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof Mode) {
+ Mode m = (Mode) o;
+ return name.equals((m.name))
+ && commandFluff == m.commandFluff
+ && prompt.equals((m.prompt))
+ && continuationPrompt.equals((m.continuationPrompt))
+ && cases.equals((m.cases));
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(name);
+ }
+
/**
* Set if this mode displays informative/confirmational messages on
* commands.
@@ -308,13 +358,17 @@
return String.join(RECORD_SEPARATOR, el);
}
- private boolean add(String field, Setting ing) {
- List<Setting> settings = cases.computeIfAbsent(field, k -> new ArrayList<>());
+ private void add(String field, Setting ing) {
+ List<Setting> settings = cases.get(field);
if (settings == null) {
- return false;
+ settings = new ArrayList<>();
+ cases.put(field, settings);
+ } else {
+ // remove obscured settings
+ long mask = ~ing.enumBits;
+ settings.removeIf(t -> (t.enumBits & mask) == 0);
}
settings.add(ing);
- return true;
}
void set(String field,
@@ -465,6 +519,37 @@
return res;
}
+ private static SelectorSets unpackEnumbits(long enumBits) {
+ class Unpacker {
+
+ SelectorSets u = new SelectorSets();
+ long b = enumBits;
+
+ <E extends Enum<E>> Set<E> unpackEnumbits(E[] values) {
+ Set<E> c = new HashSet<>();
+ for (int i = 0; i < values.length; ++i) {
+ if ((b & (1 << i)) != 0) {
+ c.add(values[i]);
+ }
+ }
+ b >>>= values.length;
+ return c;
+ }
+
+ SelectorSets unpack() {
+ // inverseof the order they were packed
+ u.ce = unpackEnumbits(FormatErrors.values());
+ u.cu = unpackEnumbits(FormatUnresolved.values());
+ u.cr = unpackEnumbits(FormatResolve.values());
+ u.cw = unpackEnumbits(FormatWhen.values());
+ u.ca = unpackEnumbits(FormatAction.values());
+ u.cc = unpackEnumbits(FormatCase.values());
+ return u;
+ }
+ }
+ return new Unpacker().unpack();
+ }
+
interface Selector<E extends Enum<E> & Selector<E>> {
SelectorCollector<E> collector(Setter.SelectorList sl);
String doc();
@@ -675,31 +760,197 @@
Setter(MessageHandler messageHandler, ArgTokenizer at) {
this.messageHandler = messageHandler;
this.at = at;
+ at.allowedOptions("-retain");
}
void fluff(String format, Object... args) {
messageHandler.fluff(format, args);
}
+ void hard(String format, Object... args) {
+ messageHandler.hard(format, args);
+ }
+
void fluffmsg(String messageKey, Object... args) {
messageHandler.fluffmsg(messageKey, args);
}
+ void hardmsg(String messageKey, Object... args) {
+ messageHandler.hardmsg(messageKey, args);
+ }
+
+ boolean showFluff() {
+ return messageHandler.showFluff();
+ }
+
void errorat(String messageKey, Object... args) {
+ if (!valid) {
+ // no spew of errors
+ return;
+ }
+ valid = false;
Object[] a2 = Arrays.copyOf(args, args.length + 2);
a2[args.length] = at.whole();
messageHandler.errormsg(messageKey, a2);
}
+ String selectorsToString(SelectorSets u) {
+ StringBuilder sb = new StringBuilder();
+ selectorToString(sb, u.cc, FormatCase.values());
+ selectorToString(sb, u.ca, FormatAction.values());
+ selectorToString(sb, u.cw, FormatWhen.values());
+ selectorToString(sb, u.cr, FormatResolve.values());
+ selectorToString(sb, u.cu, FormatUnresolved.values());
+ selectorToString(sb, u.ce, FormatErrors.values());
+ return sb.toString();
+ }
+
+ private <E extends Enum<E>> void selectorToString(StringBuilder sb, Set<E> c, E[] values) {
+ if (!c.containsAll(Arrays.asList(values))) {
+ sb.append(c.stream()
+ .sorted((x, y) -> x.ordinal() - y.ordinal())
+ .map(v -> v.name().toLowerCase(Locale.US))
+ .collect(new Collector<CharSequence, StringJoiner, String>() {
+ @Override
+ public BiConsumer<StringJoiner, CharSequence> accumulator() {
+ return StringJoiner::add;
+ }
+
+ @Override
+ public Supplier<StringJoiner> supplier() {
+ return () -> new StringJoiner(",", (sb.length() == 0)? "" : "-", "")
+ .setEmptyValue("");
+ }
+
+ @Override
+ public BinaryOperator<StringJoiner> combiner() {
+ return StringJoiner::merge;
+ }
+
+ @Override
+ public Function<StringJoiner, String> finisher() {
+ return StringJoiner::toString;
+ }
+
+ @Override
+ public Set<Characteristics> characteristics() {
+ return Collections.emptySet();
+ }
+ }));
+ }
+ }
+
+ // Show format settings -- in a predictable order, for testing...
+ void showFormatSettings(Mode sm, String f) {
+ if (sm == null) {
+ modeMap.entrySet().stream()
+ .sorted((es1, es2) -> es1.getKey().compareTo(es2.getKey()))
+ .forEach(m -> showFormatSettings(m.getValue(), f));
+ } else {
+ sm.cases.entrySet().stream()
+ .filter(ec -> (f == null)
+ ? !ec.getKey().equals(TRUNCATION_FIELD)
+ : ec.getKey().equals(f))
+ .sorted((ec1, ec2) -> ec1.getKey().compareTo(ec2.getKey()))
+ .forEach(ec -> {
+ ec.getValue().forEach(s -> {
+ hard("/set format %s %s %s %s",
+ sm.name, ec.getKey(), toStringLiteral(s.format),
+ selectorsToString(unpackEnumbits(s.enumBits)));
+
+ });
+ });
+ }
+ }
+
+ void showTruncationSettings(Mode sm) {
+ if (sm == null) {
+ modeMap.values().forEach(m -> showTruncationSettings(m));
+ } else {
+ List<Mode.Setting> trunc = sm.cases.get(TRUNCATION_FIELD);
+ if (trunc != null) {
+ trunc.forEach(s -> {
+ hard("/set truncation %s %s %s",
+ sm.name, s.format,
+ selectorsToString(unpackEnumbits(s.enumBits)));
+ });
+ }
+ }
+ }
+
+ void showPromptSettings(Mode sm) {
+ if (sm == null) {
+ modeMap.values().forEach(m -> showPromptSettings(m));
+ } else {
+ hard("/set prompt %s %s %s",
+ sm.name,
+ toStringLiteral(sm.prompt),
+ toStringLiteral(sm.continuationPrompt));
+ }
+ }
+
+ void showModeSettings(String umode, String msg) {
+ if (umode == null) {
+ modeMap.values().forEach(n -> showModeSettings(n));
+ } else {
+ Mode m;
+ String retained = retainedMap.get(umode);
+ if (retained == null) {
+ m = searchForMode(umode, msg);
+ if (m == null) {
+ return;
+ }
+ umode = m.name;
+ retained = retainedMap.get(umode);
+ } else {
+ m = modeMap.get(umode);
+ }
+ if (retained != null) {
+ Mode rm = new Mode(encodedModeIterator(retained));
+ showModeSettings(rm);
+ hard("/set mode -retain %s", umode);
+ if (m != null && !m.equals(rm)) {
+ hard("");
+ showModeSettings(m);
+ }
+ } else {
+ showModeSettings(m);
+ }
+ }
+ }
+
+ void showModeSettings(Mode sm) {
+ hard("/set mode %s %s",
+ sm.name, sm.commandFluff ? "-command" : "-quiet");
+ showPromptSettings(sm);
+ showFormatSettings(sm, null);
+ showTruncationSettings(sm);
+ }
+
+ void showFeedbackSetting() {
+ if (retainedCurrentMode != null) {
+ hard("/set feedback -retain %s", retainedCurrentMode.name);
+ }
+ if (mode != retainedCurrentMode) {
+ hard("/set feedback %s", mode.name);
+ }
+ }
+
// For /set prompt <mode> "<prompt>" "<continuation-prompt>"
boolean setPrompt() {
Mode m = nextMode();
+ String prompt = nextFormat();
+ String continuationPrompt = nextFormat();
+ checkOptionsAndRemainingInput();
+ if (valid && prompt == null) {
+ showPromptSettings(m);
+ return valid;
+ }
if (valid && m.readOnly) {
errorat("jshell.err.not.valid.with.predefined.mode", m.name);
- valid = false;
+ } else if (continuationPrompt == null) {
+ errorat("jshell.err.continuation.prompt.required");
}
- String prompt = valid ? nextFormat() : null;
- String continuationPrompt = valid ? nextFormat() : null;
if (valid) {
m.setPrompts(prompt, continuationPrompt);
} else {
@@ -714,210 +965,210 @@
*
* @return true if successful
*/
- boolean setMode() {
- at.allowedOptions("-command", "-quiet", "-delete");
- String umode = nextModeIdentifier();
- Mode om = null;
- String omode = at.next();
- if (valid && omode != null) {
- om = toMode(omode);
- }
- checkOptionsAndRemainingInput();
- boolean commandOption = at.hasOption("-command");
- boolean quietOption = at.hasOption("-quiet");
- boolean deleteOption = at.hasOption("-delete");
- // Only one (or zero) of the options can be used
- if (valid && at.optionCount() > 1) {
- errorat("jshell.err.conflicting.options");
- valid = false;
- }
- if (valid) {
- Mode m = modeMap.get(umode);
- if (m != null && m.readOnly) {
- // Cannot make changes to a the built-in modes
- errorat("jshell.err.not.valid.with.predefined.mode", m.name);
- valid = false;
- } else if (deleteOption) {
- if (m == null) {
+ boolean setMode(Consumer<String> retainer) {
+ class SetMode {
+
+ final String umode;
+ final String omode;
+ final boolean commandOption;
+ final boolean quietOption;
+ final boolean deleteOption;
+ final boolean retainOption;
+
+ SetMode() {
+ at.allowedOptions("-command", "-quiet", "-delete", "-retain");
+ umode = nextModeIdentifier();
+ omode = nextModeIdentifier();
+ checkOptionsAndRemainingInput();
+ commandOption = at.hasOption("-command");
+ quietOption = at.hasOption("-quiet");
+ deleteOption = at.hasOption("-delete");
+ retainOption = at.hasOption("-retain");
+ }
+
+ void delete() {
+ // Note: delete, for safety reasons, does NOT do name matching
+ if (commandOption || quietOption) {
+ errorat("jshell.err.conflicting.options");
+ } else if (!(retainOption ? retainedMap : modeMap).containsKey(umode)) {
// Cannot delete a mode that does not exist
errorat("jshell.err.mode.unknown", umode);
- valid = false;
- } else if (mode.name.equals(m.name)) {
+ } else if (omode != null) {
+ // old mode is for creation
+ errorat("jshell.err.unexpected.at.end", omode);
+ } else if (mode.name.equals(umode)) {
// Cannot delete the current mode out from under us
errorat("jshell.err.cannot.delete.current.mode", umode);
- valid = false;
+ } else if (retainOption && retainedCurrentMode != null &&
+ retainedCurrentMode.name.equals(umode)) {
+ // Cannot delete the retained mode or re-start will have an error
+ errorat("jshell.err.cannot.delete.retained.mode", umode);
} else {
- // Remove the mode
- modeMap.remove(umode);
+ Mode m = modeMap.get(umode);
+ if (m != null && m.readOnly) {
+ errorat("jshell.err.not.valid.with.predefined.mode", umode);
+ } else {
+ // Remove the mode
+ modeMap.remove(umode);
+ if (retainOption) {
+ // Remove the retained mode
+ retainedMap.remove(umode);
+ updateRetainedModes();
+ }
+ }
}
- } else {
- if (om != null || m == null) {
- // We are copying and existing mode and/or creating a
- // brand-new mode -- in either case create from scratch
- m = (om != null)
- ? new Mode(umode, om)
- : new Mode(umode);
- modeMap.put(umode, m);
- fluffmsg("jshell.msg.feedback.new.mode", m.name);
- // Set the current mode by name, in case we just smashed
- // the current mode
- if (umode.equals(mode.name)) {
- mode = modeMap.get(mode.name);
+ }
+
+ void retain() {
+ if (commandOption || quietOption) {
+ errorat("jshell.err.conflicting.options");
+ } else if (omode != null) {
+ // old mode is for creation
+ errorat("jshell.err.unexpected.at.end", omode);
+ } else {
+ Mode m = modeMap.get(umode);
+ if (m == null) {
+ // can only retain existing modes
+ errorat("jshell.err.mode.unknown", umode);
+ } else if (m.readOnly) {
+ errorat("jshell.err.not.valid.with.predefined.mode", umode);
+ } else {
+ // Add to local cache of retained current encodings
+ retainedMap.put(m.name, m.encode());
+ updateRetainedModes();
}
}
- if (commandOption || quietOption || om == null) {
- // set command fluff, if explicit, or wholly new
- m.setCommandFluff(!quietOption);
+ }
+
+ void updateRetainedModes() {
+ // Join all the retained encodings
+ String encoded = String.join(RECORD_SEPARATOR, retainedMap.values());
+ // Retain it
+ retainer.accept(encoded);
+ }
+
+ void create() {
+ if (commandOption && quietOption) {
+ errorat("jshell.err.conflicting.options");
+ } else if (!commandOption && !quietOption) {
+ errorat("jshell.err.mode.creation");
+ } else if (modeMap.containsKey(umode)) {
+ // Mode already exists
+ errorat("jshell.err.mode.exists", umode);
+ } else {
+ Mode om = searchForMode(omode);
+ if (valid) {
+ // We are copying an existing mode and/or creating a
+ // brand-new mode -- in either case create from scratch
+ Mode m = (om != null)
+ ? new Mode(umode, om)
+ : new Mode(umode);
+ modeMap.put(umode, m);
+ fluffmsg("jshell.msg.feedback.new.mode", m.name);
+ m.setCommandFluff(commandOption);
+ }
}
}
+
+ boolean set() {
+ if (valid && !commandOption && !quietOption && !deleteOption &&
+ omode == null && !retainOption) {
+ // Not a creation, deletion, or retain -- show mode(s)
+ showModeSettings(umode, "jshell.err.mode.creation");
+ } else if (valid && umode == null) {
+ errorat("jshell.err.missing.mode");
+ } else if (valid && deleteOption) {
+ delete();
+ } else if (valid && retainOption) {
+ retain();
+ } else if (valid) {
+ create();
+ }
+ if (!valid) {
+ fluffmsg("jshell.msg.see", "/help /set mode");
+ }
+ return valid;
+ }
}
- if (!valid) {
- fluffmsg("jshell.msg.see", "/help /set mode");
- }
- return valid;
+ return new SetMode().set();
}
- // For /set feedback <mode>
- boolean setFeedback() {
+ // For /set format <mode> <field> "<format>" <selector>...
+ boolean setFormat() {
Mode m = nextMode();
- if (valid) {
- mode = m;
- fluffmsg("jshell.msg.feedback.mode", mode.name);
+ String field = toIdentifier(next(), "jshell.err.field.name");
+ String format = nextFormat();
+ if (valid && format == null) {
+ if (field != null && m != null && !m.cases.containsKey(field)) {
+ errorat("jshell.err.field.name", field);
+ } else {
+ showFormatSettings(m, field);
+ }
} else {
- fluffmsg("jshell.msg.see", "/help /set feedback");
- printFeedbackModes();
+ installFormat(m, field, format, "/help /set format");
}
return valid;
}
- // For /set format <mode> "<format>" <selector>...
- boolean setFormat() {
- Mode m = nextMode();
- if (valid && m.readOnly) {
- errorat("jshell.err.not.valid.with.predefined.mode", m.name);
- valid = false;
- }
- String field = valid
- ? toIdentifier(at.next(), "jshell.err.missing.field", "jshell.err.field.name")
- : null;
- String format = valid ? nextFormat() : null;
- return installFormat(m, field, format, "/help /set format");
- }
-
// For /set truncation <mode> <length> <selector>...
boolean setTruncation() {
Mode m = nextMode();
- if (valid && m.readOnly) {
- errorat("jshell.err.not.valid.with.predefined.mode", m.name);
- valid = false;
- }
- String length = at.next();
+ String length = next();
if (length == null) {
- errorat("jshell.err.truncation.expected.length");
- valid = false;
+ showTruncationSettings(m);
} else {
try {
// Assure that integer format is correct
Integer.parseUnsignedInt(length);
} catch (NumberFormatException ex) {
errorat("jshell.err.truncation.length.not.integer", length);
- valid = false;
}
+ // install length into an internal format field
+ installFormat(m, TRUNCATION_FIELD, length, "/help /set truncation");
}
- // install length into an internal format field
- return installFormat(m, TRUNCATION_FIELD, length, "/help /set truncation");
- }
-
- String retainFeedback() {
- String umode = at.next();
- if (umode != null) {
- toModeIdentifier(umode);
- Mode m = valid ? toMode(umode) : null;
- if (valid && !m.readOnly && !retainedMap.containsKey(m.name)) {
- errorat("jshell.err.retained.feedback.mode.must.be.retained.or.predefined");
- valid = false;
- }
- if (valid) {
- mode = m;
- retainedCurrentMode = m;
- fluffmsg("jshell.msg.feedback.mode", mode.name);
- } else {
- fluffmsg("jshell.msg.see", "/help /retain feedback");
- return null;
- }
- }
- return mode.name;
+ return valid;
}
- /**
- * Retain (or delete from retention) a previously set mode.
- *
- * @return all retained modes encoded into a String
- */
- String retainMode() {
- at.allowedOptions("-delete");
- String umode = nextModeIdentifier();
- // -delete is the only valid option, fail for anything else
+ // For /set feedback <mode>
+ boolean setFeedback(Consumer<String> retainer) {
+ String umode = next();
checkOptionsAndRemainingInput();
- boolean deleteOption = at.hasOption("-delete");
- // Lookup the mode
- Mode m;
- if (!valid) {
- m = null;
- // Skip this stuff, we have failed already
- } else if (deleteOption) {
- // If delete, allow for deleting, from retention, a mode that
- // has been locally deleted but is retained.
- // Also require the full name.
- m = modeMap.get(umode);
- if (m == null && !retainedMap.containsKey(umode)) {
- errorat("jshell.err.mode.unknown", umode);
- valid = false;
- }
- } else {
- // For retain do normal lookup and checking
- m = toMode(umode);
- }
-
- // Built-in modes cannot be retained or deleted
- if (valid && m != null && m.readOnly) {
- errorat("jshell.err.not.valid.with.predefined.mode", umode);
- valid = false;
+ boolean retainOption = at.hasOption("-retain");
+ if (valid && umode == null && !retainOption) {
+ showFeedbackSetting();
+ hard("");
+ showFeedbackModes();
+ return true;
}
if (valid) {
- if (deleteOption) {
- if (mode.name.equals(umode)) {
- // Cannot delete the current mode out from under us
- errorat("jshell.err.cannot.delete.current.mode", umode);
- valid = false;
- } else if (retainedCurrentMode != null && retainedCurrentMode.name.equals(umode)) {
- // Cannot delete the retained mode or re-start has error
- errorat("jshell.err.cannot.delete.retained.mode", umode);
- valid = false;
- } else {
- // Delete the mode
- modeMap.remove(umode);
- retainedMap.remove(umode);
+ Mode m = umode == null
+ ? mode
+ : searchForMode(toModeIdentifier(umode));
+ if (valid && retainOption && !m.readOnly && !retainedMap.containsKey(m.name)) {
+ errorat("jshell.err.retained.feedback.mode.must.be.retained.or.predefined");
+ }
+ if (valid) {
+ if (umode != null) {
+ mode = m;
+ fluffmsg("jshell.msg.feedback.mode", mode.name);
}
- } else {
- // Retain the current encoding
- retainedMap.put(m.name, m.encode());
+ if (retainOption) {
+ retainedCurrentMode = m;
+ retainer.accept(m.name);
+ }
}
}
- if (valid) {
- // Join all the retained encodings
- return String.join(RECORD_SEPARATOR, retainedMap.values());
- } else {
- fluffmsg("jshell.msg.see", "/help /retain mode");
- return null;
+ if (!valid) {
+ fluffmsg("jshell.msg.see", "/help /set feedback");
+ return false;
}
+ return true;
}
boolean restoreEncodedModes(String allEncoded) {
try {
// Iterate over each record in each encoded mode
- String[] ms = allEncoded.split(RECORD_SEPARATOR);
- Iterator<String> itr = Arrays.asList(ms).iterator();
+ Iterator<String> itr = encodedModeIterator(allEncoded);
while (itr.hasNext()) {
// Reconstruct the encoded mode
Mode m = new Mode(itr);
@@ -934,50 +1185,60 @@
}
}
+ Iterator<String> encodedModeIterator(String encoded) {
+ String[] ms = encoded.split(RECORD_SEPARATOR);
+ return Arrays.asList(ms).iterator();
+ }
+
// install the format of a field under parsed selectors
- boolean installFormat(Mode m, String field, String format, String help) {
+ void installFormat(Mode m, String field, String format, String help) {
String slRaw;
List<SelectorList> slList = new ArrayList<>();
- while (valid && (slRaw = at.next()) != null) {
+ while (valid && (slRaw = next()) != null) {
SelectorList sl = new SelectorList();
sl.parseSelectorList(slRaw);
slList.add(sl);
}
+ checkOptionsAndRemainingInput();
if (valid) {
- if (slList.isEmpty()) {
+ if (m.readOnly) {
+ errorat("jshell.err.not.valid.with.predefined.mode", m.name);
+ } else if (slList.isEmpty()) {
// No selectors specified, then always the format
m.set(field, ALWAYS, format);
} else {
// Set the format of the field for specified selector
slList.stream()
.forEach(sl -> m.set(field,
- sl.cases.getSet(), sl.actions.getSet(), sl.whens.getSet(),
- sl.resolves.getSet(), sl.unresolvedCounts.getSet(), sl.errorCounts.getSet(),
- format));
+ sl.cases.getSet(), sl.actions.getSet(), sl.whens.getSet(),
+ sl.resolves.getSet(), sl.unresolvedCounts.getSet(), sl.errorCounts.getSet(),
+ format));
}
} else {
fluffmsg("jshell.msg.see", help);
}
- return valid;
}
void checkOptionsAndRemainingInput() {
- if (!valid) {
- return;
- }
String junk = at.remainder();
if (!junk.isEmpty()) {
errorat("jshell.err.unexpected.at.end", junk);
- valid = false;
} else {
String bad = at.badOptions();
if (!bad.isEmpty()) {
errorat("jshell.err.unknown.option", bad);
- valid = false;
}
}
}
+ String next() {
+ String s = at.next();
+ if (s == null) {
+ checkOptionsAndRemainingInput();
+ }
+ return s;
+ }
+
/**
* Check that the specified string is an identifier (Java identifier).
* If null display the missing error. If it is not an identifier,
@@ -985,45 +1246,41 @@
*
* @param id the string to check, MUST be the most recently retrieved
* token from 'at'.
- * @param missing the resource error to display if null
+ * @param missing null for no null error, otherwise the resource error to display if id is null
* @param err the resource error to display if not an identifier
* @return the identifier string, or null if null or not an identifier
*/
- String toIdentifier(String id, String missing, String err) {
- if (id == null) {
- errorat(missing);
- valid = false;
+ private String toIdentifier(String id, String err) {
+ if (!valid || id == null) {
return null;
}
if (at.isQuoted() ||
!id.codePoints().allMatch(cp -> Character.isJavaIdentifierPart(cp))) {
errorat(err, id);
- valid = false;
return null;
}
return id;
}
- String toModeIdentifier(String id) {
- return toIdentifier(id, "jshell.err.missing.mode", "jshell.err.mode.name");
+ private String toModeIdentifier(String id) {
+ return toIdentifier(id, "jshell.err.mode.name");
}
- String nextModeIdentifier() {
- return toModeIdentifier(at.next());
+ private String nextModeIdentifier() {
+ return toModeIdentifier(next());
}
- Mode nextMode() {
+ private Mode nextMode() {
String umode = nextModeIdentifier();
- return toMode(umode);
+ return searchForMode(umode);
}
- Mode toMode(String umode) {
- if (!valid) {
- return null;
- }
- if (umode == null) {
- errorat("jshell.err.missing.mode");
- valid = false;
+ private Mode searchForMode(String umode) {
+ return searchForMode(umode, null);
+ }
+
+ private Mode searchForMode(String umode, String msg) {
+ if (!valid || umode == null) {
return null;
}
Mode m = modeMap.get(umode);
@@ -1038,39 +1295,101 @@
if (matches.length == 1) {
return matches[0];
} else {
- valid = false;
+ if (msg != null) {
+ hardmsg(msg, "");
+ }
if (matches.length == 0) {
errorat("jshell.err.feedback.does.not.match.mode", umode);
} else {
errorat("jshell.err.feedback.ambiguous.mode", umode);
}
- printFeedbackModes();
+ if (showFluff()) {
+ showFeedbackModes();
+ }
return null;
}
}
- void printFeedbackModes() {
- fluffmsg("jshell.msg.feedback.mode.following");
+ void showFeedbackModes() {
+ if (!retainedMap.isEmpty()) {
+ hardmsg("jshell.msg.feedback.retained.mode.following");
+ retainedMap.keySet().stream()
+ .sorted()
+ .forEach(mk -> hard(" %s", mk));
+ }
+ hardmsg("jshell.msg.feedback.mode.following");
modeMap.keySet().stream()
- .forEach(mk -> fluff(" %s", mk));
+ .sorted()
+ .forEach(mk -> hard(" %s", mk));
+ }
+
+ // Read and test if the format string is correctly
+ private String nextFormat() {
+ return toFormat(next());
}
// Test if the format string is correctly
- final String nextFormat() {
- String format = at.next();
- if (format == null) {
- errorat("jshell.err.feedback.expected.format");
- valid = false;
+ private String toFormat(String format) {
+ if (!valid || format == null) {
return null;
}
if (!at.isQuoted()) {
errorat("jshell.err.feedback.must.be.quoted", format);
- valid = false;
- return null;
+ return null;
}
return format;
}
+ // Convert to a quoted string
+ private String toStringLiteral(String s) {
+ StringBuilder sb = new StringBuilder();
+ sb.append('"');
+ final int length = s.length();
+ for (int offset = 0; offset < length;) {
+ final int codepoint = s.codePointAt(offset);
+
+ switch (codepoint) {
+ case '\b':
+ sb.append("\\b");
+ break;
+ case '\t':
+ sb.append("\\t");
+ break;
+ case '\n':
+ sb.append("\\n");
+ break;
+ case '\f':
+ sb.append("\\f");
+ break;
+ case '\r':
+ sb.append("\\r");
+ break;
+ case '\"':
+ sb.append("\\\"");
+ break;
+ case '\'':
+ sb.append("\\'");
+ break;
+ case '\\':
+ sb.append("\\\\");
+ break;
+ default:
+ if (codepoint < 040) {
+ sb.append(String.format("\\%o", codepoint));
+ } else {
+ sb.appendCodePoint(codepoint);
+ }
+ break;
+ }
+
+ // do something with the codepoint
+ offset += Character.charCount(codepoint);
+
+ }
+ sb.append('"');
+ return sb.toString();
+ }
+
class SelectorList {
SelectorCollector<FormatCase> cases = new SelectorCollector<>(FormatCase.all);
@@ -1088,19 +1407,16 @@
Selector<?> sel = selectorMap.get(as);
if (sel == null) {
errorat("jshell.err.feedback.not.a.valid.selector", as, s);
- valid = false;
return;
}
SelectorCollector<?> collector = sel.collector(this);
if (lastCollector == null) {
if (!collector.isEmpty()) {
errorat("jshell.err.feedback.multiple.sections", as, s);
- valid = false;
return;
}
} else if (collector != lastCollector) {
errorat("jshell.err.feedback.different.selector.kinds", as, s);
- valid = false;
return;
}
collector.add(sel);
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/IOContext.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/IOContext.java Wed Oct 26 20:13:29 2016 +0000
@@ -54,7 +54,7 @@
public abstract void replaceLastHistoryEntry(String source);
- public abstract int readUserInput();
+ public abstract int readUserInput() throws IOException;
class InputInterruptedException extends Exception {
private static final long serialVersionUID = 1L;
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java Wed Oct 26 20:13:29 2016 +0000
@@ -73,7 +73,6 @@
import jdk.jshell.JShell;
import jdk.jshell.JShell.Subscription;
import jdk.jshell.MethodSnippet;
-import jdk.jshell.PersistentSnippet;
import jdk.jshell.Snippet;
import jdk.jshell.Snippet.Status;
import jdk.jshell.SnippetEvent;
@@ -134,32 +133,26 @@
final PrintStream userout;
final PrintStream usererr;
final Preferences prefs;
+ final Map<String, String> envvars;
final Locale locale;
final Feedback feedback = new Feedback();
/**
- * The constructor for the tool (used by tool launch via main and by test
- * harnesses to capture ins and outs.
- * @param in command line input -- snippets, commands and user input
- * @param cmdout command line output, feedback including errors
- * @param cmderr start-up errors and debugging info
- * @param console console control interaction
- * @param userout code execution output -- System.out.printf("hi")
- * @param usererr code execution error stream -- System.err.printf("Oops")
- * @param prefs preferences to use
- * @param locale locale to use
+ * Simple constructor for the tool used by main.
+ * @param in command line input
+ * @param out command line output, feedback including errors, user System.out
+ * @param err start-up errors and debugging info, user System.err
*/
- public JShellTool(InputStream in, PrintStream cmdout, PrintStream cmderr,
- PrintStream console,
- PrintStream userout, PrintStream usererr,
- Preferences prefs, Locale locale) {
- this(in, cmdout, cmderr, console, null, userout, usererr, prefs, locale);
+ public JShellTool(InputStream in, PrintStream out, PrintStream err) {
+ this(in, out, err, out, null, out, err,
+ Preferences.userRoot().node("tool/JShell"),
+ System.getenv(),
+ Locale.getDefault());
}
/**
- * The constructor for the tool (used by tool launch via main and by test
- * harnesses to capture ins and outs.
+ * The complete constructor for the tool (used by test harnesses).
* @param cmdin command line input -- snippets and commands
* @param cmdout command line output, feedback including errors
* @param cmderr start-up errors and debugging info
@@ -168,12 +161,13 @@
* @param userout code execution output -- System.out.printf("hi")
* @param usererr code execution error stream -- System.err.printf("Oops")
* @param prefs preferences to use
+ * @param envvars environment variable mapping to use
* @param locale locale to use
*/
public JShellTool(InputStream cmdin, PrintStream cmdout, PrintStream cmderr,
PrintStream console,
InputStream userin, PrintStream userout, PrintStream usererr,
- Preferences prefs, Locale locale) {
+ Preferences prefs, Map<String, String> envvars, Locale locale) {
this.cmdin = cmdin;
this.cmdout = cmdout;
this.cmderr = cmderr;
@@ -187,6 +181,7 @@
this.userout = userout;
this.usererr = usererr;
this.prefs = prefs;
+ this.envvars = envvars;
this.locale = locale;
}
@@ -205,12 +200,16 @@
JShell state = null;
Subscription shutdownSubscription = null;
+ static final EditorSetting BUILT_IN_EDITOR = new EditorSetting(null, false);
+
private boolean debug = false;
public boolean testPrompt = false;
private String cmdlineClasspath = null;
private String startup = null;
- private String[] editor = null;
- private boolean editorWait = false;
+ private EditorSetting editor = BUILT_IN_EDITOR;
+
+ private static final String[] EDITOR_ENV_VARS = new String[] {
+ "JSHELLEDITOR", "VISUAL", "EDITOR"};
// Commands and snippets which should be replayed
private List<String> replayableHistory;
@@ -274,7 +273,8 @@
* @param format printf format
* @param args printf args
*/
- void hard(String format, Object... args) {
+ @Override
+ public void hard(String format, Object... args) {
rawout(feedback.getPre() + format + feedback.getPost(), args);
}
@@ -289,6 +289,15 @@
}
/**
+ * Should optional informative be displayed?
+ * @return true if they should be displayed
+ */
+ @Override
+ public boolean showFluff() {
+ return feedback.shouldDisplayCommandFluff() && interactive();
+ }
+
+ /**
* Optional output
*
* @param format printf format
@@ -296,7 +305,7 @@
*/
@Override
public void fluff(String format, Object... args) {
- if (feedback.shouldDisplayCommandFluff() && interactive()) {
+ if (showFluff()) {
hard(format, args);
}
}
@@ -308,7 +317,7 @@
* @param args printf args
*/
void fluffRaw(String format, Object... args) {
- if (feedback.shouldDisplayCommandFluff() && interactive()) {
+ if (showFluff()) {
rawout(format, args);
}
}
@@ -390,7 +399,8 @@
* @param key the resource key
* @param args
*/
- void hardmsg(String key, Object... args) {
+ @Override
+ public void hardmsg(String key, Object... args) {
cmdout.println(prefix(messageFormat(key, args)));
}
@@ -429,7 +439,7 @@
*/
@Override
public void fluffmsg(String key, Object... args) {
- if (feedback.shouldDisplayCommandFluff() && interactive()) {
+ if (showFluff()) {
hardmsg(key, args);
}
}
@@ -475,10 +485,7 @@
* @throws Exception
*/
public static void main(String[] args) throws Exception {
- new JShellTool(System.in, System.out, System.err, System.out,
- System.out, System.err,
- Preferences.userRoot().node("tool/JShell"),
- Locale.getDefault())
+ new JShellTool(System.in, System.out, System.err)
.start(args);
}
@@ -502,18 +509,7 @@
}
}
- // Read retained editor setting (if any)
- String editorString = prefs.get(EDITOR_KEY, "");
- if (editorString == null || editorString.isEmpty()) {
- editor = null;
- } else {
- char waitMarker = editorString.charAt(0);
- if (waitMarker == '-' || waitMarker == '*') {
- editorWait = waitMarker == '-';
- editorString = editorString.substring(1);
- }
- editor = editorString.split(RECORD_SEPARATOR);
- }
+ configEditor();
resetState(); // Initialize
@@ -543,6 +539,23 @@
}
}
+ private EditorSetting configEditor() {
+ // Read retained editor setting (if any)
+ editor = EditorSetting.fromPrefs(prefs);
+ if (editor != null) {
+ return editor;
+ }
+ // Try getting editor setting from OS environment variables
+ for (String envvar : EDITOR_ENV_VARS) {
+ String v = envvars.get(envvar);
+ if (v != null) {
+ return editor = new EditorSetting(v.split("\\s+"), false);
+ }
+ }
+ // Default to the built-in editor
+ return editor = BUILT_IN_EDITOR;
+ }
+
/**
* Process the command line arguments.
* Set options.
@@ -682,9 +695,24 @@
}
@Override
+ public void hard(String format, Object... args) {
+ //ignore
+ }
+
+ @Override
+ public void hardmsg(String messageKey, Object... args) {
+ //ignore
+ }
+
+ @Override
public void errormsg(String messageKey, Object... args) {
startmsg(messageKey, args);
}
+
+ @Override
+ public boolean showFluff() {
+ return false;
+ }
}
private void resetState() {
@@ -746,7 +774,7 @@
startUpRun(getResourceString("startup.feedback"));
// These predefined modes are read-only
feedback.markModesReadOnly();
- // Restore user defined modes retained on previous run with /retain mode
+ // Restore user defined modes retained on previous run with /set mode -retain
String encoded = prefs.get(MODE_KEY, null);
if (encoded != null && !encoded.isEmpty()) {
if (!feedback.restoreEncodedModes(initmh, encoded)) {
@@ -756,7 +784,7 @@
}
if (commandLineFeedbackMode != null) {
// The feedback mode to use was specified on the command line, use it
- if (!feedback.setFeedback(initmh, new ArgTokenizer("--feedback", commandLineFeedbackMode))) {
+ if (!setFeedback(initmh, new ArgTokenizer("--feedback", commandLineFeedbackMode))) {
regenerateOnDeath = false;
}
commandLineFeedbackMode = null;
@@ -764,8 +792,8 @@
String fb = prefs.get(FEEDBACK_KEY, null);
if (fb != null) {
// Restore the feedback mode to use that was retained
- // on a previous run with /retain feedback
- feedback.retainFeedback(initmh, new ArgTokenizer("/retain feedback", fb));
+ // on a previous run with /set feedback -retain
+ setFeedback(initmh, new ArgTokenizer("previous retain feedback", "-retain " + fb));
}
}
}
@@ -1137,10 +1165,9 @@
return state.snippets();
}
- Stream<PersistentSnippet> dropableSnippets() {
+ Stream<Snippet> dropableSnippets() {
return state.snippets()
- .filter(sn -> state.status(sn).isActive() && sn instanceof PersistentSnippet)
- .map(sn -> (PersistentSnippet) sn);
+ .filter(sn -> state.status(sn).isActive());
}
Stream<VarSnippet> allVarSnippets() {
@@ -1229,14 +1256,6 @@
"editor", fileCompletions(Files::isExecutable),
"start", FILE_COMPLETION_PROVIDER),
STARTSWITH_MATCHER)));
- registerCommand(new Command("/retain",
- arg -> cmdRetain(arg),
- new ContinuousCompletionProvider(Map.of(
- "feedback", feedback.modeCompletions(),
- "mode", feedback.modeCompletions(),
- "editor", fileCompletions(Files::isExecutable),
- "start", FILE_COMPLETION_PROVIDER),
- STARTSWITH_MATCHER)));
registerCommand(new Command("/?",
"help.quest",
arg -> cmdHelp(arg),
@@ -1295,9 +1314,6 @@
private static final String[] SET_SUBCOMMANDS = new String[]{
"format", "truncation", "feedback", "mode", "prompt", "editor", "start"};
- private static final String[] RETAIN_SUBCOMMANDS = new String[]{
- "feedback", "mode", "editor", "start"};
-
final boolean cmdSet(String arg) {
String cmd = "/set";
ArgTokenizer at = new ArgTokenizer(cmd, arg.trim());
@@ -1306,95 +1322,61 @@
return false;
}
switch (which) {
+ case "_retain": {
+ errormsg("jshell.err.setting.to.retain.must.be.specified", at.whole());
+ return false;
+ }
+ case "_blank": {
+ // show top-level settings
+ new SetEditor().set();
+ showSetStart();
+ setFeedback(this, at); // no args so shows feedback setting
+ hardmsg("jshell.msg.set.show.mode.settings");
+ return true;
+ }
case "format":
return feedback.setFormat(this, at);
case "truncation":
return feedback.setTruncation(this, at);
case "feedback":
- return feedback.setFeedback(this, at);
+ return setFeedback(this, at);
case "mode":
- return feedback.setMode(this, at);
+ return feedback.setMode(this, at,
+ retained -> prefs.put(MODE_KEY, retained));
case "prompt":
return feedback.setPrompt(this, at);
case "editor":
- return setEditor(at, true);
+ return new SetEditor(at).set();
case "start":
- return setStart(cmd, at, true);
+ return setStart(at);
default:
errormsg("jshell.err.arg", cmd, at.val());
return false;
}
}
- final boolean cmdRetain(String arg) {
- String cmd = "/retain";
- ArgTokenizer at = new ArgTokenizer(cmd, arg.trim());
- String which = subCommand(cmd, at, RETAIN_SUBCOMMANDS);
- if (which == null) {
- return false;
- }
- switch (which) {
- case "feedback": {
- String fb = feedback.retainFeedback(this, at);
- if (fb != null) {
- // If a feedback mode has been set now, or in the past, retain it
- prefs.put(FEEDBACK_KEY, fb);
- return true;
- }
- return false;
- }
- case "mode":
- String retained = feedback.retainMode(this, at);
- if (retained != null) {
- // Retain this mode and all previously retained modes
- prefs.put(MODE_KEY, retained);
- return true;
- }
- return false;
- case "editor":
- if (!setEditor(at, false)) {
- return false;
- }
- // retain editor setting
- prefs.put(EDITOR_KEY, (editor == null)
- ? ""
- : (editorWait? "-" : "*") + String.join(RECORD_SEPARATOR, editor));
- return true;
- case "start": {
- if (!setStart(cmd, at, false)) {
- return false;
- }
- // retain startup setting
- prefs.put(STARTUP_KEY, startup);
- return true;
- }
- default:
- errormsg("jshell.err.arg", cmd, at.val());
- return false;
- }
+ boolean setFeedback(MessageHandler messageHandler, ArgTokenizer at) {
+ return feedback.setFeedback(messageHandler, at,
+ fb -> prefs.put(FEEDBACK_KEY, fb));
}
- // Print the help doc for the specified sub-command
- boolean printSubCommandHelp(String cmd, ArgTokenizer at, String helpPrefix, String[] subs) {
- String which = subCommand(cmd, at, subs);
- if (which == null) {
- return false;
+ // Find which, if any, sub-command matches.
+ // Return null on error
+ String subCommand(String cmd, ArgTokenizer at, String[] subs) {
+ at.allowedOptions("-retain");
+ String sub = at.next();
+ if (sub == null) {
+ // No sub-command was given
+ return at.hasOption("-retain")
+ ? "_retain"
+ : "_blank";
}
- hardrb(helpPrefix + which);
- return true;
- }
-
- // Find which, if any, sub-command matches
- String subCommand(String cmd, ArgTokenizer at, String[] subs) {
- String[] matches = at.next(subs);
- if (matches == null) {
- // No sub-command was given
- errormsg("jshell.err.sub.arg", cmd);
- return null;
- }
+ String[] matches = Arrays.stream(subs)
+ .filter(s -> s.startsWith(sub))
+ .toArray(size -> new String[size]);
if (matches.length == 0) {
// There are no matching sub-commands
- errormsg("jshell.err.arg", cmd, at.val());
+ errormsg("jshell.err.arg", cmd, sub);
fluffmsg("jshell.msg.use.one.of", Arrays.stream(subs)
.collect(Collectors.joining(", "))
);
@@ -1402,7 +1384,7 @@
}
if (matches.length > 1) {
// More than one sub-command matches the initial characters provided
- errormsg("jshell.err.sub.ambiguous", cmd, at.val());
+ errormsg("jshell.err.sub.ambiguous", cmd, sub);
fluffmsg("jshell.msg.use.one.of", Arrays.stream(matches)
.collect(Collectors.joining(", "))
);
@@ -1411,67 +1393,232 @@
return matches[0];
}
- // The sub-command: /set editor <editor-command-line>>
- boolean setEditor(ArgTokenizer at, boolean argsRequired) {
- at.allowedOptions("-default", "-wait");
- String prog = at.next();
- List<String> ed = new ArrayList<>();
- while (at.val() != null) {
- ed.add(at.val());
- at.nextToken();
+ static class EditorSetting {
+
+ static String BUILT_IN_REP = "-default";
+ static char WAIT_PREFIX = '-';
+ static char NORMAL_PREFIX = '*';
+
+ final String[] cmd;
+ final boolean wait;
+
+ EditorSetting(String[] cmd, boolean wait) {
+ this.wait = wait;
+ this.cmd = cmd;
+ }
+
+ // returns null if not stored in preferences
+ static EditorSetting fromPrefs(Preferences prefs) {
+ // Read retained editor setting (if any)
+ String editorString = prefs.get(EDITOR_KEY, "");
+ if (editorString == null || editorString.isEmpty()) {
+ return null;
+ } else if (editorString.equals(BUILT_IN_REP)) {
+ return BUILT_IN_EDITOR;
+ } else {
+ boolean wait = false;
+ char waitMarker = editorString.charAt(0);
+ if (waitMarker == WAIT_PREFIX || waitMarker == NORMAL_PREFIX) {
+ wait = waitMarker == WAIT_PREFIX;
+ editorString = editorString.substring(1);
+ }
+ String[] cmd = editorString.split(RECORD_SEPARATOR);
+ return new EditorSetting(cmd, wait);
+ }
+ }
+
+ static void removePrefs(Preferences prefs) {
+ prefs.remove(EDITOR_KEY);
+ }
+
+ void toPrefs(Preferences prefs) {
+ prefs.put(EDITOR_KEY, (this == BUILT_IN_EDITOR)
+ ? BUILT_IN_REP
+ : (wait ? WAIT_PREFIX : NORMAL_PREFIX) + String.join(RECORD_SEPARATOR, cmd));
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof EditorSetting) {
+ EditorSetting ed = (EditorSetting) o;
+ return Arrays.equals(cmd, ed.cmd) && wait == ed.wait;
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 71 * hash + Arrays.deepHashCode(this.cmd);
+ hash = 71 * hash + (this.wait ? 1 : 0);
+ return hash;
}
+ }
+
+ class SetEditor {
+
+ private final ArgTokenizer at;
+ private final String[] command;
+ private final boolean hasCommand;
+ private final boolean defaultOption;
+ private final boolean deleteOption;
+ private final boolean waitOption;
+ private final boolean retainOption;
+ private final int primaryOptionCount;
+
+ SetEditor(ArgTokenizer at) {
+ at.allowedOptions("-default", "-wait", "-retain", "-delete");
+ String prog = at.next();
+ List<String> ed = new ArrayList<>();
+ while (at.val() != null) {
+ ed.add(at.val());
+ at.nextToken(); // so that options are not interpreted as jshell options
+ }
+ this.at = at;
+ this.command = ed.toArray(new String[ed.size()]);
+ this.hasCommand = command.length > 0;
+ this.defaultOption = at.hasOption("-default");
+ this.deleteOption = at.hasOption("-delete");
+ this.waitOption = at.hasOption("-wait");
+ this.retainOption = at.hasOption("-retain");
+ this.primaryOptionCount = (hasCommand? 1 : 0) + (defaultOption? 1 : 0) + (deleteOption? 1 : 0);
+ }
+
+ SetEditor() {
+ this(new ArgTokenizer("", ""));
+ }
+
+ boolean set() {
+ if (!check()) {
+ return false;
+ }
+ if (primaryOptionCount == 0 && !retainOption) {
+ // No settings or -retain, so this is a query
+ EditorSetting retained = EditorSetting.fromPrefs(prefs);
+ if (retained != null) {
+ // retained editor is set
+ hard("/set editor -retain %s", format(retained));
+ }
+ if (retained == null || !retained.equals(editor)) {
+ // editor is not retained or retained is different from set
+ hard("/set editor %s", format(editor));
+ }
+ return true;
+ }
+ if (retainOption && deleteOption) {
+ EditorSetting.removePrefs(prefs);
+ }
+ install();
+ if (retainOption && !deleteOption) {
+ editor.toPrefs(prefs);
+ fluffmsg("jshell.msg.set.editor.retain", format(editor));
+ }
+ return true;
+ }
+
+ private boolean check() {
+ if (!checkOptionsAndRemainingInput(at)) {
+ return false;
+ }
+ if (primaryOptionCount > 1) {
+ errormsg("jshell.err.default.option.or.program", at.whole());
+ return false;
+ }
+ if (waitOption && !hasCommand) {
+ errormsg("jshell.err.wait.applies.to.external.editor", at.whole());
+ return false;
+ }
+ return true;
+ }
+
+ private void install() {
+ if (hasCommand) {
+ editor = new EditorSetting(command, waitOption);
+ } else if (defaultOption) {
+ editor = BUILT_IN_EDITOR;
+ } else if (deleteOption) {
+ configEditor();
+ } else {
+ return;
+ }
+ fluffmsg("jshell.msg.set.editor.set", format(editor));
+ }
+
+ private String format(EditorSetting ed) {
+ if (ed == BUILT_IN_EDITOR) {
+ return "-default";
+ } else {
+ Stream<String> elems = Arrays.stream(ed.cmd);
+ if (ed.wait) {
+ elems = Stream.concat(Stream.of("-wait"), elems);
+ }
+ return elems.collect(joining(" "));
+ }
+ }
+ }
+
+ // The sub-command: /set start <start-file>
+ boolean setStart(ArgTokenizer at) {
+ at.allowedOptions("-default", "-none", "-retain");
+ String fn = at.next();
if (!checkOptionsAndRemainingInput(at)) {
return false;
}
boolean defaultOption = at.hasOption("-default");
- boolean waitOption = at.hasOption("-wait");
- if (prog != null) {
- if (defaultOption) {
- errormsg("jshell.err.default.option.or.program", at.whole());
+ boolean noneOption = at.hasOption("-none");
+ boolean retainOption = at.hasOption("-retain");
+ boolean hasFile = fn != null;
+
+ int argCount = (defaultOption ? 1 : 0) + (noneOption ? 1 : 0) + (hasFile ? 1 : 0);
+ if (argCount > 1) {
+ errormsg("jshell.err.option.or.filename", at.whole());
+ return false;
+ }
+ if (argCount == 0 && !retainOption) {
+ // no options or filename, show current setting
+ showSetStart();
+ return true;
+ }
+ if (hasFile) {
+ String init = readFile(fn, "/set start");
+ if (init == null) {
return false;
}
- editor = ed.toArray(new String[ed.size()]);
- editorWait = waitOption;
- fluffmsg("jshell.msg.set.editor.set", prog);
+ startup = init;
} else if (defaultOption) {
- if (waitOption) {
- errormsg("jshell.err.wait.applies.to.external.editor", at.whole());
- return false;
- }
- editor = null;
- } else if (argsRequired) {
- errormsg("jshell.err.set.editor.arg");
- return false;
+ startup = DEFAULT_STARTUP;
+ } else if (noneOption) {
+ startup = "";
+ }
+ if (retainOption) {
+ // retain startup setting
+ prefs.put(STARTUP_KEY, startup);
}
return true;
}
- // The sub-command: /set start <start-file>
- boolean setStart(String cmd, ArgTokenizer at, boolean argsRequired) {
- at.allowedOptions("-default", "-none");
- String fn = at.next();
- if (!checkOptionsAndRemainingInput(at)) {
- return false;
+ void showSetStart() {
+ String retained = prefs.get(STARTUP_KEY, null);
+ if (retained != null) {
+ showSetStart(true, retained);
}
- int argCount = at.optionCount() + ((fn != null) ? 1 : 0);
- if (argCount > 1 || argsRequired && argCount == 0) {
- errormsg("jshell.err.option.or.filename", at.whole());
- return false;
+ if (retained == null || !startup.equals(retained)) {
+ showSetStart(false, startup);
}
- if (fn != null) {
- String init = readFile(fn, cmd + " start");
- if (init == null) {
- return false;
- } else {
- startup = init;
- return true;
- }
- } else if (at.hasOption("-default")) {
- startup = DEFAULT_STARTUP;
- } else if (at.hasOption("-none")) {
- startup = "";
+ }
+
+ void showSetStart(boolean isRetained, String start) {
+ String cmd = "/set start" + (isRetained ? " -retain " : " ");
+ String stset;
+ if (start.equals(DEFAULT_STARTUP)) {
+ stset = cmd + "-default";
+ } else if (start.isEmpty()) {
+ stset = cmd + "-none";
+ } else {
+ stset = prefix("startup.jsh:\n" + start + "\n" + cmd + "startup.jsh", "");
}
- return true;
+ hard(stset);
}
boolean cmdClasspath(String arg) {
@@ -1561,17 +1708,18 @@
Command[] matches = commands.values().stream()
.filter(c -> c.command.startsWith(subject))
.toArray(size -> new Command[size]);
- at.mark();
- String sub = at.next();
- if (sub != null && matches.length == 1) {
+ if (matches.length == 1) {
String cmd = matches[0].command;
- switch (cmd) {
- case "/set":
- at.rewind();
- return printSubCommandHelp(cmd, at, "help.set.", SET_SUBCOMMANDS);
- case "/retain":
- at.rewind();
- return printSubCommandHelp(cmd, at, "help.retain.", RETAIN_SUBCOMMANDS);
+ if (cmd.equals("/set")) {
+ // Print the help doc for the specified sub-command
+ String which = subCommand(cmd, at, SET_SUBCOMMANDS);
+ if (which == null) {
+ return false;
+ }
+ if (!which.equals("_blank")) {
+ hardrb("help.set." + which);
+ return true;
+ }
}
}
if (matches.length > 0) {
@@ -1761,13 +1909,13 @@
errormsg("jshell.err.drop.arg");
return false;
}
- Stream<PersistentSnippet> stream = argsToSnippets(this::dropableSnippets, args);
+ Stream<Snippet> stream = argsToSnippets(this::dropableSnippets, args);
if (stream == null) {
// Snippet not found. Error already printed
fluffmsg("jshell.msg.see.classes.etc");
return false;
}
- List<PersistentSnippet> snippets = stream.collect(toList());
+ List<Snippet> snippets = stream.collect(toList());
if (snippets.size() > args.size()) {
// One of the args references more thean one snippet
errormsg("jshell.err.drop.ambiguous");
@@ -1815,7 +1963,7 @@
String src = sb.toString();
Consumer<String> saveHandler = new SaveHandler(src, srcSet);
Consumer<String> errorHandler = s -> hard("Edit Error: %s", s);
- if (editor == null) {
+ if (editor == BUILT_IN_EDITOR) {
try {
EditPad.edit(errorHandler, src, saveHandler);
} catch (RuntimeException ex) {
@@ -1824,8 +1972,8 @@
return false;
}
} else {
- ExternalEditor.edit(editor, errorHandler, src, saveHandler, input,
- editorWait, this::hardrb);
+ ExternalEditor.edit(editor.cmd, errorHandler, src, saveHandler, input,
+ editor.wait, this::hardrb);
}
return true;
}
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/MessageHandler.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/MessageHandler.java Wed Oct 26 20:13:29 2016 +0000
@@ -37,5 +37,11 @@
void fluffmsg(String messageKey, Object... args);
+ void hard(String format, Object... args);
+
+ void hardmsg(String messageKey, Object... args);
+
void errormsg(String messageKey, Object... args);
+
+ boolean showFluff();
}
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/StopDetectingInputStream.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/StopDetectingInputStream.java Wed Oct 26 20:13:29 2016 +0000
@@ -77,9 +77,7 @@
} catch (IOException ex) {
errorHandler.accept(ex);
} finally {
- synchronized (StopDetectingInputStream.this) {
- state = StopDetectingInputStream.State.CLOSED;
- }
+ shutdown();
}
}
};
@@ -140,8 +138,10 @@
}
public synchronized void setState(State state) {
- this.state = state;
- notifyAll();
+ if (this.state != State.CLOSED) {
+ this.state = state;
+ notifyAll();
+ }
}
private synchronized State waitInputNeeded() {
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties Wed Oct 26 20:13:29 2016 +0000
@@ -52,12 +52,17 @@
jshell.err.no.such.command.or.snippet.id = No such command or snippet id: {0}
jshell.err.command.ambiguous = Command: ''{0}'' is ambiguous: {1}
-jshell.err.set.editor.arg = The ''/set editor'' command requires a path argument
jshell.msg.set.editor.set = Editor set to: {0}
+jshell.msg.set.editor.retain = Editor setting retained: {0}
jshell.err.cant.launch.editor = Cannot launch editor -- unexpected exception: {0}
jshell.msg.try.set.editor = Try /set editor to use external editor.
jshell.msg.press.return.to.leave.edit.mode = Press return to leave edit mode.
-jshell.err.wait.applies.to.external.editor = -wait applies to external editors, cannot be used with -default
+jshell.err.wait.applies.to.external.editor = -wait applies to external editors
+
+jshell.err.setting.to.retain.must.be.specified = The setting to retain must be specified -- {0}
+jshell.msg.set.show.mode.settings = \nTo show mode settings use ''/set prompt'', ''/set truncation'', ...\n\
+or use ''/set mode'' followed by the feedback mode name.
+jshell.err.continuation.prompt.required = Continuation prompt required -- {0}
jshell.msg.try.command.without.args = Try ''{0}'' without arguments.
jshell.msg.no.active = There are no active definitions.
@@ -104,12 +109,10 @@
jshell.err.mode.name = Expected a feedback mode name: {0}
jshell.err.missing.mode = Missing the feedback mode -- {0}
jshell.err.field.name = Expected a field name: {0} -- {1}
-jshell.err.missing.field = Missing the field name -- {0}
jshell.err.mode.unknown = No feedback mode named: {0} -- {1}
jshell.err.feedback.does.not.match.mode = Does not match any current feedback mode: {0} -- {1}
jshell.err.feedback.ambiguous.mode = Matches more then one current feedback mode: {0} -- {1}
-jshell.err.feedback.expected.format = Expected format missing -- {0}
jshell.err.feedback.must.be.quoted = Format ''{0}'' must be quoted -- {1}
jshell.err.feedback.not.a.valid.selector = Not a valid selector ''{0}'' in ''{1}'' -- {2}
jshell.err.feedback.multiple.sections = Selector kind in multiple sections of selector list ''{0}'' in ''{1}'' -- {2}
@@ -117,22 +120,25 @@
jshell.msg.feedback.new.mode = Created new feedback mode: {0}
jshell.msg.feedback.mode = Feedback mode: {0}
-jshell.msg.feedback.mode.following = The feedback mode should be one of the following:
+jshell.msg.feedback.mode.following = Available feedback modes:
+jshell.msg.feedback.retained.mode.following = Retained feedback modes:
+jshell.err.mode.creation = To create a new mode either the -command or the -quiet option must be used -- {0}
+jshell.err.mode.exists = Mode to be created already exists: {0} -- {1}
jshell.err.truncation.expected.length = Expected truncation length -- {0}
jshell.err.truncation.length.not.integer = Truncation length must be an integer: {0} -- {1}
jshell.err.not.valid.with.predefined.mode = Not valid with a predefined mode: {0} -- {1}
jshell.err.retained.feedback.mode.must.be.retained.or.predefined = \
-''/retain feedback <mode>'' requires that <mode> is predefined or has been retained with ''/retain mode'' -- {0}
+''/set feedback -retain <mode>'' requires that <mode> is predefined or has been retained with ''/set mode -retain'' -- {0}
jshell.err.unknown.option = Unknown option: {0} -- {1}
-jshell.err.default.option.or.program = Specify -default option or program, not both -- {0}
-jshell.err.option.or.filename = Specify either one option or a startup file name -- {0}
+jshell.err.default.option.or.program = Specify -default option, -delete option, or program -- {0}
+jshell.err.option.or.filename = Specify no more than one of -default, -none, or a startup file name -- {0}
jshell.err.unexpected.at.end = Unexpected arguments at end of command: {0} -- {1}
jshell.err.conflicting.options = Conflicting options -- {0}
jshell.err.cannot.delete.current.mode = The current feedback mode ''{0}'' cannot be deleted, use ''/set feedback'' first -- {1}
-jshell.err.cannot.delete.retained.mode = The retained feedback mode ''{0}'' cannot be deleted, use ''/retain feedback'' first -- {1}
+jshell.err.cannot.delete.retained.mode = The retained feedback mode ''{0}'' cannot be deleted, use ''/set feedback -retain'' first -- {1}
jshell.err.may.not.specify.options.and.snippets = Options and snippets must not both be used: {0}
jshell.err.no.such.snippets = No such snippet: {0}
jshell.err.the.snippet.cannot.be.used.with.this.command = This command does not accept the snippet ''{0}'' : {1}
@@ -374,36 +380,20 @@
The contents of the specified <file> become the default start-up snippets and commands.\n\n\
/set feedback <mode>\n\t\
Set the feedback mode describing displayed feedback for entered snippets and commands.\n\n\
-/set mode <mode> [<old-mode>] [-command|-quiet|-delete]\n\t\
+/set mode <mode> [<old-mode>] -command|-quiet|-delete\n\t\
Create or update a user-defined feedback mode, optionally copying from an existing mode.\n\n\
/set prompt <mode> "<prompt>" "<continuation-prompt>"\n\t\
Set the displayed prompts for a given feedback mode.\n\n\
/set truncation <mode> <length> <selector>...\n\t\
- Set the maximum length of a displayed value\n\
+ Set the maximum length of a displayed value.\n\n\
/set format <mode> <field> "<format>" <selector>...\n\t\
- Configure a feedback mode by setting the format of a field when the selector matchs.\n\n\
+ Configure a feedback mode by setting the format of a field when the selector matches.\n\n\
+/set\n\t\
+ Show editor, start, and feedback settings as /set commands.\n\t\
+ To show the settings of any of the above, omit the set value.\n\n\
To get more information about one of these forms, use /help with the form specified.\n\
For example: /help /set format
-help.retain.summary = retain jshell configuration information for subsequent sessions
-help.retain.args = editor|start|feedback|mode
-help.retain =\
-Retain jshell configuration information for future invocations of the jshell tool,\n\
-including: the external editor to use, the start-up definitions to use, the\n\
-configuration of a feedback mode, or the feedback mode to use.\n\
-\n\
-/retain editor [<command> <optional-arg>...]\n\t\
- Specify the command to launch for the /edit command.\n\t\
- The <command> is an operating system dependent string.\n\n\
-/retain start [<file>]\n\t\
- The contents of the specified <file> become the default start-up snippets and commands.\n\n\
-/retain feedback [<mode>]\n\t\
- Set the feedback mode describing displayed feedback for entered snippets and commands.\n\n\
-/retain mode <mode>\n\t\
- Create a user-defined feedback mode, optionally copying from an existing mode.\n\n\
-To get more information about one of these forms, use /help with the form specified.\n\
-For example: /help /retain feedback
-
help.quest.summary = get information about jshell
help.quest.args = [<command>|<subject>]
help.quest =\
@@ -467,11 +457,24 @@
possible fully qualified names based on the content of the specified classpath.\n\t\t\
The "<fix-shortcut>" is either Alt-F1 or Alt-Enter, depending on the platform.
+help.set._retain = \
+The '-retain' option saves a setting so that it is used in future sessions.\n\
+The -retain option can be used on the following forms of /set:\n\n\t\
+/set editor -retain\n\t\
+/set start -retain\n\t\
+/set feedback -retain\n\t\
+/set mode -retain\n\n\
+See these commands for more detail -- for example /help /set editor
+
help.set.format = \
-Set the format for reporting a snippet event.\n\
+Set the format for reporting a snippet event:\n\
\n\t\
/set format <mode> <field> "<format>" <selector>...\n\
\n\
+Show the format settings:\n\
+\n\t\
+/set format [<mode> [<field>]]\n\
+\n\
Where <mode> is the name of a previously defined feedback mode -- see '/help /set mode'.\n\
Where <field> is the name of context-specific format to define.\n\
Where <format> is a quoted string which will be the value of the field if one of\n\
@@ -541,13 +544,24 @@
/set format myformat action 'Update replaced' replaced-update\n\t\
/set format myformat display '{pre}{action} class {name}{post}' class-ok\n\t\
/set format myformat display '{pre}{action} variable {name}, reset to null{post}' replaced-vardecl,varinit-ok-update\n\n\
-Note that subsequent selectors for a field may overwrite some or all of previous used selectors -- last one wins\n
+Note that subsequent selectors for a field may overwrite some or all of previous used selectors -- last one wins\n\
+\n\
+The form without <format> shows the current format settings.\n\
+When the <mode> is specified only the format settings for that mode are shown.\n\
+When both the <mode> and <field> are specified only the format settings for that\n\
+mode and field are shown. Example:\n\t\
+/set format myformat\n\
+shows the format settings for the mode myformat\n
help.set.truncation = \
-Set the max length a displayed value.\n\
+Set the max length of a displayed value:\n\
\n\t\
/set truncation <mode> <length> <selector>...\n\
\n\
+Show the current truncation settings:\n\
+\n\t\
+/set truncation [<mode>]\n\
+\n\
Where <mode> is the name of a previously defined feedback mode -- see '/help /set mode'.\n\
Where <length> is an unsigned integer representing a maximum length.\n\
Where <selector> is only needed if you wish to fine-tune value truncation length\n\
@@ -571,63 +585,151 @@
/set trunc mymode 80\n\t\
/set truncation mymode 45 expression\n\t\
/set truncation mymode 0 vardecl-modified,replaced\n\n\
-Note that subsequent selectors for a field may overwrite some or all of previous used selectors -- last one wins\n
+Note that subsequent selectors for a field may overwrite some or all of previous used selectors -- last one wins\n\
+\n\
+The form without <length> shows the truncation settings.\n\
+When the <mode> is specified only the truncation settings for that mode are shown.\n\
+Example:\n\t\
+/set truncation myformat\n\
+shows the truncation settings for the mode myformat\n
help.set.feedback = \
-Set the feedback mode describing displayed feedback for entered snippets and commands.\n\
+Set the feedback mode describing displayed feedback for entered snippets and commands:\n\
+\n\t\
+/set feedback [-retain] <mode>\n\
+\n\
+Retain the current feedback mode for future sessions:\n\
\n\t\
-/set feedback <mode>\n\
+/set feedback -retain\n\
+\n\
+Show the feedback mode and list available modes:\n\
+\n\t\
+/set feedback\n\
\n\
Where <mode> is the name of a previously defined feedback mode.\n\
You may use just enough letters to make it unique.\n\
User-defined modes can be added, see '/help /set mode'\n\
-Currently defined feedback modes:\n
+\n\
+When the -retain option is used, the setting will be used in this and future\n\
+runs of the jshell tool.\n\
+\n\
+The form without <mode> or -retain displays the current feedback mode and available modes.\n
help.set.mode = \
-Create a user-defined feedback mode, optionally copying from an existing mode.\n\
+Create a user-defined feedback mode, optionally copying from an existing mode:\n\
\n\t\
/set mode <mode> [<old-mode>] [-command|-quiet|-delete]\n\
+Retain a user-defined feedback mode for future sessions:\n\
+\n\t\
+/set mode -retain <mode>\n\
+\n\
+Delete a user-defined feedback mode:\n\
+\n\t\
+/set mode -delete [-retain] <mode>\n\
+\n\
+Show feedback mode settings:\n\
+\n\t\
+/set mode [<mode>]\n\
\n\
Where <new-mode> is the name of a mode you wish to create.\n\
Where <old-mode> is the name of a previously defined feedback mode.\n\
If <old-mode> is present, its settings are copied to the new mode.\n\
'-command' vs '-quiet' determines if informative/verifying command feedback is displayed.\n\
\n\
-Once the new mode is created, use '/set format' and '/set prompt' to configure it.\n\
-Use '/set feedback' to use the new mode.\n\
+Once the new mode is created, use '/set format', '/set prompt' and '/set truncation'\n\
+to configure it. Use '/set feedback' to use the new mode.\n\
+\n\
+When the -retain option is used, the mode (including its component prompt, format,\n\
+and truncation settings) will be used in this and future runs of the jshell tool.\n\
+When both -retain and -delete are used, the mode is deleted from the current\n\
+and future sessions.\n\
+\n\
+The form without options shows the mode settings.\n\
+When the <mode> is specified only the mode settings for that mode are shown.\n\
+Note: the settings for the mode include the settings for prompt, format, and\n\
+truncation -- so these are displayed as well.\n\
+Example:\n\t\
+/set mode myformat\n\
+shows the mode, prompt, format, and truncation settings for the mode myformat\n
help.set.prompt = \
-Set the prompts. Both the normal prompt and the continuation-prompt must be set.\n\
+Set the prompts. Both the normal prompt and the continuation-prompt must be set:\n\
\n\t\
/set prompt <mode> \"<prompt>\" \"<continuation-prompt>\"\n\
\n\
+Show the normal prompt and the continuation-prompts:\n\
+\n\t\
+/set prompt [<mode>]\n\
+\n\
Where <mode> is the name of a previously defined feedback mode.\n\
Where <prompt> and <continuation-prompt> are quoted strings printed as input prompts;\n\
Both may optionally contain '%s' which will be substituted with the next snippet id --\n\
note that what is entered may not be assigned that id, for example it may be an error or command.\n\
-The continuation-prompt is used on the second and subsequent lines of a multi-line snippet.\n
+The continuation-prompt is used on the second and subsequent lines of a multi-line snippet.\n\
+\n\
+The form without <prompt> shows the currently set prompts.\n\
+When the <mode> is specified only the prompts for that mode are shown.\n\
+Example:\n\t\
+/set prompt myformat\n\
+shows the prompts set for the mode myformat\n
help.set.editor =\
-Specify the command to launch for the /edit command.\n\
+Specify the command to launch for the /edit command:\n\
+\n\t\
+/set editor [-retain] [-wait] <command>\n\
+\n\t\
+/set editor [-retain] -default\n\
\n\t\
-/set editor [-wait] <command>|-default\n\
+/set editor [-retain] -delete\n\
+\n\
+Retain the current editor setting for future sessions:\n\
+\n\t\
+/set editor -retain\n\
+\n\
+Show the command to launch for the /edit command:\n\
+\n\t\
+/set editor\n\
\n\
The <command> is an operating system dependent string.\n\
The <command> may include space-separated arguments (such as flags)\n\n\
If the -default option is specified, the built-in default editor will be used.\n\n\
-Otherwise an external editor should be specified in <command>. When <command>\n\
+If the -delete option is specified, previous settings are ignored -- the editor\n\
+settings are initialized as when starting the jshell tool. Specifically, if there\n\
+is a retained setting it is used (unless both -retain and -delete are specified --\n\
+which deletes the retained setting), if one of these environment variables is set\n\
+it will be used: JSHELLEDITOR, VISUAL, or EDITOR (in that order). Otherwise the\n\
+built-in default editor will be used.\n\n\
+If <command> is specified, it will be used as the external editor. The <command>\n\
+consists of the program and zero or more program arguments. When <command>\n\
is used, the temporary file to edit will be appended as the last argument.\n\
Normally, edit mode will last until the external editor exits. Some external editors\n\
will exit immediately (for example, if the edit window exists) either external editor\n\
flags should be used to prevent immediate exit, or the -wait option should be used to\n\
prompt the user to indicate when edit mode should end.\n\n\
Note: while in edit mode no command inputs are seen. After leaving edit mode changes\n\
-to the edited snippets are not seen.
+to the edited snippets are not seen.\n\
+\n\
+When the -retain option is used, the setting will be used in this and future\n\
+runs of the jshell tool.\n\
+\n\
+The form without <command> or options shows the editor setting.\n
help.set.start =\
-Set the start-up configuration -- a sequence of snippets and commands read at start-up.\n\
+Set the start-up configuration -- a sequence of snippets and commands read at start-up:\n\
+\n\t\
+/set start [-retain] <file>\n\
+\n\t\
+/set start [-retain] -default\n\
\n\t\
-/set start <file>|-default|-none\n\
+/set start [-retain] -none\n\
+\n\
+Retain the start-up configuration for future sessions:\n\
+\n\t\
+/set start -retain\n\
+\n\
+Show the start-up setting:\n\
+\n\t\
+/set start\n\
\n\
The contents of the specified <file> become the start-up snippets and commands used\n\
when the /reset or /reload commands are used in this session.\n\
@@ -637,59 +739,14 @@
or commands will be used.\n\
This command is good for testing the start-up settings. To retain them for future\n\
runs of the jshell tool use the command:\n\t\
-/retain start\n
-
-help.retain.feedback = \
-Retain which feedback mode to use for displayed feedback for entered snippets and commands.\n\
-This feedback mode will be used in this and future sessions of the jshell tool.\n\
-\n\t\
-/retain feedback [<mode>]\n\
-\n\
-Where <mode> is the name of a previously defined feedback mode.\n\
-You may use just enough letters to make it unique.\n\
-If the <mode> is not specified, this command retains the current mode (as set\n\
-with the most recent /set feedback or /retain feedback command.)\n\
-
-help.retain.mode = \
-Retain the existence and configuration of a user-defined feedback mode.\n\
-This mode will be available in this and future sessions of the jshell tool.
-\n\t\
-/retain mode <mode>\n\
+/set start -retain\n\
\n\
-Where <mode> is the name of a mode you wish to retain.\n\
-The <mode> must previously have been created with /set mode and\n\
-configured as desired with /set prompt, /set format, and /set truncation.\n
-
-help.retain.editor =\
-Retain the command to launch for the /edit command. This command will be invoked when\n\
-the /edit command is used in this and future sessions of the jshell tool.\n\
-\n\t\
-/retain editor [<command>|-default]\n\
+When the -retain option is used, the setting will be used in this and future\n\
+runs of the jshell tool.\n\
\n\
-If <command> is specified, it is an operating system dependent string which\n\
-may include space-separated arguments (such as flags). When /edit is used, the\n\
-temporary file to edit will be appended as the last argument.\n\
-If instead the -default option is specified, the built-in default editor will be used.\n\
-If neither is specified, the editor set in the last /set editor or /retain editor\n\
-command will be used.\n\
-The editor will be retained and used in this and future runs of the jshell tool.
-
-help.retain.start =\
-Retain the start-up configuration -- a sequence of snippets and commands read\n\
-at start-up.\n\
-\n\t\
-/retain start [<file>|-default|-none]\n\
-\n\
-If <file> is specified, the contents of the specified <file> become the\n\
-start-up snippets\n\
-and commands.\n\
-If instead the -default option is specified, the predefined start-up snippets\n\
-will be the start-up.\n\
-If the -none option is used, the start-up will be empty -- no start-up snippets\n\
-or commands will be used.\n\
-If none of these is specified, the start-up is the last specified in a\n\
-''/set start'' or ''/retain start'' command.\n\
-The start-up will be retained and used when the jshell tool is started or reset
+The form without <file> or options shows the start-up setting.\n\
+Note: if the start-up was last set from a file, this is shown with the\n\
+contents of the file followed by a 'set start' command.
startup.feedback = \
/set mode verbose -command \n\
@@ -743,7 +800,7 @@
/set format verbose result '{name} ==> {value}{post}' added,modified,replaced-ok-primary \n\
\n\
/set format verbose display '{result}{pre}created scratch variable {name} : {type}{post}' expression-added,modified,replaced-primary \n\
-/set format verbose display '{result}{pre}value of {name} : {type}{post}' varvalue-primary \n\
+/set format verbose display '{result}{pre}value of {name} : {type}{post}' varvalue-added,modified,replaced-primary \n\
/set format verbose display '{result}{pre}assigned to {name} : {type}{post}' assignment-primary \n\
/set format verbose display '{result}{pre}{action} variable {name} : {type}{resolve}{post}' varinit,vardecl \n\
/set format verbose display '{pre}{action} variable {name}{resolve}{post}' vardecl,varinit-notdefined \n\
@@ -773,6 +830,8 @@
\n\
/set mode silent -quiet \n\
/set prompt silent '-> ' '>> ' \n\
+/set truncation silent 80\n\
+/set truncation silent 1000 varvalue,expression\n\
/set format silent pre '| ' \n\
/set format silent post '%n' \n\
/set format silent errorpre '| ' \n\
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Eval.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Eval.java Wed Oct 26 20:13:29 2016 +0000
@@ -521,10 +521,13 @@
List<SnippetEvent> drop(Snippet si) {
Unit c = new Unit(state, si);
-
- Set<Unit> ins = c.dependents().collect(toSet());
- Set<Unit> outs = compileAndLoad(ins);
-
+ Set<Unit> outs;
+ if (si instanceof PersistentSnippet) {
+ Set<Unit> ins = c.dependents().collect(toSet());
+ outs = compileAndLoad(ins);
+ } else {
+ outs = Collections.emptySet();
+ }
return events(c, outs, null, null);
}
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java Wed Oct 26 20:13:29 2016 +0000
@@ -28,6 +28,7 @@
import jdk.jshell.spi.ExecutionControl;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
+import java.io.InterruptedIOException;
import java.io.PrintStream;
import java.text.MessageFormat;
import java.util.ArrayList;
@@ -58,7 +59,7 @@
* API. A {@code JShell} instance holds the evolving compilation and
* execution state. The state is changed with the instance methods
* {@link jdk.jshell.JShell#eval(java.lang.String) eval(String)},
- * {@link jdk.jshell.JShell#drop(jdk.jshell.PersistentSnippet) drop(PersistentSnippet)} and
+ * {@link jdk.jshell.JShell#drop(jdk.jshell.Snippet) drop(Snippet)} and
* {@link jdk.jshell.JShell#addToClasspath(java.lang.String) addToClasspath(String)}.
* The majority of methods query the state.
* A {@code JShell} instance also allows registering for events with
@@ -167,6 +168,10 @@
* user input cannot use {@code System.in} as the input stream for
* the remote process.
* <p>
+ * The {@code read} method of the {@code InputStream} may throw the {@link InterruptedIOException}
+ * to signal the user canceled the input. The currently running snippet will be automatically
+ * {@link JShell#stop() stopped}.
+ * <p>
* The default, if this is not set, is to provide an empty input stream
* -- {@code new ByteArrayInputStream(new byte[0])}.
*
@@ -428,7 +433,12 @@
}
/**
- * Remove a declaration from the state.
+ * Remove a declaration from the state. That is, if the snippet is an
+ * {@linkplain jdk.jshell.Snippet.Status#isActive() active}
+ * {@linkplain jdk.jshell.PersistentSnippet persistent} snippet, remove the
+ * snippet and update the JShell evaluation state accordingly.
+ * For all active snippets, change the {@linkplain #status status} to
+ * {@link jdk.jshell.Snippet.Status#DROPPED DROPPED}.
* @param snippet The snippet to remove
* @return The list of events from updating declarations dependent on the
* dropped snippet.
@@ -436,7 +446,7 @@
* @throws IllegalArgumentException if the snippet is not associated with
* this {@code JShell} instance.
*/
- public List<SnippetEvent> drop(PersistentSnippet snippet) throws IllegalStateException {
+ public List<SnippetEvent> drop(Snippet snippet) throws IllegalStateException {
checkIfAlive();
checkValidSnippet(snippet);
List<SnippetEvent> events = eval.drop(snippet);
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Key.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Key.java Wed Oct 26 20:13:29 2016 +0000
@@ -74,7 +74,7 @@
/**
* Grouping for snippets which persist and influence future code.
* They are keyed off at least the name. They may be Modified/Replaced
- * with new input and can be dropped (JShell#drop).
+ * with new input.
*/
static abstract class PersistentKey extends Key {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/PersistentSnippet.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/PersistentSnippet.java Wed Oct 26 20:13:29 2016 +0000
@@ -28,8 +28,8 @@
/**
* Grouping for Snippets which persist and influence future code.
* A persistent snippet can be
- * {@linkplain jdk.jshell.Snippet.Status#OVERWRITTEN overwritten)}
- * with new input and can be dropped {@link JShell#drop}.
+ * {@linkplain jdk.jshell.Snippet.Status#OVERWRITTEN overwritten}
+ * with new input.
* <p>
* <code>PersistentSnippet</code> is immutable: an access to
* any of its methods will always return the same result.
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Snippet.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Snippet.java Wed Oct 26 20:13:29 2016 +0000
@@ -443,9 +443,7 @@
/**
* The snippet is inactive because of an explicit call to
- * the {@link JShell#drop(PersistentSnippet)}.
- * Only a {@link jdk.jshell.PersistentSnippet} can have this
- * {@code Status}.
+ * the {@link JShell#drop(Snippet)}.
* <p>
* The snippet is not visible to other snippets
* ({@link Status#isDefined() isDefined() == false})
@@ -525,10 +523,11 @@
/**
* Indicates whether the Snippet is active, that is,
- * will the snippet be re-evaluated when a new
+ * will a {@linkplain jdk.jshell.PersistentSnippet persistent}
+ * snippet be re-evaluated when a new
* {@link JShell#eval(java.lang.String) JShell.eval(String)} or
- * {@link JShell#drop(jdk.jshell.PersistentSnippet)
- * JShell.drop(PersistentSnippet)} that could change
+ * {@link JShell#drop(jdk.jshell.Snippet)
+ * JShell.drop(Snippet)} that could change
* its status is invoked. This is more broad than
* {@link Status#isDefined()} since a Snippet which is
* {@link Status#RECOVERABLE_NOT_DEFINED}
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/SnippetEvent.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/SnippetEvent.java Wed Oct 26 20:13:29 2016 +0000
@@ -30,7 +30,7 @@
/**
* A description of a change to a Snippet. These are generated by direct changes
* to state with {@link JShell#eval(java.lang.String) JShell.eval(String)} or
- * {@link JShell#drop(jdk.jshell.PersistentSnippet) JShell.drop(PersistentSnippet)},
+ * {@link JShell#drop(jdk.jshell.Snippet) JShell.drop(Snippet)},
* or indirectly by these same methods as
* dependencies change or Snippets are overwritten. For direct changes, the
* {@link SnippetEvent#causeSnippet()} is {@code null}.
@@ -108,7 +108,7 @@
* creation of a new Snippet via
* {@link jdk.jshell.JShell#eval(java.lang.String) eval} or it is the
* explicit drop of a Snippet with
- * {@link jdk.jshell.JShell#drop(jdk.jshell.PersistentSnippet) drop}.
+ * {@link jdk.jshell.JShell#drop(jdk.jshell.Snippet) drop}.
*
* @return the Snippet which caused this change or {@code null} if
* directly caused by an API action.
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java Wed Oct 26 20:13:29 2016 +0000
@@ -116,6 +116,7 @@
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.QualifiedNameable;
+import javax.lang.model.element.TypeParameterElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.ArrayType;
import javax.lang.model.type.ExecutableType;
@@ -132,6 +133,7 @@
import static jdk.jshell.Util.REPL_DOESNOTMATTER_CLASS_NAME;
import static java.util.stream.Collectors.joining;
import static jdk.jshell.SourceCodeAnalysis.Completeness.DEFINITELY_INCOMPLETE;
+import static jdk.jshell.TreeDissector.printType;
/**
* The concrete implementation of SourceCodeAnalysis.
@@ -1185,7 +1187,7 @@
proc.debug(ex, "SourceCodeAnalysisImpl.element2String(..., " + el + ")");
}
- return Util.expunge(elementHeader(el));
+ return Util.expunge(elementHeader(sourceCache.originalTask, el, !hasSyntheticParameterNames(el)));
}
private boolean hasSyntheticParameterNames(Element el) {
@@ -1248,7 +1250,7 @@
topLevelName2Signature2Method.put(binaryName, cache = createMethodCache(binaryName));
}
- String handle = elementHeader(method, false);
+ String handle = elementHeader(originalTask, method, false);
return cache.getOrDefault(handle, method);
}
@@ -1276,7 +1278,7 @@
Element currentMethod = trees.getElement(getCurrentPath());
if (currentMethod != null) {
- signature2Method.put(elementHeader(currentMethod, false), currentMethod);
+ signature2Method.put(elementHeader(originalTask, currentMethod, false), currentMethod);
}
return null;
@@ -1331,39 +1333,79 @@
return availableSources = result;
}
- private String elementHeader(Element el) {
- return elementHeader(el, true);
+ private String elementHeader(AnalyzeTask at, Element el) {
+ return elementHeader(at, el, true);
}
- private String elementHeader(Element el, boolean includeParameterNames) {
+ private String elementHeader(AnalyzeTask at, Element el, boolean includeParameterNames) {
switch (el.getKind()) {
- case ANNOTATION_TYPE: case CLASS: case ENUM: case INTERFACE:
- return ((TypeElement) el).getQualifiedName().toString();
+ case ANNOTATION_TYPE: case CLASS: case ENUM: case INTERFACE: {
+ TypeElement type = (TypeElement)el;
+ String fullname = type.getQualifiedName().toString();
+ Element pkg = at.getElements().getPackageOf(el);
+ String name = pkg == null ? fullname :
+ proc.maps.fullClassNameAndPackageToClass(fullname, ((PackageElement)pkg).getQualifiedName().toString());
+
+ return name + typeParametersOpt(at, type.getTypeParameters());
+ }
+ case TYPE_PARAMETER: {
+ TypeParameterElement tp = (TypeParameterElement)el;
+ String name = tp.getSimpleName().toString();
+
+ List<? extends TypeMirror> bounds = tp.getBounds();
+ boolean boundIsObject = bounds.isEmpty() ||
+ bounds.size() == 1 && at.getTypes().isSameType(bounds.get(0), Symtab.instance(at.getContext()).objectType);
+
+ return boundIsObject
+ ? name
+ : name + " extends " + bounds.stream()
+ .map(bound -> printType(at, proc, bound))
+ .collect(joining(" & "));
+ }
case FIELD:
- return elementHeader(el.getEnclosingElement()) + "." + el.getSimpleName() + ":" + el.asType();
+ return elementHeader(at, el.getEnclosingElement()) + "." + el.getSimpleName() + ":" + el.asType();
case ENUM_CONSTANT:
- return elementHeader(el.getEnclosingElement()) + "." + el.getSimpleName();
+ return elementHeader(at, el.getEnclosingElement()) + "." + el.getSimpleName();
case EXCEPTION_PARAMETER: case LOCAL_VARIABLE: case PARAMETER: case RESOURCE_VARIABLE:
return el.getSimpleName() + ":" + el.asType();
- case CONSTRUCTOR: case METHOD:
+ case CONSTRUCTOR: case METHOD: {
StringBuilder header = new StringBuilder();
- header.append(elementHeader(el.getEnclosingElement()));
- if (el.getKind() == ElementKind.METHOD) {
- header.append(".");
- header.append(el.getSimpleName());
+
+ boolean isMethod = el.getKind() == ElementKind.METHOD;
+ ExecutableElement method = (ExecutableElement) el;
+
+ if (isMethod) {
+ // return type
+ header.append(printType(at, proc, method.getReturnType())).append(" ");
+ } else {
+ // type parameters for the constructor
+ String typeParameters = typeParametersOpt(at, method.getTypeParameters());
+ if (!typeParameters.isEmpty()) {
+ header.append(typeParameters).append(" ");
+ }
}
+
+ // receiver type
+ String clazz = elementHeader(at, el.getEnclosingElement());
+ header.append(clazz);
+
+ if (isMethod) {
+ //method name with type parameters
+ (clazz.isEmpty() ? header : header.append("."))
+ .append(typeParametersOpt(at, method.getTypeParameters()))
+ .append(el.getSimpleName());
+ }
+
+ // arguments
header.append("(");
String sep = "";
- ExecutableElement method = (ExecutableElement) el;
for (Iterator<? extends VariableElement> i = method.getParameters().iterator(); i.hasNext();) {
VariableElement p = i.next();
header.append(sep);
if (!i.hasNext() && method.isVarArgs()) {
- header.append(unwrapArrayType(p.asType()));
- header.append("...");
-
+ header.append(printType(at, proc, unwrapArrayType(p.asType()))).append("...");
} else {
- header.append(p.asType());
+ header.append(printType(at, proc, p.asType()));
}
if (includeParameterNames) {
header.append(" ");
@@ -1372,8 +1414,18 @@
sep = ", ";
}
header.append(")");
+
+ // throws
+ List<? extends TypeMirror> thrownTypes = method.getThrownTypes();
+ if (!thrownTypes.isEmpty()) {
+ header.append(" throws ")
+ .append(thrownTypes.stream()
+ .map(type -> printType(at, proc, type))
+ .collect(joining(", ")));
+ }
return header.toString();
- default:
+ }
+ default:
return el.toString();
}
}
@@ -1383,6 +1435,12 @@
}
return arrayType;
}
+ private String typeParametersOpt(AnalyzeTask at, List<? extends TypeParameterElement> typeParameters) {
+ return typeParameters.isEmpty() ? ""
+ : typeParameters.stream()
+ .map(tp -> elementHeader(at, tp))
+ .collect(joining(", ", "<", ">"));
+ }
@Override
public String analyzeType(String code, int cursor) {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/PipeInputStream.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/PipeInputStream.java Wed Oct 26 20:13:29 2016 +0000
@@ -42,7 +42,7 @@
@Override
public synchronized int read() throws IOException {
- if (start == end) {
+ if (start == end && !closed) {
inputNeeded();
}
while (start == end) {
@@ -62,6 +62,32 @@
}
}
+ @Override
+ public synchronized int read(byte[] b, int off, int len) throws IOException {
+ if (b == null) {
+ throw new NullPointerException();
+ } else if (off < 0 || len < 0 || len > b.length - off) {
+ throw new IndexOutOfBoundsException();
+ } else if (len == 0) {
+ return 0;
+ }
+
+ int c = read();
+ if (c == -1) {
+ return -1;
+ }
+ b[off] = (byte)c;
+
+ int totalRead = 1;
+ while (totalRead < len && start != end) {
+ int r = read();
+ if (r == (-1))
+ break;
+ b[off + totalRead++] = (byte) r;
+ }
+ return totalRead;
+ }
+
protected void inputNeeded() throws IOException {}
private synchronized void write(int b) {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/Util.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/Util.java Wed Oct 26 20:13:29 2016 +0000
@@ -28,6 +28,7 @@
import java.io.IOException;
import java.io.InputStream;
+import java.io.InterruptedIOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
@@ -42,6 +43,7 @@
import com.sun.jdi.VirtualMachine;
import jdk.jshell.spi.ExecutionControl;
+import jdk.jshell.spi.ExecutionControl.ExecutionControlException;
/**
@@ -54,6 +56,10 @@
*/
public class Util {
+ private static final int TAG_DATA = 0;
+ private static final int TAG_CLOSED = 1;
+ private static final int TAG_EXCEPTION = 2;
+
// never instanciated
private Util() {}
@@ -131,6 +137,25 @@
inputSignal.write('1');
inputSignal.flush();
}
+ @Override
+ public synchronized int read() throws IOException {
+ int tag = super.read();
+ switch (tag) {
+ case TAG_DATA: return super.read();
+ case TAG_CLOSED: close(); return -1;
+ case TAG_EXCEPTION:
+ int len = (super.read() << 0) + (super.read() << 8) + (super.read() << 16) + (super.read() << 24);
+ byte[] message = new byte[len];
+ for (int i = 0; i < len; i++) {
+ message[i] = (byte) super.read();
+ }
+ throw new IOException(new String(message, "UTF-8"));
+ case -1:
+ return -1;
+ default:
+ throw new IOException("Internal error: unrecognized message tag: " + tag);
+ }
+ }
};
inputs.put(e.getKey(), inputPipe.createOutput());
e.getValue().accept(inputPipe);
@@ -163,6 +188,7 @@
public static ExecutionControl remoteInputOutput(InputStream input, OutputStream output,
Map<String, OutputStream> outputStreamMap, Map<String, InputStream> inputStreamMap,
BiFunction<ObjectInput, ObjectOutput, ExecutionControl> factory) throws IOException {
+ ExecutionControl[] result = new ExecutionControl[1];
Map<String, OutputStream> augmentedStreamMap = new HashMap<>(outputStreamMap);
ObjectOutput commandOut = new ObjectOutputStream(Util.multiplexingOutputStream("$command", output));
for (Entry<String, InputStream> e : inputStreamMap.entrySet()) {
@@ -172,7 +198,28 @@
@Override
public void write(int b) throws IOException {
//value ignored, just a trigger to read from the input
- inTarget.write(in.read());
+ try {
+ int r = in.read();
+ if (r == (-1)) {
+ inTarget.write(TAG_CLOSED);
+ } else {
+ inTarget.write(new byte[] {TAG_DATA, (byte) r});
+ }
+ } catch (InterruptedIOException exc) {
+ try {
+ result[0].stop();
+ } catch (ExecutionControlException ex) {
+ debug(ex, "$" + e.getKey() + "-input-requested.write");
+ }
+ } catch (IOException exc) {
+ byte[] message = exc.getMessage().getBytes("UTF-8");
+ inTarget.write(TAG_EXCEPTION);
+ inTarget.write((message.length >> 0) & 0xFF);
+ inTarget.write((message.length >> 8) & 0xFF);
+ inTarget.write((message.length >> 16) & 0xFF);
+ inTarget.write((message.length >> 24) & 0xFF);
+ inTarget.write(message);
+ }
}
});
}
@@ -180,7 +227,7 @@
OutputStream commandInTarget = commandIn.createOutput();
augmentedStreamMap.put("$command", commandInTarget);
new DemultiplexInput(input, augmentedStreamMap, Arrays.asList(commandInTarget)).start();
- return factory.apply(new ObjectInputStream(commandIn), commandOut);
+ return result[0] = factory.apply(new ObjectInputStream(commandIn), commandOut);
}
/**
@@ -198,4 +245,13 @@
}
}
+ /**
+ * Log a serious unexpected internal exception.
+ *
+ * @param ex the exception
+ * @param where a description of the context of the exception
+ */
+ private static void debug(Throwable ex, String where) {
+ // Reserved for future logging
+ }
}
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/package-info.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/package-info.java Wed Oct 26 20:13:29 2016 +0000
@@ -46,7 +46,7 @@
* {@link jdk.jshell.SnippetEvent}. There are three major kinds of
* changes to the status of a snippet: it can created with <code>eval</code>,
* it can be dropped from the active source state with
- * {@link jdk.jshell.JShell#drop(jdk.jshell.PersistentSnippet)}, and it can have
+ * {@link jdk.jshell.JShell#drop(jdk.jshell.Snippet)}, and it can have
* its status updated as a result of a status change in another snippet.
* For
* example: given <code>js</code>, an instance of <code>JShell</code>, executing
--- a/langtools/test/Makefile Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/test/Makefile Wed Oct 26 20:13:29 2016 +0000
@@ -157,11 +157,6 @@
-refvmoptions:-Xbootclasspath/p:$(TESTBOOTCLASSPATH)
endif
-ifeq ($(ARCH_DATA_MODEL),32)
- # Set the GC options for test vms
- JTREG_GC_OPTION = -vmoption:-XX:+UseSerialGC
- JTREG_OPTIONS += $(JTREG_GC_OPTION)
-endif
# Set the max memory for jtreg target test JVMs
JTREG_TESTVM_MEMORY_OPTION = -vmoption:-Xmx768m
JTREG_OPTIONS += $(JTREG_TESTVM_MEMORY_OPTION)
@@ -256,6 +251,17 @@
JCK_COMPILER_OUTPUT_DIR = $(ABS_TEST_OUTPUT_DIR)/jck-compiler
JCK_RUNTIME_OUTPUT_DIR = $(ABS_TEST_OUTPUT_DIR)/jck-runtime-Xcompile
+# Is the test JVM 32-bit?
+DATA_MODEL := \
+ $(shell $(JT_JAVA)/bin/java -XshowSettings:properties -version 2>&1 | \
+ grep 'sun\.arch\.data\.model' | \
+ awk '{print $$3}')
+ifeq ($(DATA_MODEL), 32)
+ # Set the GC options for test vms having a smaller address space
+ JTREG_GC_OPTION = -vmoption:-XX:+UseSerialGC
+ JTREG_OPTIONS += $(JTREG_GC_OPTION)
+endif
+
# Default make rule -- warning, may take a while
all: $(JPRT_CLEAN) jtreg-tests jck-compiler-tests jck-runtime-tests $(JPRT_ARCHIVE_BUNDLE) all-summary
@echo "Testing completed successfully"
@@ -321,6 +327,7 @@
$(JTREG_EXCLUSIONS) \
$(JTREG_OPTIONS) \
$(JTREG_TESTDIRS) \
+ 2>&1 | tee $(JTREG_OUTPUT_DIR)/output.txt \
|| ( $(call EXIT_IF_FATAL,$(FATAL_JTREG_EXIT)) ; \
echo $$status > $(JTREG_OUTPUT_DIR)/status.txt \
)
--- a/langtools/test/com/sun/javadoc/testJavascript/TestJavascript.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/test/com/sun/javadoc/testJavascript/TestJavascript.java Wed Oct 26 20:13:29 2016 +0000
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 4665566 4855876 7025314 8012375 8015997 8016328 8024756
+ * @bug 4665566 4855876 7025314 8012375 8015997 8016328 8024756 8151921
* @summary Verify that the output has the right javascript.
* @author jamieh
* @library ../lib
@@ -54,11 +54,12 @@
checkOutput("index.html", true,
"<script type=\"text/javascript\">\n"
- + " targetPage = \"\" + window.location.search;\n"
- + " if (targetPage != \"\" && targetPage != \"undefined\")\n"
- + " targetPage = targetPage.substring(1);\n"
- + " if (targetPage.indexOf(\":\") != -1 || (targetPage != \"\" && !validURL(targetPage)))\n"
- + " targetPage = \"undefined\";\n"
+ + " tmpTargetPage = \"\" + window.location.search;\n"
+ + " if (tmpTargetPage != \"\" && tmpTargetPage != \"undefined\")\n"
+ + " tmpTargetPage = tmpTargetPage.substring(1);\n"
+ + " if (tmpTargetPage.indexOf(\":\") != -1 || (tmpTargetPage != \"\" && !validURL(tmpTargetPage)))\n"
+ + " tmpTargetPage = \"undefined\";\n"
+ + " targetPage = tmpTargetPage;\n"
+ " function validURL(url) {\n"
+ " try {\n"
+ " url = decodeURIComponent(url);\n"
--- a/langtools/test/jdk/javadoc/doclet/testJavascript/TestJavascript.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/test/jdk/javadoc/doclet/testJavascript/TestJavascript.java Wed Oct 26 20:13:29 2016 +0000
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 4665566 4855876 7025314 8012375 8015997 8016328 8024756 8148985
+ * @bug 4665566 4855876 7025314 8012375 8015997 8016328 8024756 8148985 8151921
* @summary Verify that the output has the right javascript.
* @author jamieh
* @library ../lib
@@ -54,11 +54,12 @@
checkOutput("index.html", true,
"<script type=\"text/javascript\">\n"
- + " targetPage = \"\" + window.location.search;\n"
- + " if (targetPage != \"\" && targetPage != \"undefined\")\n"
- + " targetPage = targetPage.substring(1);\n"
- + " if (targetPage.indexOf(\":\") != -1 || (targetPage != \"\" && !validURL(targetPage)))\n"
- + " targetPage = \"undefined\";\n"
+ + " tmpTargetPage = \"\" + window.location.search;\n"
+ + " if (tmpTargetPage != \"\" && tmpTargetPage != \"undefined\")\n"
+ + " tmpTargetPage = tmpTargetPage.substring(1);\n"
+ + " if (tmpTargetPage.indexOf(\":\") != -1 || (tmpTargetPage != \"\" && !validURL(tmpTargetPage)))\n"
+ + " tmpTargetPage = \"undefined\";\n"
+ + " targetPage = tmpTargetPage;\n"
+ " function validURL(url) {\n"
+ " try {\n"
+ " url = decodeURIComponent(url);\n"
--- a/langtools/test/jdk/javadoc/doclet/testSearch/TestSearch.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/test/jdk/javadoc/doclet/testSearch/TestSearch.java Wed Oct 26 20:13:29 2016 +0000
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8141492 8071982
+ * @bug 8141492 8071982 8141636
* @summary Test the search feature of javadoc.
* @author bpatel
* @library ../lib
@@ -45,6 +45,7 @@
checkExit(Exit.OK);
checkSearchOutput("UnnamedPkgClass.html", true);
checkJqueryAndImageFiles(true);
+ checkSearchJS();
checkFiles(false,
"package-search-index.zip",
"tag-search-index.zip");
@@ -62,6 +63,7 @@
checkSearchOutput(true);
checkSingleIndex(true);
checkJqueryAndImageFiles(true);
+ checkSearchJS();
checkFiles(true,
"member-search-index.zip",
"package-search-index.zip",
@@ -78,6 +80,7 @@
checkSearchOutput(true);
checkSingleIndex(true);
checkJqueryAndImageFiles(true);
+ checkSearchJS();
checkFiles(true,
"member-search-index.zip",
"package-search-index.zip",
@@ -110,6 +113,7 @@
checkSearchOutput(true);
checkSingleIndex(true);
checkJqueryAndImageFiles(true);
+ checkSearchJS();
checkFiles(true,
"member-search-index.zip",
"package-search-index.zip",
@@ -142,6 +146,7 @@
checkSearchOutput(true);
checkIndexNoComment();
checkJqueryAndImageFiles(true);
+ checkSearchJS();
checkFiles(true,
"member-search-index.zip",
"package-search-index.zip",
@@ -158,6 +163,7 @@
checkSearchOutput(true);
checkIndexNoDeprecated();
checkJqueryAndImageFiles(true);
+ checkSearchJS();
checkFiles(true,
"member-search-index.zip",
"package-search-index.zip",
@@ -174,6 +180,7 @@
checkSearchOutput(true);
checkSplitIndex();
checkJqueryAndImageFiles(true);
+ checkSearchJS();
checkFiles(true,
"member-search-index.zip",
"package-search-index.zip",
@@ -189,6 +196,7 @@
checkSearchOutput(true);
checkJavaFXOutput();
checkJqueryAndImageFiles(true);
+ checkSearchJS();
checkFiles(false,
"tag-search-index.zip");
checkFiles(true,
@@ -420,4 +428,11 @@
"resources/x.png",
"resources/glass.png");
}
+
+ void checkSearchJS() {
+ checkOutput("search.js", true,
+ "camelCaseRegexp = ($.ui.autocomplete.escapeRegex(request.term)).split(/(?=[A-Z])/).join(\"([a-z0-9_$]*?)\");",
+ "var camelCaseMatcher = new RegExp(\"^\" + camelCaseRegexp);",
+ "camelCaseMatcher.test(item.l)");
+ }
}
--- a/langtools/test/jdk/javadoc/tool/modules/FilterOptions.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/test/jdk/javadoc/tool/modules/FilterOptions.java Wed Oct 26 20:13:29 2016 +0000
@@ -23,7 +23,7 @@
/**
* @test
- * @bug 8159305
+ * @bug 8159305 8167383
* @summary Tests elements filtering options
* @modules
* jdk.javadoc/jdk.javadoc.internal.api
@@ -73,6 +73,10 @@
"--module", "m1", "--show-module-contents", "api");
checkModuleMode("API");
+ checkModulesSpecified("m1");
+ checkModulesIncluded("m1");
+ checkPackagesIncluded("pub");
+ checkPackagesNotIncluded("pro", "pqe");
}
@Test
@@ -81,6 +85,10 @@
"--module", "m1", "--show-module-contents", "all");
checkModuleMode("ALL");
+ checkModulesSpecified("m1");
+ checkModulesIncluded("m1");
+ checkPackagesIncluded("pub", "pqe");
+ checkPackagesNotIncluded("pro");
}
@Test
@@ -92,6 +100,7 @@
checkModulesSpecified("m1");
checkModulesIncluded("m1");
checkPackagesIncluded("pub");
+ checkPackagesNotIncluded("pqe", "pro");
checkTypesIncluded("pub.A", "pub.A.ProtectedNested", "pub.A.PublicNested");
}
@@ -102,9 +111,10 @@
"--show-packages", "all");
checkModulesSpecified("m1");
checkModulesIncluded("m1");
- checkPackagesIncluded("pub", "pro");
+ checkPackagesIncluded("pub", "pqe", "pro");
checkTypesIncluded("pub.A", "pub.A.ProtectedNested", "pub.A.PublicNested",
+ "pqe.A", "pqe.A.ProtectedNested", "pqe.A.PublicNested",
"pro.A", "pro.A.ProtectedNested", "pro.A.PublicNested");
}
@@ -221,6 +231,7 @@
checkModulesSpecified("m1");
checkModulesIncluded("m1");
checkPackagesIncluded("pub");
+ checkPackagesNotIncluded("pqe", "pro");
checkTypesIncluded("pub.A", "pub.A.PublicNested");
checkMembers(Visibility.PUBLIC);
@@ -235,6 +246,7 @@
checkModulesSpecified("m1");
checkModulesIncluded("m1");
checkPackagesIncluded("pub");
+ checkPackagesNotIncluded("pqe", "pro");
checkTypesIncluded("pub.A", "pub.A.ProtectedNested", "pub.A.PublicNested");
checkMembers(Visibility.PROTECTED);
@@ -250,6 +262,7 @@
checkModulesSpecified("m1");
checkModulesIncluded("m1");
checkPackagesIncluded("pub");
+ checkPackagesNotIncluded("pqe", "pro");
checkTypesIncluded("pub.A", "pub.A.ProtectedNested", "pub.A.PublicNested");
checkMembers(Visibility.PROTECTED);
@@ -264,10 +277,10 @@
checkModuleMode("ALL");
checkModulesSpecified("m1");
checkModulesIncluded("m1");
- checkPackagesIncluded("pub");
- checkPackagesIncluded("pro");
+ checkPackagesIncluded("pub", "pqe", "pro");
checkTypesIncluded("pub.B", "pub.B.Nested", "pub.B.ProtectedNested", "pub.B.PublicNested",
"pub.A", "pub.A.Nested", "pub.A.ProtectedNested", "pub.A.PublicNested",
+ "pqe.A", "pqe.A.Nested", "pqe.A.ProtectedNested", "pqe.A.PublicNested",
"pro.B", "pro.B.Nested", "pro.B.ProtectedNested", "pro.B.PublicNested",
"pro.A", "pro.A.Nested", "pro.A.ProtectedNested", "pro.A.PublicNested");
@@ -283,12 +296,13 @@
checkModuleMode("ALL");
checkModulesSpecified("m1");
checkModulesIncluded("m1");
- checkPackagesIncluded("pub");
- checkPackagesIncluded("pro");
+ checkPackagesIncluded("pub", "pqe", "pro");
checkTypesIncluded("pub.B", "pub.B.PrivateNested", "pub.B.Nested", "pub.B.ProtectedNested",
"pub.B.PublicNested",
"pub.A", "pub.A.PrivateNested", "pub.A.Nested", "pub.A.ProtectedNested",
"pub.A.PublicNested",
+ "pqe.A", "pqe.A.PrivateNested", "pqe.A.Nested", "pqe.A.ProtectedNested",
+ "pqe.A.PublicNested",
"pro.B", "pro.B.PrivateNested", "pro.B.Nested", "pro.B.ProtectedNested",
"pro.B.PublicNested",
"pro.A", "pro.A.PrivateNested", "pro.A.Nested", "pro.A.ProtectedNested",
@@ -365,8 +379,17 @@
.classes(createClass("pub", "B", false))
.classes(createClass("pro", "A", true))
.classes(createClass("pro", "B", false))
+ .classes(createClass("pqe", "A", true))
.exports("pub")
+ .exportsTo("pqe", "m2")
.write(src);
+
+ ModuleBuilder mb2 = new ModuleBuilder(tb, "m2");
+ mb2.comment("The second module")
+ .classes(createClass("m2pub", "A", true))
+ .requires("m1")
+ .write(src);
+
return src.toString();
}
--- a/langtools/test/jdk/javadoc/tool/modules/Modules.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/test/jdk/javadoc/tool/modules/Modules.java Wed Oct 26 20:13:29 2016 +0000
@@ -222,7 +222,10 @@
.classes("package pkg2; /** @see pkg1.A */ public class B { }")
.write(src);
+ Path out = base.resolve("out-1");
+ Files.createDirectories(out);
String log = new JavadocTask(tb)
+ .outdir(out)
.options("--module-source-path", src.toString(),
"--module-path", modulePath.toString(),
"--module", "m2")
@@ -233,7 +236,10 @@
throw new Exception("Error not found");
}
+ out = base.resolve("out-2");
+ Files.createDirectories(out);
new JavadocTask(tb)
+ .outdir(out)
.options("--module-source-path", src.toString(),
"--module-path", modulePath.toString(),
"--add-modules", "m1",
--- a/langtools/test/jdk/jshell/CommandCompletionTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/test/jdk/jshell/CommandCompletionTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -54,7 +54,7 @@
public void testCommand() {
assertCompletion("/deb|", false);
- assertCompletion("/re|", false, "/reload ", "/reset ", "/retain ");
+ assertCompletion("/re|", false, "/reload ", "/reset ");
assertCompletion("/h|", false, "/help ", "/history ");
}
@@ -195,34 +195,6 @@
);
}
- public void testRetain() throws IOException {
- List<String> p1 = listFiles(Paths.get(""));
- FileSystems.getDefault().getRootDirectories().forEach(s -> p1.add(s.toString()));
- Collections.sort(p1);
-
- String[] modes = {"concise ", "normal ", "silent ", "verbose "};
- test(false, new String[] {"--no-startup"},
- a -> assertCompletion(a, "/ret|", false, "/retain "),
- a -> assertCompletion(a, "/retain |", false, "editor ", "feedback ", "mode ", "start "),
-
- // /retain editor
- a -> assertCompletion(a, "/retain e|", false, "editor "),
- a -> assertCompletion(a, "/retain editor |", false, p1.toArray(new String[p1.size()])),
-
- // /retain feedback
- a -> assertCompletion(a, "/retain fe|", false, "feedback "),
- a -> assertCompletion(a, "/retain fe |", false, modes),
-
- // /retain mode
- a -> assertCompletion(a, "/retain mo|", false, "mode "),
- a -> assertCompletion(a, "/retain mo |", false, modes),
-
- // /retain start
- a -> assertCompletion(a, "/retain st|", false, "start "),
- a -> assertCompletion(a, "/retain st |", false, p1.toArray(new String[p1.size()]))
- );
- }
-
private void createIfNeeded(Path file) throws IOException {
if (!Files.exists(file))
Files.createFile(file);
--- a/langtools/test/jdk/jshell/CompletionSuggestionTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/test/jdk/jshell/CompletionSuggestionTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -23,8 +23,8 @@
/*
* @test
- * @bug 8131025 8141092 8153761
- * @summary Test Completion
+ * @bug 8131025 8141092 8153761 8145263
+ * @summary Test Completion and Documentation
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
* jdk.jdeps/com.sun.tools.javap
@@ -43,6 +43,8 @@
import java.util.Collections;
import java.util.Set;
import java.util.HashSet;
+import java.util.function.BiFunction;
+import java.util.function.Function;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
@@ -304,35 +306,35 @@
public void testDocumentation() throws Exception {
dontReadParameterNamesFromClassFile();
assertDocumentation("System.getProperty(|",
- "java.lang.System.getProperty(java.lang.String key)",
- "java.lang.System.getProperty(java.lang.String key, java.lang.String def)");
+ "String System.getProperty(String key)",
+ "String System.getProperty(String key, String def)");
assertEval("char[] chars = null;");
assertDocumentation("new String(chars, |",
- "java.lang.String(char[] arg0, int arg1, int arg2)");
+ "String(char[], int, int)");
assertDocumentation("String.format(|",
- "java.lang.String.format(java.lang.String arg0, java.lang.Object... arg1)",
- "java.lang.String.format(java.util.Locale arg0, java.lang.String arg1, java.lang.Object... arg2)");
- assertDocumentation("\"\".getBytes(\"\"|", "java.lang.String.getBytes(int arg0, int arg1, byte[] arg2, int arg3)",
- "java.lang.String.getBytes(java.lang.String arg0)",
- "java.lang.String.getBytes(java.nio.charset.Charset arg0)");
- assertDocumentation("\"\".getBytes(\"\" |", "java.lang.String.getBytes(int arg0, int arg1, byte[] arg2, int arg3)",
- "java.lang.String.getBytes(java.lang.String arg0)",
- "java.lang.String.getBytes(java.nio.charset.Charset arg0)");
+ "String String.format(String, Object...)",
+ "String String.format(java.util.Locale, String, Object...)");
+ assertDocumentation("\"\".getBytes(\"\"|", "void String.getBytes(int, int, byte[], int)",
+ "byte[] String.getBytes(String) throws java.io.UnsupportedEncodingException",
+ "byte[] String.getBytes(java.nio.charset.Charset)");
+ assertDocumentation("\"\".getBytes(\"\" |", "void String.getBytes(int, int, byte[], int)",
+ "byte[] String.getBytes(String) throws java.io.UnsupportedEncodingException",
+ "byte[] String.getBytes(java.nio.charset.Charset)");
}
public void testMethodsWithNoArguments() throws Exception {
dontReadParameterNamesFromClassFile();
assertDocumentation("System.out.println(|",
- "java.io.PrintStream.println()",
- "java.io.PrintStream.println(boolean arg0)",
- "java.io.PrintStream.println(char arg0)",
- "java.io.PrintStream.println(int arg0)",
- "java.io.PrintStream.println(long arg0)",
- "java.io.PrintStream.println(float arg0)",
- "java.io.PrintStream.println(double arg0)",
- "java.io.PrintStream.println(char[] arg0)",
- "java.io.PrintStream.println(java.lang.String arg0)",
- "java.io.PrintStream.println(java.lang.Object arg0)");
+ "void java.io.PrintStream.println()",
+ "void java.io.PrintStream.println(boolean)",
+ "void java.io.PrintStream.println(char)",
+ "void java.io.PrintStream.println(int)",
+ "void java.io.PrintStream.println(long)",
+ "void java.io.PrintStream.println(float)",
+ "void java.io.PrintStream.println(double)",
+ "void java.io.PrintStream.println(char[])",
+ "void java.io.PrintStream.println(String)",
+ "void java.io.PrintStream.println(Object)");
}
public void testErroneous() {
@@ -472,14 +474,14 @@
public void testDocumentationOfUserDefinedMethods() {
assertEval("void f() {}");
- assertDocumentation("f(|", "f()");
+ assertDocumentation("f(|", "void f()");
assertEval("void f(int i) {}");
- assertDocumentation("f(|", "f()", "f(int i)");
+ assertDocumentation("f(|", "void f()", "void f(int i)");
assertEval("<T> void f(T... ts) {}", DiagCheck.DIAG_WARNING, DiagCheck.DIAG_OK);
- assertDocumentation("f(|", "f()", "f(int i)", "f(T... ts)");
+ assertDocumentation("f(|", "void f()", "void f(int i)", "void <T>f(T... ts)");
assertEval("class A {}");
assertEval("void f(A a) {}");
- assertDocumentation("f(|", "f()", "f(int i)", "f(T... ts)", "f(A a)");
+ assertDocumentation("f(|", "void f()", "void f(int i)", "void <T>f(T... ts)", "void f(A a)");
}
public void testDocumentationOfUserDefinedConstructors() {
@@ -489,25 +491,25 @@
ste(MAIN_SNIPPET, VALID, VALID, true, null),
ste(a, VALID, OVERWRITTEN, false, MAIN_SNIPPET)));
assertDocumentation("new A(|", "A()", "A(int i)");
- assertEval("class A<T> { A(T t) {} A(int i) {}}",
+ assertEval("class A<T> { A(T a) {} A(int i) {} <U> A(T t, U u) {}}",
ste(MAIN_SNIPPET, VALID, VALID, true, null),
ste(a2, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
- assertDocumentation("new A(|", "A(T t)", "A(int i)");
+ assertDocumentation("new A(|", "A<T>(T a)", "A<T>(int i)", "<U> A<T>(T t, U u)");
}
public void testDocumentationOfOverriddenMethods() throws Exception {
dontReadParameterNamesFromClassFile();
assertDocumentation("\"\".wait(|",
- "java.lang.Object.wait(long arg0)",
- "java.lang.Object.wait(long arg0, int arg1)",
- "java.lang.Object.wait()");
+ "void Object.wait(long) throws InterruptedException",
+ "void Object.wait(long, int) throws InterruptedException",
+ "void Object.wait() throws InterruptedException");
assertEval("class Base {void method() {}}");
Snippet e = classKey(assertEval("class Extend extends Base {}"));
- assertDocumentation("new Extend().method(|", "Base.method()");
+ assertDocumentation("new Extend().method(|", "void Base.method()");
assertEval("class Extend extends Base {void method() {}}",
ste(MAIN_SNIPPET, VALID, VALID, true, null),
ste(e, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
- assertDocumentation("new Extend().method(|", "Extend.method()");
+ assertDocumentation("new Extend().method(|", "void Extend.method()");
}
public void testDocumentationOfInvisibleMethods() {
@@ -534,13 +536,67 @@
assertEval("void method(int n, Object o) { }");
assertEval("void method(Object n, int o) { }");
assertDocumentation("method(primitive,|",
- "method(int n, java.lang.Object o)",
- "method(java.lang.Object n, int o)");
+ "void method(int n, Object o)",
+ "void method(Object n, int o)");
assertDocumentation("method(boxed,|",
- "method(int n, java.lang.Object o)",
- "method(java.lang.Object n, int o)");
+ "void method(int n, Object o)",
+ "void method(Object n, int o)");
assertDocumentation("method(object,|",
- "method(java.lang.Object n, int o)");
+ "void method(Object n, int o)");
+ }
+
+ public void testDocumentationWithGenerics() {
+ class TestDocumentationWithGenerics {
+ private final Function<Integer, String> codeFacotry;
+ private final BiFunction<String, Integer, String> evalFormatter;
+ private final BiFunction<String, Integer, String> docFormatter;
+ int count;
+
+ TestDocumentationWithGenerics(
+ Function<Integer, String> codeFactory,
+ BiFunction<String, Integer, String> evalFormatter,
+ BiFunction<String, Integer, String> documentationFormatter) {
+ this.codeFacotry = codeFactory;
+ this.evalFormatter = evalFormatter;
+ this.docFormatter = documentationFormatter;
+ }
+
+ void assertDoc(String generics) {
+ assertDoc(generics, generics);
+ }
+
+ void assertDoc(String generics, String expectedGenerics) {
+ assertEval(evalFormatter.apply(generics, count));
+ assertDocumentation(codeFacotry.apply(count), docFormatter.apply(expectedGenerics, count));
+ count++;
+ }
+ }
+
+ TestDocumentationWithGenerics[] tests = {
+ new TestDocumentationWithGenerics(
+ i -> "f" + i + "(|",
+ (g, i) -> "<" + g + "> void f" + i + "() {}",
+ (g, i) -> "void <" + g + ">f" + i + "()"
+ ),
+ new TestDocumentationWithGenerics(
+ i -> "new C" + i + "().f(|",
+ (g, i) -> "class C" + i + "<" + g + "> { void f() {} }",
+ (g, i) -> "void C" + i + "<" + g + ">.f()"
+ )
+ };
+
+ Arrays.stream(tests).forEach(t -> {
+ t.assertDoc("T");
+ t.assertDoc("T extends Object",
+ "T");
+ t.assertDoc("T extends String");
+ t.assertDoc("T extends java.lang.String",
+ "T extends String");
+ t.assertDoc("T extends Number & Comparable<T>");
+ t.assertDoc("T extends java.io.Serializable & CharSequence");
+ t.assertDoc("K, D, M extends java.util.Map<K, D>",
+ "K, D, M extends java.util.Map<K,D>");
+ });
}
public void testVarArgs() {
--- a/langtools/test/jdk/jshell/DropTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/test/jdk/jshell/DropTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -23,14 +23,14 @@
/*
* @test
- * @bug 8081431 8080069
+ * @bug 8081431 8080069 8167128
* @summary Test of JShell#drop().
* @build KullaTesting TestingInputStream
* @run testng DropTest
*/
import jdk.jshell.DeclarationSnippet;
-import jdk.jshell.PersistentSnippet;
+import jdk.jshell.Snippet;
import jdk.jshell.VarSnippet;
import org.testng.annotations.Test;
@@ -40,9 +40,9 @@
public class DropTest extends KullaTesting {
public void testDrop() {
- PersistentSnippet var = varKey(assertEval("int x;"));
- PersistentSnippet method = methodKey(assertEval("int mu() { return x * 4; }"));
- PersistentSnippet clazz = classKey(assertEval("class C { String v() { return \"#\" + mu(); } }"));
+ Snippet var = varKey(assertEval("int x;"));
+ Snippet method = methodKey(assertEval("int mu() { return x * 4; }"));
+ Snippet clazz = classKey(assertEval("class C { String v() { return \"#\" + mu(); } }"));
assertDrop(var,
ste(var, VALID, DROPPED, true, null),
ste(method, VALID, RECOVERABLE_DEFINED, false, var));
@@ -62,7 +62,7 @@
assertEval("int x = 10;", "10",
added(VALID),
ste(method, RECOVERABLE_DEFINED, VALID, false, MAIN_SNIPPET));
- PersistentSnippet c0 = varKey(assertEval("C c0 = new C();"));
+ Snippet c0 = varKey(assertEval("C c0 = new C();"));
assertEval("c0.v();", "\"#40\"");
assertEval("C c = new C();",
ste(MAIN_SNIPPET, VALID, VALID, false, null),
@@ -88,8 +88,8 @@
}
public void testDropImport() {
- PersistentSnippet imp = importKey(assertEval("import java.util.*;"));
- PersistentSnippet decl = varKey(
+ Snippet imp = importKey(assertEval("import java.util.*;"));
+ Snippet decl = varKey(
assertEval("List<Integer> list = Arrays.asList(1, 2, 3);", "[1, 2, 3]"));
assertEval("list;", "[1, 2, 3]");
assertDrop(imp,
@@ -100,8 +100,13 @@
assertDeclareFail("list;", "compiler.err.cant.resolve.location");
}
+ public void testDropStatement() {
+ Snippet x = key(assertEval("if (true);"));
+ assertDrop(x, ste(x, VALID, DROPPED, true, null));
+ }
+
public void testDropVarToMethod() {
- PersistentSnippet x = varKey(assertEval("int x;"));
+ Snippet x = varKey(assertEval("int x;"));
DeclarationSnippet method = methodKey(assertEval("double mu() { return x * 4; }"));
assertEval("x == 0;", "true");
assertEval("mu() == 0.0;", "true");
@@ -118,7 +123,7 @@
}
public void testDropMethodToMethod() {
- PersistentSnippet a = methodKey(assertEval("double a() { return 2; }"));
+ Snippet a = methodKey(assertEval("double a() { return 2; }"));
DeclarationSnippet b = methodKey(assertEval("double b() { return a() * 10; }"));
assertEval("double c() { return b() * 3; }");
DeclarationSnippet d = methodKey(assertEval("double d() { return c() + 1000; }"));
@@ -134,7 +139,7 @@
}
public void testDropClassToMethod() {
- PersistentSnippet c = classKey(assertEval("class C { int f() { return 7; } }"));
+ Snippet c = classKey(assertEval("class C { int f() { return 7; } }"));
DeclarationSnippet m = methodKey(assertEval("int m() { return new C().f(); }"));
assertDrop(c,
ste(c, VALID, DROPPED, true, null),
@@ -145,7 +150,7 @@
}
public void testDropVarToClass() {
- PersistentSnippet x = varKey(assertEval("int x;"));
+ Snippet x = varKey(assertEval("int x;"));
DeclarationSnippet a = classKey(assertEval("class A { double a = 4 * x; }"));
assertDrop(x,
DiagCheck.DIAG_OK,
@@ -160,7 +165,7 @@
}
public void testDropMethodToClass() {
- PersistentSnippet x = methodKey(assertEval("int x() { return 0; }"));
+ Snippet x = methodKey(assertEval("int x() { return 0; }"));
DeclarationSnippet a = classKey(assertEval("class A { double a = 4 * x(); }"));
assertDrop(x,
DiagCheck.DIAG_OK,
@@ -174,10 +179,10 @@
}
public void testDropClassToClass() {
- PersistentSnippet a = classKey(assertEval("class A {}"));
- PersistentSnippet b = classKey(assertEval("class B extends A {}"));
- PersistentSnippet c = classKey(assertEval("class C extends B {}"));
- PersistentSnippet d = classKey(assertEval("class D extends C {}"));
+ Snippet a = classKey(assertEval("class A {}"));
+ Snippet b = classKey(assertEval("class B extends A {}"));
+ Snippet c = classKey(assertEval("class C extends B {}"));
+ Snippet d = classKey(assertEval("class D extends C {}"));
assertDrop(a,
DiagCheck.DIAG_OK,
DiagCheck.DIAG_ERROR,
@@ -201,9 +206,9 @@
public void testDropNoUpdate() {
String as1 = "class A {}";
String as2 = "class A extends java.util.ArrayList<Boolean> {}";
- PersistentSnippet a = classKey(assertEval(as1, added(VALID)));
- PersistentSnippet b = classKey(assertEval("class B extends A {}", added(VALID)));
- PersistentSnippet ax = classKey(assertEval(as2,
+ Snippet a = classKey(assertEval(as1, added(VALID)));
+ Snippet b = classKey(assertEval("class B extends A {}", added(VALID)));
+ Snippet ax = classKey(assertEval(as2,
ste(MAIN_SNIPPET, VALID, VALID, true, null),
ste(a, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
ste(b, VALID, VALID, true, MAIN_SNIPPET)));
--- a/langtools/test/jdk/jshell/ExternalEditorTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/test/jdk/jshell/ExternalEditorTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -193,7 +193,6 @@
@Test
public void setUnknownEditor() {
test(
- a -> assertCommand(a, "/set editor", "| The '/set editor' command requires a path argument"),
a -> assertCommand(a, "/set editor UNKNOWN", "| Editor set to: UNKNOWN"),
a -> assertCommand(a, "int a;", null),
a -> assertCommandOutputStartsWith(a, "/ed 1",
--- a/langtools/test/jdk/jshell/IdGeneratorTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/test/jdk/jshell/IdGeneratorTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -35,7 +35,6 @@
import jdk.jshell.EvalException;
import jdk.jshell.JShell;
-import jdk.jshell.PersistentSnippet;
import jdk.jshell.SnippetEvent;
import jdk.jshell.UnresolvedReferenceException;
import jdk.jshell.VarSnippet;
@@ -88,7 +87,7 @@
try (JShell jShell = builder.build()) {
List<SnippetEvent> eval = jShell.eval("int a, b;");
checkIds(eval);
- checkIds(jShell.drop((PersistentSnippet) eval.get(0).snippet()));
+ checkIds(jShell.drop(eval.get(0).snippet()));
}
}
--- a/langtools/test/jdk/jshell/IllegalArgumentExceptionTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/test/jdk/jshell/IllegalArgumentExceptionTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -31,7 +31,6 @@
import java.util.function.Consumer;
import jdk.jshell.DeclarationSnippet;
-import jdk.jshell.PersistentSnippet;
import jdk.jshell.Snippet;
import jdk.jshell.VarSnippet;
import org.testng.annotations.Test;
@@ -64,7 +63,7 @@
}
public void testDrop() {
- testIllegalArgumentException((key) -> getState().drop((PersistentSnippet) key));
+ testIllegalArgumentException((key) -> getState().drop(key));
}
public void testUnresolved() {
--- a/langtools/test/jdk/jshell/JShellStateClosedTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/test/jdk/jshell/JShellStateClosedTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -33,7 +33,6 @@
import jdk.jshell.DeclarationSnippet;
import jdk.jshell.ImportSnippet;
import jdk.jshell.MethodSnippet;
-import jdk.jshell.PersistentSnippet;
import jdk.jshell.Snippet;
import jdk.jshell.TypeDeclSnippet;
import jdk.jshell.VarSnippet;
@@ -127,7 +126,7 @@
}
public void testDrop() {
- testStateClosedException((key) -> getState().drop((PersistentSnippet) key));
+ testStateClosedException((key) -> getState().drop(key));
}
public void testUnresolved() {
--- a/langtools/test/jdk/jshell/KullaTesting.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/test/jdk/jshell/KullaTesting.java Wed Oct 26 20:13:29 2016 +0000
@@ -21,7 +21,10 @@
* questions.
*/
+import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
import java.io.PrintStream;
import java.io.StringWriter;
import java.lang.reflect.Method;
@@ -54,7 +57,6 @@
import jdk.jshell.ImportSnippet;
import jdk.jshell.Snippet.Kind;
import jdk.jshell.MethodSnippet;
-import jdk.jshell.PersistentSnippet;
import jdk.jshell.Snippet.Status;
import jdk.jshell.Snippet.SubKind;
import jdk.jshell.TypeDeclSnippet;
@@ -84,7 +86,7 @@
private SourceCodeAnalysis analysis = null;
private JShell state = null;
- private TestingInputStream inStream = null;
+ private InputStream inStream = null;
private ByteArrayOutputStream outStream = null;
private ByteArrayOutputStream errStream = null;
@@ -107,7 +109,11 @@
}
public void setInput(String s) {
- inStream.setInput(s);
+ setInput(new ByteArrayInputStream(s.getBytes()));
+ }
+
+ public void setInput(InputStream in) {
+ inStream = in;
}
public String getOutput() {
@@ -160,11 +166,27 @@
}
public void setUp(Consumer<JShell.Builder> bc) {
- inStream = new TestingInputStream();
+ InputStream in = new InputStream() {
+ @Override
+ public int read() throws IOException {
+ assertNotNull(inStream);
+ return inStream.read();
+ }
+ @Override
+ public int read(byte[] b) throws IOException {
+ assertNotNull(inStream);
+ return inStream.read(b);
+ }
+ @Override
+ public int read(byte[] b, int off, int len) throws IOException {
+ assertNotNull(inStream);
+ return inStream.read(b, off, len);
+ }
+ };
outStream = new ByteArrayOutputStream();
errStream = new ByteArrayOutputStream();
JShell.Builder builder = JShell.builder()
- .in(inStream)
+ .in(in)
.out(new PrintStream(outStream))
.err(new PrintStream(errStream));
bc.accept(builder);
@@ -733,15 +755,15 @@
assertEquals(expectedSubKind.kind(), expectedKind, "Checking kind: ");
}
- public void assertDrop(PersistentSnippet key, STEInfo mainInfo, STEInfo... updates) {
+ public void assertDrop(Snippet key, STEInfo mainInfo, STEInfo... updates) {
assertDrop(key, DiagCheck.DIAG_OK, DiagCheck.DIAG_OK, mainInfo, updates);
}
- public void assertDrop(PersistentSnippet key, DiagCheck diagMain, DiagCheck diagUpdates, STEInfo mainInfo, STEInfo... updates) {
+ public void assertDrop(Snippet key, DiagCheck diagMain, DiagCheck diagUpdates, STEInfo mainInfo, STEInfo... updates) {
assertDrop(key, diagMain, diagUpdates, new EventChain(mainInfo, null, null, updates));
}
- public void assertDrop(PersistentSnippet key, DiagCheck diagMain, DiagCheck diagUpdates, EventChain... eventChains) {
+ public void assertDrop(Snippet key, DiagCheck diagMain, DiagCheck diagUpdates, EventChain... eventChains) {
checkEvents(() -> getState().drop(key), "drop(" + key + ")", diagMain, diagUpdates, eventChains);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/jshell/PipeInputStreamTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,71 @@
+/*
+ * 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 8167461
+ * @summary Verify PipeInputStream works.
+ * @modules jdk.compiler/com.sun.tools.javac.util
+ * jdk.jshell
+ * @run testng PipeInputStreamTest
+ */
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+import org.testng.annotations.Test;
+
+import com.sun.tools.javac.util.Pair;
+
+import static org.testng.Assert.*;
+
+@Test
+public class PipeInputStreamTest {
+
+ public void testReadArrayNotBlocking() throws Exception {
+ Pair<InputStream, OutputStream> streams = createPipeStream();
+ InputStream in = streams.fst;
+ OutputStream out = streams.snd;
+ out.write('a');
+ byte[] data = new byte[12];
+ assertEquals(in.read(data), 1);
+ assertEquals(data[0], 'a');
+ out.write('a'); out.write('b'); out.write('c');
+ assertEquals(in.read(data), 3);
+ assertEquals(data[0], 'a');
+ assertEquals(data[1], 'b');
+ assertEquals(data[2], 'c');
+ }
+
+ private Pair<InputStream, OutputStream> createPipeStream() throws Exception {
+ Class<?> pipeStreamClass = Class.forName("jdk.jshell.execution.PipeInputStream");
+ Constructor<?> c = pipeStreamClass.getDeclaredConstructor();
+ c.setAccessible(true);
+ Object pipeStream = c.newInstance();
+ Method createOutputStream = pipeStreamClass.getDeclaredMethod("createOutput");
+ createOutputStream.setAccessible(true);
+ return Pair.of((InputStream) pipeStream, (OutputStream) createOutputStream.invoke(pipeStream));
+ }
+
+}
--- a/langtools/test/jdk/jshell/ReplToolTesting.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/test/jdk/jshell/ReplToolTesting.java Wed Oct 26 20:13:29 2016 +0000
@@ -93,6 +93,7 @@
private Map<String, ImportInfo> imports;
private boolean isDefaultStartUp = true;
private Preferences prefs;
+ private Map<String, String> envvars;
public JShellTool repl = null;
@@ -232,6 +233,11 @@
@BeforeMethod
public void setUp() {
prefs = new MemoryPreferences();
+ envvars = new HashMap<>();
+ }
+
+ protected void setEnvVar(String name, String value) {
+ envvars.put(name, value);
}
public void testRaw(Locale locale, String[] args, ReplTest... tests) {
@@ -247,9 +253,11 @@
new PrintStream(cmdout),
new PrintStream(cmderr),
new PrintStream(console),
+ userin,
new PrintStream(userout),
new PrintStream(usererr),
prefs,
+ envvars,
locale);
repl.testPrompt = true;
try {
@@ -462,7 +470,8 @@
private List<String> computeCompletions(String code, boolean isSmart) {
JShellTool js = this.repl != null ? this.repl
- : new JShellTool(null, null, null, null, null, null, prefs, Locale.ROOT);
+ : new JShellTool(null, null, null, null, null, null, null,
+ prefs, envvars, Locale.ROOT);
int cursor = code.indexOf('|');
code = code.replace("|", "");
assertTrue(cursor > -1, "'|' not found: " + code);
--- a/langtools/test/jdk/jshell/ReplaceTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/test/jdk/jshell/ReplaceTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -33,7 +33,6 @@
import java.util.stream.Stream;
import jdk.jshell.Snippet;
import jdk.jshell.MethodSnippet;
-import jdk.jshell.PersistentSnippet;
import jdk.jshell.TypeDeclSnippet;
import jdk.jshell.VarSnippet;
import jdk.jshell.DeclarationSnippet;
@@ -585,14 +584,14 @@
}
public void testForwardSingleImportMethodToClass1() {
- PersistentSnippet a = classKey(assertEval("class A { String s = format(\"%d\", 10); }",
+ Snippet a = classKey(assertEval("class A { String s = format(\"%d\", 10); }",
added(RECOVERABLE_DEFINED)));
assertEvalUnresolvedException("new A();", "A", 1, 0);
assertEval("import static java.lang.String.format;",
added(VALID),
ste(a, RECOVERABLE_DEFINED, VALID, false, null));
assertEval("new A().s;", "\"10\"");
- PersistentSnippet format = methodKey(assertEval("void format(String s, int d) { }",
+ Snippet format = methodKey(assertEval("void format(String s, int d) { }",
DiagCheck.DIAG_OK,
DiagCheck.DIAG_ERROR,
added(VALID),
@@ -605,14 +604,14 @@
}
public void testForwardSingleImportMethodToClass2() {
- PersistentSnippet a = classKey(assertEval("class A { String s() { return format(\"%d\", 10); } }",
+ Snippet a = classKey(assertEval("class A { String s() { return format(\"%d\", 10); } }",
added(RECOVERABLE_DEFINED)));
assertEvalUnresolvedException("new A();", "A", 1, 0);
assertEval("import static java.lang.String.format;",
added(VALID),
ste(a, RECOVERABLE_DEFINED, VALID, false, null));
assertEval("new A().s();", "\"10\"");
- PersistentSnippet format = methodKey(assertEval("void format(String s, int d) { }",
+ Snippet format = methodKey(assertEval("void format(String s, int d) { }",
DiagCheck.DIAG_OK,
DiagCheck.DIAG_ERROR,
added(VALID),
@@ -625,7 +624,7 @@
}
public void testForwardSingleImportClassToClass1() {
- PersistentSnippet a = classKey(assertEval("class A { static List<Integer> list; }",
+ Snippet a = classKey(assertEval("class A { static List<Integer> list; }",
added(RECOVERABLE_NOT_DEFINED)));
assertDeclareFail("new A();", "compiler.err.cant.resolve.location");
assertEval("import java.util.List;",
@@ -634,7 +633,7 @@
assertEval("import java.util.Arrays;", added(VALID));
assertEval("A.list = Arrays.asList(1, 2, 3);", "[1, 2, 3]");
- PersistentSnippet list = classKey(assertEval("class List {}",
+ Snippet list = classKey(assertEval("class List {}",
DiagCheck.DIAG_OK,
DiagCheck.DIAG_ERROR,
added(VALID),
@@ -647,7 +646,7 @@
}
public void testForwardSingleImportClassToClass2() {
- PersistentSnippet clsA = classKey(assertEval("class A extends ArrayList<Integer> { }",
+ Snippet clsA = classKey(assertEval("class A extends ArrayList<Integer> { }",
added(RECOVERABLE_NOT_DEFINED)));
assertDeclareFail("new A();", "compiler.err.cant.resolve.location");
assertEval("import java.util.ArrayList;",
@@ -655,7 +654,7 @@
ste(clsA, RECOVERABLE_NOT_DEFINED, VALID, true, MAIN_SNIPPET));
Snippet vara = varKey(assertEval("A a = new A();", "[]"));
- PersistentSnippet arraylist = classKey(assertEval("class ArrayList {}",
+ Snippet arraylist = classKey(assertEval("class ArrayList {}",
DiagCheck.DIAG_OK,
DiagCheck.DIAG_ERROR,
added(VALID),
@@ -671,7 +670,7 @@
}
public void testForwardImportOnDemandMethodToClass1() {
- PersistentSnippet a = classKey(assertEval("class A { String s = format(\"%d\", 10); }",
+ Snippet a = classKey(assertEval("class A { String s = format(\"%d\", 10); }",
added(RECOVERABLE_DEFINED)));
assertEvalUnresolvedException("new A();", "A", 1, 0);
assertEval("import static java.lang.String.*;",
@@ -679,7 +678,7 @@
ste(a, RECOVERABLE_DEFINED, VALID, false, null));
assertEval("A x = new A();");
assertEval("x.s;", "\"10\"");
- PersistentSnippet format = methodKey(assertEval("void format(String s, int d) { }",
+ Snippet format = methodKey(assertEval("void format(String s, int d) { }",
DiagCheck.DIAG_OK,
DiagCheck.DIAG_ERROR,
added(VALID),
@@ -693,14 +692,14 @@
}
public void testForwardImportOnDemandMethodToClass2() {
- PersistentSnippet a = classKey(assertEval("class A { String s() { return format(\"%d\", 10); } }",
+ Snippet a = classKey(assertEval("class A { String s() { return format(\"%d\", 10); } }",
added(RECOVERABLE_DEFINED)));
assertEvalUnresolvedException("new A();", "A", 1, 0);
assertEval("import static java.lang.String.*;",
added(VALID),
ste(a, RECOVERABLE_DEFINED, VALID, false, null));
assertEval("new A().s();", "\"10\"");
- PersistentSnippet format = methodKey(assertEval("void format(String s, int d) { }",
+ Snippet format = methodKey(assertEval("void format(String s, int d) { }",
DiagCheck.DIAG_OK,
DiagCheck.DIAG_ERROR,
added(VALID),
@@ -713,7 +712,7 @@
}
public void testForwardImportOnDemandClassToClass1() {
- PersistentSnippet a = classKey(assertEval("class A { static List<Integer> list; }",
+ Snippet a = classKey(assertEval("class A { static List<Integer> list; }",
added(RECOVERABLE_NOT_DEFINED)));
assertDeclareFail("new A();", "compiler.err.cant.resolve.location");
assertEval("import java.util.*;",
@@ -721,7 +720,7 @@
ste(a, RECOVERABLE_NOT_DEFINED, VALID, true, null));
assertEval("A.list = Arrays.asList(1, 2, 3);", "[1, 2, 3]");
- PersistentSnippet list = classKey(assertEval("class List {}",
+ Snippet list = classKey(assertEval("class List {}",
DiagCheck.DIAG_OK,
DiagCheck.DIAG_ERROR,
added(VALID),
@@ -734,7 +733,7 @@
}
public void testForwardImportOnDemandClassToClass2() {
- PersistentSnippet clsA = classKey(assertEval("class A extends ArrayList<Integer> { }",
+ Snippet clsA = classKey(assertEval("class A extends ArrayList<Integer> { }",
added(RECOVERABLE_NOT_DEFINED)));
assertDeclareFail("new A();", "compiler.err.cant.resolve.location");
assertEval("import java.util.*;",
@@ -742,7 +741,7 @@
ste(clsA, RECOVERABLE_NOT_DEFINED, VALID, true, MAIN_SNIPPET));
Snippet vara = varKey(assertEval("A a = new A();", "[]"));
- PersistentSnippet arraylist = classKey(assertEval("class ArrayList {}",
+ Snippet arraylist = classKey(assertEval("class ArrayList {}",
DiagCheck.DIAG_OK,
DiagCheck.DIAG_ERROR,
added(VALID),
@@ -757,7 +756,7 @@
}
public void testForwardSingleImportFieldToClass1() {
- PersistentSnippet a = classKey(assertEval("class A { static double pi() { return PI; } }",
+ Snippet a = classKey(assertEval("class A { static double pi() { return PI; } }",
added(RECOVERABLE_DEFINED)));
assertEvalUnresolvedException("new A();", "A", 1, 0);
assertEval("import static java.lang.Math.PI;",
@@ -765,7 +764,7 @@
ste(a, RECOVERABLE_DEFINED, VALID, false, null));
assertEval("Math.abs(A.pi() - 3.1415) < 0.001;", "true");
- PersistentSnippet list = varKey(assertEval("String PI;",
+ Snippet list = varKey(assertEval("String PI;",
DiagCheck.DIAG_OK,
DiagCheck.DIAG_ERROR,
added(VALID),
@@ -778,7 +777,7 @@
}
public void testForwardSingleImportFieldToClass2() {
- PersistentSnippet a = classKey(assertEval("class A { static double pi = PI; }",
+ Snippet a = classKey(assertEval("class A { static double pi = PI; }",
added(RECOVERABLE_DEFINED)));
assertEvalUnresolvedException("new A();", "A", 1, 0);
assertEval("import static java.lang.Math.PI;",
@@ -786,7 +785,7 @@
ste(a, RECOVERABLE_DEFINED, VALID, true, null));
assertEval("Math.abs(A.pi - 3.1415) < 0.001;", "true");
- PersistentSnippet list = varKey(assertEval("String PI;",
+ Snippet list = varKey(assertEval("String PI;",
DiagCheck.DIAG_OK,
DiagCheck.DIAG_ERROR,
added(VALID),
@@ -799,7 +798,7 @@
}
public void testForwardImportOnDemandFieldToClass1() {
- PersistentSnippet a = classKey(assertEval("class A { static double pi() { return PI; } }",
+ Snippet a = classKey(assertEval("class A { static double pi() { return PI; } }",
added(RECOVERABLE_DEFINED)));
assertEvalUnresolvedException("new A();", "A", 1, 0);
assertEval("import static java.lang.Math.*;",
@@ -807,7 +806,7 @@
ste(a, RECOVERABLE_DEFINED, VALID, false, null));
assertEval("Math.abs(A.pi() - 3.1415) < 0.001;", "true");
- PersistentSnippet list = varKey(assertEval("String PI;",
+ Snippet list = varKey(assertEval("String PI;",
DiagCheck.DIAG_OK,
DiagCheck.DIAG_ERROR,
added(VALID),
@@ -820,7 +819,7 @@
}
public void testForwardImportOnDemandFieldToClass2() {
- PersistentSnippet a = classKey(assertEval("class A { static double pi = PI; }",
+ Snippet a = classKey(assertEval("class A { static double pi = PI; }",
added(RECOVERABLE_DEFINED)));
assertEvalUnresolvedException("new A();", "A", 1, 0);
assertEval("import static java.lang.Math.*;",
@@ -828,7 +827,7 @@
ste(a, RECOVERABLE_DEFINED, VALID, true, null));
assertEval("Math.abs(A.pi - 3.1415) < 0.001;", "true");
- PersistentSnippet list = varKey(assertEval("String PI;",
+ Snippet list = varKey(assertEval("String PI;",
DiagCheck.DIAG_OK,
DiagCheck.DIAG_ERROR,
added(VALID),
--- a/langtools/test/jdk/jshell/StartOptionTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/test/jdk/jshell/StartOptionTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -37,6 +37,7 @@
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
+import java.util.HashMap;
import java.util.Locale;
import java.util.function.Consumer;
@@ -63,9 +64,11 @@
new PrintStream(cmdout),
new PrintStream(cmderr),
new PrintStream(console),
+ null,
new PrintStream(userout),
new PrintStream(usererr),
new ReplToolTesting.MemoryPreferences(),
+ new HashMap<>(),
Locale.ROOT);
}
--- a/langtools/test/jdk/jshell/ToolBasicTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/test/jdk/jshell/ToolBasicTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -431,12 +431,12 @@
(a) -> assertMethod(a, "void f() {}", "()V", "f"),
(a) -> assertImport(a, "import java.util.stream.*;", "", "java.util.stream.*"),
(a) -> assertCommand(a, "/save " + startUpFile.toString(), null),
- (a) -> assertCommand(a, "/retain start " + startUpFile.toString(), null)
+ (a) -> assertCommand(a, "/set start -retain " + startUpFile.toString(), null)
);
Path unknown = compiler.getPath("UNKNOWN");
test(
- (a) -> assertCommandOutputStartsWith(a, "/retain start " + unknown.toString(),
- "| File '" + unknown + "' for '/retain start' is not found.")
+ (a) -> assertCommandOutputStartsWith(a, "/set start -retain " + unknown.toString(),
+ "| File '" + unknown + "' for '/set start' is not found.")
);
test(false, new String[0],
(a) -> {
--- a/langtools/test/jdk/jshell/ToolCommandOptionTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/test/jdk/jshell/ToolCommandOptionTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8157395 8157393 8157517 8158738
+ * @bug 8157395 8157393 8157517 8158738 8167128 8163840 8167637
* @summary Tests of jshell comand options, and undoing operations
* @modules jdk.jshell/jdk.internal.jshell.tool
* @build ToolCommandOptionTest ReplToolTesting
@@ -101,13 +101,17 @@
"| Unknown option: -all -- /drop -all"),
(a) -> assertCommandOutputStartsWith(a, "/drop z",
"| No such snippet: z"),
- (a) -> assertCommandOutputStartsWith(a, "/drop 2",
- "| This command does not accept the snippet '2' : x"),
+ (a) -> assertCommand(a, "/drop 2",
+ ""),
+ (a) -> assertCommandOutputStartsWith(a, "23qwl",
+ "| Error:"),
+ (a) -> assertCommandOutputStartsWith(a, "/drop e1",
+ "| This command does not accept the snippet 'e1' : 23qwl"),
(a) -> assertCommand(a, "/dr x y",
"| dropped variable x\n" +
"| dropped variable y"),
(a) -> assertCommand(a, "/list",
- "2 : x")
+ "")
);
}
@@ -120,50 +124,118 @@
(a) -> assertCommand(a, "/set editor -furball -mattress",
"| Unknown option: -furball -mattress -- /set editor -furball -mattress"),
(a) -> assertCommand(a, "/set editor -default prog",
- "| Specify -default option or program, not both -- /set editor -default prog"),
+ "| Specify -default option, -delete option, or program -- /set editor -default prog"),
(a) -> assertCommand(a, "/set editor prog",
"| Editor set to: prog"),
(a) -> assertCommand(a, "/set editor prog -default",
- "| Editor set to: prog"),
+ "| Editor set to: prog -default"),
+ (a) -> assertCommand(a, "/set editor",
+ "| /set editor prog -default"),
(a) -> assertCommand(a, "/se ed prog -furball",
- "| Editor set to: prog"),
+ "| Editor set to: prog -furball"),
+ (a) -> assertCommand(a, "/set editor",
+ "| /set editor prog -furball"),
+ (a) -> assertCommand(a, "/se ed -delete",
+ "| Editor set to: -default"),
+ (a) -> assertCommand(a, "/set editor",
+ "| /set editor -default"),
(a) -> assertCommand(a, "/set editor prog arg1 -furball arg3 -default arg4",
- "| Editor set to: prog"),
+ "| Editor set to: prog arg1 -furball arg3 -default arg4"),
+ (a) -> assertCommand(a, "/set editor",
+ "| /set editor prog arg1 -furball arg3 -default arg4"),
(a) -> assertCommand(a, "/set editor -default",
- ""),
+ "| Editor set to: -default"),
(a) -> assertCommand(a, "/se edi -def",
- ""),
+ "| Editor set to: -default"),
(a) -> assertCommand(a, "/set editor",
- "| The '/set editor' command requires a path argument")
+ "| /set editor -default")
);
}
public void retainEditorTest() {
test(
- (a) -> assertCommand(a, "/retain editor -furball",
- "| Unknown option: -furball -- /retain editor -furball"),
- (a) -> assertCommand(a, "/retain editor -furball prog",
- "| Unknown option: -furball -- /retain editor -furball prog"),
- (a) -> assertCommand(a, "/retain editor -furball -mattress",
- "| Unknown option: -furball -mattress -- /retain editor -furball -mattress"),
- (a) -> assertCommand(a, "/retain editor -default prog",
- "| Specify -default option or program, not both -- /retain editor -default prog"),
- (a) -> assertCommand(a, "/retain editor -default -wait",
- "| -wait applies to external editors, cannot be used with -default"),
- (a) -> assertCommand(a, "/retain editor prog",
+ (a) -> assertCommand(a, "/set editor -retain -furball",
+ "| Unknown option: -furball -- /set editor -retain -furball"),
+ (a) -> assertCommand(a, "/set editor -retain -furball prog",
+ "| Unknown option: -furball -- /set editor -retain -furball prog"),
+ (a) -> assertCommand(a, "/set editor -retain -furball -mattress",
+ "| Unknown option: -furball -mattress -- /set editor -retain -furball -mattress"),
+ (a) -> assertCommand(a, "/set editor -retain -default prog",
+ "| Specify -default option, -delete option, or program -- /set editor -retain -default prog"),
+ (a) -> assertCommand(a, "/set editor -retain -wait",
+ "| -wait applies to external editors"),
+ (a) -> assertCommand(a, "/set editor -retain -default -wait",
+ "| -wait applies to external editors"),
+ (a) -> assertCommand(a, "/set editor -retain prog",
+ "| Editor set to: prog\n" +
+ "| Editor setting retained: prog"),
+ (a) -> assertCommand(a, "/set editor",
+ "| /set editor -retain prog"),
+ (a) -> assertCommand(a, "/se ed other",
+ "| Editor set to: other"),
+ (a) -> assertCommand(a, "/set editor",
+ "| /set editor -retain prog\n" +
+ "| /set editor other"),
+ (a) -> assertCommand(a, "/se ed -delete",
"| Editor set to: prog"),
- (a) -> assertCommand(a, "/retain editor prog -default",
- "| Editor set to: prog"),
- (a) -> assertCommand(a, "/ret ed prog -furball",
- "| Editor set to: prog"),
- (a) -> assertCommand(a, "/retain editor prog arg1 -furball arg3 -default arg4",
+ (a) -> assertCommand(a, "/set editor",
+ "| /set editor -retain prog"),
+ (a) -> assertCommand(a, "/set editor -retain prog -default",
+ "| Editor set to: prog -default\n" +
+ "| Editor setting retained: prog -default"),
+ (a) -> assertCommand(a, "/set editor",
+ "| /set editor -retain prog -default"),
+ (a) -> assertCommand(a, "/se ed -retain prog -furball",
+ "| Editor set to: prog -furball\n" +
+ "| Editor setting retained: prog -furball"),
+ (a) -> assertCommand(a, "/set editor -retain prog arg1 -furball arg3 -default arg4",
+ "| Editor set to: prog arg1 -furball arg3 -default arg4\n" +
+ "| Editor setting retained: prog arg1 -furball arg3 -default arg4"),
+ (a) -> assertCommand(a, "/set editor",
+ "| /set editor -retain prog arg1 -furball arg3 -default arg4"),
+ (a) -> assertCommand(a, "/set editor -retain -default",
+ "| Editor set to: -default\n" +
+ "| Editor setting retained: -default"),
+ (a) -> assertCommand(a, "/set editor",
+ "| /set editor -retain -default"),
+ (a) -> assertCommand(a, "/se e -ret -def",
+ "| Editor set to: -default\n" +
+ "| Editor setting retained: -default"),
+ (a) -> assertCommand(a, "/set editor -retain",
+ "| Editor setting retained: -default")
+ );
+ }
+
+ public void setEditorEnvTest() {
+ setEnvVar("EDITOR", "best one");
+ setEditorEnvSubtest();
+ setEnvVar("EDITOR", "not this");
+ setEnvVar("VISUAL", "best one");
+ setEditorEnvSubtest();
+ setEnvVar("VISUAL", "not this");
+ setEnvVar("JSHELLEDITOR", "best one");
+ setEditorEnvSubtest();
+ }
+
+ private void setEditorEnvSubtest() {
+ test(
+ (a) -> assertCommand(a, "/set editor",
+ "| /set editor best one"),
+ (a) -> assertCommand(a, "/set editor prog",
"| Editor set to: prog"),
- (a) -> assertCommand(a, "/retain editor -default",
- ""),
- (a) -> assertCommand(a, "/reta edi -def",
- ""),
- (a) -> assertCommand(a, "/retain editor",
- "")
+ (a) -> assertCommand(a, "/set editor",
+ "| /set editor prog"),
+ (a) -> assertCommand(a, "/set editor -delete",
+ "| Editor set to: best one"),
+ (a) -> assertCommand(a, "/set editor -retain stored editor",
+ "| Editor set to: stored editor\n" +
+ "| Editor setting retained: stored editor")
+ );
+ test(
+ (a) -> assertCommand(a, "/set editor",
+ "| /set editor -retain stored editor"),
+ (a) -> assertCommand(a, "/set editor -delete -retain",
+ "| Editor set to: best one")
);
}
@@ -178,45 +250,56 @@
(a) -> assertCommand(a, "/set start -furball -mattress",
"| Unknown option: -furball -mattress -- /set start -furball -mattress"),
(a) -> assertCommand(a, "/set start foo -default",
- "| Specify either one option or a startup file name -- /set start foo -default"),
+ "| Specify no more than one of -default, -none, or a startup file name -- /set start foo -default"),
(a) -> assertCommand(a, "/set start frfg",
"| File 'frfg' for '/set start' is not found."),
(a) -> assertCommand(a, "/set start -default",
""),
+ (a) -> assertCommand(a, "/set start",
+ "| /set start -default"),
(a) -> assertCommand(a, "/se sta -no",
""),
(a) -> assertCommand(a, "/set start",
- "| Specify either one option or a startup file name -- /set start")
+ "| /set start -none")
);
}
public void retainStartTest() {
test(
- (a) -> assertCommand(a, "/retain start -furball",
- "| Unknown option: -furball -- /retain start -furball"),
- (a) -> assertCommand(a, "/retain start -furball pyle",
- "| Unknown option: -furball -- /retain start -furball pyle"),
- (a) -> assertCommand(a, "/ret st pyle -furball",
- "| Unknown option: -furball -- /retain st pyle -furball"),
- (a) -> assertCommand(a, "/retain start -furball -mattress",
- "| Unknown option: -furball -mattress -- /retain start -furball -mattress"),
- (a) -> assertCommand(a, "/retain start foo -default",
- "| Specify either one option or a startup file name -- /retain start foo -default"),
- (a) -> assertCommand(a, "/retain start frfg",
- "| File 'frfg' for '/retain start' is not found."),
- (a) -> assertCommand(a, "/retain start -default",
+ (a) -> assertCommand(a, "/set start -retain -furball",
+ "| Unknown option: -furball -- /set start -retain -furball"),
+ (a) -> assertCommand(a, "/set start -retain -furball pyle",
+ "| Unknown option: -furball -- /set start -retain -furball pyle"),
+ (a) -> assertCommand(a, "/se st -re pyle -furball",
+ "| Unknown option: -furball -- /set st -re pyle -furball"),
+ (a) -> assertCommand(a, "/set start -retain -furball -mattress",
+ "| Unknown option: -furball -mattress -- /set start -retain -furball -mattress"),
+ (a) -> assertCommand(a, "/set start -retain foo -default",
+ "| Specify no more than one of -default, -none, or a startup file name -- /set start -retain foo -default"),
+ (a) -> assertCommand(a, "/set start -retain -default foo",
+ "| Specify no more than one of -default, -none, or a startup file name -- /set start -retain -default foo"),
+ (a) -> assertCommand(a, "/set start -retain frfg",
+ "| File 'frfg' for '/set start' is not found."),
+ (a) -> assertCommand(a, "/set start -retain -default",
""),
- (a) -> assertCommand(a, "/ret sta -no",
+ (a) -> assertCommand(a, "/set start",
+ "| /set start -retain -default"),
+ (a) -> assertCommand(a, "/set sta -no",
""),
- (a) -> assertCommand(a, "/retain start",
- "")
+ (a) -> assertCommand(a, "/set start",
+ "| /set start -retain -default\n" +
+ "| /set start -none"),
+ (a) -> assertCommand(a, "/se st -ret",
+ ""),
+ (a) -> assertCommand(a, "/se sta",
+ "| /set start -retain -none")
);
}
public void setModeTest() {
test(
- (a) -> assertCommandOutputStartsWith(a, "/set mode",
- "| Missing the feedback mode"),
+ (a) -> assertCommandOutputContains(a, "/set mode",
+ "| /set format verbose unresolved"),
(a) -> assertCommandOutputStartsWith(a, "/set mode *",
"| Expected a feedback mode name: *"),
(a) -> assertCommandOutputStartsWith(a, "/set mode -quiet",
@@ -225,11 +308,13 @@
"| Expected a feedback mode name: *"),
(a) -> assertCommandOutputStartsWith(a, "/set mode amode normal thing",
"| Unexpected arguments at end of command: thing"),
- (a) -> assertCommand(a, "/set mode mymode",
+ (a) -> assertCommandOutputStartsWith(a, "/set mode mymode",
+ "| To create a new mode either the -command or the -quiet option must be used"),
+ (a) -> assertCommand(a, "/set mode mymode -command",
"| Created new feedback mode: mymode"),
(a) -> assertCommand(a, "/set mode mymode -delete",
""),
- (a) -> assertCommand(a, "/set mode mymode normal",
+ (a) -> assertCommand(a, "/set mode mymode normal -command",
"| Created new feedback mode: mymode"),
(a) -> assertCommand(a, "/set mode -del mymode",
""),
@@ -241,18 +326,33 @@
"| Conflicting options"),
(a) -> assertCommandOutputStartsWith(a, "/set mode mymode -d",
"| No feedback mode named: mymode"),
- (a) -> assertCommandOutputStartsWith(a, "/set mode normal",
- "| Not valid with a predefined mode: normal"),
+ (a) -> assertCommandOutputStartsWith(a, "/set mode normal -c",
+ "| Mode to be created already exists: normal"),
(a) -> assertCommand(a, "/se mo -c mymode",
"| Created new feedback mode: mymode"),
+ (a) -> assertCommandOutputStartsWith(a, "/set mode mymode",
+ "| /set mode mymode -command"),
(a) -> assertCommand(a, "/set feedback mymode",
"| Feedback mode: mymode"),
+ (a) -> assertCommand(a, "/se fe",
+ "| /set feedback mymode\n" +
+ "| \n" +
+ "| Available feedback modes:\n" +
+ "| concise\n" +
+ "| mymode\n" +
+ "| normal\n" +
+ "| silent\n" +
+ "| verbose"),
(a) -> assertCommandOutputStartsWith(a, "/set mode mymode -delete",
"| The current feedback mode 'mymode' cannot be deleted"),
(a) -> assertCommand(a, "/set feedback no",
"| Feedback mode: normal"),
(a) -> assertCommandOutputStartsWith(a, "/set mode mymode -delete",
""),
+ (a) -> assertCommandOutputStartsWith(a, "/set mode mymode",
+ "| To create a new mode either the -command or the -quiet option must be used -- \n" +
+ "| Does not match any current feedback mode: mymode -- /set mode mymode\n" +
+ "| Available feedback modes:"),
(a) -> assertCommandCheckOutput(a, "/set feedback",
(s) -> assertFalse(s.contains("mymode"), "Didn't delete: " + s))
);
@@ -268,8 +368,20 @@
""),
(a) -> assertCommand(a, "45",
"blurb"),
- (a) -> assertCommand(a, "/set mode mymode normal",
+ (a) -> assertCommandOutputStartsWith(a, "/set mode mymode normal",
+ "| To create a new mode either the -command or the -quiet option must be used"),
+ (a) -> assertCommandOutputStartsWith(a, "/set mode mymode -command normal",
+ "| Mode to be created already exists: mymode"),
+ (a) -> assertCommandOutputStartsWith(a, "/set mode mymode -delete",
+ "| The current feedback mode 'mymode' cannot be deleted, use '/set feedback' first"),
+ (a) -> assertCommand(a, "/set feedback normal",
+ "| Feedback mode: normal"),
+ (a) -> assertCommand(a, "/set mode mymode -delete",
+ ""),
+ (a) -> assertCommand(a, "/set mode mymode -command normal",
"| Created new feedback mode: mymode"),
+ (a) -> assertCommand(a, "/set feedback mymode",
+ "| Feedback mode: mymode"),
(a) -> assertCommandOutputContains(a, "45",
" ==> 45")
);
@@ -277,67 +389,89 @@
public void retainModeTest() {
test(
- (a) -> assertCommandOutputStartsWith(a, "/retain mode",
+ (a) -> assertCommandOutputStartsWith(a, "/set mode -retain",
"| Missing the feedback mode"),
- (a) -> assertCommandOutputStartsWith(a, "/retain mode *",
+ (a) -> assertCommandOutputStartsWith(a, "/set mode -retain *",
"| Expected a feedback mode name: *"),
- (a) -> assertCommandOutputStartsWith(a, "/retain mode amode normal",
+ (a) -> assertCommandOutputStartsWith(a, "/set mode -retain amode normal",
"| Unexpected arguments at end of command: normal"),
- (a) -> assertCommandOutputStartsWith(a, "/retain mode mymode",
- "| Does not match any current feedback mode: mymode"),
- (a) -> assertCommandOutputStartsWith(a, "/retain mode mymode -delete",
+ (a) -> assertCommandOutputStartsWith(a, "/set mode -retain mymode",
"| No feedback mode named: mymode"),
- (a) -> assertCommandOutputStartsWith(a, "/retain mode -d mymode",
+ (a) -> assertCommandOutputStartsWith(a, "/set mode -retain mymode -delete",
+ "| No feedback mode named: mymode"),
+ (a) -> assertCommandOutputStartsWith(a, "/set mode -retain -d mymode",
"| No feedback mode named: mymode"),
- (a) -> assertCommandOutputStartsWith(a, "/retain mode normal",
+ (a) -> assertCommandOutputStartsWith(a, "/set mode -retain normal",
"| Not valid with a predefined mode: normal"),
- (a) -> assertCommand(a, "/set mode mymode verbose",
+ (a) -> assertCommand(a, "/set mode mymode verbose -command",
"| Created new feedback mode: mymode"),
- (a) -> assertCommand(a, "/retain mode mymode",
+ (a) -> assertCommand(a, "/set mode -retain mymode",
""),
(a) -> assertCommand(a, "/set mode mymode -delete",
""),
- (a) -> assertCommand(a, "/retain mode mymode -delete",
+ (a) -> assertCommand(a, "/set mode -retain mymode -delete",
""),
- (a) -> assertCommand(a, "/set mode kmode normal",
+ (a) -> assertCommand(a, "/set mode kmode normal -command",
"| Created new feedback mode: kmode"),
- (a) -> assertCommand(a, "/retain mode kmode",
+ (a) -> assertCommand(a, "/set mode -retain kmode",
""),
(a) -> assertCommand(a, "/set mode kmode -delete",
""),
- (a) -> assertCommand(a, "/set mode tmode normal",
+ (a) -> assertCommand(a, "/set mode tmode normal -command",
"| Created new feedback mode: tmode"),
- (a) -> assertCommandOutputStartsWith(a, "/retain feedback tmode",
- "| '/retain feedback <mode>' requires that <mode> is predefined or has been retained with '/retain mode'"),
+ (a) -> assertCommandOutputStartsWith(a, "/set feedback -retain tmode",
+ "| '/set feedback -retain <mode>' requires that <mode> is predefined or has been retained with '/set mode -retain'"),
(a) -> assertCommand(a, "/set format tmode display 'YES'",
""),
(a) -> assertCommand(a, "/set feedback tmode",
"| Feedback mode: tmode"),
(a) -> assertCommand(a, "45",
"YES"),
- (a) -> assertCommand(a, "/retain mode tmode",
+ (a) -> assertCommand(a, "/set mode -retain tmode",
""),
- (a) -> assertCommand(a, "/retain feedback tmode",
+ (a) -> assertCommand(a, "/set feedback -retain tmode",
"| Feedback mode: tmode"),
(a) -> assertCommand(a, "/set format tmode display 'blurb'",
""),
+ (a) -> assertCommand(a, "/set format tmode display",
+ "| /set format tmode display \"blurb\""),
+ (a) -> assertCommandOutputContains(a, "/set mode tmode",
+ "| /set format tmode display \"YES\""),
(a) -> assertCommand(a, "45",
"blurb")
);
test(
+ (a) -> assertCommand(a, "/set format tmode display",
+ "| /set format tmode display \"YES\""),
+ (a) -> assertCommandOutputContains(a, "/set mode tmode",
+ "| /set format tmode display \"YES\""),
(a) -> assertCommand(a, "45",
"YES"),
(a) -> assertCommand(a, "/set feedback kmode",
"| Feedback mode: kmode"),
- (a) -> assertCommandOutputStartsWith(a, "/retain mode kmode -delete",
+ (a) -> assertCommand(a, "/set feedback",
+ "| /set feedback -retain tmode\n" +
+ "| /set feedback kmode\n" +
+ "| \n" +
+ "| Retained feedback modes:\n" +
+ "| kmode\n" +
+ "| tmode\n" +
+ "| Available feedback modes:\n" +
+ "| concise\n" +
+ "| kmode\n" +
+ "| normal\n" +
+ "| silent\n" +
+ "| tmode\n" +
+ "| verbose"),
+ (a) -> assertCommandOutputStartsWith(a, "/set mode -retain kmode -delete",
"| The current feedback mode 'kmode' cannot be deleted"),
- (a) -> assertCommandOutputStartsWith(a, "/retain mode tmode -delete",
+ (a) -> assertCommandOutputStartsWith(a, "/set mode -retain tmode -delete",
"| The retained feedback mode 'tmode' cannot be deleted"),
- (a) -> assertCommand(a, "/retain feedback normal",
+ (a) -> assertCommand(a, "/set feedback -retain normal",
"| Feedback mode: normal"),
- (a) -> assertCommand(a, "/retain mode tmode -delete",
+ (a) -> assertCommand(a, "/set mode -retain tmode -delete",
""),
- (a) -> assertCommandOutputStartsWith(a, "/retain mode kmode -delete",
+ (a) -> assertCommandOutputStartsWith(a, "/set mode -retain kmode -delete",
"")
);
test(
--- a/langtools/test/jdk/jshell/ToolFormatTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/test/jdk/jshell/ToolFormatTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8148316 8148317 8151755 8152246 8153551 8154812 8157261
+ * @bug 8148316 8148317 8151755 8152246 8153551 8154812 8157261 8163840
* @summary Tests for output customization
* @library /tools/lib
* @modules jdk.compiler/com.sun.tools.javac.api
@@ -33,10 +33,17 @@
* @build KullaTesting TestingInputStream toolbox.ToolBox Compiler
* @run testng ToolFormatTest
*/
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import org.testng.annotations.Test;
+import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
@Test
public class ToolFormatTest extends ReplToolTesting {
@@ -81,6 +88,58 @@
}
}
+ public void testSetFormatOverride() {
+ test(
+ (a) -> assertCommand(a, "/set mode tm -c", "| Created new feedback mode: tm"),
+ (a) -> assertCommand(a, "/se fo tm x \"aaa\"", ""),
+ (a) -> assertCommand(a, "/se fo tm x \"bbb\" class,method-added", ""),
+ (a) -> assertCommand(a, "/se fo tm x",
+ "| /set format tm x \"aaa\" \n" +
+ "| /set format tm x \"bbb\" class,method-added"),
+ (a) -> assertCommand(a, "/se fo tm x \"ccc\" class,method-added,modified", ""),
+ (a) -> assertCommand(a, "/se fo tm x \"ddd\" class,method-added", ""),
+ (a) -> assertCommand(a, "/se fo tm x \"eee\" method-added", ""),
+ (a) -> assertCommand(a, "/se fo tm x",
+ "| /set format tm x \"aaa\" \n" +
+ "| /set format tm x \"ccc\" class,method-added,modified\n" +
+ "| /set format tm x \"ddd\" class,method-added\n" +
+ "| /set format tm x \"eee\" method-added"),
+ (a) -> assertCommand(a, "/se fo tm x \"EEE\" method-added,replaced", ""),
+ (a) -> assertCommand(a, "/se fo tm x",
+ "| /set format tm x \"aaa\" \n" +
+ "| /set format tm x \"ccc\" class,method-added,modified\n" +
+ "| /set format tm x \"ddd\" class,method-added\n" +
+ "| /set format tm x \"EEE\" method-added,replaced"),
+ (a) -> assertCommand(a, "/se fo tm x \"fff\" method-added,replaced-ok", ""),
+ (a) -> assertCommand(a, "/se fo tm x",
+ "| /set format tm x \"aaa\" \n" +
+ "| /set format tm x \"ccc\" class,method-added,modified\n" +
+ "| /set format tm x \"ddd\" class,method-added\n" +
+ "| /set format tm x \"EEE\" method-added,replaced\n" +
+ "| /set format tm x \"fff\" method-added,replaced-ok"),
+ (a) -> assertCommand(a, "/se fo tm x \"ggg\" method-ok", ""),
+ (a) -> assertCommand(a, "/se fo tm x",
+ "| /set format tm x \"aaa\" \n" +
+ "| /set format tm x \"ccc\" class,method-added,modified\n" +
+ "| /set format tm x \"ddd\" class,method-added\n" +
+ "| /set format tm x \"EEE\" method-added,replaced\n" +
+ "| /set format tm x \"ggg\" method-ok"),
+ (a) -> assertCommand(a, "/se fo tm x \"hhh\" method", ""),
+ (a) -> assertCommand(a, "/se fo tm x",
+ "| /set format tm x \"aaa\" \n" +
+ "| /set format tm x \"ccc\" class,method-added,modified\n" +
+ "| /set format tm x \"ddd\" class,method-added\n" +
+ "| /set format tm x \"hhh\" method"),
+ (a) -> assertCommand(a, "/se fo tm x \"iii\" method,class", ""),
+ (a) -> assertCommand(a, "/se fo tm x",
+ "| /set format tm x \"aaa\" \n" +
+ "| /set format tm x \"iii\" class,method"),
+ (a) -> assertCommand(a, "/se fo tm x \"jjj\"", ""),
+ (a) -> assertCommand(a, "/se fo tm x",
+ "| /set format tm x \"jjj\"")
+ );
+ }
+
public void testSetFormatSelector() {
List<ReplTest> tests = new ArrayList<>();
tests.add((a) -> assertCommandOutputStartsWith(a, "/set mode ate -quiet",
@@ -167,8 +226,14 @@
(a) -> assertCommandOutputStartsWith(a, "/set feedback test", ""),
(a) -> assertCommand(a, "/set format test display '{type}:{value}' primary", ""),
(a) -> assertCommand(a, "/set truncation test 20", ""),
+ (a) -> assertCommand(a, "/set truncation test", "| /set truncation test 20"),
+ (a) -> assertCommandOutputContains(a, "/set truncation", "/set truncation test 20"),
(a) -> assertCommand(a, "/set trunc test 10 varvalue", ""),
(a) -> assertCommand(a, "/set trunc test 3 assignment", ""),
+ (a) -> assertCommandOutputContains(a, "/set truncation",
+ "/set truncation test 10 varvalue"),
+ (a) -> assertCommandOutputContains(a, "/set truncation test",
+ "/set truncation test 10 varvalue"),
(a) -> assertCommand(a, "String r = s", "String:\"ABACABADABACABA ..."),
(a) -> assertCommand(a, "r", "String:\"ABACA ..."),
(a) -> assertCommand(a, "r=s", "String:\"AB")
@@ -201,6 +266,45 @@
);
}
+ public void testPrompt() {
+ test(
+ (a) -> assertCommand(a, "/set mode tp -quiet", "| Created new feedback mode: tp"),
+ (a) -> assertCommand(a, "/set prompt tp 'aaa' 'bbb'", ""),
+ (a) -> assertCommand(a, "/set prompt tp",
+ "| /set prompt tp \"aaa\" \"bbb\""),
+ (a) -> assertCommandOutputContains(a, "/set prompt",
+ "| /set prompt tp \"aaa\" \"bbb\""),
+ (a) -> assertCommand(a, "/set mode -retain tp", ""),
+ (a) -> assertCommand(a, "/set prompt tp 'ccc' 'ddd'", ""),
+ (a) -> assertCommand(a, "/set prompt tp",
+ "| /set prompt tp \"ccc\" \"ddd\""),
+ (a) -> assertCommandCheckOutput(a, "/set mode tp",
+ (s) -> {
+ try {
+ BufferedReader rdr = new BufferedReader(new StringReader(s));
+ assertEquals(rdr.readLine(), "| /set mode tp -quiet",
+ "| /set mode tp -quiet");
+ assertEquals(rdr.readLine(), "| /set prompt tp \"aaa\" \"bbb\"",
+ "| /set prompt tp \"aaa\" \"bbb\"");
+ String l = rdr.readLine();
+ while (l.startsWith("| /set format tp ")) {
+ l = rdr.readLine();
+ }
+ assertEquals(l, "| /set mode -retain tp",
+ "| /set mode -retain tp");
+ assertEquals(rdr.readLine(), "| ",
+ "| ");
+ assertEquals(rdr.readLine(), "| /set mode tp -quiet",
+ "| /set mode tp -quiet");
+ assertEquals(rdr.readLine(), "| /set prompt tp \"ccc\" \"ddd\"",
+ "| /set prompt tp \"ccc\" \"ddd\"");
+ } catch (IOException ex) {
+ fail("threw " + ex);
+ }
+ })
+ );
+ }
+
public void testShowFeedbackModes() {
test(
(a) -> assertCommandOutputContains(a, "/set feedback", "normal")
@@ -216,7 +320,8 @@
(a) -> assertCommand(a, "/se fee nmq2", ""),
(a) -> assertCommand(a, "/set mode nmc -command normal", ""),
(a) -> assertCommandOutputStartsWith(a, "/set feedback nmc", "| Feedback mode: nmc"),
- (a) -> assertCommandOutputStartsWith(a, "/set mode nm", "| Created new feedback mode: nm"),
+ (a) -> assertCommandOutputStartsWith(a, "/set mode nm -command",
+ "| Created new feedback mode: nm"),
(a) -> assertCommandOutputStartsWith(a, "/set feedback nm", "| Feedback mode: nm"),
(a) -> assertCommandOutputStartsWith(a, "/set feedback normal", "| Feedback mode: normal")
);
@@ -231,37 +336,35 @@
test(
(a) -> assertCommandOutputStartsWith(a, "/set mode tee -command foo",
"| Does not match any current feedback mode: foo"),
- (a) -> assertCommandOutputStartsWith(a, "/set mode tee flurb",
+ (a) -> assertCommandOutputStartsWith(a, "/set mode tee -quiet flurb",
"| Does not match any current feedback mode: flurb"),
- (a) -> assertCommandOutputStartsWith(a, "/set mode tee",
+ (a) -> assertCommandOutputStartsWith(a, "/set mode -command tee",
"| Created new feedback mode: tee"),
- (a) -> assertCommandOutputStartsWith(a, "/set mode verbose",
- "| Not valid with a predefined mode: verbose"),
+ (a) -> assertCommandOutputStartsWith(a, "/set mode verbose -command",
+ "| Mode to be created already exists: verbose"),
(a) -> assertCommandOutputStartsWith(a, "/set mode te -command normal",
"| Created new feedback mode: te"),
(a) -> assertCommand(a, "/set format te errorpre 'ERROR: '", ""),
(a) -> assertCommandOutputStartsWith(a, "/set feedback te",
""),
- (a) -> assertCommandOutputStartsWith(a, "/set ",
- "ERROR: The '/set' command requires a sub-command"),
(a) -> assertCommandOutputStartsWith(a, "/set xyz",
"ERROR: Invalid '/set' argument: xyz"),
(a) -> assertCommandOutputStartsWith(a, "/set f",
"ERROR: Ambiguous sub-command argument to '/set': f"),
(a) -> assertCommandOutputStartsWith(a, "/set feedback",
- "ERROR: Missing the feedback mode"),
+ "| /set feedback te"),
(a) -> assertCommandOutputStartsWith(a, "/set feedback xyz",
"ERROR: Does not match any current feedback mode"),
- (a) -> assertCommandOutputStartsWith(a, "/set format",
- "ERROR: Missing the feedback mode"),
+ (a) -> assertCommandOutputStartsWith(a, "/set feed",
+ "| /set feedback te"),
(a) -> assertCommandOutputStartsWith(a, "/set format xyz",
"ERROR: Does not match any current feedback mode"),
(a) -> assertCommandOutputStartsWith(a, "/set format t",
"ERROR: Matches more then one current feedback mode: t"),
- (a) -> assertCommandOutputStartsWith(a, "/set format te",
- "ERROR: Missing the field name"),
+ (a) -> assertCommandOutputStartsWith(a, "/set format qqq",
+ "ERROR: Does not match any current feedback mode: qqq"),
(a) -> assertCommandOutputStartsWith(a, "/set format te fld",
- "ERROR: Expected format missing"),
+ "ERROR: Expected a field name:"),
(a) -> assertCommandOutputStartsWith(a, "/set format te fld aaa",
"ERROR: Format 'aaa' must be quoted"),
(a) -> assertCommandOutputStartsWith(a, "/set format te fld 'aaa' frog",
@@ -274,30 +377,28 @@
"ERROR: Different selector kinds in same sections of"),
(a) -> assertCommandOutputStartsWith(a, "/set trunc te 20x",
"ERROR: Truncation length must be an integer: 20x"),
- (a) -> assertCommandOutputStartsWith(a, "/set trunc te",
- "ERROR: Expected truncation length"),
+ (a) -> assertCommandOutputStartsWith(a, "/set trunc qaz",
+ "ERROR: Does not match any current feedback mode: qaz -- /set trunc qaz"),
(a) -> assertCommandOutputStartsWith(a, "/set truncation te 111 import,added",
"ERROR: Different selector kinds in same sections of"),
- (a) -> assertCommandOutputStartsWith(a, "/set mode",
+ (a) -> assertCommandOutputContains(a, "/set mode",
+ "| /set truncation verbose"),
+ (a) -> assertCommandOutputStartsWith(a, "/set mode -command",
"ERROR: Missing the feedback mode"),
(a) -> assertCommandOutputStartsWith(a, "/set mode x -quiet y",
"ERROR: Does not match any current feedback mode"),
(a) -> assertCommandOutputStartsWith(a, "/set prompt",
- "ERROR: Missing the feedback mode"),
+ "| /set prompt"),
(a) -> assertCommandOutputStartsWith(a, "/set prompt te",
- "ERROR: Expected format missing"),
+ "| /set prompt te "),
(a) -> assertCommandOutputStartsWith(a, "/set prompt te aaa xyz",
"ERROR: Format 'aaa' must be quoted"),
(a) -> assertCommandOutputStartsWith(a, "/set prompt te 'aaa' xyz",
"ERROR: Format 'xyz' must be quoted"),
- (a) -> assertCommandOutputStartsWith(a, "/set prompt",
- "ERROR: Missing the feedback mode"),
- (a) -> assertCommandOutputStartsWith(a, "/set prompt te",
- "ERROR: Expected format missing"),
(a) -> assertCommandOutputStartsWith(a, "/set prompt te aaa",
"ERROR: Format 'aaa' must be quoted"),
(a) -> assertCommandOutputStartsWith(a, "/set prompt te 'aaa'",
- "ERROR: Expected format missing"),
+ "ERROR: Continuation prompt required"),
(a) -> assertCommandOutputStartsWith(a, "/set feedback normal",
"| Feedback mode: normal")
);
--- a/langtools/test/jdk/jshell/ToolLocaleMessageTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/test/jdk/jshell/ToolLocaleMessageTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -106,10 +106,11 @@
(a) -> assertCommandOK(a, "/set feedback test", "test"),
(a) -> assertCommandFail(a, "/list zebra"),
- (a) -> assertCommandFail(a, "/set editor", "/set editor"),
+ (a) -> assertCommandFail(a, "/set editor -rot", "/set editor -rot"),
(a) -> assertCommandFail(a, "/set snowball", "/set", "snowball"),
- (a) -> assertCommandFail(a, "/set", "/set", "/help"),
- (a) -> assertCommandFail(a, "/set f", "feedback"),
+ (a) -> assertCommandOK(a, "/set", "| /set feedback test", "verbose"),
+ (a) -> assertCommandFail(a, "/set f", "/set"),
+ (a) -> assertCommandOK(a, "/set fe", "| /set feedback test"),
(a) -> assertCommandFail(a, "/classpath", "/classpath"),
(a) -> assertCommandFail(a, "/help rabbits", "rabbits"),
(a) -> assertCommandFail(a, "/drop"),
@@ -164,27 +165,20 @@
(a) -> assertCommandOK(a, "/set format te errorpre 'ERROR: '"),
(a) -> assertCommandOK(a, "/set feedback te"),
- (a) -> assertCommandFail(a, "/set "),
(a) -> assertCommandFail(a, "/set xyz", "xyz"),
(a) -> assertCommandFail(a, "/set f", "/set", "f"),
- (a) -> assertCommandFail(a, "/set feedback"),
(a) -> assertCommandFail(a, "/set feedback xyz"),
- (a) -> assertCommandFail(a, "/set format"),
(a) -> assertCommandFail(a, "/set format xyz"),
(a) -> assertCommandFail(a, "/set format t"),
- (a) -> assertCommandFail(a, "/set format te"),
(a) -> assertCommandFail(a, "/set format te fld"),
(a) -> assertCommandFail(a, "/set format te fld aaa", "aaa"),
(a) -> assertCommandFail(a, "/set format te fld 'aaa' frog"),
(a) -> assertCommandFail(a, "/set format te fld 'aaa' import-frog"),
(a) -> assertCommandFail(a, "/set format te fld 'aaa' import-import"),
(a) -> assertCommandFail(a, "/set format te fld 'aaa' import,added"),
- (a) -> assertCommandFail(a, "/set mode"),
(a) -> assertCommandFail(a, "/set mode x xyz"),
(a) -> assertCommandFail(a, "/set mode x -quiet y"),
(a) -> assertCommandFail(a, "/set mode tee -command foo", "foo"),
- (a) -> assertCommandFail(a, "/set prompt"),
- (a) -> assertCommandFail(a, "/set prompt te"),
(a) -> assertCommandFail(a, "/set prompt te aaa xyz", "aaa"),
(a) -> assertCommandFail(a, "/set prompt te 'aaa' xyz", "xyz"),
(a) -> assertCommandFail(a, "/set prompt te aaa"),
--- a/langtools/test/jdk/jshell/ToolRetainTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/test/jdk/jshell/ToolRetainTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8157200
+ * @bug 8157200 8163840
* @summary Tests of what information is retained across jshell tool runs
* @modules jdk.jshell/jdk.internal.jshell.tool
* @build ToolRetainTest ReplToolTesting
@@ -41,10 +41,12 @@
(a) -> assertCommand(a, "/set feedback trm", ""),
(a) -> assertCommand(a, "/set format trm display '{name}:{value}'", ""),
(a) -> assertCommand(a, "int x = 45", "x:45"),
- (a) -> assertCommand(a, "/retain mode trm", ""),
+ (a) -> assertCommand(a, "/set mode -retain trm", ""),
(a) -> assertCommand(a, "/exit", "")
);
test(
+ (a) -> assertCommandOutputContains(a, "/set mode trm",
+ "/set format trm display \"{name}:{value}\""),
(a) -> assertCommand(a, "/set feedback trm", ""),
(a) -> assertCommand(a, "int x = 45", "x:45")
);
@@ -53,21 +55,25 @@
public void testRetain2Mode() {
test(
(a) -> assertCommand(a, "/set mode trm1 -quiet", "| Created new feedback mode: trm1"),
- (a) -> assertCommand(a, "/retain mode trm1", ""),
- (a) -> assertCommand(a, "/retain feedback trm1", ""),
+ (a) -> assertCommand(a, "/set mode -retain trm1", ""),
+ (a) -> assertCommand(a, "/set feedback -retain trm1", ""),
(a) -> assertCommand(a, "/set format trm1 display '{name}:{value}'", ""),
(a) -> assertCommand(a, "int x = 66", "x:66"),
- (a) -> assertCommand(a, "/retain mode trm1", ""),
+ (a) -> assertCommand(a, "/set mode -retain trm1", ""),
(a) -> assertCommand(a, "/exit", "")
);
test(
(a) -> assertCommand(a, "/set mode trm2 -quiet", ""),
(a) -> assertCommand(a, "/set format trm2 display '{name}={value}'", ""),
(a) -> assertCommand(a, "int x = 45", "x:45"),
- (a) -> assertCommand(a, "/retain mode trm2", ""),
+ (a) -> assertCommand(a, "/set mode -retain trm2", ""),
(a) -> assertCommand(a, "/exit", "")
);
test(
+ (a) -> assertCommandOutputContains(a, "/set mode trm1",
+ "/set format trm1 display \"{name}:{value}\""),
+ (a) -> assertCommand(a, "/set format trm2 display",
+ "| /set format trm2 display \"{name}={value}\""),
(a) -> assertCommand(a, "int x = 99", "x:99"),
(a) -> assertCommand(a, "/set feedback trm2", ""),
(a) -> assertCommand(a, "int z = 77", "z=77")
@@ -76,31 +82,48 @@
public void testRetainFeedback() {
test(
- (a) -> assertCommand(a, "/retain feedback verbose", "| Feedback mode: verbose"),
+ (a) -> assertCommand(a, "/set feedback -retain verbose", "| Feedback mode: verbose"),
(a) -> assertCommand(a, "/exit", "")
);
test(
+ (a) -> assertCommandOutputStartsWith(a, "/set feedback",
+ "| /set feedback -retain verbose\n" +
+ "| \n" +
+ "| "),
(a) -> assertCommandOutputContains(a, "int h =8", "| created variable h : int")
);
}
public void testRetainFeedbackBlank() {
+ String feedbackOut =
+ "| /set feedback -retain verbose\n" +
+ "| \n" +
+ "| Available feedback modes:\n" +
+ "| concise\n" +
+ "| normal\n" +
+ "| silent\n" +
+ "| verbose";
test(
(a) -> assertCommand(a, "/set feedback verbose", "| Feedback mode: verbose"),
- (a) -> assertCommand(a, "/retain feedback", ""),
+ (a) -> assertCommand(a, "/set feedback -retain", ""),
+ (a) -> assertCommand(a, "/set feedback", feedbackOut),
(a) -> assertCommand(a, "/exit", "")
);
test(
+ (a) -> assertCommand(a, "/set feedback", feedbackOut),
(a) -> assertCommandOutputContains(a, "int qw = 5", "| created variable qw : int")
);
}
public void testRetainEditor() {
test(
- (a) -> assertCommand(a, "/retain editor nonexistent", "| Editor set to: nonexistent"),
+ (a) -> assertCommand(a, "/set editor -retain nonexistent",
+ "| Editor set to: nonexistent\n" +
+ "| Editor setting retained: nonexistent"),
(a) -> assertCommand(a, "/exit", "")
);
test(
+ (a) -> assertCommand(a, "/set editor", "| /set editor -retain nonexistent"),
(a) -> assertCommandOutputContains(a, "int h =8", ""),
(a) -> assertCommandOutputContains(a, "/edit h", "Edit Error:")
);
@@ -109,7 +132,7 @@
public void testRetainEditorBlank() {
test(
(a) -> assertCommand(a, "/set editor nonexistent", "| Editor set to: nonexistent"),
- (a) -> assertCommand(a, "/retain editor", ""),
+ (a) -> assertCommand(a, "/set editor -retain", "| Editor setting retained: nonexistent"),
(a) -> assertCommand(a, "/exit", "")
);
test(
@@ -120,22 +143,25 @@
public void testRetainModeNeg() {
test(
- (a) -> assertCommandOutputStartsWith(a, "/retain mode verbose",
+ (a) -> assertCommandOutputStartsWith(a, "/set mode -retain verbose",
"| Not valid with a predefined mode"),
- (a) -> assertCommandOutputStartsWith(a, "/retain mode ????",
+ (a) -> assertCommandOutputStartsWith(a, "/set mode -retain ????",
"| Expected a feedback mode name: ????")
);
}
public void testRetainFeedbackNeg() {
test(
- (a) -> assertCommandOutputStartsWith(a, "/retain feedback babble1",
+ (a) -> assertCommandOutputStartsWith(a, "/set feedback -retain babble1",
"| Does not match any current feedback mode"),
- (a) -> assertCommand(a, "/set mode trfn",
+ (a) -> assertCommandOutputStartsWith(a, "/set mode trfn",
+ "| To create a new mode either the -command or the -quiet option must be used -- \n" +
+ "| Does not match any current feedback mode: trfn -- /set mode trfn"),
+ (a) -> assertCommand(a, "/set mode trfn -command",
"| Created new feedback mode: trfn"),
- (a) -> assertCommandOutputContains(a, "/retain feedback trfn",
+ (a) -> assertCommandOutputContains(a, "/set feedback -retain trfn",
"is predefined or has been retained"),
- (a) -> assertCommandOutputStartsWith(a, "/retain feedback !!!!",
+ (a) -> assertCommandOutputStartsWith(a, "/set feedback -retain !!!!",
"| Expected a feedback mode name: !!!!")
);
}
--- a/langtools/test/jdk/jshell/ToolSimpleTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/test/jdk/jshell/ToolSimpleTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8153716 8143955 8151754 8150382 8153920 8156910 8131024 8160089 8153897
+ * @bug 8153716 8143955 8151754 8150382 8153920 8156910 8131024 8160089 8153897 8167128
* @summary Simple jshell tool tests
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
@@ -193,8 +193,8 @@
"| '/save' requires a filename argument."),
(a) -> assertCommand(a, "/open",
"| '/open' requires a filename argument."),
- (a) -> assertCommand(a, "/set start",
- "| Specify either one option or a startup file name -- /set start")
+ (a) -> assertCommandOutputStartsWith(a, "/drop",
+ "| In the /drop argument, please specify an import, variable, method, or class to drop.")
);
}
@@ -217,6 +217,9 @@
a -> dropClass(a, "/drop 3", "class A", "| dropped class A"),
a -> assertImport(a, "import java.util.stream.*;", "", "java.util.stream.*"),
a -> dropImport(a, "/drop 4", "import java.util.stream.*", ""),
+ a -> assertCommand(a, "for (int i = 0; i < 10; ++i) {}", ""),
+ a -> assertCommand(a, "/drop 5", ""),
+ a -> assertCommand(a, "/list", ""),
a -> assertCommandCheckOutput(a, "/vars", assertVariables()),
a -> assertCommandCheckOutput(a, "/methods", assertMethods()),
a -> assertCommandCheckOutput(a, "/types", assertClasses()),
@@ -244,6 +247,7 @@
assertStartsWith("| In the /drop argument, please specify an import, variable, method, or class to drop.")),
a -> assertVariable(a, "int", "a"),
a -> assertCommand(a, "a", "a ==> 0"),
+ a -> assertCommand(a, "/drop 2", ""),
a -> assertCommand(a, "/drop 2",
"| This command does not accept the snippet '2' : a\n" +
"| See /types, /methods, /vars, or /list")
--- a/langtools/test/jdk/jshell/UserInputTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/test/jdk/jshell/UserInputTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -23,12 +23,15 @@
/*
* @test
- * @bug 8131023
+ * @bug 8131023 8167461
* @summary Verify that the user's code can read System.in
* @build KullaTesting TestingInputStream
* @run testng UserInputTest
*/
+import java.io.IOException;
+import java.io.InputStream;
+
import org.testng.annotations.Test;
@Test
@@ -37,8 +40,61 @@
public void testReadInput() {
setInput("AB\n");
assertEval("System.in.read()", "65");
- setInput("BC\n");
- assertEval("System.in.read()", "66");
+ setInput("CD\n");
+ assertEval("System.in.read()", "67");
+ }
+
+ public void testScanner() {
+ assertEval("import java.util.Scanner;");
+ assertEval("Scanner s = new Scanner(System.in);");
+ setInput("12\n");
+ assertEval("s.nextInt();", "12");
}
+ public void testClose() {
+ setInput(new InputStream() {
+ private final byte[] data = new byte[] {0, 1, 2};
+ private int cursor;
+ @Override public int read() throws IOException {
+ if (cursor < data.length) {
+ return data[cursor++];
+ } else {
+ return -1;
+ }
+ }
+ });
+ assertEval("int read;", "0");
+ assertEval("System.in.read();", "0");
+ assertEval("System.in.read();", "1");
+ assertEval("System.in.read();", "2");
+ assertEval("System.in.read();", "-1");
+ assertEval("System.in.read();", "-1");
+ assertEval("System.in.read();", "-1");
+ }
+
+ public void testException() {
+ setInput(new InputStream() {
+ private final int[] data = new int[] {0, 1, -2, 2};
+ private int cursor;
+ @Override public int read() throws IOException {
+ if (cursor < data.length) {
+ int d = data[cursor++];
+ if (d == (-2)) {
+ throw new IOException("Crashed");
+ }
+ return d;
+ } else {
+ return -1;
+ }
+ }
+ });
+ assertEval("int read;", "0");
+ assertEval("System.in.read();", "0");
+ assertEval("System.in.read();", "1");
+ assertEval("java.io.IOException e;");
+ assertEval("try { System.in.read(); } catch (java.io.IOException exc) { e = exc; }");
+ assertEval("e", "java.io.IOException: Crashed");
+ assertEval("System.in.read();", "2");
+ assertEval("System.in.read();", "-1");
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/8167000/T8167000.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,34 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8167000
+ * @summary Refine handling of multiple maximally specific abstract methods
+ * @compile/fail/ref=T8167000.out -XDrawDiagnostics -Werror -Xlint:unchecked T8167000.java
+ */
+
+import java.util.*;
+
+class T8167000 {
+
+ interface J {
+ List<Number> getAll(String str);
+ }
+
+ interface K {
+ Collection<Integer> getAll(String str);
+ }
+
+ interface L {
+ List getAll(String str);
+ }
+
+ interface M {
+ Collection getAll(String str);
+ }
+
+
+ static abstract class E implements J, K, L, M {
+ void test() {
+ List<String> l = getAll(""); //check that we get an unchecked warning here
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/8167000/T8167000.out Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,4 @@
+T8167000.java:31:36: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.util.List, java.util.List<java.lang.String>
+- compiler.err.warnings.and.werror
+1 error
+1 warning
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/8167000/T8167000b.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,21 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8167000
+ * @summary Refine handling of multiple maximally specific abstract methods
+ * @compile/fail/ref=T8167000b.out -XDrawDiagnostics T8167000b.java
+ */
+public class T8167000b {
+ interface A {
+ Integer m() throws Throwable;
+ }
+
+ interface B<X extends Throwable> {
+ Object m() throws X;
+ }
+
+ static abstract class E<T extends Throwable> implements A, B<T> {
+ void test() {
+ Integer l = m(); //error: unhandled T
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/8167000/T8167000b.out Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,2 @@
+T8167000b.java:18:26: compiler.err.unreported.exception.need.to.catch.or.throw: T
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/8167000/T8167000c.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,21 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8167000
+ * @summary Refine handling of multiple maximally specific abstract methods
+ * @compile/fail/ref=T8167000c.out -XDrawDiagnostics T8167000c.java
+ */
+public class T8167000c<X extends Throwable> {
+ interface A {
+ Integer m() throws Throwable;
+ }
+
+ interface B<X extends Throwable> {
+ Object m() throws X;
+ }
+
+ interface E<T extends Throwable> extends A, B<T> { }
+
+ void test() {
+ E<X> ex = () -> { throw new Throwable(); };
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/8167000/T8167000c.out Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,4 @@
+T8167000c.java:19:27: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
+- compiler.note.unchecked.filename: T8167000c.java
+- compiler.note.unchecked.recompile
+1 error
--- a/langtools/test/tools/javac/Paths/MineField.sh Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/test/tools/javac/Paths/MineField.sh Wed Oct 26 20:13:29 2016 +0000
@@ -109,9 +109,15 @@
echo 'public class Main {public static void main(String[] a) {Lib.f();}}' > Main.java
# Create a jar file that is good enough to put on the javac boot class path (i.e. contains java.lang.**)
-Sys "$jimage" extract --dir modules ${TESTJAVA}/lib/modules
-Sys "$jar" cf java-lang.jar -C modules/java.base java/lang
-Sys rm -rf modules
+if [ -r ${TESTJAVA}/lib/modules ]; then
+ Sys "$jimage" extract --dir modules ${TESTJAVA}/lib/modules
+ Sys "$jar" cf java-lang.jar -C modules/java.base java/lang
+ Sys rm -rf modules
+elif [ -d ${TESTJAVA}/modules ]; then
+ Sys "$jar" cf java-lang.jar -C ${TESTJAVA}/modules/java.base java/lang
+else
+ echo 'cannot create java-lang.jar' ; exit 1
+fi
#----------------------------------------------------------------
# Verify that javac class search order is the same as java's
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8029102/WarnSerializableElementTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,241 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8029102
+ * @summary Enhance compiler warnings for Lambda
+ * Checks that the warning for accessing non public members of a class is
+ * fired correctly.
+ * @compile/fail/ref=WarnSerializableElementTest.out -XDrawDiagnostics -Werror -XDwarnOnAccessToMembers WarnSerializableElementTest.java
+ */
+
+import java.io.Serializable;
+
+public class WarnSerializableElementTest {
+
+ void warnLambda() throws Exception {
+ SAM t3 = (SAM & Serializable)WarnSerializableElementTest::packageClassMethod;
+ SAM t4 = (SAM & Serializable)WarnSerializableElementTest::protectedClassMethod;
+ SAM t5 = (SAM & Serializable)WarnSerializableElementTest::privateClassMethod;
+
+ WarnSerializableElementTest test = new WarnSerializableElementTest();
+ SAM t6 = (SAM & Serializable)test::packageInstanceMethod;
+ SAM t7 = (SAM & Serializable)test::protectedInstanceMethod;
+ SAM t8 = (SAM & Serializable)test::privateInstanceMethod;
+
+ SAM t9 = (SAM & Serializable) c -> {
+
+ WarnSerializableElementTest.staticPackageField = "";
+ WarnSerializableElementTest.staticProtectedField = "";
+ WarnSerializableElementTest.staticPrivateField = "";
+
+ packageField = "";
+ protectedField = "";
+ privateField = "";
+
+ WarnSerializableElementTest.packageClassMethod(null);
+ WarnSerializableElementTest.protectedClassMethod(null);
+ WarnSerializableElementTest.privateClassMethod(null);
+
+ packageInstanceMethod(null);
+ protectedInstanceMethod(null);
+ privateInstanceMethod(null);
+
+ PrivateClass.effectivelyNonPublicStaticField = "";
+ PrivateClass.effectivelyNonPublicClassMethod();
+
+ PrivateClass p = new PrivateClass();
+ p.effectivelyNonPublicInstanceField = "";
+ p.effectivelyNonPublicInstanceMethod();
+
+ return null;
+ };
+ }
+
+ private void warnAnoInnerClass() throws Exception {
+ new SerializableDesc() {
+ public void m(Object param) throws Exception {
+ WarnSerializableElementTest.staticPackageField = "";
+ WarnSerializableElementTest.staticProtectedField = "";
+ WarnSerializableElementTest.staticPrivateField = "";
+
+ packageField = "";
+ protectedField = "";
+ privateField = "";
+
+ WarnSerializableElementTest.packageClassMethod(null);
+ WarnSerializableElementTest.protectedClassMethod(null);
+ WarnSerializableElementTest.privateClassMethod(null);
+
+ packageInstanceMethod(null);
+ protectedInstanceMethod(null);
+ privateInstanceMethod(null);
+
+ PrivateClass.effectivelyNonPublicStaticField = "";
+ PrivateClass.effectivelyNonPublicClassMethod();
+
+ PrivateClass p = new PrivateClass();
+ p.effectivelyNonPublicInstanceField = "";
+ p.effectivelyNonPublicInstanceMethod();
+ }
+ };
+ }
+
+ void dontWarnLambda() throws Exception {
+ SAM t1 = (SAM & Serializable)WarnSerializableElementTest::publicClassMethod;
+
+ WarnSerializableElementTest test = new WarnSerializableElementTest();
+ SAM t2 = (SAM & Serializable)test::publicInstanceMethod;
+
+ int[] buffer = {0};
+
+ SAM t3 = (SAM & Serializable) param -> {
+ Object localVar;
+ localVar = null;
+ param = null;
+
+ WarnSerializableElementTest.staticPublicField = "";
+ publicField = "";
+ WarnSerializableElementTest.publicClassMethod(null);
+ publicInstanceMethod(null);
+
+ PublicClass.effectivelyPublicStaticField = "";
+ PublicClass.effectivelyPublicClassMethod();
+
+ PublicClass p = new PublicClass();
+ p.effectivelyPublicInstanceField = "";
+ p.effectivelyPublicInstanceMethod();
+
+ int l = buffer.length;
+
+ return null;
+ };
+ }
+
+ private void dontWarnAnoInnerClass() throws Exception {
+ final int[] buffer = {0};
+ new SerializableDesc() {
+ public void m(Object param) throws Exception {
+ Object localVar;
+ localVar = null;
+ param = null;
+
+ WarnSerializableElementTest.staticPublicField = "";
+ publicField = "";
+ WarnSerializableElementTest.publicClassMethod(null);
+ publicInstanceMethod(null);
+
+ PublicClass.effectivelyPublicStaticField = "";
+ PublicClass.effectivelyPublicClassMethod();
+
+ PublicClass p = new PublicClass();
+ p.effectivelyPublicInstanceField = "";
+ p.effectivelyPublicInstanceMethod();
+
+ int l = buffer.length;
+ }
+ };
+ }
+
+ enum WarnEnum {
+ A {
+ public void m() throws Exception {
+ WarnSerializableElementTest.staticPackageField = "";
+ WarnSerializableElementTest.staticProtectedField = "";
+ WarnSerializableElementTest.staticPrivateField = "";
+
+ WarnSerializableElementTest test =
+ new WarnSerializableElementTest();
+
+ test.packageField = "";
+ test.protectedField = "";
+ test.privateField = "";
+
+ WarnSerializableElementTest.packageClassMethod(null);
+ WarnSerializableElementTest.protectedClassMethod(null);
+ WarnSerializableElementTest.privateClassMethod(null);
+
+ test.packageInstanceMethod(null);
+ test.protectedInstanceMethod(null);
+ test.privateInstanceMethod(null);
+
+ PrivateClass.effectivelyNonPublicStaticField = "";
+ PrivateClass.effectivelyNonPublicClassMethod();
+
+ PrivateClass p = new PrivateClass();
+ p.effectivelyNonPublicInstanceField = "";
+ p.effectivelyNonPublicInstanceMethod();
+ }
+ };
+
+ public void m() throws Exception {}
+ }
+
+ static String staticPackageField;
+ static private String staticPrivateField;
+ static protected String staticProtectedField;
+ static public String staticPublicField;
+
+ String packageField;
+ private String privateField;
+ protected String protectedField;
+ public String publicField;
+
+ static Object packageClassMethod(String s) {
+ return null;
+ }
+
+ static private Object privateClassMethod(String s) {
+ return null;
+ }
+
+ static protected Object protectedClassMethod(String s) {
+ return null;
+ }
+
+ static public Object publicClassMethod(String s) {
+ return null;
+ }
+
+ Object packageInstanceMethod(String s) {
+ return null;
+ }
+
+ protected Object protectedInstanceMethod(String s) {
+ return null;
+ }
+
+ private Object privateInstanceMethod(String s) {
+ return null;
+ }
+
+ public Object publicInstanceMethod(String s) {
+ return null;
+ }
+
+ interface SAM {
+ Object apply(String s) throws Exception;
+ }
+
+ interface SAM2 {
+ Object apply(String arg1, String arg2);
+ }
+
+ class SerializableDesc implements Serializable {
+ public void m(Object param) throws Exception {}
+ }
+
+ static private class PrivateClass {
+ static public String effectivelyNonPublicStaticField;
+ public String effectivelyNonPublicInstanceField;
+
+ static public void effectivelyNonPublicClassMethod() {}
+ public void effectivelyNonPublicInstanceMethod() {}
+ }
+
+ static public class PublicClass {
+ static public String effectivelyPublicStaticField;
+ public String effectivelyPublicInstanceField;
+
+ static public void effectivelyPublicClassMethod() {}
+ public void effectivelyPublicInstanceMethod() {}
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8029102/WarnSerializableElementTest.out Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,35 @@
+WarnSerializableElementTest.java:56:44: compiler.warn.access.to.member.from.serializable.element: staticPackageField
+WarnSerializableElementTest.java:57:44: compiler.warn.access.to.member.from.serializable.element: staticProtectedField
+WarnSerializableElementTest.java:58:44: compiler.warn.access.to.member.from.serializable.element: staticPrivateField
+WarnSerializableElementTest.java:60:17: compiler.warn.access.to.member.from.serializable.element: packageField
+WarnSerializableElementTest.java:61:17: compiler.warn.access.to.member.from.serializable.element: protectedField
+WarnSerializableElementTest.java:62:17: compiler.warn.access.to.member.from.serializable.element: privateField
+WarnSerializableElementTest.java:64:44: compiler.warn.access.to.member.from.serializable.element: packageClassMethod(java.lang.String)
+WarnSerializableElementTest.java:65:44: compiler.warn.access.to.member.from.serializable.element: protectedClassMethod(java.lang.String)
+WarnSerializableElementTest.java:66:44: compiler.warn.access.to.member.from.serializable.element: privateClassMethod(java.lang.String)
+WarnSerializableElementTest.java:68:17: compiler.warn.access.to.member.from.serializable.element: packageInstanceMethod(java.lang.String)
+WarnSerializableElementTest.java:69:17: compiler.warn.access.to.member.from.serializable.element: protectedInstanceMethod(java.lang.String)
+WarnSerializableElementTest.java:70:17: compiler.warn.access.to.member.from.serializable.element: privateInstanceMethod(java.lang.String)
+WarnSerializableElementTest.java:72:29: compiler.warn.access.to.member.from.serializable.element: effectivelyNonPublicStaticField
+WarnSerializableElementTest.java:73:29: compiler.warn.access.to.member.from.serializable.element: effectivelyNonPublicClassMethod()
+WarnSerializableElementTest.java:76:18: compiler.warn.access.to.member.from.serializable.element: effectivelyNonPublicInstanceField
+WarnSerializableElementTest.java:77:18: compiler.warn.access.to.member.from.serializable.element: effectivelyNonPublicInstanceMethod()
+WarnSerializableElementTest.java:141:44: compiler.warn.access.to.member.from.serializable.element: staticPackageField
+WarnSerializableElementTest.java:142:44: compiler.warn.access.to.member.from.serializable.element: staticProtectedField
+WarnSerializableElementTest.java:143:44: compiler.warn.access.to.member.from.serializable.element: staticPrivateField
+WarnSerializableElementTest.java:148:21: compiler.warn.access.to.member.from.serializable.element: packageField
+WarnSerializableElementTest.java:149:21: compiler.warn.access.to.member.from.serializable.element: protectedField
+WarnSerializableElementTest.java:150:21: compiler.warn.access.to.member.from.serializable.element: privateField
+WarnSerializableElementTest.java:152:44: compiler.warn.access.to.member.from.serializable.element: packageClassMethod(java.lang.String)
+WarnSerializableElementTest.java:153:44: compiler.warn.access.to.member.from.serializable.element: protectedClassMethod(java.lang.String)
+WarnSerializableElementTest.java:154:44: compiler.warn.access.to.member.from.serializable.element: privateClassMethod(java.lang.String)
+WarnSerializableElementTest.java:156:21: compiler.warn.access.to.member.from.serializable.element: packageInstanceMethod(java.lang.String)
+WarnSerializableElementTest.java:157:21: compiler.warn.access.to.member.from.serializable.element: protectedInstanceMethod(java.lang.String)
+WarnSerializableElementTest.java:158:21: compiler.warn.access.to.member.from.serializable.element: privateInstanceMethod(java.lang.String)
+WarnSerializableElementTest.java:160:29: compiler.warn.access.to.member.from.serializable.element: effectivelyNonPublicStaticField
+WarnSerializableElementTest.java:161:29: compiler.warn.access.to.member.from.serializable.element: effectivelyNonPublicClassMethod()
+WarnSerializableElementTest.java:164:18: compiler.warn.access.to.member.from.serializable.element: effectivelyNonPublicInstanceField
+WarnSerializableElementTest.java:165:18: compiler.warn.access.to.member.from.serializable.element: effectivelyNonPublicInstanceMethod()
+- compiler.err.warnings.and.werror
+1 error
+32 warnings
--- a/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTest.java Wed Oct 26 15:46:13 2016 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,241 +0,0 @@
-/*
- * @test /nodynamiccopyright/
- * @bug 8029102
- * @summary Enhance compiler warnings for Lambda
- * Checks that the warning for accessing non public members of a class is
- * fired correctly.
- * @compile/fail/ref=WarnSerializableLambdaTest.out -XDrawDiagnostics -Werror -XDwarnOnAccessToSensitiveMembers WarnSerializableLambdaTest.java
- */
-
-import java.io.Serializable;
-
-public class WarnSerializableLambdaTest {
-
- void warnLambda() throws Exception {
- SAM t3 = (SAM & Serializable)WarnSerializableLambdaTest::packageClassMethod;
- SAM t4 = (SAM & Serializable)WarnSerializableLambdaTest::protectedClassMethod;
- SAM t5 = (SAM & Serializable)WarnSerializableLambdaTest::privateClassMethod;
-
- WarnSerializableLambdaTest test = new WarnSerializableLambdaTest();
- SAM t6 = (SAM & Serializable)test::packageInstanceMethod;
- SAM t7 = (SAM & Serializable)test::protectedInstanceMethod;
- SAM t8 = (SAM & Serializable)test::privateInstanceMethod;
-
- SAM t9 = (SAM & Serializable) c -> {
-
- WarnSerializableLambdaTest.staticPackageField = "";
- WarnSerializableLambdaTest.staticProtectedField = "";
- WarnSerializableLambdaTest.staticPrivateField = "";
-
- packageField = "";
- protectedField = "";
- privateField = "";
-
- WarnSerializableLambdaTest.packageClassMethod(null);
- WarnSerializableLambdaTest.protectedClassMethod(null);
- WarnSerializableLambdaTest.privateClassMethod(null);
-
- packageInstanceMethod(null);
- protectedInstanceMethod(null);
- privateInstanceMethod(null);
-
- PrivateClass.effectivelyNonPublicStaticField = "";
- PrivateClass.effectivelyNonPublicClassMethod();
-
- PrivateClass p = new PrivateClass();
- p.effectivelyNonPublicInstanceField = "";
- p.effectivelyNonPublicInstanceMethod();
-
- return null;
- };
- }
-
- private void warnAnoInnerClass() throws Exception {
- new SerializableDesc() {
- public void m(Object param) throws Exception {
- WarnSerializableLambdaTest.staticPackageField = "";
- WarnSerializableLambdaTest.staticProtectedField = "";
- WarnSerializableLambdaTest.staticPrivateField = "";
-
- packageField = "";
- protectedField = "";
- privateField = "";
-
- WarnSerializableLambdaTest.packageClassMethod(null);
- WarnSerializableLambdaTest.protectedClassMethod(null);
- WarnSerializableLambdaTest.privateClassMethod(null);
-
- packageInstanceMethod(null);
- protectedInstanceMethod(null);
- privateInstanceMethod(null);
-
- PrivateClass.effectivelyNonPublicStaticField = "";
- PrivateClass.effectivelyNonPublicClassMethod();
-
- PrivateClass p = new PrivateClass();
- p.effectivelyNonPublicInstanceField = "";
- p.effectivelyNonPublicInstanceMethod();
- }
- };
- }
-
- void dontWarnLambda() throws Exception {
- SAM t1 = (SAM & Serializable)WarnSerializableLambdaTest::publicClassMethod;
-
- WarnSerializableLambdaTest test = new WarnSerializableLambdaTest();
- SAM t2 = (SAM & Serializable)test::publicInstanceMethod;
-
- int[] buffer = {0};
-
- SAM t3 = (SAM & Serializable) param -> {
- Object localVar;
- localVar = null;
- param = null;
-
- WarnSerializableLambdaTest.staticPublicField = "";
- publicField = "";
- WarnSerializableLambdaTest.publicClassMethod(null);
- publicInstanceMethod(null);
-
- PublicClass.effectivelyPublicStaticField = "";
- PublicClass.effectivelyPublicClassMethod();
-
- PublicClass p = new PublicClass();
- p.effectivelyPublicInstanceField = "";
- p.effectivelyPublicInstanceMethod();
-
- int l = buffer.length;
-
- return null;
- };
- }
-
- private void dontWarnAnoInnerClass() throws Exception {
- final int[] buffer = {0};
- new SerializableDesc() {
- public void m(Object param) throws Exception {
- Object localVar;
- localVar = null;
- param = null;
-
- WarnSerializableLambdaTest.staticPublicField = "";
- publicField = "";
- WarnSerializableLambdaTest.publicClassMethod(null);
- publicInstanceMethod(null);
-
- PublicClass.effectivelyPublicStaticField = "";
- PublicClass.effectivelyPublicClassMethod();
-
- PublicClass p = new PublicClass();
- p.effectivelyPublicInstanceField = "";
- p.effectivelyPublicInstanceMethod();
-
- int l = buffer.length;
- }
- };
- }
-
- enum WarnEnum {
- A {
- public void m() throws Exception {
- WarnSerializableLambdaTest.staticPackageField = "";
- WarnSerializableLambdaTest.staticProtectedField = "";
- WarnSerializableLambdaTest.staticPrivateField = "";
-
- WarnSerializableLambdaTest test =
- new WarnSerializableLambdaTest();
-
- test.packageField = "";
- test.protectedField = "";
- test.privateField = "";
-
- WarnSerializableLambdaTest.packageClassMethod(null);
- WarnSerializableLambdaTest.protectedClassMethod(null);
- WarnSerializableLambdaTest.privateClassMethod(null);
-
- test.packageInstanceMethod(null);
- test.protectedInstanceMethod(null);
- test.privateInstanceMethod(null);
-
- PrivateClass.effectivelyNonPublicStaticField = "";
- PrivateClass.effectivelyNonPublicClassMethod();
-
- PrivateClass p = new PrivateClass();
- p.effectivelyNonPublicInstanceField = "";
- p.effectivelyNonPublicInstanceMethod();
- }
- };
-
- public void m() throws Exception {}
- }
-
- static String staticPackageField;
- static private String staticPrivateField;
- static protected String staticProtectedField;
- static public String staticPublicField;
-
- String packageField;
- private String privateField;
- protected String protectedField;
- public String publicField;
-
- static Object packageClassMethod(String s) {
- return null;
- }
-
- static private Object privateClassMethod(String s) {
- return null;
- }
-
- static protected Object protectedClassMethod(String s) {
- return null;
- }
-
- static public Object publicClassMethod(String s) {
- return null;
- }
-
- Object packageInstanceMethod(String s) {
- return null;
- }
-
- protected Object protectedInstanceMethod(String s) {
- return null;
- }
-
- private Object privateInstanceMethod(String s) {
- return null;
- }
-
- public Object publicInstanceMethod(String s) {
- return null;
- }
-
- interface SAM {
- Object apply(String s) throws Exception;
- }
-
- interface SAM2 {
- Object apply(String arg1, String arg2);
- }
-
- class SerializableDesc implements Serializable {
- public void m(Object param) throws Exception {}
- }
-
- static private class PrivateClass {
- static public String effectivelyNonPublicStaticField;
- public String effectivelyNonPublicInstanceField;
-
- static public void effectivelyNonPublicClassMethod() {}
- public void effectivelyNonPublicInstanceMethod() {}
- }
-
- static public class PublicClass {
- static public String effectivelyPublicStaticField;
- public String effectivelyPublicInstanceField;
-
- static public void effectivelyPublicClassMethod() {}
- public void effectivelyPublicInstanceMethod() {}
- }
-}
--- a/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTest.out Wed Oct 26 15:46:13 2016 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-WarnSerializableLambdaTest.java:15:38: compiler.warn.access.to.sensitive.member.from.serializable.element: packageClassMethod(java.lang.String)
-WarnSerializableLambdaTest.java:16:38: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedClassMethod(java.lang.String)
-WarnSerializableLambdaTest.java:17:38: compiler.warn.access.to.sensitive.member.from.serializable.element: privateClassMethod(java.lang.String)
-WarnSerializableLambdaTest.java:20:38: compiler.warn.access.to.sensitive.member.from.serializable.element: packageInstanceMethod(java.lang.String)
-WarnSerializableLambdaTest.java:21:38: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedInstanceMethod(java.lang.String)
-WarnSerializableLambdaTest.java:22:38: compiler.warn.access.to.sensitive.member.from.serializable.element: privateInstanceMethod(java.lang.String)
-WarnSerializableLambdaTest.java:26:39: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPackageField
-WarnSerializableLambdaTest.java:27:39: compiler.warn.access.to.sensitive.member.from.serializable.element: staticProtectedField
-WarnSerializableLambdaTest.java:28:39: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPrivateField
-WarnSerializableLambdaTest.java:30:13: compiler.warn.access.to.sensitive.member.from.serializable.element: packageField
-WarnSerializableLambdaTest.java:31:13: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedField
-WarnSerializableLambdaTest.java:32:13: compiler.warn.access.to.sensitive.member.from.serializable.element: privateField
-WarnSerializableLambdaTest.java:34:39: compiler.warn.access.to.sensitive.member.from.serializable.element: packageClassMethod(java.lang.String)
-WarnSerializableLambdaTest.java:35:39: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedClassMethod(java.lang.String)
-WarnSerializableLambdaTest.java:36:39: compiler.warn.access.to.sensitive.member.from.serializable.element: privateClassMethod(java.lang.String)
-WarnSerializableLambdaTest.java:38:13: compiler.warn.access.to.sensitive.member.from.serializable.element: packageInstanceMethod(java.lang.String)
-WarnSerializableLambdaTest.java:39:13: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedInstanceMethod(java.lang.String)
-WarnSerializableLambdaTest.java:40:13: compiler.warn.access.to.sensitive.member.from.serializable.element: privateInstanceMethod(java.lang.String)
-WarnSerializableLambdaTest.java:42:25: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicStaticField
-WarnSerializableLambdaTest.java:43:25: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicClassMethod()
-WarnSerializableLambdaTest.java:46:14: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceField
-WarnSerializableLambdaTest.java:47:14: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceMethod()
-WarnSerializableLambdaTest.java:56:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPackageField
-WarnSerializableLambdaTest.java:57:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticProtectedField
-WarnSerializableLambdaTest.java:58:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPrivateField
-WarnSerializableLambdaTest.java:60:17: compiler.warn.access.to.sensitive.member.from.serializable.element: packageField
-WarnSerializableLambdaTest.java:61:17: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedField
-WarnSerializableLambdaTest.java:62:17: compiler.warn.access.to.sensitive.member.from.serializable.element: privateField
-WarnSerializableLambdaTest.java:64:43: compiler.warn.access.to.sensitive.member.from.serializable.element: packageClassMethod(java.lang.String)
-WarnSerializableLambdaTest.java:65:43: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedClassMethod(java.lang.String)
-WarnSerializableLambdaTest.java:66:43: compiler.warn.access.to.sensitive.member.from.serializable.element: privateClassMethod(java.lang.String)
-WarnSerializableLambdaTest.java:68:17: compiler.warn.access.to.sensitive.member.from.serializable.element: packageInstanceMethod(java.lang.String)
-WarnSerializableLambdaTest.java:69:17: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedInstanceMethod(java.lang.String)
-WarnSerializableLambdaTest.java:70:17: compiler.warn.access.to.sensitive.member.from.serializable.element: privateInstanceMethod(java.lang.String)
-WarnSerializableLambdaTest.java:72:29: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicStaticField
-WarnSerializableLambdaTest.java:73:29: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicClassMethod()
-WarnSerializableLambdaTest.java:76:18: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceField
-WarnSerializableLambdaTest.java:77:18: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceMethod()
-WarnSerializableLambdaTest.java:141:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPackageField
-WarnSerializableLambdaTest.java:142:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticProtectedField
-WarnSerializableLambdaTest.java:143:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPrivateField
-WarnSerializableLambdaTest.java:148:21: compiler.warn.access.to.sensitive.member.from.serializable.element: packageField
-WarnSerializableLambdaTest.java:149:21: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedField
-WarnSerializableLambdaTest.java:150:21: compiler.warn.access.to.sensitive.member.from.serializable.element: privateField
-WarnSerializableLambdaTest.java:152:43: compiler.warn.access.to.sensitive.member.from.serializable.element: packageClassMethod(java.lang.String)
-WarnSerializableLambdaTest.java:153:43: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedClassMethod(java.lang.String)
-WarnSerializableLambdaTest.java:154:43: compiler.warn.access.to.sensitive.member.from.serializable.element: privateClassMethod(java.lang.String)
-WarnSerializableLambdaTest.java:156:21: compiler.warn.access.to.sensitive.member.from.serializable.element: packageInstanceMethod(java.lang.String)
-WarnSerializableLambdaTest.java:157:21: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedInstanceMethod(java.lang.String)
-WarnSerializableLambdaTest.java:158:21: compiler.warn.access.to.sensitive.member.from.serializable.element: privateInstanceMethod(java.lang.String)
-WarnSerializableLambdaTest.java:160:29: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicStaticField
-WarnSerializableLambdaTest.java:161:29: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicClassMethod()
-WarnSerializableLambdaTest.java:164:18: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceField
-WarnSerializableLambdaTest.java:165:18: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceMethod()
-- compiler.err.warnings.and.werror
-1 error
-54 warnings
--- a/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestb.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestb.java Wed Oct 26 20:13:29 2016 +0000
@@ -4,7 +4,7 @@
* @summary Enhance compiler warnings for Lambda
* Checks that the warning for accessing non public members of a class is
* fired correctly.
- * @compile/fail/ref=WarnSerializableLambdaTestb.out -XDrawDiagnostics -Werror -XDwarnOnAccessToSensitiveMembers WarnSerializableLambdaTestb.java
+ * @compile/fail/ref=WarnSerializableLambdaTestb.out -XDrawDiagnostics -Werror -XDwarnOnAccessToMembers WarnSerializableLambdaTestb.java
*/
import java.io.Serializable;
--- a/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestb.out Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestb.out Wed Oct 26 20:13:29 2016 +0000
@@ -1,7 +1,5 @@
-WarnSerializableLambdaTestb.java:14:69: compiler.warn.access.to.sensitive.member.from.serializable.element: test()
-WarnSerializableLambdaTestb.java:18:69: compiler.warn.access.to.sensitive.member.from.serializable.element: test()
-WarnSerializableLambdaTestb.java:36:40: compiler.warn.access.to.sensitive.member.from.serializable.element: j
-WarnSerializableLambdaTestb.java:50:25: compiler.warn.access.to.sensitive.member.from.serializable.element: r
+WarnSerializableLambdaTestb.java:36:40: compiler.warn.access.to.member.from.serializable.element: j
+WarnSerializableLambdaTestb.java:50:25: compiler.warn.access.to.member.from.serializable.element: r
- compiler.err.warnings.and.werror
1 error
-4 warnings
+2 warnings
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestc.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,20 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8026721
+ * @summary Enhance Lambda serialization
+ * Checks that the warning for accessing non public members of a class is fired correctly.
+ * @compile -Xlint:serial -Werror WarnSerializableLambdaTestc.java
+ */
+
+import javax.tools.SimpleJavaFileObject;
+import java.io.Serializable;
+
+public class WarnSerializableLambdaTestc {
+ public interface SerializableIntf<T> extends Serializable {
+ String get(T o);
+ }
+
+ private void dontWarn() {
+ SerializableIntf<SimpleJavaFileObject> s = SimpleJavaFileObject::getName;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestc.out Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,4 @@
+WarnSerializableLambdaTestc.java:18:52: compiler.warn.access.to.member.from.serializable.lambda
+- compiler.err.warnings.and.werror
+1 error
+1 warning
--- a/langtools/test/tools/javac/api/ToolProvider/ToolProviderTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/test/tools/javac/api/ToolProvider/ToolProviderTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -21,8 +21,11 @@
* questions.
*/
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Objects;
import javax.tools.ToolProvider;
-import java.util.Objects;
/**
* @test
@@ -36,6 +39,18 @@
// run in other vm to ensure the initialization code path is exercised.
public class ToolProviderTest {
public static void main(String... args) {
+ // The following code allows the test to be skipped when run on
+ // an exploded image.
+ // See https://bugs.openjdk.java.net/browse/JDK-8155858
+ Path javaHome = Paths.get(System.getProperty("java.home"));
+ Path image = javaHome.resolve("lib").resolve("modules");
+ Path modules = javaHome.resolve("modules");
+ if (!Files.exists(image) && Files.exists(modules)) {
+ System.err.println("Test running on exploded image");
+ System.err.println("Test skipped!");
+ return;
+ }
+
System.setSecurityManager(new SecurityManager());
Objects.requireNonNull(ToolProvider.getSystemDocumentationTool());
--- a/langtools/test/tools/javac/diags/CheckResourceKeys.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/test/tools/javac/diags/CheckResourceKeys.java Wed Oct 26 20:13:29 2016 +0000
@@ -257,6 +257,8 @@
// ignore package and class names
if (cs.matches("(com|java|javax|jdk|sun)\\.[A-Za-z.]+"))
continue;
+ if (cs.matches("(java|javax|sun)\\."))
+ continue;
// ignore debug flag names
if (cs.startsWith("debug."))
continue;
--- a/langtools/test/tools/javac/diags/examples.not-yet.txt Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/test/tools/javac/diags/examples.not-yet.txt Wed Oct 26 20:13:29 2016 +0000
@@ -111,6 +111,7 @@
compiler.err.cant.inherit.from.anon # error for subclass of anonymous class
compiler.misc.bad.class.file # class file is malformed
compiler.misc.bad.const.pool.entry # constant pool entry has wrong type
+compiler.warn.access.to.member.from.serializable.lambda # in order to generate it we need to modify a restricted package
# The following module-related messages will have to stay on the not-yet list for various reasons:
compiler.warn.locn.unknown.file.on.module.path # Never issued ATM (short circuited with an if (false))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RemovalFilename.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+// key: compiler.note.removal.filename
+// key: compiler.note.removal.recompile
+// options: -Xlint:-removal
+
+class RemovalFilename {
+ RemovalClass d;
+}
+
+@Deprecated(forRemoval=true)
+class RemovalClass { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RemovalFilenameAdditional.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+// key: compiler.note.removal.filename.additional
+// key: compiler.warn.has.been.deprecated.for.removal
+// options: -Xmaxwarns 1
+
+class RemovalFilename {
+ RemovalClass d;
+}
+
+class RemovalFilenameAdditional {
+ RemovalClass d;
+}
+
+@Deprecated(forRemoval=true)
+class RemovalClass { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RemovalPlural/RemovalClass.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+@Deprecated(forRemoval=true)
+class RemovalClass { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RemovalPlural/RemovalFilename.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+class RemovalFileName {
+ RemovalClass d;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RemovalPlural/RemovalPlural.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+// key: compiler.note.removal.plural
+// key: compiler.note.removal.recompile
+// options: -Xlint:-removal
+
+class RemovalPlural {
+ RemovalClass d;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RemovalPluralAdditional/RemovalClass.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+@Deprecated(forRemoval=true)
+class RemovalClass { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RemovalPluralAdditional/RemovalFilename.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+class RemovalFileName {
+ RemovalClass d;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RemovalPluralAdditional/RemovalPlural.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+class RemovalPlural {
+ RemovalClass d;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RemovalPluralAdditional/RemovalPluralAdditional.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+// key: compiler.note.removal.plural.additional
+// key: compiler.warn.has.been.deprecated.for.removal
+// options: -Xlint:deprecation -Xmaxwarns 1
+
+class RemovalPluralAdditional {
+ RemovalClass d;
+}
--- a/langtools/test/tools/javac/diags/examples/WarnSerializableLambda.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/test/tools/javac/diags/examples/WarnSerializableLambda.java Wed Oct 26 20:13:29 2016 +0000
@@ -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
@@ -21,21 +21,24 @@
* questions.
*/
-// key: compiler.warn.access.to.sensitive.member.from.serializable.element
-// options: -XDwarnOnAccessToSensitiveMembers
+// key: compiler.warn.access.to.member.from.serializable.element
+// options: -XDwarnOnAccessToMembers
import java.io.Serializable;
public class WarnSerializableLambda {
- interface SAM {
- void apply(String s);
- }
-
private void m1() {
- SAM s = (SAM & Serializable) c -> {
- packageField = "";
+ new SerializableClass() {
+ @Override
+ public void m() {
+ packageField = "";
+ }
};
}
String packageField;
+
+ class SerializableClass implements Serializable {
+ public void m() {}
+ }
}
--- a/langtools/test/tools/javac/generics/rawOverride/7062745/GenericOverrideTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/test/tools/javac/generics/rawOverride/7062745/GenericOverrideTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -120,10 +120,10 @@
}
}
- boolean moreSpecificThan(TypeArgumentKind that, boolean strict) {
+ boolean moreSpecificThan(TypeArgumentKind that) {
switch (this) {
case NONE:
- return that == this || !strict;
+ return that == this;
case UNBOUND:
return that == this || that == NONE;
case INTEGER:
@@ -198,6 +198,7 @@
void check(Result<?> res) {
boolean errorExpected = false;
+ boolean loose = false;
int mostSpecific = 0;
//first check that either |R1| <: |R2| or |R2| <: |R1|
@@ -208,39 +209,43 @@
} else {
mostSpecific = rets[0].moreSpecificThan(rets[1]) ? 1 : 2;
}
+ } else if (sigs[0] != sigs[1]) {
+ mostSpecific = sigs[0] == SignatureKind.GENERIC ? 2 : 1;
+ loose = true;
}
//check that either TA1 <= TA2 or TA2 <= TA1 (unless most specific return found above is raw)
if (!errorExpected) {
if (targs[0] != targs[1]) {
- boolean useStrictCheck = targs[0].moreSpecificThan(targs[1], true) ||
- targs[1].moreSpecificThan(targs[0], true);
- if (!targs[0].moreSpecificThan(targs[1], useStrictCheck) &&
- !targs[1].moreSpecificThan(targs[0], useStrictCheck)) {
+ boolean ta1ms = targs[0].moreSpecificThan(targs[1]);
+ boolean ta2ms = targs[1].moreSpecificThan(targs[0]);
+ if (!ta1ms && !ta2ms) {
errorExpected = true;
+ } else if (mostSpecific != 0) {
+ errorExpected = !loose && targs[mostSpecific - 1] != TypeArgumentKind.NONE &&
+ (mostSpecific == 1 ? !ta1ms : !ta2ms);
} else {
- int mostSpecific2 = targs[0].moreSpecificThan(targs[1], useStrictCheck) ? 1 : 2;
- if (mostSpecific != 0 && mostSpecific2 != mostSpecific) {
- errorExpected = mostSpecific == 1 ?
- targs[0] != TypeArgumentKind.NONE :
- targs[1] != TypeArgumentKind.NONE;
- } else {
- mostSpecific = mostSpecific2;
- }
+ mostSpecific = ta1ms ? 1 : 2;
}
- } else if (mostSpecific == 0) {
- //when no signature is better than the other, an arbitrary choice
- //must be made - javac always picks the second signature
- mostSpecific = 2;
}
}
- //finally, check that most specific return type is compatible with expected type
+ if (mostSpecific == 0) {
+ //when no signature is better than the other, an arbitrary choice
+ //must be made - javac always picks the second signature
+ mostSpecific = 2;
+ }
+
if (!errorExpected) {
ReturnTypeKind msrt = mostSpecific == 1 ? rets[0] : rets[1];
TypeArgumentKind msta = mostSpecific == 1 ? targs[0] : targs[1];
SignatureKind mssig = mostSpecific == 1 ? sigs[0] : sigs[1];
+ //check that most specific is subsignature
+ errorExpected = sigs[0] != sigs[1] &&
+ mssig == SignatureKind.GENERIC;
+
+ //finally, check that most specific return type is compatible with expected type
if (!msrt.moreSpecificThan(rets[2]) ||
!msta.assignableTo(targs[2], mssig, level)) {
errorExpected = true;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/8168480/T8168480.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,125 @@
+/*
+ * @test
+ * @bug 8168480
+ * @summary Speculative attribution of lambda causes NPE in Flow
+ * @compile T8168480.java
+ */
+
+import java.util.function.Supplier;
+
+class T8168480 {
+ void f(Runnable r) { }
+ void s(Supplier<Runnable> r) { }
+
+ private void testVoid(boolean cond) {
+ f(() ->
+ new Runnable() {
+ public void run() {
+ switch (42) {
+ default:
+ break;
+ }
+ }
+ }.run());
+
+ f(() ->
+ f(() -> {
+ switch (42) {
+ default:
+ break;
+ }
+ }));
+
+ f(() -> {
+ if (cond) {
+ new Runnable() {
+ public void run() {
+ switch (42) {
+ default:
+ break;
+ }
+ }
+ }.run();
+ } else {
+ f(() -> {
+ switch (42) {
+ default:
+ break;
+ }
+ });
+ }
+ });
+ }
+
+ private void testReturn(boolean cond) {
+ s(() ->
+ new Runnable() {
+ public void run() {
+ switch (42) {
+ default:
+ break;
+ }
+ }
+ });
+
+ s(() ->
+ () -> {
+ switch (42) {
+ default:
+ break;
+ }
+ });
+
+ s(() -> {
+ if (cond) {
+ return new Runnable() {
+ public void run() {
+ switch (42) {
+ default:
+ break;
+ }
+ }
+ };
+ } else {
+ return () -> {
+ switch (42) {
+ default:
+ break;
+ }
+ };
+ }
+ });
+
+ s(() -> {
+ return cond ?
+ new Runnable() {
+ public void run() {
+ switch (42) {
+ default:
+ break;
+ }
+ }
+ } : () -> {
+ switch (42) {
+ default:
+ break;
+ }
+ };
+ });
+
+ s(() -> cond ?
+ new Runnable() {
+ public void run() {
+ switch (42) {
+ default:
+ break;
+ }
+ }
+ } : () -> {
+ switch (42) {
+ default:
+ break;
+ }
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/8168480/T8168480b.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,12 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8168480
+ * @summary Speculative attribution of lambda causes NPE in Flow
+ * @compile/fail/ref=T8168480b.out -XDrawDiagnostics T8168480b.java
+ */
+
+import java.util.function.Supplier;
+
+class T8168480b {
+ Supplier<Runnable> ssr = () -> () -> { while (true); System.err.println("Hello"); };
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/8168480/T8168480b.out Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,2 @@
+T8168480b.java:11:57: compiler.err.unreachable.stmt
+1 error
--- a/langtools/test/tools/javac/lambda/intersection/IntersectionTargetTypeTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/test/tools/javac/lambda/intersection/IntersectionTargetTypeTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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,6 +26,7 @@
* @bug 8002099 8010822
* @summary Add support for intersection types in cast expression
* @modules jdk.compiler/com.sun.tools.javac.util
+ * @run main/othervm IntersectionTargetTypeTest
*/
import com.sun.source.util.JavacTask;
--- a/langtools/test/tools/javac/modules/EdgeCases.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/test/tools/javac/modules/EdgeCases.java Wed Oct 26 20:13:29 2016 +0000
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8154283
+ * @bug 8154283 8167320
* @summary tests for multi-module mode compilation
* @library /tools/lib
* @modules
@@ -54,6 +54,7 @@
//import com.sun.source.util.JavacTask; // conflicts with toolbox.JavacTask
import com.sun.tools.javac.api.JavacTaskImpl;
import com.sun.tools.javac.code.Symbol.ModuleSymbol;
+import com.sun.tools.javac.code.Symtab;
import toolbox.JarTask;
import toolbox.JavacTask;
@@ -449,4 +450,12 @@
}
}
+ @Test
+ public void testGetDirectivesComplete(Path base) throws Exception {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ JavacTaskImpl task = (JavacTaskImpl) compiler.getTask(null, null, null, null, null, null);
+ Symtab syms = Symtab.instance(task.getContext());
+
+ syms.java_base.getDirectives();
+ }
}
--- a/langtools/test/tools/javac/modules/ModulePathTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/test/tools/javac/modules/ModulePathTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -29,7 +29,7 @@
* jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
* jdk.jdeps/com.sun.tools.javap
- * jdk.jlink/jdk.tools.jmod
+ * jdk.jlink
* @build toolbox.ToolBox toolbox.JarTask toolbox.JavacTask toolbox.ModuleBuilder
* ModuleTestBase
* @run main ModulePathTest
@@ -39,6 +39,7 @@
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.util.spi.ToolProvider;
import toolbox.JarTask;
import toolbox.JavacTask;
@@ -420,6 +421,9 @@
"--class-path", dir.toString(),
jmod.toString()
};
- jdk.tools.jmod.Main.run(args, System.out);
+ ToolProvider jmodTool = ToolProvider.findFirst("jmod").orElseThrow(() ->
+ new RuntimeException("jmod tool not found")
+ );
+ jmodTool.run(System.out, System.err, args);
}
}
--- a/langtools/test/tools/javac/processing/model/testgetallmembers/Main.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/test/tools/javac/processing/model/testgetallmembers/Main.java Wed Oct 26 20:13:29 2016 +0000
@@ -31,6 +31,7 @@
*/
import java.io.File;
+import java.nio.file.Path;
import java.util.*;
import java.util.Map.Entry;
@@ -84,7 +85,9 @@
continue;
if (type.endsWith("module-info"))
continue;
- String moduleName = fm.asPath(file).getName(1).toString();
+ Path path = fm.asPath(file);
+ int moduleIndex = path.getNameCount() - type.split("\\Q.\\E").length - 1;
+ String moduleName = path.getName(moduleIndex).toString();
try {
ModuleElement me = elements.getModuleElement(moduleName);
me.getClass();
--- a/langtools/test/tools/javac/processing/rounds/OverwriteBetweenCompilations.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/test/tools/javac/processing/rounds/OverwriteBetweenCompilations.java Wed Oct 26 20:13:29 2016 +0000
@@ -25,7 +25,7 @@
* @test
* @bug 8038455
* @summary Verify that annotation processor can overwrite source and class files it generated
- * during previous compilations, and that the Symbols are updated appropriatelly.
+ * during previous compilations, and that the Symbols are updated appropriately.
* @library /tools/lib /tools/javac/lib/
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
--- a/langtools/test/tools/javac/profiles/ProfileOptionTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/test/tools/javac/profiles/ProfileOptionTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -176,9 +176,14 @@
Arrays.asList(fo));
task.analyze();
- List<String> expectDiagCodes = (p.value >= e.getKey().value)
- ? Collections.<String>emptyList()
- : Arrays.asList("compiler.err.not.in.profile");
+ List<String> expectDiagCodes = new ArrayList<>();
+ if (fo.getName().equals("TPolicyFile.java")) {
+ expectDiagCodes.add("compiler.warn.has.been.deprecated.for.removal");
+ }
+
+ if (p.value < e.getKey().value) {
+ expectDiagCodes.add("compiler.err.not.in.profile");
+ }
checkDiags(opts + " " + fo.getName(), dl.getDiagnostics(), expectDiagCodes);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/Removal.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,544 @@
+/*
+ * 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 8145471
+ * @summary javac changes for enhanced deprecation
+ * @library /tools/lib
+ * @modules jdk.compiler/com.sun.tools.javac.api
+ * @modules jdk.compiler/com.sun.tools.javac.main
+ * @build toolbox.JavacTask toolbox.TestRunner toolbox.ToolBox
+ * @run main Removal
+ */
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.EnumMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import toolbox.JavacTask;
+import toolbox.Task.Expect;
+import toolbox.Task.OutputKind;
+import toolbox.TestRunner;
+import toolbox.ToolBox;
+
+/*
+ * From JEP 277, JDK-8085614
+ *
+ * use site | API declaration site
+ * context | not dep. ord. dep. term. dep.
+ * +----------------------------------
+ * not dep. | N W W
+ * |
+ * ord. dep. | N N (2) W (4)
+ * |
+ * term. dep. | N N (3) W (5)
+ */
+
+public class Removal extends TestRunner {
+ public static void main(String... args) throws Exception {
+ Removal r = new Removal();
+ r.runTests(m -> new Object[] { Paths.get(m.getName()) });
+ r.report();
+ }
+
+ private final ToolBox tb = new ToolBox();
+ private final Path libSrc = Paths.get("lib").resolve("src");
+ private final Path libClasses = Paths.get("lib").resolve("classes");
+ int testCount = 0;
+
+ /**
+ * Options that may be used during compilation.
+ */
+ enum Options {
+ DEFAULT(),
+ XLINT_DEPRECATED("-Xlint:deprecation"),
+ XLINT_NO_REMOVAL("-Xlint:-removal");
+
+ Options(String... opts) {
+ this.opts = Arrays.asList(opts);
+ }
+
+ final List<String> opts;
+ }
+
+ /**
+ * The kind of deprecation.
+ */
+ enum DeprKind {
+ NONE("", null),
+ DEPRECATED("@Deprecated ", "compiler.warn.has.been.deprecated"),
+ REMOVAL("@Deprecated(forRemoval=true) ", "compiler.warn.has.been.deprecated.for.removal");
+ DeprKind(String anno, String warn) {
+ this.anno = anno;
+ this.warn = warn;
+ }
+ final String anno;
+ final String warn;
+ }
+
+ final String[] lib = {
+ "package lib; public class Class {\n"
+ + " public static void method() { }\n"
+ + " @Deprecated public static void depMethod() { }\n"
+ + " @Deprecated(forRemoval=true) public static void remMethod() { }\n"
+ + " public static int field;\n"
+ + " @Deprecated public static int depField;\n"
+ + " @Deprecated(forRemoval=true) public static int remField;\n"
+ + "}",
+ "package lib; @Deprecated public class DepClass { }",
+ "package lib; @Deprecated(forRemoval=true) public class RemClass { }"
+ };
+
+ /**
+ * The kind of declaration to be referenced at the use site.
+ */
+ enum RefKind {
+ CLASS("lib.%s c;", "Class", "DepClass", "RemClass"),
+ METHOD("{ lib.Class.%s(); }", "method", "depMethod", "remMethod"),
+ FIELD("int i = lib.Class.%s;", "field", "depField", "remField");
+
+ RefKind(String template, String def, String dep, String rem) {
+ fragments.put(DeprKind.NONE, String.format(template, def));
+ fragments.put(DeprKind.DEPRECATED, String.format(template, dep));
+ fragments.put(DeprKind.REMOVAL, String.format(template, rem));
+ }
+
+ String getFragment(DeprKind k) {
+ return fragments.get(k);
+ }
+
+ private final Map<DeprKind, String> fragments = new EnumMap<>(DeprKind.class);
+ }
+
+ /**
+ * Get source code for a reference to a possibly-deprecated item declared in a library.
+ * @param refKind the kind of element (class, method, field) being referenced
+ * @param declDeprKind the kind of deprecation on the declaration of the item being referenced
+ * @param useDeprKind the kind of deprecation enclosing the use site
+ * @return
+ */
+ static String getSource(RefKind refKind, DeprKind declDeprKind, DeprKind useDeprKind) {
+ return "package p; "
+ + useDeprKind.anno
+ + "class Class { "
+ + refKind.getFragment(declDeprKind)
+ + " }";
+ }
+
+ private static final String NO_OUTPUT = null;
+
+ public Removal() throws IOException {
+ super(System.err);
+ initLib();
+ }
+
+ void initLib() throws IOException {
+ tb.writeJavaFiles(libSrc, lib);
+
+ new JavacTask(tb)
+ .outdir(Files.createDirectories(libClasses))
+ .files(tb.findJavaFiles(libSrc))
+ .run()
+ .writeAll();
+ }
+
+ void report() {
+ out.println(testCount + " test cases");
+ }
+
+ /*
+ * Declaration site: not deprecated; use site: not deprecated
+ * Options: default
+ * Expect: no warnings
+ */
+ @Test
+ public void test_DeclNone_UseNone(Path base) throws IOException {
+ for (RefKind rk : RefKind.values()) {
+ test(base,
+ getSource(rk, DeprKind.NONE, DeprKind.NONE),
+ Options.DEFAULT,
+ NO_OUTPUT);
+ }
+ }
+
+ /*
+ * Declaration site: not deprecated; use site: deprecated
+ * Options: default
+ * Expect: no warnings
+ */
+ @Test
+ public void test_DeclNone_UseDeprecated(Path base) throws IOException {
+ for (RefKind rk : RefKind.values()) {
+ test(base,
+ getSource(rk, DeprKind.NONE, DeprKind.DEPRECATED),
+ Options.DEFAULT,
+ NO_OUTPUT);
+ }
+ }
+
+ /*
+ * Declaration site: not deprecated; use site: deprecated for removal
+ * Options: default
+ * Expect: no warnings
+ */
+ @Test
+ public void test_DeclNone_UseRemoval(Path base) throws IOException {
+ for (RefKind rk : RefKind.values()) {
+ test(base,
+ getSource(rk, DeprKind.NONE, DeprKind.REMOVAL),
+ Options.DEFAULT,
+ NO_OUTPUT);
+ }
+ }
+
+ /*
+ * Declaration site: deprecated; use site: not deprecated
+ * Options: default
+ * Expect: deprecated note
+ */
+ @Test
+ public void test_DeclDeprecated_UseNone_Default(Path base) throws IOException {
+ for (RefKind rk : RefKind.values()) {
+ test(base,
+ getSource(rk, DeprKind.DEPRECATED, DeprKind.NONE),
+ Options.DEFAULT,
+ "compiler.note.deprecated.filename: Class.java");
+ }
+ }
+
+ /*
+ * Declaration site: deprecated; use site: not deprecated
+ * Options: -Xlint:deprecation
+ * Expect: deprecated warning
+ */
+ @Test
+ public void test_DeclDeprecated_UseNone_XlintDep(Path base) throws IOException {
+ for (RefKind rk : RefKind.values()) {
+ String error = "<unset>";
+ switch (rk) {
+ case CLASS:
+ error = "Class.java:1:29: compiler.warn.has.been.deprecated: lib.DepClass, lib";
+ break;
+
+ case METHOD:
+ error = "Class.java:1:37: compiler.warn.has.been.deprecated: depMethod(), lib.Class";
+ break;
+
+ case FIELD:
+ error = "Class.java:1:43: compiler.warn.has.been.deprecated: depField, lib.Class";
+ break;
+ }
+
+ test(base,
+ getSource(rk, DeprKind.DEPRECATED, DeprKind.NONE),
+ Options.XLINT_DEPRECATED,
+ error);
+ }
+ }
+
+ /*
+ * Declaration site: deprecated; use site: deprecated
+ * Options: default
+ * Expect: no warnings
+ */
+ @Test
+ public void test_DeclDeprecated_UseDeprecated(Path base) throws IOException {
+ for (RefKind rk : RefKind.values()) {
+ test(base,
+ getSource(rk, DeprKind.DEPRECATED, DeprKind.DEPRECATED),
+ Options.DEFAULT,
+ NO_OUTPUT);
+ }
+ }
+
+ /*
+ * Declaration site: deprecated; use site: deprecated for removal
+ * Options: default
+ * Expect: no warnings
+ */
+ @Test
+ public void test_DeclDeprecated_UseRemoval(Path base) throws IOException {
+ for (RefKind rk : RefKind.values()) {
+ test(base,
+ getSource(rk, DeprKind.DEPRECATED, DeprKind.REMOVAL),
+ Options.DEFAULT,
+ NO_OUTPUT);
+ }
+ }
+
+ /*
+ * Declaration site: deprecated for removal; use site: not deprecated
+ * Options: default
+ * Expect: removal warning
+ */
+ @Test
+ public void test_DeclRemoval_UseNone_Default(Path base) throws IOException {
+ for (RefKind rk : RefKind.values()) {
+ String error = "<unset>";
+ switch (rk) {
+ case CLASS:
+ error = "Class.java:1:29: compiler.warn.has.been.deprecated.for.removal: lib.RemClass, lib";
+ break;
+
+ case METHOD:
+ error = "Class.java:1:37: compiler.warn.has.been.deprecated.for.removal: remMethod(), lib.Class";
+ break;
+
+ case FIELD:
+ error = "Class.java:1:43: compiler.warn.has.been.deprecated.for.removal: remField, lib.Class";
+ break;
+ }
+
+ test(base,
+ getSource(rk, DeprKind.REMOVAL, DeprKind.NONE),
+ Options.DEFAULT,
+ error);
+ }
+ }
+
+ /*
+ * Declaration site: deprecated for removal; use site: not deprecated
+ * Options: default, @SuppressWarnings("removal")
+ * Expect: removal warning
+ */
+ @Test
+ public void test_DeclRemoval_UseNone_SuppressRemoval(Path base) throws IOException {
+ for (RefKind rk : RefKind.values()) {
+ String source =
+ getSource(rk, DeprKind.REMOVAL, DeprKind.NONE)
+ .replace("class Class", "@SuppressWarnings(\"removal\") class Class");
+
+ test(base,
+ source,
+ Options.DEFAULT,
+ null);
+ }
+ }
+
+ /*
+ * Declaration site: deprecated for removal; use site: not deprecated
+ * Options: -Xlint:-removal
+ * Expect: removal note
+ */
+ @Test
+ public void test_DeclRemoval_UseNone_XlintNoRemoval(Path base) throws IOException {
+ for (RefKind rk : RefKind.values()) {
+ test(base,
+ getSource(rk, DeprKind.REMOVAL, DeprKind.NONE),
+ Options.XLINT_NO_REMOVAL,
+ "compiler.note.removal.filename: Class.java");
+ }
+ }
+
+ /*
+ * Declaration site: deprecated for removal; use site: deprecated
+ * Options: default
+ * Expect: removal warning
+ */
+ @Test
+ public void test_DeclRemoval_UseDeprecated_Default(Path base) throws IOException {
+ for (RefKind rk : RefKind.values()) {
+ String error = "<unset>";
+ switch (rk) {
+ case CLASS:
+ error = "Class.java:1:41: compiler.warn.has.been.deprecated.for.removal: lib.RemClass, lib";
+ break;
+
+ case METHOD:
+ error = "Class.java:1:49: compiler.warn.has.been.deprecated.for.removal: remMethod(), lib.Class";
+ break;
+
+ case FIELD:
+ error = "Class.java:1:55: compiler.warn.has.been.deprecated.for.removal: remField, lib.Class";
+ break;
+ }
+
+ test(base,
+ getSource(rk, DeprKind.REMOVAL, DeprKind.DEPRECATED),
+ Options.DEFAULT,
+ error);
+ }
+ }
+
+ /*
+ * Declaration site: deprecated for removal; use site: deprecated
+ * Options: -Xlint:-removal
+ * Expect: removal note
+ */
+ @Test
+ public void test_DeclRemoval_UseDeprecated_XlintNoRemoval(Path base) throws IOException {
+ for (RefKind rk : RefKind.values()) {
+ test(base,
+ getSource(rk, DeprKind.REMOVAL, DeprKind.DEPRECATED),
+ Options.XLINT_NO_REMOVAL,
+ "compiler.note.removal.filename: Class.java");
+ }
+ }
+
+ /*
+ * Declaration site: deprecated for removal; use site: deprecated for removal
+ * Options: default
+ * Expect: removal warning
+ */
+ @Test
+ public void test_DeclRemoval_UseRemoval_Default(Path base) throws IOException {
+ for (RefKind rk : RefKind.values()) {
+ String error = "<unset>";
+ switch (rk) {
+ case CLASS:
+ error = "Class.java:1:58: compiler.warn.has.been.deprecated.for.removal: lib.RemClass, lib";
+ break;
+
+ case METHOD:
+ error = "Class.java:1:66: compiler.warn.has.been.deprecated.for.removal: remMethod(), lib.Class";
+ break;
+
+ case FIELD:
+ error = "Class.java:1:72: compiler.warn.has.been.deprecated.for.removal: remField, lib.Class";
+ break;
+ }
+
+ test(base,
+ getSource(rk, DeprKind.REMOVAL, DeprKind.REMOVAL),
+ Options.DEFAULT,
+ error);
+ }
+ }
+
+ /*
+ * Declaration site: deprecated for removal; use site: deprecated for removal
+ * Options: -Xlint:-removal
+ * Expect: removal note
+ */
+ @Test
+ public void test_DeclRemoval_UseRemoval_XlintNoRemoval(Path base) throws IOException {
+ for (RefKind rk : RefKind.values()) {
+ test(base,
+ getSource(rk, DeprKind.REMOVAL, DeprKind.REMOVAL),
+ Options.XLINT_NO_REMOVAL,
+ "compiler.note.removal.filename: Class.java");
+ }
+ }
+
+ /*
+ * Additional special case:
+ * there should not be any warnings for any reference in a type-import statement.
+ */
+ @Test
+ public void test_UseImports(Path base) throws IOException {
+ String source =
+ "import lib.Class;\n"
+ + "import lib.DepClass;\n"
+ + "import lib.RemClass;\n"
+ + "class C { }";
+ for (Options o : Options.values()) {
+ test(base, source, o, NO_OUTPUT);
+ }
+ }
+
+ /**
+ * Compile source code with given options, and check for expected output.
+ * The compilation is done twice, first against the library in source form,
+ * and then again, against the compiled library.
+ * @param base base working directory
+ * @param source the source code to be compiled
+ * @param options the options for the compilation
+ * @param expectText the expected output, or NO_OUTPUT, if none expected.
+ * @throws IOException if an error occurs during the compilation
+ */
+ private void test(Path base, String source, Options options, String expectText) throws IOException {
+ test(base.resolve("lib-source"), libSrc, source, options, expectText);
+ test(base.resolve("lib-classes"), libClasses, source, options, expectText);
+ }
+
+ /**
+ * Compile source code with given options against a given version of the library,
+ * and check for expected output.
+ * @param base base working directory
+ * @param lib the directory containing the library, in either source or compiled form
+ * @param source the source code to be compiled
+ * @param options the options for the compilation
+ * @param expectText the expected output, or NO_OUTPUT, if none expected.
+ * @throws IOException if an error occurs during the compilation
+ */
+ private void test(Path base, Path lib, String source, Options options, String expectText)
+ throws IOException {
+ Expect expect = (expectText != null && expectText.contains("compiler.warn.")) ? Expect.FAIL : Expect.SUCCESS;
+ test(base, lib, source, options.opts, expect, expectText);
+ }
+
+ /**
+ * Compile source code with given options against a given version of the library,
+ * and check for expected exit code and expected output.
+ * @param base base working directory
+ * @param lib the directory containing the library, in either source or compiled form
+ * @param source the source code to be compiled
+ * @param options the options for the compilation
+ * @param expect the expected outcome of the compilation
+ * @param expectText the expected output, or NO_OUTPUT, if none expected.
+ * @throws IOException if an error occurs during the compilation
+ */
+ private void test(Path base, Path lib, String source, List<String> options,
+ Expect expect, String expectText) throws IOException {
+ testCount++;
+
+ Path src = base.resolve("src");
+ Path classes = Files.createDirectories(base.resolve("classes"));
+ tb.writeJavaFiles(src, source);
+
+ List<String> allOptions = new ArrayList<>();
+ allOptions.add("-XDrawDiagnostics");
+ allOptions.add("-Werror");
+ allOptions.addAll(options);
+
+ out.println("Source: " + source);
+ out.println("Classpath: " + lib);
+ out.println("Options: " + options.stream().collect(Collectors.joining(" ")));
+
+ String log = new JavacTask(tb)
+ .outdir(classes)
+ .classpath(lib) // use classpath for libSrc or libClasses
+ .files(tb.findJavaFiles(src))
+ .options(allOptions.toArray(new String[0]))
+ .run(expect)
+ .writeAll()
+ .getOutput(OutputKind.DIRECT);
+
+ if (expectText == null) {
+ if (!log.trim().isEmpty())
+ error("Unexpected text found: >>>" + log + "<<<");
+ } else {
+ if (!log.contains(expectText))
+ error("expected text not found: >>>" + expectText + "<<<");
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/jdeprscan/tests/jdk/jdeprscan/TestRelease.java Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,58 @@
+/*
+ * 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 8167965
+ * @summary Test proper handling of the --release option.
+ * @modules jdk.jdeps/com.sun.tools.jdeprscan
+ * @build jdk.jdeprscan.TestRelease
+ * @run testng jdk.jdeprscan.TestRelease
+ */
+
+package jdk.jdeprscan;
+
+import com.sun.tools.jdeprscan.Main;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+public class TestRelease {
+ static boolean invoke(String arg) {
+ return Main.call(System.out, System.err, "--list", "--release", arg);
+ }
+
+ @Test
+ public void testSuccess() {
+ assertTrue(invoke("6"));
+ assertTrue(invoke("7"));
+ assertTrue(invoke("8"));
+ assertTrue(invoke("9"));
+ }
+
+ @Test
+ public void testFailure() {
+ assertFalse(invoke("5"));
+ }
+}
--- a/langtools/test/tools/lib/toolbox/JavadocTask.java Wed Oct 26 15:46:13 2016 -0400
+++ b/langtools/test/tools/lib/toolbox/JavadocTask.java Wed Oct 26 20:13:29 2016 +0000
@@ -38,7 +38,9 @@
import java.util.stream.Stream;
import javax.tools.DocumentationTool.DocumentationTask;
+import javax.tools.DocumentationTool;
import javax.tools.JavaFileManager;
+import javax.tools.JavaFileManager.Location;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
@@ -303,7 +305,8 @@
if (fileManager == null)
fileManager = internalFileManager = jdtool.getStandardFileManager(null, null, null);
if (outdir != null)
- setLocationFromPaths(StandardLocation.CLASS_OUTPUT, Collections.singletonList(outdir));
+ setLocationFromPaths(DocumentationTool.Location.DOCUMENTATION_OUTPUT,
+ Collections.singletonList(outdir));
if (classpath != null)
setLocationFromPaths(StandardLocation.CLASS_PATH, classpath);
if (sourcepath != null)
@@ -326,7 +329,7 @@
}
}
- private void setLocationFromPaths(StandardLocation location, List<Path> files) throws IOException {
+ private void setLocationFromPaths(Location location, List<Path> files) throws IOException {
if (!(fileManager instanceof StandardJavaFileManager))
throw new IllegalStateException("not a StandardJavaFileManager");
((StandardJavaFileManager) fileManager).setLocationFromPaths(location, files);
--- a/make/CopyImportModules.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/make/CopyImportModules.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -41,14 +41,14 @@
ifeq ($(OPENJDK_TARGET_OS), windows)
TO_BIN_FILTER := %$(SHARED_LIBRARY_SUFFIX) %.diz %.pdb %.map
- $(eval $(call SetupCopyFiles,COPY_LIBS_TO_BIN, \
+ $(eval $(call SetupCopyFiles, COPY_LIBS_TO_BIN, \
SRC := $(LIBS_DIR), \
DEST := $(JDK_OUTPUTDIR)/bin, \
FILES := $(filter $(TO_BIN_FILTER), \
$(call CacheFind, $(LIBS_DIR))) \
))
- $(eval $(call SetupCopyFiles,COPY_LIBS_TO_LIB, \
+ $(eval $(call SetupCopyFiles, COPY_LIBS_TO_LIB, \
SRC := $(LIBS_DIR), \
DEST := $(JDK_OUTPUTDIR)/lib, \
FILES := $(filter-out $(TO_BIN_FILTER), \
--- a/make/CreateBuildJdkCopy.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/make/CreateBuildJdkCopy.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -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
--- a/make/CreateJmods.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/make/CreateJmods.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -44,6 +44,10 @@
CONF_DIR := $(firstword $(wildcard $(addsuffix /$(MODULE), \
$(SUPPORT_OUTPUTDIR)/modules_conf $(IMPORT_MODULES_CONF))))
CLASSES_DIR := $(wildcard $(JDK_OUTPUTDIR)/modules/$(MODULE))
+INCLUDE_HEADERS_DIR := $(firstword $(wildcard $(addsuffix /$(MODULE), \
+ $(SUPPORT_OUTPUTDIR)/modules_include $(IMPORT_MODULES_INCLUDE_HEADERS))))
+MAN_DIR := $(firstword $(wildcard $(addsuffix /$(MODULE), \
+ $(SUPPORT_OUTPUTDIR)/modules_man $(IMPORT_MODULES_MAN))))
$(eval $(call FillCacheFind, \
$(LIBS_DIR) $(CMDS_DIR) $(CONF_DIR) $(CLASSES_DIR) \
@@ -65,6 +69,14 @@
JMOD_FLAGS += --class-path $(CLASSES_DIR)
DEPS += $(call CacheFind, $(CLASSES_DIR))
endif
+ifneq ($(INCLUDE_HEADERS_DIR), )
+ JMOD_FLAGS += --header-files $(INCLUDE_HEADERS_DIR)
+ DEPS += $(call CacheFind, $(INCLUDE_HEADERS_DIR))
+endif
+ifneq ($(MAN_DIR), )
+ JMOD_FLAGS += --man-pages $(MAN_DIR)
+ DEPS += $(call CacheFind, $(MAN_DIR))
+endif
# Add dependencies on other jmod files. Only java.base needs access to other
# jmods.
@@ -103,7 +115,7 @@
--os-arch $(OPENJDK_TARGET_CPU_LEGACY) \
--os-version $(REQUIRED_OS_VERSION) \
--module-path $(JMODS_DIR) \
- --exclude '**{_the.*,*.diz,*.debuginfo,*.dSYM/**,*.dSYM,*.pdb,*.map}' \
+ --exclude '**{_the.*,*.diz,*.debuginfo,*.dSYM/**,*.dSYM,*.pdb,*.map}' \
$(JMOD_FLAGS) $(SUPPORT_OUTPUTDIR)/jmods/$(notdir $@)
$(MV) $(SUPPORT_OUTPUTDIR)/jmods/$(notdir $@) $@
--- a/make/GensrcModuleInfo.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/make/GensrcModuleInfo.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -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
--- a/make/Images.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/make/Images.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -131,35 +131,41 @@
$(JLINK_JLI_CLASSES) \
#
+JLINK_JRE_EXTRA_OPTS := --no-man-pages --no-header-files
+
ifeq ($(JLINK_KEEP_PACKAGED_MODULES), true)
- JLINK_EXTRA_OPTS := --keep-packaged-modules $(JDK_IMAGE_DIR)/jmods
+ JLINK_JDK_EXTRA_OPTS := --keep-packaged-modules $(JDK_IMAGE_DIR)/jmods
endif
$(JDK_IMAGE_DIR)/$(JIMAGE_TARGET_FILE): $(JMODS) \
$(call DependOnVariable, JDK_MODULES_LIST) $(BASE_RELEASE_FILE)
$(ECHO) Creating jdk jimage
$(RM) -r $(JDK_IMAGE_DIR)
- $(JLINK_TOOL) --output $(JDK_IMAGE_DIR) \
- --add-modules $(JDK_MODULES_LIST) $(JLINK_EXTRA_OPTS)
+ $(JLINK_TOOL) --add-modules $(JDK_MODULES_LIST) \
+ $(JLINK_JDK_EXTRA_OPTS) \
+ --output $(JDK_IMAGE_DIR)
$(TOUCH) $@
$(JRE_IMAGE_DIR)/$(JIMAGE_TARGET_FILE): $(JMODS) \
$(call DependOnVariable, JRE_MODULES_LIST) $(BASE_RELEASE_FILE)
$(ECHO) Creating jre jimage
$(RM) -r $(JRE_IMAGE_DIR)
- $(JLINK_TOOL) --output $(JRE_IMAGE_DIR) \
- --add-modules $(JRE_MODULES_LIST)
+ $(JLINK_TOOL) --add-modules $(JRE_MODULES_LIST) \
+ $(JLINK_JRE_EXTRA_OPTS) \
+ --output $(JRE_IMAGE_DIR)
$(TOUCH) $@
JRE_COMPACT1_IMAGE_DIR := $(JRE_IMAGE_DIR)-compact1
JRE_COMPACT2_IMAGE_DIR := $(JRE_IMAGE_DIR)-compact2
JRE_COMPACT3_IMAGE_DIR := $(JRE_IMAGE_DIR)-compact3
+
$(JRE_COMPACT1_IMAGE_DIR)/$(JIMAGE_TARGET_FILE): $(JMODS) \
$(call DependOnVariable, JRE_COMPACT1_MODULES_LIST) $(BASE_RELEASE_FILE)
$(ECHO) Creating jre compact1 jimage
$(RM) -r $(JRE_COMPACT1_IMAGE_DIR)
$(JLINK_TOOL) --add-modules $(JRE_COMPACT1_MODULES_LIST) \
+ $(JLINK_JRE_EXTRA_OPTS) \
--output $(JRE_COMPACT1_IMAGE_DIR)
$(TOUCH) $@
@@ -168,6 +174,7 @@
$(ECHO) Creating jre compact2 jimage
$(RM) -r $(JRE_COMPACT2_IMAGE_DIR)
$(JLINK_TOOL) --add-modules $(JRE_COMPACT2_MODULES_LIST) \
+ $(JLINK_JRE_EXTRA_OPTS) \
--output $(JRE_COMPACT2_IMAGE_DIR)
$(TOUCH) $@
@@ -176,6 +183,7 @@
$(ECHO) Creating jre compact3 jimage
$(RM) -r $(JRE_COMPACT3_IMAGE_DIR)
$(JLINK_TOOL) --add-modules $(JRE_COMPACT3_MODULES_LIST) \
+ $(JLINK_JRE_EXTRA_OPTS) \
--output $(JRE_COMPACT3_IMAGE_DIR)
$(TOUCH) $@
@@ -313,16 +321,6 @@
endif # Windows
################################################################################
-# /include dir
-
-$(eval $(call SetupCopyFiles,COPY_INCLUDES, \
- SRC := $(JDK_OUTPUTDIR)/include, \
- DEST := $(JDK_IMAGE_DIR)/include, \
- FILES := $(call CacheFind,$(JDK_OUTPUTDIR)/include)))
-
-JDK_TARGETS += $(COPY_INCLUDES)
-
-################################################################################
# doc files
JRE_DOC_FILES ?= LICENSE ASSEMBLY_EXCEPTION THIRD_PARTY_README
@@ -412,7 +410,7 @@
################################################################################
# /sample dir
-$(eval $(call SetupCopyFiles,COPY_SAMPLES, \
+$(eval $(call SetupCopyFiles, COPY_SAMPLES, \
SRC := $(SUPPORT_OUTPUTDIR)/sample/image, \
DEST := $(JDK_IMAGE_DIR)/sample, \
FILES := $(if $(wildcard $(SUPPORT_OUTPUTDIR)/sample/image), \
--- a/make/Init.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/make/Init.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 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
--- a/make/InitSupport.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/make/InitSupport.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
--- a/make/Jprt.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/make/Jprt.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 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
--- a/make/JrtfsJar.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/make/JrtfsJar.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2014, 2015, 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
@@ -46,7 +46,7 @@
jdk/internal/jrtfs \
#
-$(eval $(call SetupJavaCompilation,BUILD_JRTFS, \
+$(eval $(call SetupJavaCompilation, BUILD_JRTFS, \
SETUP := GENERATE_OLDBYTECODE, \
SRC := $(JDK_TOPDIR)/src/java.base/share/classes, \
EXCLUDE_FILES := module-info.java, \
@@ -57,7 +57,7 @@
# file will not be copied unless META-INF/services would also be added to the INCLUDES.
# Adding META-INF/services would include all files in that directory when only the one
# is needed, which is why this explicit copy is defined instead.
-$(eval $(call SetupCopyFiles,COPY_JIMAGE_SERVICE_PROVIDER, \
+$(eval $(call SetupCopyFiles, COPY_JIMAGE_SERVICE_PROVIDER, \
SRC := $(JDK_TOPDIR)/src/java.base/share/classes, \
DEST := $(SUPPORT_OUTPUTDIR)/jrtfs_classes, \
FILES := META-INF/services/java.nio.file.spi.FileSystemProvider))
--- a/make/MacBundles.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/make/MacBundles.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
--- a/make/Main.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/make/Main.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -237,7 +237,7 @@
# Build hotspot target
ifeq ($(BUILD_HOTSPOT),true)
-hotspot:
+ hotspot:
+($(CD) $(HOTSPOT_TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f BuildHotspot.gmk)
endif
@@ -548,7 +548,7 @@
# The demos are currently linking to libjvm and libjava, just like all other
# jdk libs, even though they don't need to. To avoid warnings, make sure they
# aren't built until after libjava and libjvm are available to link to.
- demos-jdk: $(JAVA_TARGETS)
+ demos-jdk: java.base-libs exploded-image-optimize
# Declare dependency from <module>-java to <module>-gensrc
$(foreach m, $(GENSRC_MODULES), $(eval $m-java: $m-gensrc))
@@ -698,7 +698,7 @@
test-make: clean-test-make
- build-test-lib: java
+ build-test-lib: exploded-image-optimize
build-test-failure-handler: interim-langtools
--- a/make/common/CORE_PKGS.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/make/common/CORE_PKGS.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2001, 2015, 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
--- a/make/common/JarArchive.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/make/common/JarArchive.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
@@ -242,7 +242,7 @@
# potential changes.
$$(if $$(filter $$($1_VARDEPS_FILE) $$($1_MANIFEST), $$?), \
$$(if $$($1_MANIFEST), \
- $(SED) -e '$(DOLLAR)$(DOLLAR)a\' $$($1_MANIFEST) > $$($1_MANIFEST_FILE) $$(NEWLINE) \
+ $(CP) $$($1_MANIFEST) $$($1_MANIFEST_FILE) $$(NEWLINE) \
, \
$(RM) $$($1_MANIFEST_FILE) && $(TOUCH) $$($1_MANIFEST_FILE) $$(NEWLINE)) \
$$(if $$($1_JARMAIN), \
--- a/make/common/JavaCompilation.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/make/common/JavaCompilation.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
--- a/make/common/NON_CORE_PKGS.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/make/common/NON_CORE_PKGS.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2002, 2015, 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
--- a/make/common/SetupJavaCompilers.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/make/common/SetupJavaCompilers.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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 @@
include JavaCompilation.gmk
-DISABLE_WARNINGS := -Xlint:all,-deprecation,-unchecked,-rawtypes,-cast,-serial,-dep-ann,-static,-fallthrough,-try,-varargs,-empty,-finally
+DISABLE_WARNINGS := -Xlint:all,-deprecation,-removal,-unchecked,-rawtypes,-cast,-serial,-dep-ann,-static,-fallthrough,-try,-varargs,-empty,-finally
# If warnings needs to be non-fatal for testing purposes use a command like:
# make JAVAC_WARNINGS="-Xlint:all -Xmaxwarns 10000"
-JAVAC_WARNINGS := -Xlint:all -Werror
+JAVAC_WARNINGS := -Xlint:all,-removal -Werror
# The BOOT_JAVAC setup uses the boot jdk compiler to compile the tools
# and the interim javac, to be run by the boot jdk.
--- a/make/devkit/Tools.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/make/devkit/Tools.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2013, 2015, 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
--- a/make/devkit/createWindowsDevkit.sh Wed Oct 26 15:46:13 2016 -0400
+++ b/make/devkit/createWindowsDevkit.sh Wed Oct 26 20:13:29 2016 +0000
@@ -1,6 +1,6 @@
#!/bin/bash
#
-# 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
--- a/nashorn/.hgtags Wed Oct 26 15:46:13 2016 -0400
+++ b/nashorn/.hgtags Wed Oct 26 20:13:29 2016 +0000
@@ -373,3 +373,5 @@
17ed43add2f9e3528686cd786ae2ed49c8ed36e9 jdk-9+137
4a6ee1185fc821df063e4d1537fa7ad2ebe9eb02 jdk-9+138
e3b11296395b39bfeb3364f26c2ef77fa652e300 jdk-9+139
+785843878cf78d50cc2959ea2c5a4202bbe885b4 jdk-9+140
+a46b7d3867957a868a6cc8ee66c05079b883733a jdk-9+141
--- a/nashorn/make/BuildNashorn.gmk Wed Oct 26 15:46:13 2016 -0400
+++ b/nashorn/make/BuildNashorn.gmk Wed Oct 26 20:13:29 2016 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2010, 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
--- a/nashorn/src/jdk.dynalink/share/classes/jdk/dynalink/beans/CallerSensitiveDynamicMethod.java Wed Oct 26 15:46:13 2016 -0400
+++ b/nashorn/src/jdk.dynalink/share/classes/jdk/dynalink/beans/CallerSensitiveDynamicMethod.java Wed Oct 26 20:13:29 2016 +0000
@@ -100,7 +100,6 @@
import jdk.dynalink.SecureLookupSupplier;
import jdk.dynalink.internal.AccessControlContextFactory;
import jdk.dynalink.linker.support.Lookup;
-import jdk.internal.module.Modules;
import jdk.internal.reflect.CallerSensitive;
@@ -180,57 +179,10 @@
}
private static MethodHandle unreflect(final MethodHandles.Lookup lookup, final Method m) {
- try {
- return Lookup.unreflect(lookup, m);
- } catch (final IllegalAccessError iae) {
- if (addModuleRead(lookup, m)) {
- try {
- return Lookup.unreflect(lookup, m);
- } catch (final IllegalAccessError e2) {
- // fall through and throw original error as cause
- }
- }
- throw iae;
- }
+ return Lookup.unreflect(lookup, m);
}
private static MethodHandle unreflectConstructor(final MethodHandles.Lookup lookup, final Constructor<?> c) {
- try {
- return Lookup.unreflectConstructor(lookup, c);
- } catch (final IllegalAccessError iae) {
- if (addModuleRead(lookup, c)) {
- try {
- return Lookup.unreflectConstructor(lookup, c);
- } catch (final IllegalAccessError e2) {
- // fall through and throw original error as cause
- }
- }
- throw iae;
- }
- }
-
-
- private static boolean addModuleRead(final MethodHandles.Lookup lookup, final Executable e) {
- // Don't add module read link if this is not a CallerSensitive member
- if (!e.isAnnotationPresent(CallerSensitive.class)) {
- return false;
- }
-
- // If the lookup is public lookup, don't bother adding module read link!
- // public lookup cannot unreflect caller sensitives anyway!
- if (lookup == MethodHandles.publicLookup()) {
- return false;
- }
-
- // try to add missing module read from using module to declararing module!
- final Class<?> declClass = e.getDeclaringClass();
- final Module useModule = lookup.lookupClass().getModule();
- final Module declModule = declClass.getModule();
- if (useModule != null && declModule != null && declModule.isExported(declClass.getPackageName())) {
- Modules.addReads(useModule, declModule);
- return true;
- }
-
- return false;
+ return Lookup.unreflectConstructor(lookup, c);
}
}
--- a/nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Console.java Wed Oct 26 15:46:13 2016 -0400
+++ b/nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Console.java Wed Oct 26 20:13:29 2016 +0000
@@ -42,6 +42,8 @@
import jdk.internal.jline.console.ConsoleReader;
import jdk.internal.jline.console.KeyMap;
import jdk.internal.jline.extra.EditingHistory;
+import jdk.internal.misc.Signal;
+import jdk.internal.misc.Signal.Handler;
class Console implements AutoCloseable {
private static final String DOCUMENTATION_SHORTCUT = "\033\133\132"; //Shift-TAB
@@ -68,6 +70,21 @@
in.addCompleter(completer);
Runtime.getRuntime().addShutdownHook(new Thread((Runnable)this::saveHistory));
bind(DOCUMENTATION_SHORTCUT, (ActionListener)evt -> showDocumentation(docHelper));
+ try {
+ Signal.handle(new Signal("CONT"), new Handler() {
+ @Override public void handle(Signal sig) {
+ try {
+ in.getTerminal().reset();
+ in.redrawLine();
+ in.flush();
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+ });
+ } catch (IllegalArgumentException ignored) {
+ //the CONT signal does not exist on this platform
+ }
}
String readLine(final String prompt) throws IOException {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java Wed Oct 26 15:46:13 2016 -0400
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java Wed Oct 26 20:13:29 2016 +0000
@@ -129,10 +129,11 @@
@Override
public String getProgram(final String... statements) {
+ Objects.requireNonNull(statements);
final StringBuilder sb = new StringBuilder();
for (final String statement : statements) {
- sb.append(statement).append(';');
+ sb.append(Objects.requireNonNull(statement)).append(';');
}
return sb.toString();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/ArrayIterator.java Wed Oct 26 15:46:13 2016 -0400
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/ArrayIterator.java Wed Oct 26 20:13:29 2016 +0000
@@ -47,13 +47,25 @@
private final Global global;
- ArrayIterator(final Object iteratedObject, final IterationKind iterationKind, final Global global) {
+ private ArrayIterator(final Object iteratedObject, final IterationKind iterationKind, final Global global) {
super(global.getArrayIteratorPrototype(), $nasgenmap$);
this.iteratedObject = iteratedObject instanceof ScriptObject ? (ScriptObject) iteratedObject : null;
this.iterationKind = iterationKind;
this.global = global;
}
+ static ArrayIterator newArrayValueIterator(final Object iteratedObject) {
+ return new ArrayIterator(Global.toObject(iteratedObject), IterationKind.VALUE, Global.instance());
+ }
+
+ static ArrayIterator newArrayKeyIterator(final Object iteratedObject) {
+ return new ArrayIterator(Global.toObject(iteratedObject), IterationKind.KEY, Global.instance());
+ }
+
+ static ArrayIterator newArrayKeyValueIterator(final Object iteratedObject) {
+ return new ArrayIterator(Global.toObject(iteratedObject), IterationKind.KEY_VALUE, Global.instance());
+ }
+
/**
* 22.1.5.2.1 %ArrayIteratorPrototype%.next()
*
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeArray.java Wed Oct 26 15:46:13 2016 -0400
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeArray.java Wed Oct 26 20:13:29 2016 +0000
@@ -1726,7 +1726,7 @@
*/
@Function(attributes = Attribute.NOT_ENUMERABLE)
public static Object entries(final Object self) {
- return new ArrayIterator(Global.toObject(self), AbstractIterator.IterationKind.KEY_VALUE, Global.instance());
+ return ArrayIterator.newArrayKeyValueIterator(self);
}
/**
@@ -1737,7 +1737,7 @@
*/
@Function(attributes = Attribute.NOT_ENUMERABLE)
public static Object keys(final Object self) {
- return new ArrayIterator(Global.toObject(self), AbstractIterator.IterationKind.KEY, Global.instance());
+ return ArrayIterator.newArrayKeyIterator(self);
}
/**
@@ -1748,7 +1748,7 @@
*/
@Function(attributes = Attribute.NOT_ENUMERABLE)
public static Object values(final Object self) {
- return new ArrayIterator(Global.toObject(self), AbstractIterator.IterationKind.VALUE, Global.instance());
+ return ArrayIterator.newArrayValueIterator(self);
}
/**
@@ -1759,7 +1759,7 @@
*/
@Function(attributes = Attribute.NOT_ENUMERABLE, name = "@@iterator")
public static Object getIterator(final Object self) {
- return new ArrayIterator(Global.toObject(self), AbstractIterator.IterationKind.VALUE, Global.instance());
+ return ArrayIterator.newArrayValueIterator(self);
}
/**
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFloat32Array.java Wed Oct 26 15:46:13 2016 -0400
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFloat32Array.java Wed Oct 26 20:13:29 2016 +0000
@@ -232,6 +232,17 @@
return (NativeFloat32Array)ArrayBufferView.subarrayImpl(self, begin, end);
}
+ /**
+ * ECMA 6 22.2.3.30 %TypedArray%.prototype [ @@iterator ] ( )
+ *
+ * @param self the self reference
+ * @return an iterator over the array's values
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE, name = "@@iterator")
+ public static Object getIterator(final Object self) {
+ return ArrayIterator.newArrayValueIterator(self);
+ }
+
@Override
protected ScriptObject getPrototype(final Global global) {
return global.getFloat32ArrayPrototype();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFloat64Array.java Wed Oct 26 15:46:13 2016 -0400
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFloat64Array.java Wed Oct 26 20:13:29 2016 +0000
@@ -232,6 +232,17 @@
return (NativeFloat64Array)ArrayBufferView.subarrayImpl(self, begin, end);
}
+ /**
+ * ECMA 6 22.2.3.30 %TypedArray%.prototype [ @@iterator ] ( )
+ *
+ * @param self the self reference
+ * @return an iterator over the array's values
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE, name = "@@iterator")
+ public static Object getIterator(final Object self) {
+ return ArrayIterator.newArrayValueIterator(self);
+ }
+
@Override
protected ScriptObject getPrototype(final Global global) {
return global.getFloat64ArrayPrototype();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt16Array.java Wed Oct 26 15:46:13 2016 -0400
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt16Array.java Wed Oct 26 20:13:29 2016 +0000
@@ -225,6 +225,17 @@
return (NativeInt16Array)ArrayBufferView.subarrayImpl(self, begin, end);
}
+ /**
+ * ECMA 6 22.2.3.30 %TypedArray%.prototype [ @@iterator ] ( )
+ *
+ * @param self the self reference
+ * @return an iterator over the array's values
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE, name = "@@iterator")
+ public static Object getIterator(final Object self) {
+ return ArrayIterator.newArrayValueIterator(self);
+ }
+
@Override
protected ScriptObject getPrototype(final Global global) {
return global.getInt16ArrayPrototype();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt32Array.java Wed Oct 26 15:46:13 2016 -0400
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt32Array.java Wed Oct 26 20:13:29 2016 +0000
@@ -224,6 +224,17 @@
return (NativeInt32Array)ArrayBufferView.subarrayImpl(self, begin, end);
}
+ /**
+ * ECMA 6 22.2.3.30 %TypedArray%.prototype [ @@iterator ] ( )
+ *
+ * @param self the self reference
+ * @return an iterator over the array's values
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE, name = "@@iterator")
+ public static Object getIterator(final Object self) {
+ return ArrayIterator.newArrayValueIterator(self);
+ }
+
@Override
protected ScriptObject getPrototype(final Global global) {
return global.getInt32ArrayPrototype();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt8Array.java Wed Oct 26 15:46:13 2016 -0400
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt8Array.java Wed Oct 26 20:13:29 2016 +0000
@@ -224,6 +224,17 @@
return (NativeInt8Array)ArrayBufferView.subarrayImpl(self, begin, end);
}
+ /**
+ * ECMA 6 22.2.3.30 %TypedArray%.prototype [ @@iterator ] ( )
+ *
+ * @param self the self reference
+ * @return an iterator over the array's values
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE, name = "@@iterator")
+ public static Object getIterator(final Object self) {
+ return ArrayIterator.newArrayValueIterator(self);
+ }
+
@Override
protected ScriptObject getPrototype(final Global global) {
return global.getInt8ArrayPrototype();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeRegExp.java Wed Oct 26 15:46:13 2016 -0400
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeRegExp.java Wed Oct 26 20:13:29 2016 +0000
@@ -701,13 +701,9 @@
}
thisIndex = matcher.end();
- if (thisIndex == string.length() && matcher.start() == matcher.end()) {
- // Avoid getting empty match at end of string twice
- break;
- }
- // ECMA 15.5.4.10 String.prototype.match(regexp)
- if (thisIndex == previousLastIndex) {
+ // ECMA6 21.2.5.6 step 8.g.iv.5: If matchStr is empty advance index by one
+ if (matcher.start() == matcher.end()) {
setLastIndex(thisIndex + 1);
previousLastIndex = thisIndex + 1;
} else {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint16Array.java Wed Oct 26 15:46:13 2016 -0400
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint16Array.java Wed Oct 26 20:13:29 2016 +0000
@@ -229,6 +229,17 @@
return (NativeUint16Array)ArrayBufferView.subarrayImpl(self, begin, end);
}
+ /**
+ * ECMA 6 22.2.3.30 %TypedArray%.prototype [ @@iterator ] ( )
+ *
+ * @param self the self reference
+ * @return an iterator over the array's values
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE, name = "@@iterator")
+ public static Object getIterator(final Object self) {
+ return ArrayIterator.newArrayValueIterator(self);
+ }
+
@Override
protected ScriptObject getPrototype(final Global global) {
return global.getUint16ArrayPrototype();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint32Array.java Wed Oct 26 15:46:13 2016 -0400
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint32Array.java Wed Oct 26 20:13:29 2016 +0000
@@ -244,6 +244,17 @@
return (NativeUint32Array)ArrayBufferView.subarrayImpl(self, begin, end);
}
+ /**
+ * ECMA 6 22.2.3.30 %TypedArray%.prototype [ @@iterator ] ( )
+ *
+ * @param self the self reference
+ * @return an iterator over the array's values
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE, name = "@@iterator")
+ public static Object getIterator(final Object self) {
+ return ArrayIterator.newArrayValueIterator(self);
+ }
+
@Override
protected ScriptObject getPrototype(final Global global) {
return global.getUint32ArrayPrototype();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint8Array.java Wed Oct 26 15:46:13 2016 -0400
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint8Array.java Wed Oct 26 20:13:29 2016 +0000
@@ -230,6 +230,17 @@
return (NativeUint8Array)ArrayBufferView.subarrayImpl(self, begin, end);
}
+ /**
+ * ECMA 6 22.2.3.30 %TypedArray%.prototype [ @@iterator ] ( )
+ *
+ * @param self the self reference
+ * @return an iterator over the array's values
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE, name = "@@iterator")
+ public static Object getIterator(final Object self) {
+ return ArrayIterator.newArrayValueIterator(self);
+ }
+
@Override
protected ScriptObject getPrototype(final Global global) {
return global.getUint8ArrayPrototype();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java Wed Oct 26 15:46:13 2016 -0400
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java Wed Oct 26 20:13:29 2016 +0000
@@ -82,7 +82,6 @@
private static final MethodHandle SET_ELEM = specialCall(MethodHandles.lookup(), Uint8ClampedArrayData.class, "setElem", void.class, int.class, int.class).methodHandle();
private static final MethodHandle RINT_D = staticCall(MethodHandles.lookup(), Uint8ClampedArrayData.class, "rint", double.class, double.class).methodHandle();
private static final MethodHandle RINT_O = staticCall(MethodHandles.lookup(), Uint8ClampedArrayData.class, "rint", Object.class, Object.class).methodHandle();
- private static final MethodHandle CLAMP_LONG = staticCall(MethodHandles.lookup(), Uint8ClampedArrayData.class, "clampLong", long.class, long.class).methodHandle();
private Uint8ClampedArrayData(final ByteBuffer nb, final int start, final int end) {
super((nb.position(start).limit(end)).slice(), end - start);
@@ -124,8 +123,6 @@
return MH.filterArguments(setter, 2, RINT_O);
} else if (elementType == double.class) {
return MH.filterArguments(setter, 2, RINT_D);
- } else if (elementType == long.class) {
- return MH.filterArguments(setter, 2, CLAMP_LONG);
}
}
return setter;
@@ -195,7 +192,7 @@
@Override
public ArrayData set(final int index, final double value, final boolean strict) {
- return set(index, rint(value), strict);
+ return set(index, (int) rint(value), strict);
}
private static double rint(final double rint) {
@@ -207,15 +204,6 @@
return rint(JSType.toNumber(rint));
}
- @SuppressWarnings("unused")
- private static long clampLong(final long l) {
- if(l < 0L) {
- return 0L;
- } else if(l > 0xffL) {
- return 0xffL;
- }
- return l;
- }
}
/**
@@ -278,6 +266,17 @@
return (NativeUint8ClampedArray)ArrayBufferView.subarrayImpl(self, begin, end);
}
+ /**
+ * ECMA 6 22.2.3.30 %TypedArray%.prototype [ @@iterator ] ( )
+ *
+ * @param self the self reference
+ * @return an iterator over the array's values
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE, name = "@@iterator")
+ public static Object getIterator(final Object self) {
+ return ArrayIterator.newArrayValueIterator(self);
+ }
+
@Override
protected ScriptObject getPrototype(final Global global) {
return global.getUint8ClampedArrayPrototype();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java Wed Oct 26 15:46:13 2016 -0400
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java Wed Oct 26 20:13:29 2016 +0000
@@ -389,6 +389,15 @@
// is created, and invalidated forever once the second global is created.
private final AtomicReference<GlobalConstants> globalConstantsRef = new AtomicReference<>();
+ // Are java.sql, java.sql.rowset modules found in the system?
+ static final boolean javaSqlFound, javaSqlRowsetFound;
+
+ static {
+ final Layer boot = Layer.boot();
+ javaSqlFound = boot.findModule("java.sql").isPresent();
+ javaSqlRowsetFound = boot.findModule("java.sql.rowset").isPresent();
+ }
+
/**
* Get the current global scope
* @return the current global scope
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptLoader.java Wed Oct 26 15:46:13 2016 -0400
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptLoader.java Wed Oct 26 20:13:29 2016 +0000
@@ -68,12 +68,23 @@
private Module createModule(final String moduleName) {
final Module structMod = context.getStructLoader().getModule();
- final ModuleDescriptor descriptor
- = new ModuleDescriptor.Builder(moduleName)
+ final ModuleDescriptor.Builder builder =
+ new ModuleDescriptor.Builder(moduleName)
+ .requires("java.base")
+ .requires("java.logging")
.requires(NASHORN_MODULE.getName())
.requires(structMod.getName())
- .conceals(SCRIPTS_PKG)
- .build();
+ .conceals(SCRIPTS_PKG);
+
+ if (Context.javaSqlFound) {
+ builder.requires("java.sql");
+ }
+
+ if (Context.javaSqlRowsetFound) {
+ builder.requires("java.sql.rowset");
+ }
+
+ final ModuleDescriptor descriptor = builder.build();
final Module mod = Context.createModuleTrusted(structMod.getLayer(), descriptor, this);
loadModuleManipulator();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/StructureLoader.java Wed Oct 26 15:46:13 2016 -0400
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/StructureLoader.java Wed Oct 26 20:13:29 2016 +0000
@@ -64,6 +64,7 @@
private Module createModule(final String moduleName) {
final ModuleDescriptor descriptor
= new ModuleDescriptor.Builder(moduleName)
+ .requires("java.base")
.requires(NASHORN_MODULE.getName())
.conceals(SCRIPTS_PKG)
.build();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java Wed Oct 26 15:46:13 2016 -0400
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java Wed Oct 26 20:13:29 2016 +0000
@@ -78,14 +78,17 @@
prioritizedLinkers = new GuardingDynamicLinker[] {
new NashornLinker(),
new NashornPrimitiveLinker(),
- new NashornStaticClassLinker(beansLinker),
new BoundCallableLinker(),
new JavaSuperAdapterLinker(beansLinker),
new JSObjectLinker(nashornBeansLinker),
new BrowserJSObjectLinker(nashornBeansLinker),
new ReflectionCheckLinker()
};
- fallbackLinkers = new GuardingDynamicLinker[] {nashornBeansLinker, new NashornBottomLinker() };
+ fallbackLinkers = new GuardingDynamicLinker[] {
+ new NashornStaticClassLinker(beansLinker),
+ nashornBeansLinker,
+ new NashornBottomLinker()
+ };
}
// do not create me!!
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java Wed Oct 26 15:46:13 2016 -0400
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java Wed Oct 26 20:13:29 2016 +0000
@@ -68,7 +68,7 @@
@Override
public GuardedInvocation getGuardedInvocation(final LinkRequest request, final LinkerServices linkerServices) throws Exception {
final Object self = request.getReceiver();
- if (self.getClass() != StaticClass.class) {
+ if (self == null || self.getClass() != StaticClass.class) {
return null;
}
final Class<?> receiverClass = ((StaticClass) self).getRepresentedClass();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8164708.js Wed Oct 26 20:13:29 2016 +0000
@@ -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.
+ */
+
+/**
+ * JDK-8164708: String.prototype.replace replaces empty match twice
+ *
+ * @test
+ * @run
+ */
+
+Assert.assertEquals("4005".replace(/\B(?=(\d{3})+(?!\d))/g, ","), "4,005");
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8168146.js Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,37 @@
+/*
+ * 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-8168146: Infinite recursion in Uint8ClampedArray.set
+ *
+ * @test
+ * @run
+ */
+
+
+var a = new Uint8ClampedArray(10);
+
+for (var i = 0; i < 10; i++) {
+ a[i] = i;
+ Assert.assertTrue(a[i] === i);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/JDK-8168140.js Wed Oct 26 20:13:29 2016 +0000
@@ -0,0 +1,68 @@
+/*
+ * 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-8168140: TypedArrays should implement ES6 iterator protocol
+ *
+ * @test
+ * @run
+ * @option --language=es6
+ */
+
+let TypedArrayTypes = [
+ Int8Array,
+ Uint8Array,
+ Uint8ClampedArray,
+ Int16Array,
+ Uint16Array,
+ Int32Array,
+ Uint32Array,
+ Float32Array,
+ Float64Array
+];
+
+let arrays = [];
+let sum = 0;
+
+TypedArrayTypes.forEach(function(ArrayType) {
+ var a = new ArrayType(10);
+ for (let i = 0; i < a.length; i++) {
+ a[i] = i;
+ }
+ arrays.push(a);
+});
+
+Assert.assertTrue(arrays.length === 9);
+
+for (let array of arrays) {
+
+ Assert.assertTrue(array.length === 10);
+ let count = 0;
+
+ for (let value of array) {
+ Assert.assertTrue(value === count++);
+ sum += value;
+ }
+}
+
+Assert.assertTrue(sum === 405);
--- a/nashorn/test/src/jdk/dynalink/test/DynamicLinkerFactoryTest.java Wed Oct 26 15:46:13 2016 -0400
+++ b/nashorn/test/src/jdk/dynalink/test/DynamicLinkerFactoryTest.java Wed Oct 26 20:13:29 2016 +0000
@@ -39,6 +39,7 @@
import jdk.dynalink.NoSuchDynamicMethodException;
import jdk.dynalink.Operation;
import jdk.dynalink.StandardOperation;
+import jdk.dynalink.beans.StaticClass;
import jdk.dynalink.linker.GuardedInvocation;
import jdk.dynalink.linker.GuardingDynamicLinker;
import jdk.dynalink.linker.LinkRequest;
@@ -234,6 +235,15 @@
@Test
public void autoLoadedLinkerTest() {
+ testAutoLoadedLinkerInvoked(new Object(), "toString");
+ }
+
+ @Test
+ public void autoLoadedLinkerSeesStaticMethod() {
+ testAutoLoadedLinkerInvoked(StaticClass.forClass(System.class), "currentTimeMillis");
+ }
+
+ private static void testAutoLoadedLinkerInvoked(final Object target, final String methodName) {
final DynamicLinkerFactory factory = newDynamicLinkerFactory(false);
final DynamicLinker linker = factory.createLinker();
@@ -241,22 +251,21 @@
checkOneAutoLoadingError(factory);
final MethodType mt = MethodType.methodType(Object.class, Object.class);
- // create a callsite with TestLinkerOperation
- final CallSite cs = linker.link(new SimpleRelinkableCallSite(new CallSiteDescriptor(
- MethodHandles.publicLookup(), new TestLinkerOperation(), mt)));
- boolean reachedAutoLinker = false;
-
+ final CallSiteDescriptor testDescriptor = new CallSiteDescriptor(MethodHandles.publicLookup(),
+ new NamedOperation(StandardOperation.GET_METHOD, methodName), mt);
+ final CallSite cs = linker.link(new SimpleRelinkableCallSite(testDescriptor));
+ TrustedGuardingDynamicLinkerExporter.enable();
try {
- cs.getTarget().invoke(new Object());
- } catch (final ReachedAutoLoadedDynamicLinkerException e) {
- // TrustedGuardingDynamicLinkerExporter threw exception on TestLinkerOperation as expected!
- reachedAutoLinker = true;
+ cs.getTarget().invoke(target);
+ // The linker was loaded and it observed our invocation
+ Assert.assertTrue(TrustedGuardingDynamicLinkerExporter.isLastCallSiteDescriptor(testDescriptor));
} catch (final Throwable th) {
throw new RuntimeException(th);
+ } finally {
+ TrustedGuardingDynamicLinkerExporter.disable();
}
- Assert.assertTrue(reachedAutoLinker);
}
@Test
--- a/nashorn/test/src/jdk/dynalink/test/ReachedAutoLoadedDynamicLinkerException.java Wed Oct 26 15:46:13 2016 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. 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.dynalink.test;
-
-/**
- * Exception used to signal to the test method that the control has reached auto loaded
- * dynamic linker.
- */
-public final class ReachedAutoLoadedDynamicLinkerException extends RuntimeException {
-}
--- a/nashorn/test/src/jdk/dynalink/test/TestLinkerOperation.java Wed Oct 26 15:46:13 2016 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. 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.dynalink.test;
-
-import jdk.dynalink.Operation;
-
-public final class TestLinkerOperation implements Operation {
-}
--- a/nashorn/test/src/jdk/dynalink/test/TrustedGuardingDynamicLinkerExporter.java Wed Oct 26 15:46:13 2016 -0400
+++ b/nashorn/test/src/jdk/dynalink/test/TrustedGuardingDynamicLinkerExporter.java Wed Oct 26 20:13:29 2016 +0000
@@ -25,8 +25,8 @@
package jdk.dynalink.test;
-import java.util.ArrayList;
import java.util.List;
+import jdk.dynalink.CallSiteDescriptor;
import jdk.dynalink.linker.GuardingDynamicLinker;
import jdk.dynalink.linker.GuardingDynamicLinkerExporter;
import jdk.dynalink.linker.LinkRequest;
@@ -37,20 +37,32 @@
*/
public final class TrustedGuardingDynamicLinkerExporter extends GuardingDynamicLinkerExporter {
+ private static final ThreadLocal<CallSiteDescriptor> lastDescriptor = new ThreadLocal<>();
+ private static boolean enabled = false;
+
+ public static void enable() {
+ reset(true);
+ }
+
+ public static void disable() {
+ reset(false);
+ }
+ public static boolean isLastCallSiteDescriptor(final CallSiteDescriptor desc) {
+ return lastDescriptor.get() == desc;
+ }
+
+ private static void reset(final boolean enable) {
+ lastDescriptor.set(null);
+ enabled = enable;
+ }
+
@Override
public List<GuardingDynamicLinker> get() {
- final ArrayList<GuardingDynamicLinker> linkers = new ArrayList<>();
- linkers.add((GuardingDynamicLinker) (final LinkRequest linkRequest, final LinkerServices linkerServices) -> {
- // handle only the TestLinkerOperation instances
- if (linkRequest.getCallSiteDescriptor().getOperation() instanceof TestLinkerOperation) {
- System.out.println("inside " + this.getClass().getName());
- // throw exception to signal to the test method that the control has reached here!
- throw new ReachedAutoLoadedDynamicLinkerException();
- } else {
- // any other operation!
- return null;
+ return List.of(((GuardingDynamicLinker) (final LinkRequest linkRequest, final LinkerServices linkerServices) -> {
+ if (enabled) {
+ lastDescriptor.set(linkRequest.getCallSiteDescriptor());
}
- });
- return linkers;
+ return null;
+ }));
}
}
--- a/test/failure_handler/src/share/conf/common.properties Wed Oct 26 15:46:13 2016 -0400
+++ b/test/failure_handler/src/share/conf/common.properties Wed Oct 26 20:13:29 2016 +0000
@@ -34,9 +34,8 @@
jcmd.vm.classloader_stats jcmd.vm.stringtable \
jcmd.vm.symboltable jcmd.vm.uptime jcmd.vm.dynlibs \
jcmd.vm.system_properties \
- jcmd.gc.class_stats jcmd.gc.class_histogram \
- jstack \
- jmap.heap jmap.histo jmap.clstats jmap.finalizerinfo
+ jcmd.gc.heap_info jcmd.gc.class_stats jcmd.gc.class_histogram jcmd.gc.finalizer_info \
+ jstack
jinfo.app=jinfo
@@ -55,16 +54,12 @@
jcmd.gc.class_stats.args=%p GC.class_stats
jcmd.gc.class_histogram.args=%p GC.class_histogram
+jcmd.gc.finalizer_info.args=%p GC.finalizer_info
+jcmd.gc.heap_info.args=%p GC.heap_info
jstack.app=jstack
jstack.params.repeat=6
-jmap.app=jmap
-jmap.heap.args=-heap %p
-jmap.histo.args=-histo %p
-jmap.clstats.args=-clstats %p
-jmap.finalizerinfo.args=-finalizerinfo %p
-
################################################################################
# environment info to gather
################################################################################
--- a/test/lib/jdk/test/lib/cli/predicate/NotPredicate.java Wed Oct 26 15:46:13 2016 -0400
+++ b/test/lib/jdk/test/lib/cli/predicate/NotPredicate.java Wed Oct 26 20:13:29 2016 +0000
@@ -19,7 +19,6 @@
* 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.cli.predicate;
--- a/test/lib/jdk/test/lib/cli/predicate/OrPredicate.java Wed Oct 26 15:46:13 2016 -0400
+++ b/test/lib/jdk/test/lib/cli/predicate/OrPredicate.java Wed Oct 26 20:13:29 2016 +0000
@@ -19,7 +19,6 @@
* 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.cli.predicate;
--- a/test/lib/sun/hotspot/WhiteBox.java Wed Oct 26 15:46:13 2016 -0400
+++ b/test/lib/sun/hotspot/WhiteBox.java Wed Oct 26 20:13:29 2016 +0000
@@ -19,7 +19,6 @@
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
- *
*/
package sun.hotspot;
--- a/test/lib/sun/hotspot/code/BlobType.java Wed Oct 26 15:46:13 2016 -0400
+++ b/test/lib/sun/hotspot/code/BlobType.java Wed Oct 26 20:13:29 2016 +0000
@@ -19,7 +19,6 @@
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
- *
*/
package sun.hotspot.code;
--- a/test/lib/sun/hotspot/code/CodeBlob.java Wed Oct 26 15:46:13 2016 -0400
+++ b/test/lib/sun/hotspot/code/CodeBlob.java Wed Oct 26 20:13:29 2016 +0000
@@ -19,7 +19,6 @@
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
- *
*/
package sun.hotspot.code;
--- a/test/lib/sun/hotspot/code/NMethod.java Wed Oct 26 15:46:13 2016 -0400
+++ b/test/lib/sun/hotspot/code/NMethod.java Wed Oct 26 20:13:29 2016 +0000
@@ -19,7 +19,6 @@
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
- *
*/
package sun.hotspot.code;
--- a/test/lib/sun/hotspot/cpuinfo/CPUInfo.java Wed Oct 26 15:46:13 2016 -0400
+++ b/test/lib/sun/hotspot/cpuinfo/CPUInfo.java Wed Oct 26 20:13:29 2016 +0000
@@ -19,7 +19,6 @@
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
- *
*/
package sun.hotspot.cpuinfo;
--- a/test/lib/sun/hotspot/gc/GC.java Wed Oct 26 15:46:13 2016 -0400
+++ b/test/lib/sun/hotspot/gc/GC.java Wed Oct 26 20:13:29 2016 +0000
@@ -19,7 +19,6 @@
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
- *
*/
package sun.hotspot.gc;