# HG changeset patch
# User duke
# Date 1499288980 -7200
# Node ID c61cc8a344569ca0024b81770661f26b2e819a20
# Parent 18569c523d38ad0c30ea57cb18fe95633359124a# Parent fb08f550b0c78651427fb41ae27c0a67c7140296
Merge
diff -r 18569c523d38 -r c61cc8a34456 .hgtags-top-repo
--- a/.hgtags-top-repo Sat Apr 08 03:25:14 2017 +0000
+++ b/.hgtags-top-repo Wed Jul 05 23:09:40 2017 +0200
@@ -405,3 +405,6 @@
fe8466adaef8178dba94be53c789a0aaa87d13bb jdk-9+159
4d29ee32d926ebc960072d51a3bc558f95c1cbad jdk-9+160
cda60babd152d889aba4d8f20a8f643ab151d3de jdk-9+161
+21b063d75b3edbffb9bebc8872d990920c4ae1e5 jdk-9+162
+c38c6b270ccc8e2b86d1631bcf42248241b54d2c jdk-9+163
+7810f75d016a52e32295c4233009de5ca90e31af jdk-9+164
diff -r 18569c523d38 -r c61cc8a34456 common/autoconf/basics.m4
--- a/common/autoconf/basics.m4 Sat Apr 08 03:25:14 2017 +0000
+++ b/common/autoconf/basics.m4 Wed Jul 05 23:09:40 2017 +0200
@@ -1098,6 +1098,7 @@
BASIC_PATH_PROGS(HG, hg)
BASIC_PATH_PROGS(STAT, stat)
BASIC_PATH_PROGS(TIME, time)
+ BASIC_PATH_PROGS(FLOCK, flock)
# 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)
diff -r 18569c523d38 -r c61cc8a34456 common/autoconf/flags.m4
--- a/common/autoconf/flags.m4 Sat Apr 08 03:25:14 2017 +0000
+++ b/common/autoconf/flags.m4 Wed Jul 05 23:09:40 2017 +0200
@@ -355,7 +355,7 @@
SHARED_LIBRARY_FLAGS="-dynamiclib -compatibility_version 1.0.0 -current_version 1.0.0 $PICFLAG"
JVM_CFLAGS="$JVM_CFLAGS $PICFLAG"
fi
- SET_EXECUTABLE_ORIGIN='-Wl,-rpath,@loader_path[$]1'
+ SET_EXECUTABLE_ORIGIN='-Wl,-rpath,@loader_path$(or [$]1,/.)'
SET_SHARED_LIBRARY_ORIGIN="$SET_EXECUTABLE_ORIGIN"
SET_SHARED_LIBRARY_NAME='-Wl,-install_name,@rpath/[$]1'
SET_SHARED_LIBRARY_MAPFILE='-Wl,-exported_symbols_list,[$]1'
@@ -375,7 +375,7 @@
# Linking is different on MacOSX
PICFLAG=''
SHARED_LIBRARY_FLAGS="-dynamiclib -compatibility_version 1.0.0 -current_version 1.0.0 $PICFLAG"
- SET_EXECUTABLE_ORIGIN='-Wl,-rpath,@loader_path[$]1'
+ SET_EXECUTABLE_ORIGIN='-Wl,-rpath,@loader_path$(or [$]1,/.)'
SET_SHARED_LIBRARY_ORIGIN="$SET_EXECUTABLE_ORIGIN"
SET_SHARED_LIBRARY_NAME='-Wl,-install_name,@rpath/[$]1'
SET_SHARED_LIBRARY_MAPFILE='-Wl,-exported_symbols_list,[$]1'
diff -r 18569c523d38 -r c61cc8a34456 common/autoconf/generated-configure.sh
--- a/common/autoconf/generated-configure.sh Sat Apr 08 03:25:14 2017 +0000
+++ b/common/autoconf/generated-configure.sh Wed Jul 05 23:09:40 2017 +0200
@@ -932,6 +932,7 @@
IS_GNU_TIME
PATCH
DTRACE
+FLOCK
TIME
STAT
HG
@@ -994,6 +995,7 @@
OPENJDK_TARGET_CPU_LEGACY_LIB
OPENJDK_TARGET_CPU_LEGACY
REQUIRED_OS_VERSION
+REQUIRED_OS_ARCH
REQUIRED_OS_NAME
COMPILE_TYPE
OPENJDK_TARGET_CPU_ENDIAN
@@ -1292,6 +1294,7 @@
HG
STAT
TIME
+FLOCK
DTRACE
PATCH
DSYMUTIL
@@ -2256,6 +2259,7 @@
HG Override default value for HG
STAT Override default value for STAT
TIME Override default value for TIME
+ FLOCK Override default value for FLOCK
DTRACE Override default value for DTRACE
PATCH Override default value for PATCH
DSYMUTIL Override default value for DSYMUTIL
@@ -5173,7 +5177,7 @@
#CUSTOM_AUTOCONF_INCLUDE
# Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1489410066
+DATE_WHEN_GENERATED=1490900744
###############################################################################
#
@@ -16038,13 +16042,15 @@
fi
fi
if test "x$OPENJDK_TARGET_OS" = "xmacosx"; then
- REQUIRED_OS_NAME=Darwin
+ REQUIRED_OS_NAME="Mac OS X"
REQUIRED_OS_VERSION=11.2
fi
if test "x$OPENJDK_TARGET_OS" = "xaix"; then
REQUIRED_OS_NAME=AIX
REQUIRED_OS_VERSION=7.1
fi
+ REQUIRED_OS_ARCH=${OPENJDK_TARGET_CPU}
+
@@ -23056,6 +23062,203 @@
fi
+
+
+ # Publish this variable in the help.
+
+
+ if [ -z "${FLOCK+x}" ]; then
+ # The variable is not set by user, try to locate tool using the code snippet
+ for ac_prog in flock
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_FLOCK+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $FLOCK in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_FLOCK="$FLOCK" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_FLOCK="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+FLOCK=$ac_cv_path_FLOCK
+if test -n "$FLOCK"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FLOCK" >&5
+$as_echo "$FLOCK" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$FLOCK" && break
+done
+
+ else
+ # The variable is set, but is it from the command line or the environment?
+
+ # Try to remove the string !FLOCK! from our list.
+ try_remove_var=${CONFIGURE_OVERRIDDEN_VARIABLES//!FLOCK!/}
+ if test "x$try_remove_var" = "x$CONFIGURE_OVERRIDDEN_VARIABLES"; then
+ # If it failed, the variable was not from the command line. Ignore it,
+ # but warn the user (except for BASH, which is always set by the calling BASH).
+ if test "xFLOCK" != xBASH; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring value of FLOCK from the environment. Use command line variables instead." >&5
+$as_echo "$as_me: WARNING: Ignoring value of FLOCK from the environment. Use command line variables instead." >&2;}
+ fi
+ # Try to locate tool using the code snippet
+ for ac_prog in flock
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_FLOCK+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $FLOCK in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_FLOCK="$FLOCK" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_FLOCK="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+FLOCK=$ac_cv_path_FLOCK
+if test -n "$FLOCK"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FLOCK" >&5
+$as_echo "$FLOCK" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$FLOCK" && break
+done
+
+ else
+ # If it succeeded, then it was overridden by the user. We will use it
+ # for the tool.
+
+ # First remove it from the list of overridden variables, so we can test
+ # for unknown variables in the end.
+ CONFIGURE_OVERRIDDEN_VARIABLES="$try_remove_var"
+
+ # Check if we try to supply an empty value
+ if test "x$FLOCK" = x; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Setting user supplied tool FLOCK= (no value)" >&5
+$as_echo "$as_me: Setting user supplied tool FLOCK= (no value)" >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for FLOCK" >&5
+$as_echo_n "checking for FLOCK... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5
+$as_echo "disabled" >&6; }
+ else
+ # Check if the provided tool contains a complete path.
+ tool_specified="$FLOCK"
+ tool_basename="${tool_specified##*/}"
+ if test "x$tool_basename" = "x$tool_specified"; then
+ # A command without a complete path is provided, search $PATH.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Will search for user supplied tool FLOCK=$tool_basename" >&5
+$as_echo "$as_me: Will search for user supplied tool FLOCK=$tool_basename" >&6;}
+ # Extract the first word of "$tool_basename", so it can be a program name with args.
+set dummy $tool_basename; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_FLOCK+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $FLOCK in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_FLOCK="$FLOCK" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_FLOCK="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+FLOCK=$ac_cv_path_FLOCK
+if test -n "$FLOCK"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FLOCK" >&5
+$as_echo "$FLOCK" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ if test "x$FLOCK" = x; then
+ as_fn_error $? "User supplied tool $tool_basename could not be found" "$LINENO" 5
+ fi
+ else
+ # Otherwise we believe it is a complete path. Use it as it is.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Will use user supplied tool FLOCK=$tool_specified" >&5
+$as_echo "$as_me: Will use user supplied tool FLOCK=$tool_specified" >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for FLOCK" >&5
+$as_echo_n "checking for FLOCK... " >&6; }
+ if test ! -x "$tool_specified"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+$as_echo "not found" >&6; }
+ as_fn_error $? "User supplied tool FLOCK=$tool_specified does not exist or is not executable" "$LINENO" 5
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $tool_specified" >&5
+$as_echo "$tool_specified" >&6; }
+ fi
+ fi
+ fi
+
+ fi
+
+
# Dtrace is usually found in /usr/sbin on Solaris, but that directory may not
# be in the user path.
@@ -49486,7 +49689,7 @@
SHARED_LIBRARY_FLAGS="-dynamiclib -compatibility_version 1.0.0 -current_version 1.0.0 $PICFLAG"
JVM_CFLAGS="$JVM_CFLAGS $PICFLAG"
fi
- SET_EXECUTABLE_ORIGIN='-Wl,-rpath,@loader_path$1'
+ SET_EXECUTABLE_ORIGIN='-Wl,-rpath,@loader_path$(or $1,/.)'
SET_SHARED_LIBRARY_ORIGIN="$SET_EXECUTABLE_ORIGIN"
SET_SHARED_LIBRARY_NAME='-Wl,-install_name,@rpath/$1'
SET_SHARED_LIBRARY_MAPFILE='-Wl,-exported_symbols_list,$1'
@@ -49506,7 +49709,7 @@
# Linking is different on MacOSX
PICFLAG=''
SHARED_LIBRARY_FLAGS="-dynamiclib -compatibility_version 1.0.0 -current_version 1.0.0 $PICFLAG"
- SET_EXECUTABLE_ORIGIN='-Wl,-rpath,@loader_path$1'
+ SET_EXECUTABLE_ORIGIN='-Wl,-rpath,@loader_path$(or $1,/.)'
SET_SHARED_LIBRARY_ORIGIN="$SET_EXECUTABLE_ORIGIN"
SET_SHARED_LIBRARY_NAME='-Wl,-install_name,@rpath/$1'
SET_SHARED_LIBRARY_MAPFILE='-Wl,-exported_symbols_list,$1'
diff -r 18569c523d38 -r c61cc8a34456 common/autoconf/platform.m4
--- a/common/autoconf/platform.m4 Sat Apr 08 03:25:14 2017 +0000
+++ b/common/autoconf/platform.m4 Wed Jul 05 23:09:40 2017 +0200
@@ -452,15 +452,17 @@
fi
fi
if test "x$OPENJDK_TARGET_OS" = "xmacosx"; then
- REQUIRED_OS_NAME=Darwin
+ REQUIRED_OS_NAME="Mac OS X"
REQUIRED_OS_VERSION=11.2
fi
if test "x$OPENJDK_TARGET_OS" = "xaix"; then
REQUIRED_OS_NAME=AIX
REQUIRED_OS_VERSION=7.1
fi
+ REQUIRED_OS_ARCH=${OPENJDK_TARGET_CPU}
AC_SUBST(REQUIRED_OS_NAME)
+ AC_SUBST(REQUIRED_OS_ARCH)
AC_SUBST(REQUIRED_OS_VERSION)
])
diff -r 18569c523d38 -r c61cc8a34456 common/autoconf/spec.gmk.in
--- a/common/autoconf/spec.gmk.in Sat Apr 08 03:25:14 2017 +0000
+++ b/common/autoconf/spec.gmk.in Wed Jul 05 23:09:40 2017 +0200
@@ -48,7 +48,7 @@
# The default make arguments
MAKE_ARGS = $(MAKE_LOG_FLAGS) -r -R -I $(TOPDIR)/make/common SPEC=$(SPEC) \
- MAKE_LOG_FLAGS="$(MAKE_LOG_FLAGS)" LOG_LEVEL=$(LOG_LEVEL)
+ MAKE_LOG_FLAGS="$(MAKE_LOG_FLAGS)" $(MAKE_LOG_VARS)
OUTPUT_SYNC_SUPPORTED:=@OUTPUT_SYNC_SUPPORTED@
OUTPUT_SYNC:=@OUTPUT_SYNC@
@@ -101,8 +101,9 @@
OPENJDK_BUILD_CPU_BITS:=@OPENJDK_BUILD_CPU_BITS@
OPENJDK_BUILD_CPU_ENDIAN:=@OPENJDK_BUILD_CPU_ENDIAN@
-# Legacy OS values for use in release file.
+# OS values for use in release file.
REQUIRED_OS_NAME:=@REQUIRED_OS_NAME@
+REQUIRED_OS_ARCH:=@REQUIRED_OS_ARCH@
REQUIRED_OS_VERSION:=@REQUIRED_OS_VERSION@
LIBM:=@LIBM@
@@ -636,6 +637,7 @@
DSYMUTIL:=@DSYMUTIL@
FIND:=@FIND@
FIND_DELETE:=@FIND_DELETE@
+FLOCK:=@FLOCK@
ECHO:=@ECHO@
EGREP:=@EGREP@
FGREP:=@FGREP@
diff -r 18569c523d38 -r c61cc8a34456 common/bin/shell-profiler.sh
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/common/bin/shell-profiler.sh Wed Jul 05 23:09:40 2017 +0200
@@ -0,0 +1,69 @@
+#!/bin/bash
+#
+# Copyright (c) 2012, 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.
+#
+
+# Usage: sh shell-tracer.sh
+#
+# This shell script is supposed to be set as a replacement for SHELL in make,
+# causing it to be called whenever make wants to execute shell commands.
+# The is suitable for passing on to the old shell,
+# typically beginning with -c.
+#
+# This script will run the shell command line and it will also store a simple
+# log of the the time it takes to execute the command in the OUTPUT_FILE, using
+# utility for time measure specified with TIME_CMD option.
+#
+# Type of time measure utility is specified with TIME_CMD_TYPE option.
+# Recognized options values of TIME_CMD_TYPE option: "gnutime", "flock".
+
+TIME_CMD_TYPE="$1"
+TIME_CMD="$2"
+OUTPUT_FILE="$3"
+shift
+shift
+shift
+if [ "$TIME_CMD_TYPE" = "gnutime" ]; then
+ # Escape backslashes (\) and percent chars (%). See man for GNU 'time'.
+ msg=${@//\\/\\\\}
+ msg=${msg//%/%%}
+ "$TIME_CMD" -f "[TIME:%E] $msg" -a -o "$OUTPUT_FILE" "$@"
+elif [ "$TIME_CMD_TYPE" = "flock" ]; then
+ # Emulated GNU 'time' with 'flock' and 'date'.
+ ts=`date +%s%3N`
+ "$@"
+ status=$?
+ ts2=`date +%s%3N`
+ millis=$((ts2 - ts))
+ ms=$(($millis % 1000))
+ seconds=$((millis / 1000))
+ ss=$(($seconds % 60))
+ minutes=$(($seconds / 60))
+ mm=$(($minutes % 60))
+ hh=$(($minutes / 60)):
+ [ $hh != "0:" ] || hh=
+ # Synchronize on this script.
+ flock -w 10 "$0" printf "[TIME:${hh}${mm}:${ss}.%.2s] %s\n" $ms "$*" >> "$OUTPUT_FILE" || true
+ exit $status
+else
+ "$@"
+fi
diff -r 18569c523d38 -r c61cc8a34456 common/bin/shell-tracer.sh
--- a/common/bin/shell-tracer.sh Sat Apr 08 03:25:14 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-#!/bin/bash
-#
-# Copyright (c) 2012, 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.
-#
-
-# Usage: sh shell-tracer.sh
-#
-# This shell script is supposed to be set as a replacement for SHELL in make,
-# causing it to be called whenever make wants to execute shell commands.
-# The is suitable for passing on to the old shell,
-# typically beginning with -c.
-#
-# This script will make sure the shell command line is executed with
-# OLD_SHELL -x, and it will also store a simple log of the the time it takes to
-# execute the command in the OUTPUT_FILE, using the "time" utility as pointed
-# to by TIME_CMD. If TIME_CMD is "-", no timestamp will be stored.
-
-TIME_CMD="$1"
-OUTPUT_FILE="$2"
-OLD_SHELL="$3"
-shift
-shift
-shift
-if [ "$TIME_CMD" != "-" ]; then
-"$TIME_CMD" -f "[TIME:%E] $*" -a -o "$OUTPUT_FILE" "$OLD_SHELL" -x "$@"
-else
-"$OLD_SHELL" -x "$@"
-fi
diff -r 18569c523d38 -r c61cc8a34456 common/conf/jib-profiles.js
--- a/common/conf/jib-profiles.js Sat Apr 08 03:25:14 2017 +0000
+++ b/common/conf/jib-profiles.js Wed Jul 05 23:09:40 2017 +0200
@@ -910,7 +910,7 @@
freetype: {
organization: common.organization,
ext: "tar.gz",
- revision: "2.3.4+1.0",
+ revision: "2.7.1-v120+1.0",
module: "freetype-" + input.target_platform
}
};
diff -r 18569c523d38 -r c61cc8a34456 corba/.hgtags
--- a/corba/.hgtags Sat Apr 08 03:25:14 2017 +0000
+++ b/corba/.hgtags Wed Jul 05 23:09:40 2017 +0200
@@ -405,3 +405,6 @@
6feea77d2083c99e44aa3e272d07b7fb3b801683 jdk-9+159
c7688f2fa07936b089ca0e9a0a0eff68ff37a542 jdk-9+160
18f02bc43fe96aef36791d0df7aca748485210cc jdk-9+161
+18ffcf99a3b4a10457853d94190e825bdf07e39b jdk-9+162
+493011dee80e51c2a2b064d049183c047df36d80 jdk-9+163
+965bbae3072702f7c0d95c240523b65e6bb19261 jdk-9+164
diff -r 18569c523d38 -r c61cc8a34456 corba/src/java.corba/share/classes/module-info.java
--- a/corba/src/java.corba/share/classes/module-info.java Sat Apr 08 03:25:14 2017 +0000
+++ b/corba/src/java.corba/share/classes/module-info.java Wed Jul 05 23:09:40 2017 +0200
@@ -26,6 +26,7 @@
/**
* Defines the Java binding of the OMG CORBA APIs, and the RMI-IIOP API.
*
+ * @moduleGraph
* @since 9
*/
@Deprecated(since="9", forRemoval=true)
diff -r 18569c523d38 -r c61cc8a34456 corba/src/java.corba/share/classes/sun/corba/Bridge.java
--- a/corba/src/java.corba/share/classes/sun/corba/Bridge.java Sat Apr 08 03:25:14 2017 +0000
+++ b/corba/src/java.corba/share/classes/sun/corba/Bridge.java Wed Jul 05 23:09:40 2017 +0200
@@ -59,10 +59,10 @@
*
* The code that calls Bridge.get() must have the following Permissions:
*
- * - RuntimePermission "reflectionFactoryAccess"
* - BridgePermission "getBridge"
* - ReflectPermission "suppressAccessChecks"
- * - StackFramePermission "retainClassReference"
+ * - RuntimePermission "getStackWalkerWithClassReference"
+ * - RuntimePermission "reflectionFactoryAccess"
*
*
* All of these permissions are required to obtain and correctly initialize
@@ -105,10 +105,10 @@
/** Fetch the Bridge singleton. This requires the following
* permissions:
*
- * - RuntimePermission "reflectionFactoryAccess"
* - BridgePermission "getBridge"
* - ReflectPermission "suppressAccessChecks"
- * - StackFramePermission "retainClassReference"
+ * - RuntimePermission "getStackWalkerWithClassReference"
+ * - RuntimePermission "reflectionFactoryAccess"
*
* @return The singleton instance of the Bridge class
* @throws SecurityException if the caller does not have the
diff -r 18569c523d38 -r c61cc8a34456 hotspot/.hgtags
--- a/hotspot/.hgtags Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/.hgtags Wed Jul 05 23:09:40 2017 +0200
@@ -565,3 +565,6 @@
9211c2e89c1cd11ec2d5752b0f97131a7d7525c7 jdk-9+159
94b4e2e5331d38eab6a3639c3511b2e0715df0e9 jdk-9+160
191ffbdb3d7b734288daa7fb76b37a0a85dfe7eb jdk-9+161
+b01c519b715ef6f785d0631adee0a6537cf6c12e jdk-9+162
+983fe207555724d98f4876991e1cbafbcf2733e8 jdk-9+163
+0af429be8bbaeaaf0cb838e9af28c953dda6a9c8 jdk-9+164
diff -r 18569c523d38 -r c61cc8a34456 hotspot/make/gensrc/Gensrc-jdk.internal.vm.compiler.gmk
--- a/hotspot/make/gensrc/Gensrc-jdk.internal.vm.compiler.gmk Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/make/gensrc/Gensrc-jdk.internal.vm.compiler.gmk Wed Jul 05 23:09:40 2017 +0200
@@ -81,6 +81,7 @@
PROCESSOR_PATH := $(call PathList, $(PROCESSOR_JARS))
ADD_EXPORTS := \
+ --add-modules jdk.internal.vm.ci \
--add-exports jdk.internal.vm.ci/jdk.vm.ci.aarch64=ALL-UNNAMED \
--add-exports jdk.internal.vm.ci/jdk.vm.ci.amd64=ALL-UNNAMED \
--add-exports jdk.internal.vm.ci/jdk.vm.ci.code=ALL-UNNAMED \
diff -r 18569c523d38 -r c61cc8a34456 hotspot/make/lib/CompileJvm.gmk
--- a/hotspot/make/lib/CompileJvm.gmk Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/make/lib/CompileJvm.gmk Wed Jul 05 23:09:40 2017 +0200
@@ -118,6 +118,12 @@
OPENJDK_TARGET_CPU_VM_VERSION := amd64
else ifeq ($(OPENJDK_TARGET_CPU), sparcv9)
OPENJDK_TARGET_CPU_VM_VERSION := sparc
+else ifeq ($(HOTSPOT_TARGET_CPU_ARCH), arm)
+ ifeq ($(OPENJDK_TARGET_CPU), aarch64)
+ # This sets the Oracle Aarch64 port to use arm64
+ # while the original Aarch64 port uses aarch64
+ OPENJDK_TARGET_CPU_VM_VERSION := arm64
+ endif
else
OPENJDK_TARGET_CPU_VM_VERSION := $(OPENJDK_TARGET_CPU)
endif
diff -r 18569c523d38 -r c61cc8a34456 hotspot/make/test/JtregNative.gmk
--- a/hotspot/make/test/JtregNative.gmk Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/make/test/JtregNative.gmk Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2015, 2017, 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
@@ -48,6 +48,8 @@
$(HOTSPOT_TOPDIR)/test/runtime/jni/PrivateInterfaceMethods \
$(HOTSPOT_TOPDIR)/test/runtime/jni/ToStringInInterfaceTest \
$(HOTSPOT_TOPDIR)/test/runtime/jni/CalleeSavedRegisters \
+ $(HOTSPOT_TOPDIR)/test/runtime/jni/CallWithJNIWeak \
+ $(HOTSPOT_TOPDIR)/test/runtime/jni/ReturnJNIWeak \
$(HOTSPOT_TOPDIR)/test/runtime/modules/getModuleJNI \
$(HOTSPOT_TOPDIR)/test/runtime/SameObject \
$(HOTSPOT_TOPDIR)/test/runtime/BoolReturn \
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/cpu/aarch64/vm/aarch64.ad
--- a/hotspot/src/cpu/aarch64/vm/aarch64.ad Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/cpu/aarch64/vm/aarch64.ad Wed Jul 05 23:09:40 2017 +0200
@@ -15501,7 +15501,7 @@
%}
instruct string_indexofUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2,
- iRegI_R0 result, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI tmp4, rFlagsReg cr)
+ iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
%{
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
@@ -15520,7 +15520,7 @@
%}
instruct string_indexofLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2,
- iRegI_R0 result, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI tmp4, rFlagsReg cr)
+ iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
%{
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
@@ -15539,7 +15539,7 @@
%}
instruct string_indexofUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2,
- iRegI_R0 result, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI tmp4, rFlagsReg cr)
+ iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
%{
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
@@ -15558,7 +15558,7 @@
%}
instruct string_indexofLU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2,
- iRegI_R0 result, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI tmp4, rFlagsReg cr)
+ iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
%{
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LU);
match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
@@ -15577,8 +15577,8 @@
%}
instruct string_indexof_conUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2,
- immI_le_4 int_cnt2, iRegI_R0 result, iRegI tmp1, iRegI tmp2,
- iRegI tmp3, iRegI tmp4, rFlagsReg cr)
+ immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2,
+ iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
%{
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
@@ -15598,8 +15598,8 @@
%}
instruct string_indexof_conLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2,
- immI_le_4 int_cnt2, iRegI_R0 result, iRegI tmp1, iRegI tmp2,
- iRegI tmp3, iRegI tmp4, rFlagsReg cr)
+ immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2,
+ iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
%{
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
@@ -15619,8 +15619,8 @@
%}
instruct string_indexof_conUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2,
- immI_1 int_cnt2, iRegI_R0 result, iRegI tmp1, iRegI tmp2,
- iRegI tmp3, iRegI tmp4, rFlagsReg cr)
+ immI_1 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2,
+ iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
%{
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
@@ -15640,8 +15640,8 @@
%}
instruct string_indexof_conLU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2,
- immI_1 int_cnt2, iRegI_R0 result, iRegI tmp1, iRegI tmp2,
- iRegI tmp3, iRegI tmp4, rFlagsReg cr)
+ immI_1 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2,
+ iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
%{
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LU);
match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
@@ -15661,8 +15661,8 @@
%}
instruct string_indexofU_char(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch,
- iRegI_R0 result, iRegI tmp1, iRegI tmp2,
- iRegI tmp3, rFlagsReg cr)
+ iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2,
+ iRegINoSp tmp3, rFlagsReg cr)
%{
match(Set result (StrIndexOfChar (Binary str1 cnt1) ch));
effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch,
@@ -16101,7 +16101,7 @@
// ====================REDUCTION ARITHMETIC====================================
-instruct reduce_add2I(iRegINoSp dst, iRegIorL2I src1, vecD src2, iRegI tmp, iRegI tmp2)
+instruct reduce_add2I(iRegINoSp dst, iRegIorL2I src1, vecD src2, iRegINoSp tmp, iRegINoSp tmp2)
%{
match(Set dst (AddReductionVI src1 src2));
ins_cost(INSN_COST);
@@ -16120,7 +16120,7 @@
ins_pipe(pipe_class_default);
%}
-instruct reduce_add4I(iRegINoSp dst, iRegIorL2I src1, vecX src2, vecX tmp, iRegI tmp2)
+instruct reduce_add4I(iRegINoSp dst, iRegIorL2I src1, vecX src2, vecX tmp, iRegINoSp tmp2)
%{
match(Set dst (AddReductionVI src1 src2));
ins_cost(INSN_COST);
@@ -16138,7 +16138,7 @@
ins_pipe(pipe_class_default);
%}
-instruct reduce_mul2I(iRegINoSp dst, iRegIorL2I src1, vecD src2, iRegI tmp)
+instruct reduce_mul2I(iRegINoSp dst, iRegIorL2I src1, vecD src2, iRegINoSp tmp)
%{
match(Set dst (MulReductionVI src1 src2));
ins_cost(INSN_COST);
@@ -16157,7 +16157,7 @@
ins_pipe(pipe_class_default);
%}
-instruct reduce_mul4I(iRegINoSp dst, iRegIorL2I src1, vecX src2, vecX tmp, iRegI tmp2)
+instruct reduce_mul4I(iRegINoSp dst, iRegIorL2I src1, vecX src2, vecX tmp, iRegINoSp tmp2)
%{
match(Set dst (MulReductionVI src1 src2));
ins_cost(INSN_COST);
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/cpu/aarch64/vm/jniFastGetField_aarch64.cpp
--- a/hotspot/src/cpu/aarch64/vm/jniFastGetField_aarch64.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/cpu/aarch64/vm/jniFastGetField_aarch64.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -82,6 +82,11 @@
__ eor(robj, robj, rcounter); // obj, since
// robj ^ rcounter ^ rcounter == robj
// robj is address dependent on rcounter.
+
+ // If mask changes we need to ensure that the inverse is still encodable as an immediate
+ STATIC_ASSERT(JNIHandles::weak_tag_mask == 1);
+ __ andr(robj, robj, ~JNIHandles::weak_tag_mask);
+
__ ldr(robj, Address(robj, 0)); // *obj
__ lsr(roffset, c_rarg2, 2); // offset
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp
--- a/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2015, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -2052,13 +2052,31 @@
__ reset_last_Java_frame(false);
- // Unpack oop result
+ // Unbox oop result, e.g. JNIHandles::resolve result.
if (ret_type == T_OBJECT || ret_type == T_ARRAY) {
- Label L;
- __ cbz(r0, L);
- __ ldr(r0, Address(r0, 0));
- __ bind(L);
- __ verify_oop(r0);
+ Label done, not_weak;
+ __ cbz(r0, done); // Use NULL as-is.
+ STATIC_ASSERT(JNIHandles::weak_tag_mask == 1u);
+ __ tbz(r0, 0, not_weak); // Test for jweak tag.
+ // Resolve jweak.
+ __ ldr(r0, Address(r0, -JNIHandles::weak_tag_value));
+ __ verify_oop(r0);
+#if INCLUDE_ALL_GCS
+ if (UseG1GC) {
+ __ g1_write_barrier_pre(noreg /* obj */,
+ r0 /* pre_val */,
+ rthread /* thread */,
+ rscratch1 /* tmp */,
+ true /* tosca_live */,
+ true /* expand_call */);
+ }
+#endif // INCLUDE_ALL_GCS
+ __ b(done);
+ __ bind(not_weak);
+ // Resolve (untagged) jobject.
+ __ ldr(r0, Address(r0, 0));
+ __ verify_oop(r0);
+ __ bind(done);
}
if (CheckJNICalls) {
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.cpp
--- a/hotspot/src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -1399,13 +1399,32 @@
// and result handler will pick it up
{
- Label no_oop, store_result;
+ Label no_oop, not_weak, store_result;
__ adr(t, ExternalAddress(AbstractInterpreter::result_handler(T_OBJECT)));
__ cmp(t, result_handler);
__ br(Assembler::NE, no_oop);
- // retrieve result
+ // Unbox oop result, e.g. JNIHandles::resolve result.
__ pop(ltos);
- __ cbz(r0, store_result);
+ __ cbz(r0, store_result); // Use NULL as-is.
+ STATIC_ASSERT(JNIHandles::weak_tag_mask == 1u);
+ __ tbz(r0, 0, not_weak); // Test for jweak tag.
+ // Resolve jweak.
+ __ ldr(r0, Address(r0, -JNIHandles::weak_tag_value));
+#if INCLUDE_ALL_GCS
+ if (UseG1GC) {
+ __ enter(); // Barrier may call runtime.
+ __ g1_write_barrier_pre(noreg /* obj */,
+ r0 /* pre_val */,
+ rthread /* thread */,
+ t /* tmp */,
+ true /* tosca_live */,
+ true /* expand_call */);
+ __ leave();
+ }
+#endif // INCLUDE_ALL_GCS
+ __ b(store_result);
+ __ bind(not_weak);
+ // Resolve (untagged) jobject.
__ ldr(r0, Address(r0, 0));
__ bind(store_result);
__ str(r0, Address(rfp, frame::interpreter_frame_oop_temp_offset*wordSize));
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/cpu/arm/vm/interp_masm_arm.cpp
--- a/hotspot/src/cpu/arm/vm/interp_masm_arm.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/cpu/arm/vm/interp_masm_arm.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2017, 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
@@ -476,185 +476,6 @@
}
//////////////////////////////////////////////////////////////////////////////////
-#if INCLUDE_ALL_GCS
-
-// G1 pre-barrier.
-// Blows all volatile registers (R0-R3 on 32-bit ARM, R0-R18 on AArch64, Rtemp, LR).
-// If store_addr != noreg, then previous value is loaded from [store_addr];
-// in such case store_addr and new_val registers are preserved;
-// otherwise pre_val register is preserved.
-void InterpreterMacroAssembler::g1_write_barrier_pre(Register store_addr,
- Register new_val,
- Register pre_val,
- Register tmp1,
- Register tmp2) {
- Label done;
- Label runtime;
-
- if (store_addr != noreg) {
- assert_different_registers(store_addr, new_val, pre_val, tmp1, tmp2, noreg);
- } else {
- assert (new_val == noreg, "should be");
- assert_different_registers(pre_val, tmp1, tmp2, noreg);
- }
-
- Address in_progress(Rthread, in_bytes(JavaThread::satb_mark_queue_offset() +
- SATBMarkQueue::byte_offset_of_active()));
- Address index(Rthread, in_bytes(JavaThread::satb_mark_queue_offset() +
- SATBMarkQueue::byte_offset_of_index()));
- Address buffer(Rthread, in_bytes(JavaThread::satb_mark_queue_offset() +
- SATBMarkQueue::byte_offset_of_buf()));
-
- // Is marking active?
- assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "adjust this code");
- ldrb(tmp1, in_progress);
- cbz(tmp1, done);
-
- // Do we need to load the previous value?
- if (store_addr != noreg) {
- load_heap_oop(pre_val, Address(store_addr, 0));
- }
-
- // Is the previous value null?
- cbz(pre_val, done);
-
- // Can we store original value in the thread's buffer?
- // Is index == 0?
- // (The index field is typed as size_t.)
-
- ldr(tmp1, index); // tmp1 := *index_adr
- ldr(tmp2, buffer);
-
- subs(tmp1, tmp1, wordSize); // tmp1 := tmp1 - wordSize
- b(runtime, lt); // If negative, goto runtime
-
- str(tmp1, index); // *index_adr := tmp1
-
- // Record the previous value
- str(pre_val, Address(tmp2, tmp1));
- b(done);
-
- bind(runtime);
-
- // save the live input values
-#ifdef AARCH64
- if (store_addr != noreg) {
- raw_push(store_addr, new_val);
- } else {
- raw_push(pre_val, ZR);
- }
-#else
- if (store_addr != noreg) {
- // avoid raw_push to support any ordering of store_addr and new_val
- push(RegisterSet(store_addr) | RegisterSet(new_val));
- } else {
- push(pre_val);
- }
-#endif // AARCH64
-
- if (pre_val != R0) {
- mov(R0, pre_val);
- }
- mov(R1, Rthread);
-
- call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), R0, R1);
-
-#ifdef AARCH64
- if (store_addr != noreg) {
- raw_pop(store_addr, new_val);
- } else {
- raw_pop(pre_val, ZR);
- }
-#else
- if (store_addr != noreg) {
- pop(RegisterSet(store_addr) | RegisterSet(new_val));
- } else {
- pop(pre_val);
- }
-#endif // AARCH64
-
- bind(done);
-}
-
-// G1 post-barrier.
-// Blows all volatile registers (R0-R3 on 32-bit ARM, R0-R18 on AArch64, Rtemp, LR).
-void InterpreterMacroAssembler::g1_write_barrier_post(Register store_addr,
- Register new_val,
- Register tmp1,
- Register tmp2,
- Register tmp3) {
-
- Address queue_index(Rthread, in_bytes(JavaThread::dirty_card_queue_offset() +
- DirtyCardQueue::byte_offset_of_index()));
- Address buffer(Rthread, in_bytes(JavaThread::dirty_card_queue_offset() +
- DirtyCardQueue::byte_offset_of_buf()));
-
- BarrierSet* bs = Universe::heap()->barrier_set();
- CardTableModRefBS* ct = (CardTableModRefBS*)bs;
- Label done;
- Label runtime;
-
- // Does store cross heap regions?
-
- eor(tmp1, store_addr, new_val);
-#ifdef AARCH64
- logical_shift_right(tmp1, tmp1, HeapRegion::LogOfHRGrainBytes);
- cbz(tmp1, done);
-#else
- movs(tmp1, AsmOperand(tmp1, lsr, HeapRegion::LogOfHRGrainBytes));
- b(done, eq);
-#endif
-
- // crosses regions, storing NULL?
-
- cbz(new_val, done);
-
- // storing region crossing non-NULL, is card already dirty?
- const Register card_addr = tmp1;
- assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
-
- mov_address(tmp2, (address)ct->byte_map_base, symbolic_Relocation::card_table_reference);
- add(card_addr, tmp2, AsmOperand(store_addr, lsr, CardTableModRefBS::card_shift));
-
- ldrb(tmp2, Address(card_addr));
- cmp(tmp2, (int)G1SATBCardTableModRefBS::g1_young_card_val());
- b(done, eq);
-
- membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreLoad), tmp2);
-
- assert(CardTableModRefBS::dirty_card_val() == 0, "adjust this code");
- ldrb(tmp2, Address(card_addr));
- cbz(tmp2, done);
-
- // storing a region crossing, non-NULL oop, card is clean.
- // dirty card and log.
-
- strb(zero_register(tmp2), Address(card_addr));
-
- ldr(tmp2, queue_index);
- ldr(tmp3, buffer);
-
- subs(tmp2, tmp2, wordSize);
- b(runtime, lt); // go to runtime if now negative
-
- str(tmp2, queue_index);
-
- str(card_addr, Address(tmp3, tmp2));
- b(done);
-
- bind(runtime);
-
- if (card_addr != R0) {
- mov(R0, card_addr);
- }
- mov(R1, Rthread);
- call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), R0, R1);
-
- bind(done);
-}
-
-#endif // INCLUDE_ALL_GCS
-//////////////////////////////////////////////////////////////////////////////////
// Java Expression Stack
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/cpu/arm/vm/interp_masm_arm.hpp
--- a/hotspot/src/cpu/arm/vm/interp_masm_arm.hpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/cpu/arm/vm/interp_masm_arm.hpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2017, 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
@@ -146,27 +146,6 @@
void set_card(Register card_table_base, Address card_table_addr, Register tmp);
-#if INCLUDE_ALL_GCS
- // G1 pre-barrier.
- // Blows all volatile registers (R0-R3 on 32-bit ARM, R0-R18 on AArch64, Rtemp, LR).
- // If store_addr != noreg, then previous value is loaded from [store_addr];
- // in such case store_addr and new_val registers are preserved;
- // otherwise pre_val register is preserved.
- void g1_write_barrier_pre(Register store_addr,
- Register new_val,
- Register pre_val,
- Register tmp1,
- Register tmp2);
-
- // G1 post-barrier.
- // Blows all volatile registers (R0-R3 on 32-bit ARM, R0-R18 on AArch64, Rtemp, LR).
- void g1_write_barrier_post(Register store_addr,
- Register new_val,
- Register tmp1,
- Register tmp2,
- Register tmp3);
-#endif // INCLUDE_ALL_GCS
-
void pop_ptr(Register r);
void pop_i(Register r = R0_tos);
#ifdef AARCH64
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/cpu/arm/vm/jniFastGetField_arm.cpp
--- a/hotspot/src/cpu/arm/vm/jniFastGetField_arm.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/cpu/arm/vm/jniFastGetField_arm.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2017, 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
@@ -119,6 +119,14 @@
__ ldr_s32(Rsafept_cnt, Address(Rsafepoint_counter_addr));
__ tbnz(Rsafept_cnt, 0, slow_case);
+#ifdef AARCH64
+ // If mask changes we need to ensure that the inverse is still encodable as an immediate
+ STATIC_ASSERT(JNIHandles::weak_tag_mask == 1);
+ __ andr(R1, R1, ~JNIHandles::weak_tag_mask);
+#else
+ __ bic(R1, R1, JNIHandles::weak_tag_mask);
+#endif
+
if (os::is_MP()) {
// Address dependency restricts memory access ordering. It's cheaper than explicit LoadLoad barrier
__ andr(Rtmp1, Rsafept_cnt, (unsigned)1);
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/cpu/arm/vm/macroAssembler_arm.cpp
--- a/hotspot/src/cpu/arm/vm/macroAssembler_arm.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/cpu/arm/vm/macroAssembler_arm.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2017, 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
@@ -2211,6 +2211,219 @@
b(done, eq);
}
+
+void MacroAssembler::resolve_jobject(Register value,
+ Register tmp1,
+ Register tmp2) {
+ assert_different_registers(value, tmp1, tmp2);
+ Label done, not_weak;
+ cbz(value, done); // Use NULL as-is.
+ STATIC_ASSERT(JNIHandles::weak_tag_mask == 1u);
+ tbz(value, 0, not_weak); // Test for jweak tag.
+ // Resolve jweak.
+ ldr(value, Address(value, -JNIHandles::weak_tag_value));
+ verify_oop(value);
+#if INCLUDE_ALL_GCS
+ if (UseG1GC) {
+ g1_write_barrier_pre(noreg, // store_addr
+ noreg, // new_val
+ value, // pre_val
+ tmp1, // tmp1
+ tmp2); // tmp2
+ }
+#endif // INCLUDE_ALL_GCS
+ b(done);
+ bind(not_weak);
+ // Resolve (untagged) jobject.
+ ldr(value, Address(value));
+ verify_oop(value);
+ bind(done);
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////
+
+#if INCLUDE_ALL_GCS
+
+// G1 pre-barrier.
+// Blows all volatile registers (R0-R3 on 32-bit ARM, R0-R18 on AArch64, Rtemp, LR).
+// If store_addr != noreg, then previous value is loaded from [store_addr];
+// in such case store_addr and new_val registers are preserved;
+// otherwise pre_val register is preserved.
+void MacroAssembler::g1_write_barrier_pre(Register store_addr,
+ Register new_val,
+ Register pre_val,
+ Register tmp1,
+ Register tmp2) {
+ Label done;
+ Label runtime;
+
+ if (store_addr != noreg) {
+ assert_different_registers(store_addr, new_val, pre_val, tmp1, tmp2, noreg);
+ } else {
+ assert (new_val == noreg, "should be");
+ assert_different_registers(pre_val, tmp1, tmp2, noreg);
+ }
+
+ Address in_progress(Rthread, in_bytes(JavaThread::satb_mark_queue_offset() +
+ SATBMarkQueue::byte_offset_of_active()));
+ Address index(Rthread, in_bytes(JavaThread::satb_mark_queue_offset() +
+ SATBMarkQueue::byte_offset_of_index()));
+ Address buffer(Rthread, in_bytes(JavaThread::satb_mark_queue_offset() +
+ SATBMarkQueue::byte_offset_of_buf()));
+
+ // Is marking active?
+ assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "adjust this code");
+ ldrb(tmp1, in_progress);
+ cbz(tmp1, done);
+
+ // Do we need to load the previous value?
+ if (store_addr != noreg) {
+ load_heap_oop(pre_val, Address(store_addr, 0));
+ }
+
+ // Is the previous value null?
+ cbz(pre_val, done);
+
+ // Can we store original value in the thread's buffer?
+ // Is index == 0?
+ // (The index field is typed as size_t.)
+
+ ldr(tmp1, index); // tmp1 := *index_adr
+ ldr(tmp2, buffer);
+
+ subs(tmp1, tmp1, wordSize); // tmp1 := tmp1 - wordSize
+ b(runtime, lt); // If negative, goto runtime
+
+ str(tmp1, index); // *index_adr := tmp1
+
+ // Record the previous value
+ str(pre_val, Address(tmp2, tmp1));
+ b(done);
+
+ bind(runtime);
+
+ // save the live input values
+#ifdef AARCH64
+ if (store_addr != noreg) {
+ raw_push(store_addr, new_val);
+ } else {
+ raw_push(pre_val, ZR);
+ }
+#else
+ if (store_addr != noreg) {
+ // avoid raw_push to support any ordering of store_addr and new_val
+ push(RegisterSet(store_addr) | RegisterSet(new_val));
+ } else {
+ push(pre_val);
+ }
+#endif // AARCH64
+
+ if (pre_val != R0) {
+ mov(R0, pre_val);
+ }
+ mov(R1, Rthread);
+
+ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), R0, R1);
+
+#ifdef AARCH64
+ if (store_addr != noreg) {
+ raw_pop(store_addr, new_val);
+ } else {
+ raw_pop(pre_val, ZR);
+ }
+#else
+ if (store_addr != noreg) {
+ pop(RegisterSet(store_addr) | RegisterSet(new_val));
+ } else {
+ pop(pre_val);
+ }
+#endif // AARCH64
+
+ bind(done);
+}
+
+// G1 post-barrier.
+// Blows all volatile registers (R0-R3 on 32-bit ARM, R0-R18 on AArch64, Rtemp, LR).
+void MacroAssembler::g1_write_barrier_post(Register store_addr,
+ Register new_val,
+ Register tmp1,
+ Register tmp2,
+ Register tmp3) {
+
+ Address queue_index(Rthread, in_bytes(JavaThread::dirty_card_queue_offset() +
+ DirtyCardQueue::byte_offset_of_index()));
+ Address buffer(Rthread, in_bytes(JavaThread::dirty_card_queue_offset() +
+ DirtyCardQueue::byte_offset_of_buf()));
+
+ BarrierSet* bs = Universe::heap()->barrier_set();
+ CardTableModRefBS* ct = (CardTableModRefBS*)bs;
+ Label done;
+ Label runtime;
+
+ // Does store cross heap regions?
+
+ eor(tmp1, store_addr, new_val);
+#ifdef AARCH64
+ logical_shift_right(tmp1, tmp1, HeapRegion::LogOfHRGrainBytes);
+ cbz(tmp1, done);
+#else
+ movs(tmp1, AsmOperand(tmp1, lsr, HeapRegion::LogOfHRGrainBytes));
+ b(done, eq);
+#endif
+
+ // crosses regions, storing NULL?
+
+ cbz(new_val, done);
+
+ // storing region crossing non-NULL, is card already dirty?
+ const Register card_addr = tmp1;
+ assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
+
+ mov_address(tmp2, (address)ct->byte_map_base, symbolic_Relocation::card_table_reference);
+ add(card_addr, tmp2, AsmOperand(store_addr, lsr, CardTableModRefBS::card_shift));
+
+ ldrb(tmp2, Address(card_addr));
+ cmp(tmp2, (int)G1SATBCardTableModRefBS::g1_young_card_val());
+ b(done, eq);
+
+ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreLoad), tmp2);
+
+ assert(CardTableModRefBS::dirty_card_val() == 0, "adjust this code");
+ ldrb(tmp2, Address(card_addr));
+ cbz(tmp2, done);
+
+ // storing a region crossing, non-NULL oop, card is clean.
+ // dirty card and log.
+
+ strb(zero_register(tmp2), Address(card_addr));
+
+ ldr(tmp2, queue_index);
+ ldr(tmp3, buffer);
+
+ subs(tmp2, tmp2, wordSize);
+ b(runtime, lt); // go to runtime if now negative
+
+ str(tmp2, queue_index);
+
+ str(card_addr, Address(tmp3, tmp2));
+ b(done);
+
+ bind(runtime);
+
+ if (card_addr != R0) {
+ mov(R0, card_addr);
+ }
+ mov(R1, Rthread);
+ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), R0, R1);
+
+ bind(done);
+}
+
+#endif // INCLUDE_ALL_GCS
+
+//////////////////////////////////////////////////////////////////////////////////
+
#ifdef AARCH64
void MacroAssembler::load_sized_value(Register dst, Address src, size_t size_in_bytes, bool is_signed) {
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/cpu/arm/vm/macroAssembler_arm.hpp
--- a/hotspot/src/cpu/arm/vm/macroAssembler_arm.hpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/cpu/arm/vm/macroAssembler_arm.hpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2017, 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
@@ -402,6 +402,29 @@
void biased_locking_enter_with_cas(Register obj_reg, Register old_mark_reg, Register new_mark_reg,
Register tmp, Label& slow_case, int* counter_addr);
+ void resolve_jobject(Register value, Register tmp1, Register tmp2);
+
+#if INCLUDE_ALL_GCS
+ // G1 pre-barrier.
+ // Blows all volatile registers (R0-R3 on 32-bit ARM, R0-R18 on AArch64, Rtemp, LR).
+ // If store_addr != noreg, then previous value is loaded from [store_addr];
+ // in such case store_addr and new_val registers are preserved;
+ // otherwise pre_val register is preserved.
+ void g1_write_barrier_pre(Register store_addr,
+ Register new_val,
+ Register pre_val,
+ Register tmp1,
+ Register tmp2);
+
+ // G1 post-barrier.
+ // Blows all volatile registers (R0-R3 on 32-bit ARM, R0-R18 on AArch64, Rtemp, LR).
+ void g1_write_barrier_post(Register store_addr,
+ Register new_val,
+ Register tmp1,
+ Register tmp2,
+ Register tmp3);
+#endif // INCLUDE_ALL_GCS
+
#ifndef AARCH64
void nop() {
mov(R0, R0);
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/cpu/arm/vm/sharedRuntime_arm.cpp
--- a/hotspot/src/cpu/arm/vm/sharedRuntime_arm.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/cpu/arm/vm/sharedRuntime_arm.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2017, 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
@@ -1732,14 +1732,7 @@
case T_FLOAT : // fall through
case T_DOUBLE : /* nothing to do */ break;
case T_OBJECT : // fall through
- case T_ARRAY : {
- Label L;
- __ cbz(R0, L);
- __ ldr(R0, Address(R0));
- __ verify_oop(R0);
- __ bind(L);
- break;
- }
+ case T_ARRAY : break; // See JNIHandles::resolve below
default:
ShouldNotReachHere();
}
@@ -1748,13 +1741,14 @@
if (CheckJNICalls) {
__ str(__ zero_register(Rtemp), Address(Rthread, JavaThread::pending_jni_exception_check_fn_offset()));
}
+#endif // AARCH64
- // Unhandle the result
+ // Unbox oop result, e.g. JNIHandles::resolve value in R0.
if (ret_type == T_OBJECT || ret_type == T_ARRAY) {
- __ cmp(R0, 0);
- __ ldr(R0, Address(R0), ne);
+ __ resolve_jobject(R0, // value
+ Rtemp, // tmp1
+ R1_tmp); // tmp2
}
-#endif // AARCH64
// Any exception pending?
__ ldr(Rtemp, Address(Rthread, Thread::pending_exception_offset()));
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/cpu/arm/vm/templateInterpreterGenerator_arm.cpp
--- a/hotspot/src/cpu/arm/vm/templateInterpreterGenerator_arm.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/cpu/arm/vm/templateInterpreterGenerator_arm.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2017, 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
@@ -1240,28 +1240,25 @@
__ str(__ zero_register(Rtemp), Address(Rthread, JavaThread::pending_jni_exception_check_fn_offset()));
}
- // Unbox if the result is non-zero object
+ // Unbox oop result, e.g. JNIHandles::resolve result if it's an oop.
+ {
+ Label Lnot_oop;
#ifdef AARCH64
- {
- Label L, Lnull;
__ mov_slow(Rtemp, AbstractInterpreter::result_handler(T_OBJECT));
__ cmp(Rresult_handler, Rtemp);
- __ b(L, ne);
- __ cbz(Rsaved_result, Lnull);
- __ ldr(Rsaved_result, Address(Rsaved_result));
- __ bind(Lnull);
- // Store oop on the stack for GC
- __ str(Rsaved_result, Address(FP, frame::interpreter_frame_oop_temp_offset * wordSize));
- __ bind(L);
+ __ b(Lnot_oop, ne);
+#else // !AARCH64
+ // For ARM32, Rresult_handler is -1 for oop result, 0 otherwise.
+ __ cbz(Rresult_handler, Lnot_oop);
+#endif // !AARCH64
+ Register value = AARCH64_ONLY(Rsaved_result) NOT_AARCH64(Rsaved_result_lo);
+ __ resolve_jobject(value, // value
+ Rtemp, // tmp1
+ R1_tmp); // tmp2
+ // Store resolved result in frame for GC visibility.
+ __ str(value, Address(FP, frame::interpreter_frame_oop_temp_offset * wordSize));
+ __ bind(Lnot_oop);
}
-#else
- __ tst(Rsaved_result_lo, Rresult_handler);
- __ ldr(Rsaved_result_lo, Address(Rsaved_result_lo), ne);
-
- // Store oop on the stack for GC
- __ cmp(Rresult_handler, 0);
- __ str(Rsaved_result_lo, Address(FP, frame::interpreter_frame_oop_temp_offset * wordSize), ne);
-#endif // AARCH64
#ifdef AARCH64
// Restore SP (drop native parameters area), to keep SP in sync with extended_sp in frame
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/cpu/ppc/vm/frame_ppc.cpp
--- a/hotspot/src/cpu/ppc/vm/frame_ppc.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/cpu/ppc/vm/frame_ppc.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2015 SAP SE. All rights reserved.
+ * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -171,10 +171,7 @@
switch (method->result_type()) {
case T_OBJECT:
case T_ARRAY: {
- oop* obj_p = *(oop**)lresult;
- oop obj = (obj_p == NULL) ? (oop)NULL : *obj_p;
- assert(obj == NULL || Universe::heap()->is_in(obj), "sanity check");
- *oop_result = obj;
+ *oop_result = JNIHandles::resolve(*(jobject*)lresult);
break;
}
// We use std/stfd to store the values.
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp
--- a/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2016 SAP SE. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -3033,6 +3033,34 @@
stbx(R0, Rtmp, Robj);
}
+// Kills R31 if value is a volatile register.
+void MacroAssembler::resolve_jobject(Register value, Register tmp1, Register tmp2, bool needs_frame) {
+ Label done;
+ cmpdi(CCR0, value, 0);
+ beq(CCR0, done); // Use NULL as-is.
+
+ clrrdi(tmp1, value, JNIHandles::weak_tag_size);
+#if INCLUDE_ALL_GCS
+ if (UseG1GC) { andi_(tmp2, value, JNIHandles::weak_tag_mask); }
+#endif
+ ld(value, 0, tmp1); // Resolve (untagged) jobject.
+
+#if INCLUDE_ALL_GCS
+ if (UseG1GC) {
+ Label not_weak;
+ beq(CCR0, not_weak); // Test for jweak tag.
+ verify_oop(value);
+ g1_write_barrier_pre(noreg, // obj
+ noreg, // offset
+ value, // pre_val
+ tmp1, tmp2, needs_frame);
+ bind(not_weak);
+ }
+#endif // INCLUDE_ALL_GCS
+ verify_oop(value);
+ bind(done);
+}
+
#if INCLUDE_ALL_GCS
// General G1 pre-barrier generator.
// Goal: record the previous value if it is not null.
@@ -3094,7 +3122,7 @@
bind(runtime);
- // VM call need frame to access(write) O register.
+ // May need to preserve LR. Also needed if current frame is not compatible with C calling convention.
if (needs_frame) {
save_LR_CR(Rtmp1);
push_frame_reg_args(0, Rtmp2);
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/cpu/ppc/vm/macroAssembler_ppc.hpp
--- a/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.hpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.hpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2016 SAP SE. All rights reserved.
+ * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -649,6 +649,8 @@
void card_write_barrier_post(Register Rstore_addr, Register Rnew_val, Register Rtmp);
void card_table_write(jbyte* byte_map_base, Register Rtmp, Register Robj);
+ void resolve_jobject(Register value, Register tmp1, Register tmp2, bool needs_frame);
+
#if INCLUDE_ALL_GCS
// General G1 pre-barrier generator.
void g1_write_barrier_pre(Register Robj, RegisterOrConstant offset, Register Rpre_val,
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp
--- a/hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2016 SAP SE. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -2477,16 +2477,11 @@
__ reset_last_Java_frame();
- // Unpack oop result.
+ // Unbox oop result, e.g. JNIHandles::resolve value.
// --------------------------------------------------------------------------
if (ret_type == T_OBJECT || ret_type == T_ARRAY) {
- Label skip_unboxing;
- __ cmpdi(CCR0, R3_RET, 0);
- __ beq(CCR0, skip_unboxing);
- __ ld(R3_RET, 0, R3_RET);
- __ bind(skip_unboxing);
- __ verify_oop(R3_RET);
+ __ resolve_jobject(R3_RET, r_temp_1, r_temp_2, /* needs_frame */ false); // kills R31
}
if (CheckJNICalls) {
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/cpu/ppc/vm/templateInterpreterGenerator_ppc.cpp
--- a/hotspot/src/cpu/ppc/vm/templateInterpreterGenerator_ppc.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/cpu/ppc/vm/templateInterpreterGenerator_ppc.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2015, 2016 SAP SE. All rights reserved.
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -401,11 +401,8 @@
case T_LONG:
break;
case T_OBJECT:
- // unbox result if not null
- __ cmpdi(CCR0, R3_RET, 0);
- __ beq(CCR0, done);
- __ ld(R3_RET, 0, R3_RET);
- __ verify_oop(R3_RET);
+ // JNIHandles::resolve result.
+ __ resolve_jobject(R3_RET, R11_scratch1, R12_scratch2, /* needs_frame */ true); // kills R31
break;
case T_FLOAT:
break;
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/cpu/s390/vm/macroAssembler_s390.cpp
--- a/hotspot/src/cpu/s390/vm/macroAssembler_s390.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/cpu/s390/vm/macroAssembler_s390.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -3439,6 +3439,34 @@
z_mvi(0, store_addr, 0); // Store byte 0.
}
+void MacroAssembler::resolve_jobject(Register value, Register tmp1, Register tmp2) {
+ NearLabel Ldone;
+ z_ltgr(tmp1, value);
+ z_bre(Ldone); // Use NULL result as-is.
+
+ z_nill(value, ~JNIHandles::weak_tag_mask);
+ z_lg(value, 0, value); // Resolve (untagged) jobject.
+
+#if INCLUDE_ALL_GCS
+ if (UseG1GC) {
+ NearLabel Lnot_weak;
+ z_tmll(tmp1, JNIHandles::weak_tag_mask); // Test for jweak tag.
+ z_braz(Lnot_weak);
+ verify_oop(value);
+ g1_write_barrier_pre(noreg /* obj */,
+ noreg /* offset */,
+ value /* pre_val */,
+ noreg /* val */,
+ tmp1 /* tmp1 */,
+ tmp2 /* tmp2 */,
+ true /* pre_val_needed */);
+ bind(Lnot_weak);
+ }
+#endif // INCLUDE_ALL_GCS
+ verify_oop(value);
+ bind(Ldone);
+}
+
#if INCLUDE_ALL_GCS
//------------------------------------------------------
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/cpu/s390/vm/macroAssembler_s390.hpp
--- a/hotspot/src/cpu/s390/vm/macroAssembler_s390.hpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/cpu/s390/vm/macroAssembler_s390.hpp Wed Jul 05 23:09:40 2017 +0200
@@ -726,6 +726,8 @@
// Write to card table for modification at store_addr - register is destroyed afterwards.
void card_write_barrier_post(Register store_addr, Register tmp);
+ void resolve_jobject(Register value, Register tmp1, Register tmp2);
+
#if INCLUDE_ALL_GCS
// General G1 pre-barrier generator.
// Purpose: record the previous value if it is not null.
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/cpu/s390/vm/sharedRuntime_s390.cpp
--- a/hotspot/src/cpu/s390/vm/sharedRuntime_s390.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/cpu/s390/vm/sharedRuntime_s390.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2016 SAP SE. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -2272,13 +2272,9 @@
__ reset_last_Java_frame();
- // Unpack oop result
+ // Unpack oop result, e.g. JNIHandles::resolve result.
if (ret_type == T_OBJECT || ret_type == T_ARRAY) {
- NearLabel L;
- __ compare64_and_branch(Z_RET, (RegisterOrConstant)0L, Assembler::bcondEqual, L);
- __ z_lg(Z_RET, 0, Z_RET);
- __ bind(L);
- __ verify_oop(Z_RET);
+ __ resolve_jobject(Z_RET, /* tmp1 */ Z_R13, /* tmp2 */ Z_R7);
}
if (CheckJNICalls) {
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/cpu/s390/vm/templateInterpreterGenerator_s390.cpp
--- a/hotspot/src/cpu/s390/vm/templateInterpreterGenerator_s390.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/cpu/s390/vm/templateInterpreterGenerator_s390.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2016 SAP SE. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1695,14 +1695,11 @@
// from the jni handle to z_ijava_state.oop_temp. This is
// necessary, because we reset the jni handle block below.
// NOTE: frame::interpreter_frame_result() depends on this, too.
- { NearLabel no_oop_result, store_oop_result;
+ { NearLabel no_oop_result;
__ load_absolute_address(Z_R1, AbstractInterpreter::result_handler(T_OBJECT));
__ compareU64_and_branch(Z_R1, Rresult_handler, Assembler::bcondNotEqual, no_oop_result);
- __ compareU64_and_branch(Rlresult, (intptr_t)0L, Assembler::bcondEqual, store_oop_result);
- __ z_lg(Rlresult, 0, Rlresult); // unbox
- __ bind(store_oop_result);
+ __ resolve_jobject(Rlresult, /* tmp1 */ Rmethod, /* tmp2 */ Z_R1);
__ z_stg(Rlresult, oop_tmp_offset, Z_fp);
- __ verify_oop(Rlresult);
__ bind(no_oop_result);
}
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/cpu/sparc/vm/jniFastGetField_sparc.cpp
--- a/hotspot/src/cpu/sparc/vm/jniFastGetField_sparc.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/cpu/sparc/vm/jniFastGetField_sparc.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -68,6 +68,7 @@
__ andcc (G4, 1, G0);
__ br (Assembler::notZero, false, Assembler::pn, label1);
__ delayed()->srl (O2, 2, O4);
+ __ andn (O1, JNIHandles::weak_tag_mask, O1);
__ ld_ptr (O1, 0, O5);
assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
@@ -147,6 +148,7 @@
__ andcc (G4, 1, G0);
__ br (Assembler::notZero, false, Assembler::pn, label1);
__ delayed()->srl (O2, 2, O4);
+ __ andn (O1, JNIHandles::weak_tag_mask, O1);
__ ld_ptr (O1, 0, O5);
__ add (O5, O4, O5);
@@ -219,6 +221,7 @@
__ andcc (G4, 1, G0);
__ br (Assembler::notZero, false, Assembler::pn, label1);
__ delayed()->srl (O2, 2, O4);
+ __ andn (O1, JNIHandles::weak_tag_mask, O1);
__ ld_ptr (O1, 0, O5);
assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp
--- a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -2754,15 +2754,30 @@
__ verify_thread(); // G2_thread must be correct
__ reset_last_Java_frame();
- // Unpack oop result
+ // Unbox oop result, e.g. JNIHandles::resolve value in I0.
if (ret_type == T_OBJECT || ret_type == T_ARRAY) {
- Label L;
- __ addcc(G0, I0, G0);
- __ brx(Assembler::notZero, true, Assembler::pt, L);
- __ delayed()->ld_ptr(I0, 0, I0);
- __ mov(G0, I0);
- __ bind(L);
- __ verify_oop(I0);
+ Label done, not_weak;
+ __ br_null(I0, false, Assembler::pn, done); // Use NULL as-is.
+ __ delayed()->andcc(I0, JNIHandles::weak_tag_mask, G0); // Test for jweak
+ __ brx(Assembler::zero, true, Assembler::pt, not_weak);
+ __ delayed()->ld_ptr(I0, 0, I0); // Maybe resolve (untagged) jobject.
+ // Resolve jweak.
+ __ ld_ptr(I0, -JNIHandles::weak_tag_value, I0);
+#if INCLUDE_ALL_GCS
+ if (UseG1GC) {
+ // Copy to O0 because macro doesn't allow pre_val in input reg.
+ __ mov(I0, O0);
+ __ g1_write_barrier_pre(noreg /* obj */,
+ noreg /* index */,
+ 0 /* offset */,
+ O0 /* pre_val */,
+ G3_scratch /* tmp */,
+ true /* preserve_o_regs */);
+ }
+#endif // INCLUDE_ALL_GCS
+ __ bind(not_weak);
+ __ verify_oop(I0);
+ __ bind(done);
}
if (CheckJNICalls) {
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/cpu/sparc/vm/templateInterpreterGenerator_sparc.cpp
--- a/hotspot/src/cpu/sparc/vm/templateInterpreterGenerator_sparc.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/cpu/sparc/vm/templateInterpreterGenerator_sparc.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -1516,11 +1516,23 @@
__ set((intptr_t)AbstractInterpreter::result_handler(T_OBJECT), G3_scratch);
__ cmp_and_brx_short(G3_scratch, Lscratch, Assembler::notEqual, Assembler::pt, no_oop);
- __ addcc(G0, O0, O0);
- __ brx(Assembler::notZero, true, Assembler::pt, store_result); // if result is not NULL:
- __ delayed()->ld_ptr(O0, 0, O0); // unbox it
- __ mov(G0, O0);
-
+ // Unbox oop result, e.g. JNIHandles::resolve value in O0.
+ __ br_null(O0, false, Assembler::pn, store_result); // Use NULL as-is.
+ __ delayed()->andcc(O0, JNIHandles::weak_tag_mask, G0); // Test for jweak
+ __ brx(Assembler::zero, true, Assembler::pt, store_result);
+ __ delayed()->ld_ptr(O0, 0, O0); // Maybe resolve (untagged) jobject.
+ // Resolve jweak.
+ __ ld_ptr(O0, -JNIHandles::weak_tag_value, O0);
+#if INCLUDE_ALL_GCS
+ if (UseG1GC) {
+ __ g1_write_barrier_pre(noreg /* obj */,
+ noreg /* index */,
+ 0 /* offset */,
+ O0 /* pre_val */,
+ G3_scratch /* tmp */,
+ true /* preserve_o_regs */);
+ }
+#endif // INCLUDE_ALL_GCS
__ bind(store_result);
// Store it where gc will look for it and result handler expects it.
__ st_ptr(O0, FP, (frame::interpreter_frame_oop_temp_offset*wordSize) + STACK_BIAS);
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/cpu/x86/vm/jniFastGetField_x86_32.cpp
--- a/hotspot/src/cpu/x86/vm/jniFastGetField_x86_32.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/cpu/x86/vm/jniFastGetField_x86_32.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2017, 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
@@ -85,6 +85,9 @@
__ movptr (rdx, Address(rsp, 2*wordSize)); // obj
}
__ movptr(rax, Address(rsp, 3*wordSize)); // jfieldID
+
+ __ clear_jweak_tag(rdx);
+
__ movptr(rdx, Address(rdx, 0)); // *obj
__ shrptr (rax, 2); // offset
@@ -202,6 +205,9 @@
__ movptr(rdx, Address(rsp, 3*wordSize)); // obj
}
__ movptr(rsi, Address(rsp, 4*wordSize)); // jfieldID
+
+ __ clear_jweak_tag(rdx);
+
__ movptr(rdx, Address(rdx, 0)); // *obj
__ shrptr(rsi, 2); // offset
@@ -291,6 +297,9 @@
__ movptr(rdx, Address(rsp, 2*wordSize)); // obj
}
__ movptr(rax, Address(rsp, 3*wordSize)); // jfieldID
+
+ __ clear_jweak_tag(rdx);
+
__ movptr(rdx, Address(rdx, 0)); // *obj
__ shrptr(rax, 2); // offset
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/cpu/x86/vm/jniFastGetField_x86_64.cpp
--- a/hotspot/src/cpu/x86/vm/jniFastGetField_x86_64.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/cpu/x86/vm/jniFastGetField_x86_64.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2017, 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
@@ -80,6 +80,9 @@
// robj ^ rcounter ^ rcounter == robj
// robj is data dependent on rcounter.
}
+
+ __ clear_jweak_tag(robj);
+
__ movptr(robj, Address(robj, 0)); // *obj
__ mov (roffset, c_rarg2);
__ shrptr(roffset, 2); // offset
@@ -178,6 +181,9 @@
// robj ^ rcounter ^ rcounter == robj
// robj is data dependent on rcounter.
}
+
+ __ clear_jweak_tag(robj);
+
__ movptr(robj, Address(robj, 0)); // *obj
__ mov (roffset, c_rarg2);
__ shrptr(roffset, 2); // offset
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -5129,6 +5129,43 @@
}
+void MacroAssembler::resolve_jobject(Register value,
+ Register thread,
+ Register tmp) {
+ assert_different_registers(value, thread, tmp);
+ Label done, not_weak;
+ testptr(value, value);
+ jcc(Assembler::zero, done); // Use NULL as-is.
+ testptr(value, JNIHandles::weak_tag_mask); // Test for jweak tag.
+ jcc(Assembler::zero, not_weak);
+ // Resolve jweak.
+ movptr(value, Address(value, -JNIHandles::weak_tag_value));
+ verify_oop(value);
+#if INCLUDE_ALL_GCS
+ if (UseG1GC) {
+ g1_write_barrier_pre(noreg /* obj */,
+ value /* pre_val */,
+ thread /* thread */,
+ tmp /* tmp */,
+ true /* tosca_live */,
+ true /* expand_call */);
+ }
+#endif // INCLUDE_ALL_GCS
+ jmp(done);
+ bind(not_weak);
+ // Resolve (untagged) jobject.
+ movptr(value, Address(value, 0));
+ verify_oop(value);
+ bind(done);
+}
+
+void MacroAssembler::clear_jweak_tag(Register possibly_jweak) {
+ const int32_t inverted_jweak_mask = ~static_cast(JNIHandles::weak_tag_mask);
+ STATIC_ASSERT(inverted_jweak_mask == -2); // otherwise check this code
+ // The inverted mask is sign-extended
+ andptr(possibly_jweak, inverted_jweak_mask);
+}
+
//////////////////////////////////////////////////////////////////////////////////
#if INCLUDE_ALL_GCS
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -297,6 +297,9 @@
void store_check(Register obj); // store check for obj - register is destroyed afterwards
void store_check(Register obj, Address dst); // same as above, dst is exact store location (reg. is destroyed)
+ void resolve_jobject(Register value, Register thread, Register tmp);
+ void clear_jweak_tag(Register possibly_jweak);
+
#if INCLUDE_ALL_GCS
void g1_write_barrier_pre(Register obj,
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -2226,14 +2226,11 @@
__ reset_last_Java_frame(thread, false);
- // Unpack oop result
+ // Unbox oop result, e.g. JNIHandles::resolve value.
if (ret_type == T_OBJECT || ret_type == T_ARRAY) {
- Label L;
- __ cmpptr(rax, (int32_t)NULL_WORD);
- __ jcc(Assembler::equal, L);
- __ movptr(rax, Address(rax, 0));
- __ bind(L);
- __ verify_oop(rax);
+ __ resolve_jobject(rax /* value */,
+ thread /* thread */,
+ rcx /* tmp */);
}
if (CheckJNICalls) {
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -2579,14 +2579,11 @@
__ reset_last_Java_frame(false);
- // Unpack oop result
+ // Unbox oop result, e.g. JNIHandles::resolve value.
if (ret_type == T_OBJECT || ret_type == T_ARRAY) {
- Label L;
- __ testptr(rax, rax);
- __ jcc(Assembler::zero, L);
- __ movptr(rax, Address(rax, 0));
- __ bind(L);
- __ verify_oop(rax);
+ __ resolve_jobject(rax /* value */,
+ r15_thread /* thread */,
+ rcx /* tmp */);
}
if (CheckJNICalls) {
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86.cpp
--- a/hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -1193,16 +1193,16 @@
// and result handler will pick it up
{
- Label no_oop, store_result;
+ Label no_oop, not_weak, store_result;
__ lea(t, ExternalAddress(AbstractInterpreter::result_handler(T_OBJECT)));
__ cmpptr(t, Address(rbp, frame::interpreter_frame_result_handler_offset*wordSize));
__ jcc(Assembler::notEqual, no_oop);
// retrieve result
__ pop(ltos);
- __ testptr(rax, rax);
- __ jcc(Assembler::zero, store_result);
- __ movptr(rax, Address(rax, 0));
- __ bind(store_result);
+ // Unbox oop result, e.g. JNIHandles::resolve value.
+ __ resolve_jobject(rax /* value */,
+ thread /* thread */,
+ t /* tmp */);
__ movptr(Address(rbp, frame::interpreter_frame_oop_temp_offset*wordSize), rax);
// keep stack depth as expected by pushing oop which will eventually be discarded
__ push(ltos);
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp
--- a/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -406,10 +406,12 @@
// oop_temp where the garbage collector can see it before
// we release the handle it might be protected by.
if (handler->result_type() == &ffi_type_pointer) {
- if (result[0])
- istate->set_oop_temp(*(oop *) result[0]);
- else
+ if (result[0] == 0) {
istate->set_oop_temp(NULL);
+ } else {
+ jobject handle = reinterpret_cast(result[0]);
+ istate->set_oop_temp(JNIHandles::resolve(handle));
+ }
}
// Reset handle block
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/share/vm/Xusage.txt
--- a/hotspot/src/share/vm/Xusage.txt Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/share/vm/Xusage.txt Wed Jul 05 23:09:40 2017 +0200
@@ -12,7 +12,7 @@
-Xms set initial Java heap size
-Xmx set maximum Java heap size
-Xss set java thread stack size
- -Xprof output cpu profiling data
+ -Xprof output cpu profiling data (deprecated)
-Xfuture enable strictest checks, anticipating future default
-Xrs reduce use of OS signals by Java/VM (see documentation)
-Xcheck:jni perform additional checks for JNI functions
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/share/vm/c1/c1_GraphBuilder.cpp
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -1540,7 +1540,7 @@
ciMethod* caller = state()->scope()->method();
ciMethodData* md = caller->method_data_or_null();
ciProfileData* data = md->bci_to_data(invoke_bci);
- if (data->is_CallTypeData() || data->is_VirtualCallTypeData()) {
+ if (data != NULL && (data->is_CallTypeData() || data->is_VirtualCallTypeData())) {
bool has_return = data->is_CallTypeData() ? ((ciCallTypeData*)data)->has_return() : ((ciVirtualCallTypeData*)data)->has_return();
// May not be true in case of an inlined call through a method handle intrinsic.
if (has_return) {
@@ -1758,7 +1758,7 @@
start = has_receiver ? 1 : 0;
if (profile_arguments()) {
ciProfileData* data = method()->method_data()->bci_to_data(bci());
- if (data->is_CallTypeData() || data->is_VirtualCallTypeData()) {
+ if (data != NULL && (data->is_CallTypeData() || data->is_VirtualCallTypeData())) {
n = data->is_CallTypeData() ? data->as_CallTypeData()->number_of_arguments() : data->as_VirtualCallTypeData()->number_of_arguments();
}
}
@@ -4349,7 +4349,7 @@
}
ciMethodData* md = m->method_data_or_null();
ciProfileData* data = md->bci_to_data(invoke_bci);
- if (data->is_CallTypeData() || data->is_VirtualCallTypeData()) {
+ if (data != NULL && (data->is_CallTypeData() || data->is_VirtualCallTypeData())) {
append(new ProfileReturnType(m , invoke_bci, callee, ret));
}
}
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/share/vm/c1/c1_LIRGenerator.cpp
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -3262,50 +3262,52 @@
int bci = x->bci_of_invoke();
ciMethodData* md = x->method()->method_data_or_null();
ciProfileData* data = md->bci_to_data(bci);
- if ((data->is_CallTypeData() && data->as_CallTypeData()->has_arguments()) ||
- (data->is_VirtualCallTypeData() && data->as_VirtualCallTypeData()->has_arguments())) {
- ByteSize extra = data->is_CallTypeData() ? CallTypeData::args_data_offset() : VirtualCallTypeData::args_data_offset();
- int base_offset = md->byte_offset_of_slot(data, extra);
- LIR_Opr mdp = LIR_OprFact::illegalOpr;
- ciTypeStackSlotEntries* args = data->is_CallTypeData() ? ((ciCallTypeData*)data)->args() : ((ciVirtualCallTypeData*)data)->args();
-
- Bytecodes::Code bc = x->method()->java_code_at_bci(bci);
- int start = 0;
- int stop = data->is_CallTypeData() ? ((ciCallTypeData*)data)->number_of_arguments() : ((ciVirtualCallTypeData*)data)->number_of_arguments();
- if (x->callee()->is_loaded() && x->callee()->is_static() && Bytecodes::has_receiver(bc)) {
- // first argument is not profiled at call (method handle invoke)
- assert(x->method()->raw_code_at_bci(bci) == Bytecodes::_invokehandle, "invokehandle expected");
- start = 1;
+ if (data != NULL) {
+ if ((data->is_CallTypeData() && data->as_CallTypeData()->has_arguments()) ||
+ (data->is_VirtualCallTypeData() && data->as_VirtualCallTypeData()->has_arguments())) {
+ ByteSize extra = data->is_CallTypeData() ? CallTypeData::args_data_offset() : VirtualCallTypeData::args_data_offset();
+ int base_offset = md->byte_offset_of_slot(data, extra);
+ LIR_Opr mdp = LIR_OprFact::illegalOpr;
+ ciTypeStackSlotEntries* args = data->is_CallTypeData() ? ((ciCallTypeData*)data)->args() : ((ciVirtualCallTypeData*)data)->args();
+
+ Bytecodes::Code bc = x->method()->java_code_at_bci(bci);
+ int start = 0;
+ int stop = data->is_CallTypeData() ? ((ciCallTypeData*)data)->number_of_arguments() : ((ciVirtualCallTypeData*)data)->number_of_arguments();
+ if (x->callee()->is_loaded() && x->callee()->is_static() && Bytecodes::has_receiver(bc)) {
+ // first argument is not profiled at call (method handle invoke)
+ assert(x->method()->raw_code_at_bci(bci) == Bytecodes::_invokehandle, "invokehandle expected");
+ start = 1;
+ }
+ ciSignature* callee_signature = x->callee()->signature();
+ // method handle call to virtual method
+ bool has_receiver = x->callee()->is_loaded() && !x->callee()->is_static() && !Bytecodes::has_receiver(bc);
+ ciSignatureStream callee_signature_stream(callee_signature, has_receiver ? x->callee()->holder() : NULL);
+
+ bool ignored_will_link;
+ ciSignature* signature_at_call = NULL;
+ x->method()->get_method_at_bci(bci, ignored_will_link, &signature_at_call);
+ ciSignatureStream signature_at_call_stream(signature_at_call);
+
+ // if called through method handle invoke, some arguments may have been popped
+ for (int i = 0; i < stop && i+start < x->nb_profiled_args(); i++) {
+ int off = in_bytes(TypeEntriesAtCall::argument_type_offset(i)) - in_bytes(TypeEntriesAtCall::args_data_offset());
+ ciKlass* exact = profile_type(md, base_offset, off,
+ args->type(i), x->profiled_arg_at(i+start), mdp,
+ !x->arg_needs_null_check(i+start),
+ signature_at_call_stream.next_klass(), callee_signature_stream.next_klass());
+ if (exact != NULL) {
+ md->set_argument_type(bci, i, exact);
+ }
+ }
+ } else {
+#ifdef ASSERT
+ Bytecodes::Code code = x->method()->raw_code_at_bci(x->bci_of_invoke());
+ int n = x->nb_profiled_args();
+ assert(MethodData::profile_parameters() && (MethodData::profile_arguments_jsr292_only() ||
+ (x->inlined() && ((code == Bytecodes::_invokedynamic && n <= 1) || (code == Bytecodes::_invokehandle && n <= 2)))),
+ "only at JSR292 bytecodes");
+#endif
}
- ciSignature* callee_signature = x->callee()->signature();
- // method handle call to virtual method
- bool has_receiver = x->callee()->is_loaded() && !x->callee()->is_static() && !Bytecodes::has_receiver(bc);
- ciSignatureStream callee_signature_stream(callee_signature, has_receiver ? x->callee()->holder() : NULL);
-
- bool ignored_will_link;
- ciSignature* signature_at_call = NULL;
- x->method()->get_method_at_bci(bci, ignored_will_link, &signature_at_call);
- ciSignatureStream signature_at_call_stream(signature_at_call);
-
- // if called through method handle invoke, some arguments may have been popped
- for (int i = 0; i < stop && i+start < x->nb_profiled_args(); i++) {
- int off = in_bytes(TypeEntriesAtCall::argument_type_offset(i)) - in_bytes(TypeEntriesAtCall::args_data_offset());
- ciKlass* exact = profile_type(md, base_offset, off,
- args->type(i), x->profiled_arg_at(i+start), mdp,
- !x->arg_needs_null_check(i+start),
- signature_at_call_stream.next_klass(), callee_signature_stream.next_klass());
- if (exact != NULL) {
- md->set_argument_type(bci, i, exact);
- }
- }
- } else {
-#ifdef ASSERT
- Bytecodes::Code code = x->method()->raw_code_at_bci(x->bci_of_invoke());
- int n = x->nb_profiled_args();
- assert(MethodData::profile_parameters() && (MethodData::profile_arguments_jsr292_only() ||
- (x->inlined() && ((code == Bytecodes::_invokedynamic && n <= 1) || (code == Bytecodes::_invokehandle && n <= 2)))),
- "only at JSR292 bytecodes");
-#endif
}
}
}
@@ -3396,24 +3398,26 @@
int bci = x->bci_of_invoke();
ciMethodData* md = x->method()->method_data_or_null();
ciProfileData* data = md->bci_to_data(bci);
- assert(data->is_CallTypeData() || data->is_VirtualCallTypeData(), "wrong profile data type");
- ciReturnTypeEntry* ret = data->is_CallTypeData() ? ((ciCallTypeData*)data)->ret() : ((ciVirtualCallTypeData*)data)->ret();
- LIR_Opr mdp = LIR_OprFact::illegalOpr;
-
- bool ignored_will_link;
- ciSignature* signature_at_call = NULL;
- x->method()->get_method_at_bci(bci, ignored_will_link, &signature_at_call);
-
- // The offset within the MDO of the entry to update may be too large
- // to be used in load/store instructions on some platforms. So have
- // profile_type() compute the address of the profile in a register.
- ciKlass* exact = profile_type(md, md->byte_offset_of_slot(data, ret->type_offset()), 0,
- ret->type(), x->ret(), mdp,
- !x->needs_null_check(),
- signature_at_call->return_type()->as_klass(),
- x->callee()->signature()->return_type()->as_klass());
- if (exact != NULL) {
- md->set_return_type(bci, exact);
+ if (data != NULL) {
+ assert(data->is_CallTypeData() || data->is_VirtualCallTypeData(), "wrong profile data type");
+ ciReturnTypeEntry* ret = data->is_CallTypeData() ? ((ciCallTypeData*)data)->ret() : ((ciVirtualCallTypeData*)data)->ret();
+ LIR_Opr mdp = LIR_OprFact::illegalOpr;
+
+ bool ignored_will_link;
+ ciSignature* signature_at_call = NULL;
+ x->method()->get_method_at_bci(bci, ignored_will_link, &signature_at_call);
+
+ // The offset within the MDO of the entry to update may be too large
+ // to be used in load/store instructions on some platforms. So have
+ // profile_type() compute the address of the profile in a register.
+ ciKlass* exact = profile_type(md, md->byte_offset_of_slot(data, ret->type_offset()), 0,
+ ret->type(), x->ret(), mdp,
+ !x->needs_null_check(),
+ signature_at_call->return_type()->as_klass(),
+ x->callee()->signature()->return_type()->as_klass());
+ if (exact != NULL) {
+ md->set_return_type(bci, exact);
+ }
}
}
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/share/vm/ci/ciMethodData.cpp
--- a/hotspot/src/share/vm/ci/ciMethodData.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/share/vm/ci/ciMethodData.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -408,11 +408,13 @@
MethodData* mdo = get_MethodData();
if (mdo != NULL) {
ProfileData* data = mdo->bci_to_data(bci);
- if (data->is_CallTypeData()) {
- data->as_CallTypeData()->set_argument_type(i, k->get_Klass());
- } else {
- assert(data->is_VirtualCallTypeData(), "no arguments!");
- data->as_VirtualCallTypeData()->set_argument_type(i, k->get_Klass());
+ if (data != NULL) {
+ if (data->is_CallTypeData()) {
+ data->as_CallTypeData()->set_argument_type(i, k->get_Klass());
+ } else {
+ assert(data->is_VirtualCallTypeData(), "no arguments!");
+ data->as_VirtualCallTypeData()->set_argument_type(i, k->get_Klass());
+ }
}
}
}
@@ -430,11 +432,13 @@
MethodData* mdo = get_MethodData();
if (mdo != NULL) {
ProfileData* data = mdo->bci_to_data(bci);
- if (data->is_CallTypeData()) {
- data->as_CallTypeData()->set_return_type(k->get_Klass());
- } else {
- assert(data->is_VirtualCallTypeData(), "no arguments!");
- data->as_VirtualCallTypeData()->set_return_type(k->get_Klass());
+ if (data != NULL) {
+ if (data->is_CallTypeData()) {
+ data->as_CallTypeData()->set_return_type(k->get_Klass());
+ } else {
+ assert(data->is_VirtualCallTypeData(), "no arguments!");
+ data->as_VirtualCallTypeData()->set_return_type(k->get_Klass());
+ }
}
}
}
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/share/vm/classfile/classFileParser.cpp
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -105,6 +105,12 @@
#define JAVA_9_VERSION 53
+void ClassFileParser::set_class_bad_constant_seen(short bad_constant) {
+ assert((bad_constant == 19 || bad_constant == 20) && _major_version >= JAVA_9_VERSION,
+ "Unexpected bad constant pool entry");
+ if (_bad_constant_seen == 0) _bad_constant_seen = bad_constant;
+}
+
void ClassFileParser::parse_constant_pool_entries(const ClassFileStream* const stream,
ConstantPool* cp,
const int length,
@@ -302,6 +308,18 @@
}
break;
}
+ case 19:
+ case 20: {
+ // Record that an error occurred in these two cases but keep parsing so
+ // that ACC_Module can be checked for in the access_flags. Need to
+ // throw NoClassDefFoundError in that case.
+ if (_major_version >= JAVA_9_VERSION) {
+ cfs->guarantee_more(3, CHECK);
+ cfs->get_u2_fast();
+ set_class_bad_constant_seen(tag);
+ break;
+ }
+ }
default: {
classfile_parse_error("Unknown constant tag %u in class file %s",
tag,
@@ -359,14 +377,18 @@
#endif
void ClassFileParser::parse_constant_pool(const ClassFileStream* const stream,
- ConstantPool* const cp,
- const int length,
- TRAPS) {
+ ConstantPool* const cp,
+ const int length,
+ TRAPS) {
assert(cp != NULL, "invariant");
assert(stream != NULL, "invariant");
// parsing constant pool entries
parse_constant_pool_entries(stream, cp, length, CHECK);
+ if (class_bad_constant_seen() != 0) {
+ // a bad CP entry has been detected previously so stop parsing and just return.
+ return;
+ }
int index = 1; // declared outside of loops for portability
@@ -1244,6 +1266,10 @@
}
} else if (_major_version >= JAVA_1_5_VERSION) {
if (attribute_name == vmSymbols::tag_signature()) {
+ if (generic_signature_index != 0) {
+ classfile_parse_error(
+ "Multiple Signature attributes for field in class file %s", CHECK);
+ }
if (attribute_length != 2) {
classfile_parse_error(
"Wrong size %u for field's Signature attribute in class file %s",
@@ -2565,6 +2591,11 @@
}
} else if (_major_version >= JAVA_1_5_VERSION) {
if (method_attribute_name == vmSymbols::tag_signature()) {
+ if (generic_signature_index != 0) {
+ classfile_parse_error(
+ "Multiple Signature attributes for method in class file %s",
+ CHECK_NULL);
+ }
if (method_attribute_length != 2) {
classfile_parse_error(
"Invalid Signature attribute length %u in class file %s",
@@ -3284,6 +3315,10 @@
}
} else if (_major_version >= JAVA_1_5_VERSION) {
if (tag == vmSymbols::tag_signature()) {
+ if (_generic_signature_index != 0) {
+ classfile_parse_error(
+ "Multiple Signature attributes in class file %s", CHECK);
+ }
if (attribute_length != 2) {
classfile_parse_error(
"Wrong Signature attribute length %u in class file %s",
@@ -5558,6 +5593,7 @@
_protection_domain(protection_domain),
_access_flags(),
_pub_level(pub_level),
+ _bad_constant_seen(0),
_synthetic_flag(false),
_sde_length(false),
_sde_buffer(NULL),
@@ -5765,9 +5801,15 @@
verify_legal_class_modifiers(flags, CHECK);
+ short bad_constant = class_bad_constant_seen();
+ if (bad_constant != 0) {
+ // Do not throw CFE until after the access_flags are checked because if
+ // ACC_MODULE is set in the access flags, then NCDFE must be thrown, not CFE.
+ classfile_parse_error("Unknown constant tag %u in class file %s", bad_constant, CHECK);
+ }
+
_access_flags.set_flags(flags);
-
// This class and superclass
_this_class_index = stream->get_u2_fast();
check_property(
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/share/vm/classfile/classFileParser.hpp
--- a/hotspot/src/share/vm/classfile/classFileParser.hpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/share/vm/classfile/classFileParser.hpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -122,6 +122,15 @@
// for tracing and notifications
Publicity _pub_level;
+ // Used to keep track of whether a constant pool item 19 or 20 is found. These
+ // correspond to CONSTANT_Module and CONSTANT_Package tags and are not allowed
+ // in regular class files. For class file version >= 53, a CFE cannot be thrown
+ // immediately when these are seen because a NCDFE must be thrown if the class's
+ // access_flags have ACC_MODULE set. But, the access_flags haven't been looked
+ // at yet. So, the bad constant pool item is cached here. A value of zero
+ // means that no constant pool item 19 or 20 was found.
+ short _bad_constant_seen;
+
// class attributes parsed before the instance klass is created:
bool _synthetic_flag;
int _sde_length;
@@ -161,6 +170,8 @@
void fill_instance_klass(InstanceKlass* ik, bool cf_changed_in_CFLH, TRAPS);
void set_klass(InstanceKlass* instance);
+ void set_class_bad_constant_seen(short bad_constant);
+ short class_bad_constant_seen() { return _bad_constant_seen; }
void set_class_synthetic_flag(bool x) { _synthetic_flag = x; }
void set_class_sourcefile_index(u2 x) { _sourcefile_index = x; }
void set_class_generic_signature_index(u2 x) { _generic_signature_index = x; }
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/share/vm/classfile/moduleEntry.hpp
--- a/hotspot/src/share/vm/classfile/moduleEntry.hpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/share/vm/classfile/moduleEntry.hpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, 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
@@ -36,8 +36,8 @@
#include "utilities/ostream.hpp"
#define UNNAMED_MODULE "Unnamed Module"
-#define JAVAPKG "java/"
-#define JAVAPKG_LEN 5
+#define JAVAPKG "java"
+#define JAVAPKG_LEN 4
#define JAVA_BASE_NAME "java.base"
class ModuleClosure;
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/share/vm/classfile/modules.cpp
--- a/hotspot/src/share/vm/classfile/modules.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/share/vm/classfile/modules.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -325,7 +325,8 @@
// Only modules defined to either the boot or platform class loader, can define a "java/" package.
if (!h_loader.is_null() &&
!SystemDictionary::is_platform_class_loader(h_loader) &&
- strncmp(package_name, JAVAPKG, JAVAPKG_LEN) == 0) {
+ (strncmp(package_name, JAVAPKG, JAVAPKG_LEN) == 0 &&
+ (package_name[JAVAPKG_LEN] == '/' || package_name[JAVAPKG_LEN] == '\0'))) {
const char* class_loader_name = SystemDictionary::loader_name(h_loader());
size_t pkg_len = strlen(package_name);
char* pkg_name = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, pkg_len);
@@ -748,7 +749,8 @@
// Only modules defined to either the boot or platform class loader, can define a "java/" package.
if (!loader_data->is_the_null_class_loader_data() &&
!loader_data->is_platform_class_loader_data() &&
- strncmp(package_name, JAVAPKG, JAVAPKG_LEN) == 0) {
+ (strncmp(package_name, JAVAPKG, JAVAPKG_LEN) == 0 &&
+ (package_name[JAVAPKG_LEN] == '/' || package_name[JAVAPKG_LEN] == '\0'))) {
const char* class_loader_name = SystemDictionary::loader_name(loader_data);
size_t pkg_len = strlen(package_name);
char* pkg_name = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, pkg_len);
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/share/vm/classfile/stringTable.cpp
--- a/hotspot/src/share/vm/classfile/stringTable.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/share/vm/classfile/stringTable.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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,10 +96,14 @@
// Pick hashing algorithm
unsigned int StringTable::hash_string(const jchar* s, int len) {
- return use_alternate_hashcode() ? AltHashing::murmur3_32(seed(), s, len) :
+ return use_alternate_hashcode() ? alt_hash_string(s, len) :
java_lang_String::hash_code(s, len);
}
+unsigned int StringTable::alt_hash_string(const jchar* s, int len) {
+ return AltHashing::murmur3_32(seed(), s, len);
+}
+
unsigned int StringTable::hash_string(oop string) {
EXCEPTION_MARK;
if (string == NULL) {
@@ -117,11 +121,10 @@
}
}
-oop StringTable::lookup_shared(jchar* name, int len) {
- // java_lang_String::hash_code() was used to compute hash values in the shared table. Don't
- // use the hash value from StringTable::hash_string() as it might use alternate hashcode.
- return _shared_table.lookup((const char*)name,
- java_lang_String::hash_code(name, len), len);
+oop StringTable::lookup_shared(jchar* name, int len, unsigned int hash) {
+ assert(hash == java_lang_String::hash_code(name, len),
+ "hash must be computed using java_lang_String::hash_code");
+ return _shared_table.lookup((const char*)name, hash, len);
}
oop StringTable::lookup_in_main_table(int index, jchar* name,
@@ -156,7 +159,7 @@
unsigned int hashValue;
int index;
if (use_alternate_hashcode()) {
- hashValue = hash_string(name, len);
+ hashValue = alt_hash_string(name, len);
index = hash_to_index(hashValue);
} else {
hashValue = hashValue_arg;
@@ -199,12 +202,15 @@
}
oop StringTable::lookup(jchar* name, int len) {
- oop string = lookup_shared(name, len);
+ // shared table always uses java_lang_String::hash_code
+ unsigned int hash = java_lang_String::hash_code(name, len);
+ oop string = lookup_shared(name, len, hash);
if (string != NULL) {
return string;
}
-
- unsigned int hash = hash_string(name, len);
+ if (use_alternate_hashcode()) {
+ hash = alt_hash_string(name, len);
+ }
int index = the_table()->hash_to_index(hash);
string = the_table()->lookup_in_main_table(index, name, len, hash);
@@ -215,12 +221,15 @@
oop StringTable::intern(Handle string_or_null, jchar* name,
int len, TRAPS) {
- oop found_string = lookup_shared(name, len);
+ // shared table always uses java_lang_String::hash_code
+ unsigned int hashValue = java_lang_String::hash_code(name, len);
+ oop found_string = lookup_shared(name, len, hashValue);
if (found_string != NULL) {
return found_string;
}
-
- unsigned int hashValue = hash_string(name, len);
+ if (use_alternate_hashcode()) {
+ hashValue = alt_hash_string(name, len);
+ }
int index = the_table()->hash_to_index(hashValue);
found_string = the_table()->lookup_in_main_table(index, name, len, hashValue);
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/share/vm/classfile/stringTable.hpp
--- a/hotspot/src/share/vm/classfile/stringTable.hpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/share/vm/classfile/stringTable.hpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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,7 +56,7 @@
unsigned int hashValue, TRAPS);
oop lookup_in_main_table(int index, jchar* chars, int length, unsigned int hashValue);
- static oop lookup_shared(jchar* name, int len);
+ static oop lookup_shared(jchar* name, int len, unsigned int hash);
// Apply the give oop closure to the entries to the buckets
// in the range [start_idx, end_idx).
@@ -65,6 +65,13 @@
// in the range [start_idx, end_idx).
static void buckets_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int start_idx, int end_idx, int* processed, int* removed);
+ // Hashing algorithm, used as the hash value used by the
+ // StringTable for bucket selection and comparison (stored in the
+ // HashtableEntry structures). This is used in the String.intern() method.
+ static unsigned int hash_string(const jchar* s, int len);
+ static unsigned int hash_string(oop string);
+ static unsigned int alt_hash_string(const jchar* s, int len);
+
StringTable() : RehashableHashtable((int)StringTableSize,
sizeof (HashtableEntry)) {}
@@ -109,12 +116,6 @@
}
static void possibly_parallel_oops_do(OopClosure* f);
- // Hashing algorithm, used as the hash value used by the
- // StringTable for bucket selection and comparison (stored in the
- // HashtableEntry structures). This is used in the String.intern() method.
- static unsigned int hash_string(const jchar* s, int len);
- static unsigned int hash_string(oop string);
-
// Internal test.
static void test_alt_hash() PRODUCT_RETURN;
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/share/vm/classfile/vmSymbols.hpp
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -561,6 +561,7 @@
template(int_StringBuffer_signature, "(I)Ljava/lang/StringBuffer;") \
template(char_StringBuffer_signature, "(C)Ljava/lang/StringBuffer;") \
template(int_String_signature, "(I)Ljava/lang/String;") \
+ template(boolean_boolean_int_signature, "(ZZ)I") \
template(codesource_permissioncollection_signature, "(Ljava/security/CodeSource;Ljava/security/PermissionCollection;)V") \
/* signature symbols needed by intrinsics */ \
VM_INTRINSICS_DO(VM_INTRINSIC_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, template, VM_ALIAS_IGNORE) \
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/share/vm/compiler/compilerDefinitions.cpp
--- a/hotspot/src/share/vm/compiler/compilerDefinitions.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/share/vm/compiler/compilerDefinitions.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -100,7 +100,9 @@
FLAG_SET_ERGO(size_t, MetaspaceSize, 12*M);
}
if (FLAG_IS_DEFAULT(MaxRAM)) {
- FLAG_SET_ERGO(uint64_t, MaxRAM, 1ULL*G);
+ // Do not use FLAG_SET_ERGO to update MaxRAM, as this will impact
+ // heap setting done based on available phys_mem (see Arguments::set_heap_size).
+ FLAG_SET_DEFAULT(MaxRAM, 1ULL*G);
}
if (FLAG_IS_DEFAULT(CompileThreshold)) {
FLAG_SET_ERGO(intx, CompileThreshold, 1500);
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/share/vm/oops/instanceKlass.cpp
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -2456,22 +2456,24 @@
void InstanceKlass::check_prohibited_package(Symbol* class_name,
Handle class_loader,
TRAPS) {
- ResourceMark rm(THREAD);
if (!class_loader.is_null() &&
!SystemDictionary::is_platform_class_loader(class_loader) &&
- class_name != NULL &&
- strncmp(class_name->as_C_string(), JAVAPKG, JAVAPKG_LEN) == 0) {
- TempNewSymbol pkg_name = InstanceKlass::package_from_name(class_name, CHECK);
- assert(pkg_name != NULL, "Error in parsing package name starting with 'java/'");
- char* name = pkg_name->as_C_string();
- const char* class_loader_name = SystemDictionary::loader_name(class_loader());
- StringUtils::replace_no_expand(name, "/", ".");
- const char* msg_text1 = "Class loader (instance of): ";
- const char* msg_text2 = " tried to load prohibited package name: ";
- size_t len = strlen(msg_text1) + strlen(class_loader_name) + strlen(msg_text2) + strlen(name) + 1;
- char* message = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, len);
- jio_snprintf(message, len, "%s%s%s%s", msg_text1, class_loader_name, msg_text2, name);
- THROW_MSG(vmSymbols::java_lang_SecurityException(), message);
+ class_name != NULL) {
+ ResourceMark rm(THREAD);
+ char* name = class_name->as_C_string();
+ if (strncmp(name, JAVAPKG, JAVAPKG_LEN) == 0 && name[JAVAPKG_LEN] == '/') {
+ TempNewSymbol pkg_name = InstanceKlass::package_from_name(class_name, CHECK);
+ assert(pkg_name != NULL, "Error in parsing package name starting with 'java/'");
+ name = pkg_name->as_C_string();
+ const char* class_loader_name = SystemDictionary::loader_name(class_loader());
+ StringUtils::replace_no_expand(name, "/", ".");
+ const char* msg_text1 = "Class loader (instance of): ";
+ const char* msg_text2 = " tried to load prohibited package name: ";
+ size_t len = strlen(msg_text1) + strlen(class_loader_name) + strlen(msg_text2) + strlen(name) + 1;
+ char* message = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, len);
+ jio_snprintf(message, len, "%s%s%s%s", msg_text1, class_loader_name, msg_text2, name);
+ THROW_MSG(vmSymbols::java_lang_SecurityException(), message);
+ }
}
return;
}
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/share/vm/opto/arraycopynode.cpp
--- a/hotspot/src/share/vm/opto/arraycopynode.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/share/vm/opto/arraycopynode.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -225,7 +225,6 @@
Node* dest = in(ArrayCopyNode::Dest);
const Type* src_type = phase->type(src);
const TypeAryPtr* ary_src = src_type->isa_aryptr();
- assert(ary_src != NULL, "should be an array copy/clone");
if (is_arraycopy() || is_copyofrange() || is_copyof()) {
const Type* dest_type = phase->type(dest);
@@ -286,7 +285,8 @@
copy_type = dest_elem;
} else {
- assert (is_clonebasic(), "should be");
+ assert(ary_src != NULL, "should be a clone");
+ assert(is_clonebasic(), "should be");
disjoint_bases = true;
assert(src->is_AddP(), "should be base + off");
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/share/vm/opto/callnode.cpp
--- a/hotspot/src/share/vm/opto/callnode.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/share/vm/opto/callnode.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -784,8 +784,8 @@
}
// May modify (by reflection) if an boxing object is passed
// as argument or returned.
- if (returns_pointer() && (proj_out(TypeFunc::Parms) != NULL)) {
- Node* proj = proj_out(TypeFunc::Parms);
+ Node* proj = returns_pointer() ? proj_out(TypeFunc::Parms) : NULL;
+ if (proj != NULL) {
const TypeInstPtr* inst_t = phase->type(proj)->isa_instptr();
if ((inst_t != NULL) && (!inst_t->klass_is_exact() ||
(inst_t->klass() == boxing_klass))) {
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/share/vm/opto/castnode.cpp
--- a/hotspot/src/share/vm/opto/castnode.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/share/vm/opto/castnode.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -225,7 +225,10 @@
}
// Similar to ConvI2LNode::Ideal() for the same reasons
- if (can_reshape && !phase->C->major_progress()) {
+ // Do not narrow the type of range check dependent CastIINodes to
+ // avoid corruption of the graph if a CastII is replaced by TOP but
+ // the corresponding range check is not removed.
+ if (can_reshape && !_range_check_dependency && !phase->C->major_progress()) {
const TypeInt* this_type = this->type()->is_int();
const TypeInt* in_type = phase->type(in(1))->isa_int();
if (in_type != NULL && this_type != NULL &&
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/share/vm/opto/convertnode.cpp
--- a/hotspot/src/share/vm/opto/convertnode.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/share/vm/opto/convertnode.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -294,8 +294,7 @@
}
#ifdef _LP64
- // Convert ConvI2L(AddI(x, y)) to AddL(ConvI2L(x), ConvI2L(y)) or
- // ConvI2L(CastII(AddI(x, y))) to AddL(ConvI2L(CastII(x)), ConvI2L(CastII(y))),
+ // Convert ConvI2L(AddI(x, y)) to AddL(ConvI2L(x), ConvI2L(y))
// but only if x and y have subranges that cannot cause 32-bit overflow,
// under the assumption that x+y is in my own subrange this->type().
@@ -319,13 +318,6 @@
Node* z = in(1);
int op = z->Opcode();
- Node* ctrl = NULL;
- if (op == Op_CastII && z->as_CastII()->has_range_check()) {
- // Skip CastII node but save control dependency
- ctrl = z->in(0);
- z = z->in(1);
- op = z->Opcode();
- }
if (op == Op_AddI || op == Op_SubI) {
Node* x = z->in(1);
Node* y = z->in(2);
@@ -385,8 +377,8 @@
}
assert(rxlo == (int)rxlo && rxhi == (int)rxhi, "x should not overflow");
assert(rylo == (int)rylo && ryhi == (int)ryhi, "y should not overflow");
- Node* cx = phase->C->constrained_convI2L(phase, x, TypeInt::make(rxlo, rxhi, widen), ctrl);
- Node* cy = phase->C->constrained_convI2L(phase, y, TypeInt::make(rylo, ryhi, widen), ctrl);
+ Node* cx = phase->C->constrained_convI2L(phase, x, TypeInt::make(rxlo, rxhi, widen), NULL);
+ Node* cy = phase->C->constrained_convI2L(phase, y, TypeInt::make(rylo, ryhi, widen), NULL);
switch (op) {
case Op_AddI: return new AddLNode(cx, cy);
case Op_SubI: return new SubLNode(cx, cy);
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/share/vm/opto/ifnode.cpp
--- a/hotspot/src/share/vm/opto/ifnode.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/share/vm/opto/ifnode.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -249,6 +249,13 @@
predicate_proj = proj;
}
}
+
+ // If all the defs of the phi are the same constant, we already have the desired end state.
+ // Skip the split that would create empty phi and region nodes.
+ if((r->req() - req_c) == 1) {
+ return NULL;
+ }
+
if (nb_predicate_proj > 1) {
// Can happen in case of loop unswitching and when the loop is
// optimized out: it's not a loop anymore so we don't care about
@@ -1458,8 +1465,9 @@
// be skipped. For example, range check predicate has two checks
// for lower and upper bounds.
ProjNode* unc_proj = proj_out(1 - prev_dom->as_Proj()->_con)->as_Proj();
- if (unc_proj->is_uncommon_trap_proj(Deoptimization::Reason_predicate) != NULL)
- prev_dom = idom;
+ if ((unc_proj != NULL) && (unc_proj->is_uncommon_trap_proj(Deoptimization::Reason_predicate) != NULL)) {
+ prev_dom = idom;
+ }
// Now walk the current IfNode's projections.
// Loop ends when 'this' has no more uses.
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/share/vm/opto/lcm.cpp
--- a/hotspot/src/share/vm/opto/lcm.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/share/vm/opto/lcm.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -254,10 +254,12 @@
const TypePtr *adr_type = NULL; // Do not need this return value here
const Node* base = mach->get_base_and_disp(offset, adr_type);
if (base == NULL || base == NodeSentinel) {
- // Narrow oop address doesn't have base, only index
- if( val->bottom_type()->isa_narrowoop() &&
- MacroAssembler::needs_explicit_null_check(offset) )
- continue; // Give up if offset is beyond page size
+ // Narrow oop address doesn't have base, only index.
+ // Give up if offset is beyond page size or if heap base is not protected.
+ if (val->bottom_type()->isa_narrowoop() &&
+ (MacroAssembler::needs_explicit_null_check(offset) ||
+ !Universe::narrow_oop_use_implicit_null_checks()))
+ continue;
// cannot reason about it; is probably not implicit null exception
} else {
const TypePtr* tptr;
@@ -269,12 +271,17 @@
// only regular oops are expected here
tptr = base->bottom_type()->is_ptr();
}
- // Give up if offset is not a compile-time constant
- if( offset == Type::OffsetBot || tptr->_offset == Type::OffsetBot )
+ // Give up if offset is not a compile-time constant.
+ if (offset == Type::OffsetBot || tptr->_offset == Type::OffsetBot)
continue;
offset += tptr->_offset; // correct if base is offseted
- if( MacroAssembler::needs_explicit_null_check(offset) )
- continue; // Give up is reference is beyond 4K page size
+ // Give up if reference is beyond page size.
+ if (MacroAssembler::needs_explicit_null_check(offset))
+ continue;
+ // Give up if base is a decode node and the heap base is not protected.
+ if (base->is_Mach() && base->as_Mach()->ideal_Opcode() == Op_DecodeN &&
+ !Universe::narrow_oop_use_implicit_null_checks())
+ continue;
}
}
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/share/vm/opto/library_call.cpp
--- a/hotspot/src/share/vm/opto/library_call.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/share/vm/opto/library_call.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -2372,10 +2372,10 @@
// the barriers get omitted and the unsafe reference begins to "pollute"
// the alias analysis of the rest of the graph, either Compile::can_alias
// or Compile::must_alias will throw a diagnostic assert.)
- bool need_mem_bar;
+ bool need_mem_bar = false;
switch (kind) {
case Relaxed:
- need_mem_bar = mismatched || can_access_non_heap;
+ need_mem_bar = mismatched && !adr_type->isa_aryptr();
break;
case Opaque:
// Opaque uses CPUOrder membars for protection against code movement.
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/share/vm/opto/loopTransform.cpp
--- a/hotspot/src/share/vm/opto/loopTransform.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/share/vm/opto/loopTransform.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -3174,6 +3174,11 @@
return false;
}
+ Node* exit = head->loopexit()->proj_out(0);
+ if (exit == NULL) {
+ return false;
+ }
+
#ifndef PRODUCT
if (TraceLoopOpts) {
tty->print("ArrayFill ");
@@ -3281,7 +3286,6 @@
*/
// Redirect the old control and memory edges that are outside the loop.
- Node* exit = head->loopexit()->proj_out(0);
// Sometimes the memory phi of the head is used as the outgoing
// state of the loop. It's safe in this case to replace it with the
// result_mem.
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/share/vm/opto/parse2.cpp
--- a/hotspot/src/share/vm/opto/parse2.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/share/vm/opto/parse2.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -826,6 +826,9 @@
ciMethodData* methodData = method()->method_data();
if (!methodData->is_mature()) return PROB_UNKNOWN;
ciProfileData* data = methodData->bci_to_data(bci());
+ if (data == NULL) {
+ return PROB_UNKNOWN;
+ }
if (!data->is_JumpData()) return PROB_UNKNOWN;
// get taken and not taken values
@@ -917,8 +920,8 @@
// of the OSR-ed method, and we want to deopt to gather more stats.
// If you have ANY counts, then this loop is simply 'cold' relative
// to the OSR loop.
- if (data->as_BranchData()->taken() +
- data->as_BranchData()->not_taken() == 0 ) {
+ if (data == NULL ||
+ (data->as_BranchData()->taken() + data->as_BranchData()->not_taken() == 0)) {
// This is the only way to return PROB_UNKNOWN:
return PROB_UNKNOWN;
}
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/share/vm/opto/stringopts.cpp
--- a/hotspot/src/share/vm/opto/stringopts.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/share/vm/opto/stringopts.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -891,8 +891,9 @@
ctrl_path.push(cn);
ctrl_path.push(cn->proj_out(0));
ctrl_path.push(cn->proj_out(0)->unique_out());
- if (cn->proj_out(0)->unique_out()->as_Catch()->proj_out(0) != NULL) {
- ctrl_path.push(cn->proj_out(0)->unique_out()->as_Catch()->proj_out(0));
+ Node* catchproj = cn->proj_out(0)->unique_out()->as_Catch()->proj_out(0);
+ if (catchproj != NULL) {
+ ctrl_path.push(catchproj);
}
} else {
ShouldNotReachHere();
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/share/vm/prims/jni.cpp
--- a/hotspot/src/share/vm/prims/jni.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/share/vm/prims/jni.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -935,8 +935,7 @@
inline void get_long() { _arguments->push_long(va_arg(_ap, jlong)); }
inline void get_float() { _arguments->push_float((jfloat)va_arg(_ap, jdouble)); } // float is coerced to double w/ va_arg
inline void get_double() { _arguments->push_double(va_arg(_ap, jdouble)); }
- inline void get_object() { jobject l = va_arg(_ap, jobject);
- _arguments->push_oop(Handle((oop *)l, false)); }
+ inline void get_object() { _arguments->push_jobject(va_arg(_ap, jobject)); }
inline void set_ap(va_list rap) {
va_copy(_ap, rap);
@@ -1025,7 +1024,7 @@
inline void get_long() { _arguments->push_long((_ap++)->j); }
inline void get_float() { _arguments->push_float((_ap++)->f); }
inline void get_double() { _arguments->push_double((_ap++)->d);}
- inline void get_object() { _arguments->push_oop(Handle((oop *)(_ap++)->l, false)); }
+ inline void get_object() { _arguments->push_jobject((_ap++)->l); }
inline void set_ap(const jvalue *rap) { _ap = rap; }
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/share/vm/prims/jvmtiEnv.cpp
--- a/hotspot/src/share/vm/prims/jvmtiEnv.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/share/vm/prims/jvmtiEnv.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -1796,6 +1796,13 @@
}
}
+ if (initial_object != NULL) {
+ oop init_obj = JNIHandles::resolve_external_guard(initial_object);
+ if (init_obj == NULL) {
+ return JVMTI_ERROR_INVALID_OBJECT;
+ }
+ }
+
Thread *thread = Thread::current();
HandleMark hm(thread);
KlassHandle kh (thread, k_oop);
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/share/vm/runtime/arguments.cpp
--- a/hotspot/src/share/vm/runtime/arguments.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -2856,6 +2856,10 @@
if (res != JNI_OK) {
return res;
}
+ } else if (match_option(option, "--permit-illegal-access")) {
+ if (!create_property("jdk.module.permitIllegalAccess", "true", ExternalProperty)) {
+ return JNI_ENOMEM;
+ }
// -agentlib and -agentpath
} else if (match_option(option, "-agentlib:", &tail) ||
(is_absolute_path = match_option(option, "-agentpath:", &tail))) {
@@ -3098,6 +3102,7 @@
// -Xprof
} else if (match_option(option, "-Xprof")) {
#if INCLUDE_FPROF
+ log_warning(arguments)("Option -Xprof was deprecated in version 9 and will likely be removed in a future release.");
_has_profile = true;
#else // INCLUDE_FPROF
jio_fprintf(defaultStream::error_stream(),
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/share/vm/runtime/java.cpp
--- a/hotspot/src/share/vm/runtime/java.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/share/vm/runtime/java.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -621,6 +621,13 @@
}
}
+void vm_exit_during_initialization() {
+ vm_notify_during_shutdown(NULL, NULL);
+
+ // Failure during initialization, we don't want to dump core
+ vm_abort(false);
+}
+
void vm_exit_during_initialization(Handle exception) {
tty->print_cr("Error occurred during initialization of VM");
// If there are exceptions on this thread it must be cleared
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/share/vm/runtime/java.hpp
--- a/hotspot/src/share/vm/runtime/java.hpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/share/vm/runtime/java.hpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -45,6 +45,7 @@
extern void notify_vm_shutdown();
// VM exit if error occurs during initialization of VM
+extern void vm_exit_during_initialization();
extern void vm_exit_during_initialization(Handle exception);
extern void vm_exit_during_initialization(Symbol* exception_name, const char* message);
extern void vm_exit_during_initialization(const char* error, const char* message = NULL);
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/share/vm/runtime/javaCalls.cpp
--- a/hotspot/src/share/vm/runtime/javaCalls.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/share/vm/runtime/javaCalls.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -328,9 +328,9 @@
// Verify the arguments
if (CheckJNICalls) {
- args->verify(method, result->get_type(), thread);
+ args->verify(method, result->get_type());
}
- else debug_only(args->verify(method, result->get_type(), thread));
+ else debug_only(args->verify(method, result->get_type()));
#if INCLUDE_JVMCI
}
#else
@@ -442,12 +442,43 @@
//--------------------------------------------------------------------------------------
// Implementation of JavaCallArguments
+inline bool is_value_state_indirect_oop(uint state) {
+ assert(state != JavaCallArguments::value_state_oop,
+ "Checking for handles after removal");
+ assert(state < JavaCallArguments::value_state_limit,
+ "Invalid value state %u", state);
+ return state != JavaCallArguments::value_state_primitive;
+}
+
+inline oop resolve_indirect_oop(intptr_t value, uint state) {
+ switch (state) {
+ case JavaCallArguments::value_state_handle:
+ {
+ oop* ptr = reinterpret_cast(value);
+ return Handle::raw_resolve(ptr);
+ }
+
+ case JavaCallArguments::value_state_jobject:
+ {
+ jobject obj = reinterpret_cast(value);
+ return JNIHandles::resolve(obj);
+ }
+
+ default:
+ ShouldNotReachHere();
+ return NULL;
+ }
+}
+
intptr_t* JavaCallArguments::parameters() {
// First convert all handles to oops
for(int i = 0; i < _size; i++) {
- if (_is_oop[i]) {
- // Handle conversion
- _value[i] = cast_from_oop(Handle::raw_resolve((oop *)_value[i]));
+ uint state = _value_state[i];
+ assert(state != value_state_oop, "Multiple handle conversions");
+ if (is_value_state_indirect_oop(state)) {
+ oop obj = resolve_indirect_oop(_value[i], state);
+ _value[i] = cast_from_oop(obj);
+ _value_state[i] = value_state_oop;
}
}
// Return argument vector
@@ -457,30 +488,42 @@
class SignatureChekker : public SignatureIterator {
private:
- bool *_is_oop;
- int _pos;
+ int _pos;
BasicType _return_type;
- intptr_t* _value;
- Thread* _thread;
+ u_char* _value_state;
+ intptr_t* _value;
public:
bool _is_return;
- SignatureChekker(Symbol* signature, BasicType return_type, bool is_static, bool* is_oop, intptr_t* value, Thread* thread) : SignatureIterator(signature) {
- _is_oop = is_oop;
- _is_return = false;
- _return_type = return_type;
- _pos = 0;
- _value = value;
- _thread = thread;
-
+ SignatureChekker(Symbol* signature,
+ BasicType return_type,
+ bool is_static,
+ u_char* value_state,
+ intptr_t* value) :
+ SignatureIterator(signature),
+ _pos(0),
+ _return_type(return_type),
+ _value_state(value_state),
+ _value(value),
+ _is_return(false)
+ {
if (!is_static) {
check_value(true); // Receiver must be an oop
}
}
void check_value(bool type) {
- guarantee(_is_oop[_pos++] == type, "signature does not match pushed arguments");
+ uint state = _value_state[_pos++];
+ if (type) {
+ guarantee(is_value_state_indirect_oop(state),
+ "signature does not match pushed arguments: %u at %d",
+ state, _pos - 1);
+ } else {
+ guarantee(state == JavaCallArguments::value_state_primitive,
+ "signature does not match pushed arguments: %u at %d",
+ state, _pos - 1);
+ }
}
void check_doing_return(bool state) { _is_return = state; }
@@ -515,24 +558,20 @@
return;
}
- // verify handle and the oop pointed to by handle
- int p = _pos;
- bool bad = false;
- // If argument is oop
- if (_is_oop[p]) {
- intptr_t v = _value[p];
- if (v != 0 ) {
- size_t t = (size_t)v;
- bad = (t < (size_t)os::vm_page_size() ) || !Handle::raw_resolve((oop *)v)->is_oop_or_null(true);
- if (CheckJNICalls && bad) {
- ReportJNIFatalError((JavaThread*)_thread, "Bad JNI oop argument");
- }
- }
- // for the regular debug case.
- assert(!bad, "Bad JNI oop argument");
+ intptr_t v = _value[_pos];
+ if (v != 0) {
+ // v is a "handle" referring to an oop, cast to integral type.
+ // There shouldn't be any handles in very low memory.
+ guarantee((size_t)v >= (size_t)os::vm_page_size(),
+ "Bad JNI oop argument %d: " PTR_FORMAT, _pos, v);
+ // Verify the pointee.
+ oop vv = resolve_indirect_oop(v, _value_state[_pos]);
+ guarantee(vv->is_oop_or_null(true),
+ "Bad JNI oop argument %d: " PTR_FORMAT " -> " PTR_FORMAT,
+ _pos, v, p2i(vv));
}
- check_value(true);
+ check_value(true); // Verify value state.
}
void do_bool() { check_int(T_BOOLEAN); }
@@ -549,8 +588,7 @@
};
-void JavaCallArguments::verify(const methodHandle& method, BasicType return_type,
- Thread *thread) {
+void JavaCallArguments::verify(const methodHandle& method, BasicType return_type) {
guarantee(method->size_of_parameters() == size_of_parameters(), "wrong no. of arguments pushed");
// Treat T_OBJECT and T_ARRAY as the same
@@ -559,7 +597,11 @@
// Check that oop information is correct
Symbol* signature = method->signature();
- SignatureChekker sc(signature, return_type, method->is_static(),_is_oop, _value, thread);
+ SignatureChekker sc(signature,
+ return_type,
+ method->is_static(),
+ _value_state,
+ _value);
sc.iterate_parameters();
sc.check_doing_return(true);
sc.iterate_returntype();
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/share/vm/runtime/javaCalls.hpp
--- a/hotspot/src/share/vm/runtime/javaCalls.hpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/share/vm/runtime/javaCalls.hpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -80,11 +80,11 @@
_default_size = 8 // Must be at least # of arguments in JavaCalls methods
};
- intptr_t _value_buffer [_default_size + 1];
- bool _is_oop_buffer[_default_size + 1];
+ intptr_t _value_buffer [_default_size + 1];
+ u_char _value_state_buffer[_default_size + 1];
intptr_t* _value;
- bool* _is_oop;
+ u_char* _value_state;
int _size;
int _max_size;
bool _start_at_zero; // Support late setting of receiver
@@ -92,8 +92,8 @@
void initialize() {
// Starts at first element to support set_receiver.
- _value = &_value_buffer[1];
- _is_oop = &_is_oop_buffer[1];
+ _value = &_value_buffer[1];
+ _value_state = &_value_state_buffer[1];
_max_size = _default_size;
_size = 0;
@@ -101,6 +101,23 @@
JVMCI_ONLY(_alternative_target = NULL;)
}
+ // Helper for push_oop and the like. The value argument is a
+ // "handle" that refers to an oop. We record the address of the
+ // handle rather than the designated oop. The handle is later
+ // resolved to the oop by parameters(). This delays the exposure of
+ // naked oops until it is GC-safe.
+ template
+ inline int push_oop_impl(T handle, int size) {
+ // JNITypes::put_obj expects an oop value, so we play fast and
+ // loose with the type system. The cast from handle type to oop
+ // *must* use a C-style cast. In a product build it performs a
+ // reinterpret_cast. In a debug build (more accurately, in a
+ // CHECK_UNHANDLED_OOPS build) it performs a static_cast, invoking
+ // the debug-only oop class's conversion from void* constructor.
+ JNITypes::put_obj((oop)handle, _value, size); // Updates size.
+ return size; // Return the updated size.
+ }
+
public:
JavaCallArguments() { initialize(); }
@@ -111,11 +128,12 @@
JavaCallArguments(int max_size) {
if (max_size > _default_size) {
- _value = NEW_RESOURCE_ARRAY(intptr_t, max_size + 1);
- _is_oop = NEW_RESOURCE_ARRAY(bool, max_size + 1);
+ _value = NEW_RESOURCE_ARRAY(intptr_t, max_size + 1);
+ _value_state = NEW_RESOURCE_ARRAY(u_char, max_size + 1);
- // Reserve room for potential receiver in value and is_oop
- _value++; _is_oop++;
+ // Reserve room for potential receiver in value and state
+ _value++;
+ _value_state++;
_max_size = max_size;
_size = 0;
@@ -136,25 +154,52 @@
}
#endif
- inline void push_oop(Handle h) { _is_oop[_size] = true;
- JNITypes::put_obj((oop)h.raw_value(), _value, _size); }
+ // The possible values for _value_state elements.
+ enum {
+ value_state_primitive,
+ value_state_oop,
+ value_state_handle,
+ value_state_jobject,
+ value_state_limit
+ };
- inline void push_int(int i) { _is_oop[_size] = false;
- JNITypes::put_int(i, _value, _size); }
+ inline void push_oop(Handle h) {
+ _value_state[_size] = value_state_handle;
+ _size = push_oop_impl(h.raw_value(), _size);
+ }
+
+ inline void push_jobject(jobject h) {
+ _value_state[_size] = value_state_jobject;
+ _size = push_oop_impl(h, _size);
+ }
- inline void push_double(double d) { _is_oop[_size] = false; _is_oop[_size + 1] = false;
- JNITypes::put_double(d, _value, _size); }
+ inline void push_int(int i) {
+ _value_state[_size] = value_state_primitive;
+ JNITypes::put_int(i, _value, _size);
+ }
+
+ inline void push_double(double d) {
+ _value_state[_size] = value_state_primitive;
+ _value_state[_size + 1] = value_state_primitive;
+ JNITypes::put_double(d, _value, _size);
+ }
- inline void push_long(jlong l) { _is_oop[_size] = false; _is_oop[_size + 1] = false;
- JNITypes::put_long(l, _value, _size); }
+ inline void push_long(jlong l) {
+ _value_state[_size] = value_state_primitive;
+ _value_state[_size + 1] = value_state_primitive;
+ JNITypes::put_long(l, _value, _size);
+ }
- inline void push_float(float f) { _is_oop[_size] = false;
- JNITypes::put_float(f, _value, _size); }
+ inline void push_float(float f) {
+ _value_state[_size] = value_state_primitive;
+ JNITypes::put_float(f, _value, _size);
+ }
// receiver
Handle receiver() {
assert(_size > 0, "must at least be one argument");
- assert(_is_oop[0], "first argument must be an oop");
+ assert(_value_state[0] == value_state_handle,
+ "first argument must be an oop");
assert(_value[0] != 0, "receiver must be not-null");
return Handle((oop*)_value[0], false);
}
@@ -162,11 +207,11 @@
void set_receiver(Handle h) {
assert(_start_at_zero == false, "can only be called once");
_start_at_zero = true;
- _is_oop--;
+ _value_state--;
_value--;
_size++;
- _is_oop[0] = true;
- _value[0] = (intptr_t)h.raw_value();
+ _value_state[0] = value_state_handle;
+ push_oop_impl(h.raw_value(), 0);
}
// Converts all Handles to oops, and returns a reference to parameter vector
@@ -174,7 +219,7 @@
int size_of_parameters() const { return _size; }
// Verify that pushed arguments fits a given method
- void verify(const methodHandle& method, BasicType return_type, Thread *thread);
+ void verify(const methodHandle& method, BasicType return_type);
};
// All calls to Java have to go via JavaCalls. Sets up the stack frame
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/share/vm/runtime/jniHandles.cpp
--- a/hotspot/src/share/vm/runtime/jniHandles.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/share/vm/runtime/jniHandles.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017, 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,9 @@
#include "runtime/jniHandles.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/thread.inline.hpp"
+#if INCLUDE_ALL_GCS
+#include "gc/g1/g1SATBCardTableModRefBS.hpp"
+#endif
JNIHandleBlock* JNIHandles::_global_handles = NULL;
JNIHandleBlock* JNIHandles::_weak_global_handles = NULL;
@@ -92,28 +95,48 @@
jobject res = NULL;
if (!obj.is_null()) {
// ignore null handles
- MutexLocker ml(JNIGlobalHandle_lock);
- assert(Universe::heap()->is_in_reserved(obj()), "sanity check");
- res = _weak_global_handles->allocate_handle(obj());
+ {
+ MutexLocker ml(JNIGlobalHandle_lock);
+ assert(Universe::heap()->is_in_reserved(obj()), "sanity check");
+ res = _weak_global_handles->allocate_handle(obj());
+ }
+ // Add weak tag.
+ assert(is_ptr_aligned(res, weak_tag_alignment), "invariant");
+ char* tptr = reinterpret_cast(res) + weak_tag_value;
+ res = reinterpret_cast(tptr);
} else {
CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
}
return res;
}
+template
+oop JNIHandles::resolve_jweak(jweak handle) {
+ assert(is_jweak(handle), "precondition");
+ oop result = jweak_ref(handle);
+ result = guard_value(result);
+#if INCLUDE_ALL_GCS
+ if (result != NULL && UseG1GC) {
+ G1SATBCardTableModRefBS::enqueue(result);
+ }
+#endif // INCLUDE_ALL_GCS
+ return result;
+}
+
+template oop JNIHandles::resolve_jweak(jweak);
+template oop JNIHandles::resolve_jweak(jweak);
void JNIHandles::destroy_global(jobject handle) {
if (handle != NULL) {
assert(is_global_handle(handle), "Invalid delete of global JNI handle");
- *((oop*)handle) = deleted_handle(); // Mark the handle as deleted, allocate will reuse it
+ jobject_ref(handle) = deleted_handle();
}
}
void JNIHandles::destroy_weak_global(jobject handle) {
if (handle != NULL) {
- assert(!CheckJNICalls || is_weak_global_handle(handle), "Invalid delete of weak global JNI handle");
- *((oop*)handle) = deleted_handle(); // Mark the handle as deleted, allocate will reuse it
+ jweak_ref(handle) = deleted_handle();
}
}
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/share/vm/runtime/jniHandles.hpp
--- a/hotspot/src/share/vm/runtime/jniHandles.hpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/share/vm/runtime/jniHandles.hpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017, 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,7 +40,28 @@
static JNIHandleBlock* _weak_global_handles; // First weak global handle block
static oop _deleted_handle; // Sentinel marking deleted handles
+ inline static bool is_jweak(jobject handle);
+ inline static oop& jobject_ref(jobject handle); // NOT jweak!
+ inline static oop& jweak_ref(jobject handle);
+
+ template inline static oop guard_value(oop value);
+ template inline static oop resolve_impl(jobject handle);
+ template static oop resolve_jweak(jweak handle);
+
public:
+ // Low tag bit in jobject used to distinguish a jweak. jweak is
+ // type equivalent to jobject, but there are places where we need to
+ // be able to distinguish jweak values from other jobjects, and
+ // is_weak_global_handle is unsuitable for performance reasons. To
+ // provide such a test we add weak_tag_value to the (aligned) byte
+ // address designated by the jobject to produce the corresponding
+ // jweak. Accessing the value of a jobject must account for it
+ // being a possibly offset jweak.
+ static const uintptr_t weak_tag_size = 1;
+ static const uintptr_t weak_tag_alignment = (1u << weak_tag_size);
+ static const uintptr_t weak_tag_mask = weak_tag_alignment - 1;
+ static const int weak_tag_value = 1;
+
// Resolve handle into oop
inline static oop resolve(jobject handle);
// Resolve externally provided handle into oop with some guards
@@ -176,36 +197,85 @@
#endif
};
+inline bool JNIHandles::is_jweak(jobject handle) {
+ STATIC_ASSERT(weak_tag_size == 1);
+ STATIC_ASSERT(weak_tag_value == 1);
+ return (reinterpret_cast(handle) & weak_tag_mask) != 0;
+}
+
+inline oop& JNIHandles::jobject_ref(jobject handle) {
+ assert(!is_jweak(handle), "precondition");
+ return *reinterpret_cast(handle);
+}
+
+inline oop& JNIHandles::jweak_ref(jobject handle) {
+ assert(is_jweak(handle), "precondition");
+ char* ptr = reinterpret_cast(handle) - weak_tag_value;
+ return *reinterpret_cast(ptr);
+}
+
+// external_guard is true if called from resolve_external_guard.
+// Treat deleted (and possibly zapped) as NULL for external_guard,
+// else as (asserted) error.
+template
+inline oop JNIHandles::guard_value(oop value) {
+ if (!external_guard) {
+ assert(value != badJNIHandle, "Pointing to zapped jni handle area");
+ assert(value != deleted_handle(), "Used a deleted global handle");
+ } else if ((value == badJNIHandle) || (value == deleted_handle())) {
+ value = NULL;
+ }
+ return value;
+}
+
+// external_guard is true if called from resolve_external_guard.
+template
+inline oop JNIHandles::resolve_impl(jobject handle) {
+ assert(handle != NULL, "precondition");
+ oop result;
+ if (is_jweak(handle)) { // Unlikely
+ result = resolve_jweak(handle);
+ } else {
+ result = jobject_ref(handle);
+ // Construction of jobjects canonicalize a null value into a null
+ // jobject, so for non-jweak the pointee should never be null.
+ assert(external_guard || result != NULL,
+ "Invalid value read from jni handle");
+ result = guard_value(result);
+ }
+ return result;
+}
inline oop JNIHandles::resolve(jobject handle) {
- oop result = (handle == NULL ? (oop)NULL : *(oop*)handle);
- assert(result != NULL || (handle == NULL || !CheckJNICalls || is_weak_global_handle(handle)), "Invalid value read from jni handle");
- assert(result != badJNIHandle, "Pointing to zapped jni handle area");
+ oop result = NULL;
+ if (handle != NULL) {
+ result = resolve_impl(handle);
+ }
return result;
-};
-
+}
+// Resolve some erroneous cases to NULL, rather than treating them as
+// possibly unchecked errors. In particular, deleted handles are
+// treated as NULL (though a deleted and later reallocated handle
+// isn't detected).
inline oop JNIHandles::resolve_external_guard(jobject handle) {
- if (handle == NULL) return NULL;
- oop result = *(oop*)handle;
- if (result == NULL || result == badJNIHandle) return NULL;
+ oop result = NULL;
+ if (handle != NULL) {
+ result = resolve_impl(handle);
+ }
return result;
-};
-
+}
inline oop JNIHandles::resolve_non_null(jobject handle) {
assert(handle != NULL, "JNI handle should not be null");
- oop result = *(oop*)handle;
- assert(result != NULL, "Invalid value read from jni handle");
- assert(result != badJNIHandle, "Pointing to zapped jni handle area");
- // Don't let that private _deleted_handle object escape into the wild.
- assert(result != deleted_handle(), "Used a deleted global handle.");
+ oop result = resolve_impl(handle);
+ assert(result != NULL, "NULL read from jni handle");
return result;
-};
+}
inline void JNIHandles::destroy_local(jobject handle) {
if (handle != NULL) {
- *((oop*)handle) = deleted_handle(); // Mark the handle as deleted, allocate will reuse it
+ jobject_ref(handle) = deleted_handle();
}
}
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/share/vm/runtime/mutexLocker.cpp
--- a/hotspot/src/share/vm/runtime/mutexLocker.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/share/vm/runtime/mutexLocker.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -181,13 +181,13 @@
}
if (UseG1GC) {
- def(SATB_Q_FL_lock , PaddedMutex , special, true, Monitor::_safepoint_check_never);
- def(SATB_Q_CBL_mon , PaddedMonitor, nonleaf, true, Monitor::_safepoint_check_never);
- def(Shared_SATB_Q_lock , PaddedMutex , nonleaf, true, Monitor::_safepoint_check_never);
+ def(SATB_Q_FL_lock , PaddedMutex , special , true, Monitor::_safepoint_check_never);
+ def(SATB_Q_CBL_mon , PaddedMonitor, leaf - 1 , true, Monitor::_safepoint_check_never);
+ def(Shared_SATB_Q_lock , PaddedMutex , leaf - 1 , true, Monitor::_safepoint_check_never);
- def(DirtyCardQ_FL_lock , PaddedMutex , special, true, Monitor::_safepoint_check_never);
- def(DirtyCardQ_CBL_mon , PaddedMonitor, nonleaf, true, Monitor::_safepoint_check_never);
- def(Shared_DirtyCardQ_lock , PaddedMutex , nonleaf, true, Monitor::_safepoint_check_never);
+ def(DirtyCardQ_FL_lock , PaddedMutex , special , true, Monitor::_safepoint_check_never);
+ def(DirtyCardQ_CBL_mon , PaddedMonitor, leaf - 1 , true, Monitor::_safepoint_check_never);
+ def(Shared_DirtyCardQ_lock , PaddedMutex , leaf - 1 , true, Monitor::_safepoint_check_never);
def(FreeList_lock , PaddedMutex , leaf , true, Monitor::_safepoint_check_never);
def(SecondaryFreeList_lock , PaddedMonitor, leaf , true, Monitor::_safepoint_check_never);
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/share/vm/runtime/thread.cpp
--- a/hotspot/src/share/vm/runtime/thread.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/share/vm/runtime/thread.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -3409,9 +3409,16 @@
Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_System(), true, CHECK);
instanceKlassHandle klass (THREAD, k);
- JavaValue result(T_VOID);
+ JavaValue result(T_INT);
+ JavaCallArguments args;
+ args.push_int(DisplayVMOutputToStderr);
+ args.push_int(log_is_enabled(Debug, init)); // print stack trace if exception thrown
JavaCalls::call_static(&result, klass, vmSymbols::initPhase2_name(),
- vmSymbols::void_method_signature(), CHECK);
+ vmSymbols::boolean_boolean_int_signature(), &args, CHECK);
+ if (result.get_jint() != JNI_OK) {
+ vm_exit_during_initialization(); // no message or exception
+ }
+
universe_post_module_init();
}
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/share/vm/shark/sharkNativeWrapper.cpp
--- a/hotspot/src/share/vm/shark/sharkNativeWrapper.cpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/share/vm/shark/sharkNativeWrapper.cpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright 2009, 2010 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -300,6 +300,7 @@
not_null, merge);
builder()->SetInsertPoint(not_null);
+#error Needs to be updated for tagged jweak; see JNIHandles.
Value *unboxed_result = builder()->CreateLoad(result);
builder()->CreateBr(merge);
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/share/vm/utilities/debug.hpp
--- a/hotspot/src/share/vm/utilities/debug.hpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/share/vm/utilities/debug.hpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -140,6 +140,9 @@
// For backward compatibility.
#define assert(p, ...) vmassert(p, __VA_ARGS__)
+#ifndef ASSERT
+#define vmassert_status(p, status, msg)
+#else
// This version of vmassert is for use with checking return status from
// library calls that return actual error values eg. EINVAL,
// ENOMEM etc, rather than returning -1 and setting errno.
@@ -155,6 +158,7 @@
BREAKPOINT; \
} \
} while (0)
+#endif
// For backward compatibility.
#define assert_status(p, status, msg) vmassert_status(p, status, msg)
diff -r 18569c523d38 -r c61cc8a34456 hotspot/src/share/vm/utilities/globalDefinitions_xlc.hpp
--- a/hotspot/src/share/vm/utilities/globalDefinitions_xlc.hpp Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/src/share/vm/utilities/globalDefinitions_xlc.hpp Wed Jul 05 23:09:40 2017 +0200
@@ -1,6 +1,6 @@
/*
* Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2016 SAP SE. All rights reserved.
+ * Copyright (c) 2012, 2017 SAP SE. All rights reserved.
* 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,9 @@
// offset_of as it is defined for gcc.
#define offset_of(klass,field) (size_t)((intx)&(((klass*)16)->field) - 16)
+// AIX 5.3 has buggy __thread support. (see JDK-8176442).
+#define USE_LIBRARY_BASED_TLS_ONLY 1
+
#ifndef USE_LIBRARY_BASED_TLS_ONLY
#define THREAD_LOCAL_DECL __thread
#endif
diff -r 18569c523d38 -r c61cc8a34456 hotspot/test/ProblemList.txt
--- a/hotspot/test/ProblemList.txt Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/test/ProblemList.txt Wed Jul 05 23:09:40 2017 +0200
@@ -79,7 +79,5 @@
# :hotspot_misc
-testlibrary_tests/ctw/JarDirTest.java 8172457 windows-all
-
#############################################################################
diff -r 18569c523d38 -r c61cc8a34456 hotspot/test/compiler/arraycopy/TestObjectArrayCopy.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/arraycopy/TestObjectArrayCopy.java Wed Jul 05 23:09:40 2017 +0200
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2017, SAP SE 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 8176505
+ * @summary Wrong assertion 'should be an array copy/clone' in arraycopynode.cpp
+ *
+ * @run main/othervm -Xbatch -XX:-UseOnStackReplacement compiler.arraycopy.TestObjectArrayCopy
+ *
+ * @author Volker Simonis
+ */
+
+package compiler.arraycopy;
+
+public class TestObjectArrayCopy {
+
+ public static boolean crash(Object src) {
+ String[] dst = new String[1];
+ System.arraycopy(src, 0, dst, 0, 1);
+ return dst[0] == null;
+ }
+
+ public static void main(String[] args) {
+ String[] sa = new String[1];
+ for (int i = 0; i < 20_000; i++) {
+ crash(sa);
+ }
+ }
+}
diff -r 18569c523d38 -r c61cc8a34456 hotspot/test/compiler/c2/TestNPEHeapBased.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/c2/TestNPEHeapBased.java Wed Jul 05 23:09:40 2017 +0200
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017 SAP SE. All rights reserved.
+ * 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 8176518
+ * @summary Invalid ImplicitNullChecks when heap base not protected
+ *
+ * @run main/othervm -XX:ObjectAlignmentInBytes=16 -XX:HeapBaseMinAddress=64g
+ * -XX:-TieredCompilation -Xbatch
+ * compiler.c2.TestNPEHeapBased
+ * @requires vm.bits == "64"
+ */
+
+package compiler.c2;
+public class TestNPEHeapBased {
+
+ TestNPEHeapBased instance = null;
+ int i = 0;
+
+ public void set_i(int value) {
+ instance.i = value;
+ }
+
+
+ static final int loop_cnt = 200000;
+
+ public static void main(String args[]){
+ TestNPEHeapBased xyz = new TestNPEHeapBased();
+ xyz.instance = xyz;
+ for (int x = 0; x < loop_cnt; x++) xyz.set_i(x);
+ xyz.instance = null;
+ try {
+ xyz.set_i(0);
+ } catch (NullPointerException npe) {
+ System.out.println("Got expected NullPointerException:");
+ npe.printStackTrace();
+ return;
+ }
+ throw new InternalError("NullPointerException is missing!");
+ }
+
+}
diff -r 18569c523d38 -r c61cc8a34456 hotspot/test/compiler/loopopts/TestLoopPeeling.java
--- a/hotspot/test/compiler/loopopts/TestLoopPeeling.java Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/test/compiler/loopopts/TestLoopPeeling.java Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8078262
+ * @bug 8078262 8177095
* @summary Tests correct dominator information after loop peeling.
*
* @run main/othervm -Xcomp
@@ -40,14 +40,16 @@
public static void main(String args[]) {
TestLoopPeeling test = new TestLoopPeeling();
try {
- test.testArrayAccess(0, 1);
+ test.testArrayAccess1(0, 1);
+ test.testArrayAccess2(0);
+ test.testArrayAccess3(0, false);
test.testArrayAllocation(0, 1);
} catch (Exception e) {
// Ignore exceptions
}
}
- public void testArrayAccess(int index, int inc) {
+ public void testArrayAccess1(int index, int inc) {
int storeIndex = -1;
for (; index < 10; index += inc) {
@@ -63,7 +65,7 @@
if (index == 42) {
// This store and the corresponding range check are moved out of the
- // loop and both used after old loop and the peeled iteration exit.
+ // loop and both used after main loop and the peeled iteration exit.
// For the peeled iteration, storeIndex is always -1 and the ConvI2L
// is replaced by TOP. However, the range check is not folded because
// we don't do the split if optimization in PhaseIdealLoop2.
@@ -77,6 +79,44 @@
}
}
+ public int testArrayAccess2(int index) {
+ // Load1 and the corresponding range check are moved out of the loop
+ // and both are used after the main loop and the peeled iteration exit.
+ // For the peeled iteration, storeIndex is always Integer.MIN_VALUE and
+ // for the main loop it is 0. Hence, the merging phi has type int:<=0.
+ // Load1 reads the array at index ConvI2L(CastII(AddI(storeIndex, -1)))
+ // where the CastII is range check dependent and has type int:>=0.
+ // The CastII gets pushed through the AddI and its type is changed to int:>=1
+ // which does not overlap with the input type of storeIndex (int:<=0).
+ // The CastII is replaced by TOP causing a cascade of other eliminations.
+ // Since the control path through the range check CmpU(AddI(storeIndex, -1))
+ // is not eliminated, the graph is in a corrupted state. We fail once we merge
+ // with the result of Load2 because we get data from a non-dominating region.
+ int storeIndex = Integer.MIN_VALUE;
+ for (; index < 10; ++index) {
+ if (index == 42) {
+ return array[storeIndex-1]; // Load1
+ }
+ storeIndex = 0;
+ }
+ return array[42]; // Load2
+ }
+
+ public int testArrayAccess3(int index, boolean b) {
+ // Same as testArrayAccess2 but manifests as crash in register allocator.
+ int storeIndex = Integer.MIN_VALUE;
+ for (; index < 10; ++index) {
+ if (b) {
+ return 0;
+ }
+ if (index == 42) {
+ return array[storeIndex-1]; // Load1
+ }
+ storeIndex = 0;
+ }
+ return array[42]; // Load2
+ }
+
public byte[] testArrayAllocation(int index, int inc) {
int allocationCount = -1;
byte[] result;
@@ -88,7 +128,7 @@
if (index == 42) {
// This allocation and the corresponding size check are moved out of the
- // loop and both used after old loop and the peeled iteration exit.
+ // loop and both used after main loop and the peeled iteration exit.
// For the peeled iteration, allocationCount is always -1 and the ConvI2L
// is replaced by TOP. However, the size check is not folded because
// we don't do the split if optimization in PhaseIdealLoop2.
diff -r 18569c523d38 -r c61cc8a34456 hotspot/test/runtime/MinimalVM/JMX.java
--- a/hotspot/test/runtime/MinimalVM/JMX.java Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/test/runtime/MinimalVM/JMX.java Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, 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
@@ -47,9 +47,8 @@
.shouldContain("-Dcom.sun.management is not supported in this VM.")
.shouldHaveExitValue(1);
- pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), Long.toString(ProcessTools.getProcessId()), "VM.print_threads"});
+ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), "-l"});
new OutputAnalyzer(pb.start())
- .shouldContain("Could not find any processes matching ")
- .shouldHaveExitValue(1);
+ .shouldNotMatch("^" + Long.toString(ProcessTools.getProcessId()) + "\\s+.*$");
}
}
diff -r 18569c523d38 -r c61cc8a34456 hotspot/test/runtime/constantPool/ACCModule52.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/constantPool/ACCModule52.java Wed Jul 05 23:09:40 2017 +0200
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2017, 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 jdk.internal.org.objectweb.asm.*;
+
+/*
+ * @test
+ * @summary Test that the JVM ignores ACC_MODULE if it is set for a version
+ * 52 class file.
+ * @bug 8175383
+ * @library /test/lib
+ * @modules java.base/jdk.internal.org.objectweb.asm
+ * @compile -XDignore.symbol.file ACCModule52.java
+ * @run main ACCModule52
+ */
+
+public class ACCModule52 {
+
+ static final String CLASS_NAME = "ACCModule52Pkg";
+
+ public static void main(String[] args) throws Exception {
+ int ACC_MODULE = 0x8000;
+ ClassWriter cw = new ClassWriter(0);
+ cw.visit(Opcodes.V1_8,
+ Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT + Opcodes.ACC_SYNTHETIC + ACC_MODULE,
+ CLASS_NAME,
+ null,
+ "java/lang/Object",
+ null);
+
+ cw.visitEnd();
+ byte[] bytes = cw.toByteArray();
+
+
+ ClassLoader loader = new ClassLoader(ACCModule52.class.getClassLoader()) {
+ @Override
+ protected Class> findClass(String cn)throws ClassNotFoundException {
+ if (cn.equals(CLASS_NAME)) {
+ Class superClass = super.defineClass(cn, bytes, 0, bytes.length);
+ } else {
+ throw new ClassNotFoundException(cn);
+ }
+ return null;
+ }
+ };
+
+ Class> clazz = loader.loadClass(CLASS_NAME);
+ }
+}
diff -r 18569c523d38 -r c61cc8a34456 hotspot/test/runtime/constantPool/ConstModule.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/constantPool/ConstModule.java Wed Jul 05 23:09:40 2017 +0200
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2017, 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 jdk.internal.org.objectweb.asm.*;
+
+/*
+ * @test
+ * @summary Test scenarios for constant pool CONSTANT_Module and CONSTANT_Package
+ * types, for class file versions 53 and 52, when ACC_MODULE is set and
+ * not set in the access_flags.
+ * @bug 8175383
+ * @library /test/lib
+ * @modules java.base/jdk.internal.org.objectweb.asm
+ * @compile -XDignore.symbol.file ConstModule.java
+ * @run main ConstModule
+ */
+
+public class ConstModule {
+
+ static final int ACC_MODULE = 0x8000;
+ static final boolean MODULE_TEST = true;
+ static final boolean PACKAGE_TEST = false;
+ static final boolean CFE_EXCEPTION = true;
+ static final boolean NCDFE_EXCEPTION = false;
+
+ public static void main(String[] args) throws Exception {
+
+ // Test that the JVM throws CFE for constant pool CONSTANT_Module type, for
+ // class file version 53, when ACC_MODULE is not set in the access_flags.
+ ConstModule.write_and_load(Opcodes.V1_9,
+ Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT + Opcodes.ACC_SYNTHETIC,
+ "jdk.fooMod", "FooMod", MODULE_TEST, CFE_EXCEPTION);
+
+ // Test that the JVM throws NCDFE for constant pool CONSTANT_Module type,
+ // for class file version 53, when ACC_MODULE is set in the access_flags.
+ ConstModule.write_and_load(Opcodes.V1_9,
+ Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT + Opcodes.ACC_SYNTHETIC + ACC_MODULE,
+ "jdk.fooModACC", "FooModACC", MODULE_TEST, NCDFE_EXCEPTION);
+
+ // Test that the JVM throws CFE for constant pool CONSTANT_Module type, for
+ // class file version 52, even when ACC_MODULE is set in the access_flags.
+ ConstModule.write_and_load(Opcodes.V1_8,
+ Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT + Opcodes.ACC_SYNTHETIC + ACC_MODULE,
+ "jdk.fooModACC52", "FooModACC52", MODULE_TEST, CFE_EXCEPTION);
+
+ // Test that the JVM throws CFE for constant pool CONSTANT_Package type, for
+ // class file version 53, when ACC_MODULE is not set in the access_flags.
+ ConstModule.write_and_load(Opcodes.V1_9,
+ Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT + Opcodes.ACC_SYNTHETIC,
+ "jdk.fooPkg", "FooPkg", PACKAGE_TEST, CFE_EXCEPTION);
+
+ // Test that the JVM throws NCDFE for constant pool CONSTANT_Package type,
+ // for class file version 53, when ACC_MODULE is set in the access_flags.
+ ConstModule.write_and_load(Opcodes.V1_9,
+ Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT + Opcodes.ACC_SYNTHETIC + ACC_MODULE,
+ "jdk.fooModACC", "FooModACC", PACKAGE_TEST, NCDFE_EXCEPTION);
+
+ // Test that the JVM throws CFE for constant pool CONSTANT_Package type, for
+ // class file version 52, even when ACC_MODULE is set in the access_flags.
+ ConstModule.write_and_load(Opcodes.V1_8,
+ Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT + Opcodes.ACC_SYNTHETIC + ACC_MODULE,
+ "jdk.fooModACC52", "FooModACC52", PACKAGE_TEST, CFE_EXCEPTION);
+
+ }
+
+ public static void write_and_load(int version,
+ int access_flags,
+ String attr,
+ String class_name,
+ boolean module_test,
+ boolean throwCFE) throws Exception {
+ ClassWriter cw = new ClassWriter(0);
+ cw.visit(version,
+ access_flags,
+ class_name,
+ null,
+ "java/lang/Object",
+ null);
+
+ if (module_test)
+ cw.visitAttribute(new TestModuleAttribute(attr));
+ else
+ cw.visitAttribute(new TestPackageAttribute(attr));
+
+ cw.visitEnd();
+ byte[] bytes = cw.toByteArray();
+
+
+ ClassLoader loader = new ClassLoader(ConstModule.class.getClassLoader()) {
+ @Override
+ protected Class> findClass(String cn)throws ClassNotFoundException {
+ if (cn.equals(class_name)) {
+ try {
+ Class superClass = super.defineClass(cn, bytes, 0, bytes.length);
+ throw new RuntimeException("Expected ClassFormatError not thrown");
+ } catch (java.lang.ClassFormatError e) {
+ if (!throwCFE) {
+ throw new RuntimeException("Unexpected ClassFormatError exception: " + e.getMessage());
+ }
+ if (module_test && !e.getMessage().contains(
+ "Unknown constant tag 19 in class file")) {
+ throw new RuntimeException("Wrong ClassFormatError exception: " + e.getMessage());
+ } else if (!module_test && !e.getMessage().contains(
+ "Unknown constant tag 20 in class file")) {
+ throw new RuntimeException("Wrong ClassFormatError exception: " + e.getMessage());
+ }
+ } catch (java.lang.NoClassDefFoundError f) {
+ if (throwCFE) {
+ throw new RuntimeException("Unexpected NoClassDefFoundError exception: " + f.getMessage());
+ }
+ if (!f.getMessage().contains(
+ "is not a class because access_flag ACC_MODULE is set")) {
+ throw new RuntimeException("Wrong NoClassDefFoundError exception: " + f.getMessage());
+ }
+ }
+ } else {
+ throw new ClassNotFoundException(cn);
+ }
+ return null;
+ }
+ };
+
+ Class> clazz = loader.loadClass(class_name);
+ }
+
+ /**
+ * ConstModuleAttr attribute.
+ *
+ * {@code
+ *
+ * MainClass_attribute {
+ * // index to CONSTANT_utf8_info structure in constant pool representing
+ * // the string "ConstModuleAttr"
+ * u2 attribute_name_index;
+ * u4 attribute_length;
+ *
+ * // index to CONSTANT_Module_info structure
+ * u2 module_name_index
+ * }
+ *
+ * }
+ */
+ public static class TestModuleAttribute extends Attribute {
+ private final String moduleName;
+
+ public TestModuleAttribute(String moduleName) {
+ super("ConstModuleAttr");
+ this.moduleName = moduleName;
+ }
+
+ public TestModuleAttribute() {
+ this(null);
+ }
+
+ @Override
+ protected Attribute read(ClassReader cr,
+ int off,
+ int len,
+ char[] buf,
+ int codeOff,
+ Label[] labels)
+ {
+ String mn = cr.readModule(off, buf);
+ off += 2;
+ return new TestModuleAttribute(mn);
+ }
+
+ @Override
+ protected ByteVector write(ClassWriter cw,
+ byte[] code,
+ int len,
+ int maxStack,
+ int maxLocals)
+ {
+ ByteVector attr = new ByteVector();
+ attr.putShort(cw.newModule(moduleName));
+ return attr;
+ }
+ }
+
+ /**
+ * ConstPackageAttr attribute.
+ *
+ * {@code
+ *
+ * MainClass_attribute {
+ * // index to CONSTANT_utf8_info structure in constant pool representing
+ * // the string "ConstPackageAttr"
+ * u2 attribute_name_index;
+ * u4 attribute_length;
+ *
+ * // index to CONSTANT_Package_info structure
+ * u2 module_name_index
+ * }
+ *
+ * }
+ */
+ public static class TestPackageAttribute extends Attribute {
+ private final String packageName;
+
+ public TestPackageAttribute(String packageName) {
+ super("ConstPackageAttr");
+ this.packageName = packageName;
+ }
+
+ public TestPackageAttribute() {
+ this(null);
+ }
+
+ @Override
+ protected Attribute read(ClassReader cr,
+ int off,
+ int len,
+ char[] buf,
+ int codeOff,
+ Label[] labels)
+ {
+ String mn = cr.readPackage(off, buf);
+ off += 2;
+ return new TestPackageAttribute(mn);
+ }
+
+ @Override
+ protected ByteVector write(ClassWriter cw,
+ byte[] code,
+ int len,
+ int maxStack,
+ int maxLocals)
+ {
+ ByteVector attr = new ByteVector();
+ attr.putShort(cw.newPackage(packageName));
+ return attr;
+ }
+ }
+}
diff -r 18569c523d38 -r c61cc8a34456 hotspot/test/runtime/duplAttributes/DupSignatureAttrs.jcod
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/duplAttributes/DupSignatureAttrs.jcod Wed Jul 05 23:09:40 2017 +0200
@@ -0,0 +1,615 @@
+/*
+ * Copyright (c) 2017, 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 containing duplicate Signature attributes. Loading it should cause a
+// ClassFormatError exception.
+class DupClassSigAttrs {
+ 0xCAFEBABE;
+ 0; // minor version
+ 53; // version
+ [33] { // Constant Pool
+ ; // first element is empty
+ Method #6 #17; // #1 at 0x0A
+ Field #18 #19; // #2 at 0x0F
+ String #20; // #3 at 0x14
+ Method #21 #22; // #4 at 0x17
+ class #23; // #5 at 0x1C
+ class #24; // #6 at 0x1F
+ Utf8 ""; // #7 at 0x22
+ Utf8 "()V"; // #8 at 0x2B
+ Utf8 "Code"; // #9 at 0x31
+ Utf8 "LineNumberTable"; // #10 at 0x38
+ Utf8 "main"; // #11 at 0x4A
+ Utf8 "([Ljava/lang/String;)V"; // #12 at 0x51
+ Utf8 "Exceptions"; // #13 at 0x6A
+ class #25; // #14 at 0x77
+ Utf8 "SourceFile"; // #15 at 0x7A
+ Utf8 "DupClassSigAttrs.java"; // #16 at 0x87
+ NameAndType #7 #8; // #17 at 0x9F
+ class #26; // #18 at 0xA4
+ NameAndType #27 #28; // #19 at 0xA7
+ Utf8 "hi"; // #20 at 0xAC
+ class #29; // #21 at 0xB1
+ NameAndType #30 #31; // #22 at 0xB4
+ Utf8 "DupClassSigAttrs"; // #23 at 0xB9
+ Utf8 "java/lang/Object"; // #24 at 0xCC
+ Utf8 "java/lang/Throwable"; // #25 at 0xDF
+ Utf8 "java/lang/System"; // #26 at 0xF5
+ Utf8 "out"; // #27 at 0x0108
+ Utf8 "Ljava/io/PrintStream;"; // #28 at 0x010E
+ Utf8 "java/io/PrintStream"; // #29 at 0x0126
+ Utf8 "println"; // #30 at 0x013C
+ Utf8 "(Ljava/lang/String;)V"; // #31 at 0x0146
+ Utf8 "Signature"; // #32 at 0x015E
+ } // Constant Pool
+
+ 0x0021; // access
+ #5;// this_cpx
+ #6;// super_cpx
+
+ [0] { // Interfaces
+ } // Interfaces
+
+ [0] { // fields
+ } // fields
+
+ [2] { // methods
+ { // Member at 0x0176
+ 0x0001; // access
+ #7; // name_cpx
+ #8; // sig_cpx
+ [1] { // Attributes
+ Attr(#9, 29) { // Code at 0x017E
+ 1; // max_stack
+ 1; // max_locals
+ Bytes[5]{
+ 0x2AB70001B1;
+ };
+ [0] { // Traps
+ } // end Traps
+ [1] { // Attributes
+ Attr(#10, 6) { // LineNumberTable at 0x0195
+ [1] { // LineNumberTable
+ 0 1; // at 0x01A1
+ }
+ } // end LineNumberTable
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ ;
+ { // Member at 0x01A1
+ 0x0009; // access
+ #11; // name_cpx
+ #12; // sig_cpx
+ [2] { // Attributes
+ Attr(#9, 37) { // Code at 0x01A9
+ 2; // max_stack
+ 1; // max_locals
+ Bytes[9]{
+ 0xB200021203B60004;
+ 0xB1;
+ };
+ [0] { // Traps
+ } // end Traps
+ [1] { // Attributes
+ Attr(#10, 10) { // LineNumberTable at 0x01C4
+ [2] { // LineNumberTable
+ 0 4; // at 0x01D0
+ 8 5; // at 0x01D4
+ }
+ } // end LineNumberTable
+ } // Attributes
+ } // end Code
+ ;
+ Attr(#13, 4) { // Exceptions at 0x01D4
+ [1] { // Exceptions
+ #14; // at 0x01DE
+ }
+ } // end Exceptions
+ } // Attributes
+ } // Member
+ } // methods
+
+ [3] { // Attributes
+ Attr(#15, 2) { // SourceFile at 0x01E0
+ #16;
+ } // end SourceFile
+ ;
+ Attr(#32, 2) { // Signature at 0x01E8
+ #16;
+ } // end Signature
+ ;
+ Attr(#32, 2) { // *** Duplicate *** Signature at 0x01F0
+ #16;
+ } // end Signature
+ } // Attributes
+} // end class DupClassSigAttrs
+
+
+// Class containing a method with duplicate Signature attributes. Loading it
+// should cause a ClassFormatError exception.
+class DupMthSigAttrs {
+ 0xCAFEBABE;
+ 0; // minor version
+ 53; // version
+ [33] { // Constant Pool
+ ; // first element is empty
+ Method #6 #17; // #1 at 0x0A
+ Field #18 #19; // #2 at 0x0F
+ String #20; // #3 at 0x14
+ Method #21 #22; // #4 at 0x17
+ class #23; // #5 at 0x1C
+ class #24; // #6 at 0x1F
+ Utf8 ""; // #7 at 0x22
+ Utf8 "()V"; // #8 at 0x2B
+ Utf8 "Code"; // #9 at 0x31
+ Utf8 "LineNumberTable"; // #10 at 0x38
+ Utf8 "main"; // #11 at 0x4A
+ Utf8 "([Ljava/lang/String;)V"; // #12 at 0x51
+ Utf8 "Exceptions"; // #13 at 0x6A
+ class #25; // #14 at 0x77
+ Utf8 "SourceFile"; // #15 at 0x7A
+ Utf8 "DupMthSigAttrs.java"; // #16 at 0x87
+ NameAndType #7 #8; // #17 at 0x9D
+ class #26; // #18 at 0xA2
+ NameAndType #27 #28; // #19 at 0xA5
+ Utf8 "hi"; // #20 at 0xAA
+ class #29; // #21 at 0xAF
+ NameAndType #30 #31; // #22 at 0xB2
+ Utf8 "DupMthSigAttrs"; // #23 at 0xB7
+ Utf8 "java/lang/Object"; // #24 at 0xC8
+ Utf8 "java/lang/Throwable"; // #25 at 0xDB
+ Utf8 "java/lang/System"; // #26 at 0xF1
+ Utf8 "out"; // #27 at 0x0104
+ Utf8 "Ljava/io/PrintStream;"; // #28 at 0x010A
+ Utf8 "java/io/PrintStream"; // #29 at 0x0122
+ Utf8 "println"; // #30 at 0x0138
+ Utf8 "(Ljava/lang/String;)V"; // #31 at 0x0142
+ Utf8 "Signature"; // #32 at 0x015A
+ } // Constant Pool
+
+ 0x0021; // access
+ #5;// this_cpx
+ #6;// super_cpx
+
+ [0] { // Interfaces
+ } // Interfaces
+
+ [0] { // fields
+ } // fields
+
+ [2] { // methods
+ { // Member at 0x0172
+ 0x0001; // access
+ #7; // name_cpx
+ #8; // sig_cpx
+ [1] { // Attributes
+ Attr(#9, 29) { // Code at 0x017A
+ 1; // max_stack
+ 1; // max_locals
+ Bytes[5]{
+ 0x2AB70001B1;
+ };
+ [0] { // Traps
+ } // end Traps
+ [1] { // Attributes
+ Attr(#10, 6) { // LineNumberTable at 0x0191
+ [1] { // LineNumberTable
+ 0 1; // at 0x019D
+ }
+ } // end LineNumberTable
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ ;
+ { // Member at 0x019D
+ 0x0009; // access
+ #11; // name_cpx
+ #12; // sig_cpx
+ [4] { // Attributes
+ Attr(#9, 37) { // Code at 0x01A5
+ 2; // max_stack
+ 1; // max_locals
+ Bytes[9]{
+ 0xB200021203B60004;
+ 0xB1;
+ };
+ [0] { // Traps
+ } // end Traps
+ [1] { // Attributes
+ Attr(#10, 10) { // LineNumberTable at 0x01C0
+ [2] { // LineNumberTable
+ 0 4; // at 0x01CC
+ 8 5; // at 0x01D0
+ }
+ } // end LineNumberTable
+ } // Attributes
+ } // end Code
+ ;
+ Attr(#32, 2) { // Signature at 0x01D0
+ #16;
+ } // end Signature
+ ;
+ Attr(#13, 4) { // Exceptions at 0x01D8
+ [1] { // Exceptions
+ #14; // at 0x01E2
+ }
+ } // end Exceptions
+ ;
+ Attr(#32, 2) { // *** Duplicate *** Signature at 0x01E2
+ #16;
+ } // end Signature
+ } // Attributes
+ } // Member
+ } // methods
+
+ [1] { // Attributes
+ Attr(#15, 2) { // SourceFile at 0x01EC
+ #16;
+ } // end SourceFile
+ } // Attributes
+} // end class DupMthSigAttrs
+
+
+// Class containing a field with duplicate Signature attributes. Loading it
+// should cause a ClassFormatError exception.
+class DupFldSigAttrs {
+ 0xCAFEBABE;
+ 0; // minor version
+ 53; // version
+ [42] { // Constant Pool
+ ; // first element is empty
+ Method #9 #23; // #1 at 0x0A
+ Field #24 #25; // #2 at 0x0F
+ Field #8 #26; // #3 at 0x14
+ Method #27 #28; // #4 at 0x19
+ class #29; // #5 at 0x1E
+ String #30; // #6 at 0x21
+ Method #5 #31; // #7 at 0x24
+ class #32; // #8 at 0x29
+ class #33; // #9 at 0x2C
+ Utf8 "str"; // #10 at 0x2F
+ Utf8 "Ljava/lang/String;"; // #11 at 0x35
+ Utf8 ""; // #12 at 0x4A
+ Utf8 "()V"; // #13 at 0x53
+ Utf8 "Code"; // #14 at 0x59
+ Utf8 "LineNumberTable"; // #15 at 0x60
+ Utf8 "main"; // #16 at 0x72
+ Utf8 "([Ljava/lang/String;)V"; // #17 at 0x79
+ Utf8 "Exceptions"; // #18 at 0x92
+ class #34; // #19 at 0x9F
+ Utf8 ""; // #20 at 0xA2
+ Utf8 "SourceFile"; // #21 at 0xAD
+ Utf8 "DupFldSigAttrs.java"; // #22 at 0xBA
+ NameAndType #12 #13; // #23 at 0xD0
+ class #35; // #24 at 0xD5
+ NameAndType #36 #37; // #25 at 0xD8
+ NameAndType #10 #11; // #26 at 0xDD
+ class #38; // #27 at 0xE2
+ NameAndType #39 #40; // #28 at 0xE5
+ Utf8 "java/lang/String"; // #29 at 0xEA
+ Utf8 "Hi"; // #30 at 0xFD
+ NameAndType #12 #40; // #31 at 0x0102
+ Utf8 "DupFldSigAttrs"; // #32 at 0x0107
+ Utf8 "java/lang/Object"; // #33 at 0x0118
+ Utf8 "java/lang/Throwable"; // #34 at 0x012B
+ Utf8 "java/lang/System"; // #35 at 0x0141
+ Utf8 "out"; // #36 at 0x0154
+ Utf8 "Ljava/io/PrintStream;"; // #37 at 0x015A
+ Utf8 "java/io/PrintStream"; // #38 at 0x0172
+ Utf8 "println"; // #39 at 0x0188
+ Utf8 "(Ljava/lang/String;)V"; // #40 at 0x0192
+ Utf8 "Signature"; // #41 at 0x01AA
+ } // Constant Pool
+
+ 0x0021; // access
+ #8;// this_cpx
+ #9;// super_cpx
+
+ [0] { // Interfaces
+ } // Interfaces
+
+ [1] { // fields
+ { // Member at 0x01C0
+ 0x0008; // access
+ #10; // name_cpx
+ #11; // sig_cpx
+ [2] { // Attributes
+ Attr(#41, 2) { // Signature at 0x01C8
+ #16;
+ } // end Signature
+ ;
+ Attr(#41, 2) { // *** Duplicate *** Signature at 0x01D0
+ #16;
+ } // end Signature
+ } // Attributes
+ } // Member
+ } // fields
+
+ [3] { // methods
+ { // Member at 0x01DA
+ 0x0001; // access
+ #12; // name_cpx
+ #13; // sig_cpx
+ [1] { // Attributes
+ Attr(#14, 29) { // Code at 0x01E2
+ 1; // max_stack
+ 1; // max_locals
+ Bytes[5]{
+ 0x2AB70001B1;
+ };
+ [0] { // Traps
+ } // end Traps
+ [1] { // Attributes
+ Attr(#15, 6) { // LineNumberTable at 0x01F9
+ [1] { // LineNumberTable
+ 0 1; // at 0x0205
+ }
+ } // end LineNumberTable
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ ;
+ { // Member at 0x0205
+ 0x0009; // access
+ #16; // name_cpx
+ #17; // sig_cpx
+ [2] { // Attributes
+ Attr(#14, 38) { // Code at 0x020D
+ 2; // max_stack
+ 1; // max_locals
+ Bytes[10]{
+ 0xB20002B20003B600;
+ 0x04B1;
+ };
+ [0] { // Traps
+ } // end Traps
+ [1] { // Attributes
+ Attr(#15, 10) { // LineNumberTable at 0x0229
+ [2] { // LineNumberTable
+ 0 6; // at 0x0235
+ 9 7; // at 0x0239
+ }
+ } // end LineNumberTable
+ } // Attributes
+ } // end Code
+ ;
+ Attr(#18, 4) { // Exceptions at 0x0239
+ [1] { // Exceptions
+ #19; // at 0x0243
+ }
+ } // end Exceptions
+ } // Attributes
+ } // Member
+ ;
+ { // Member at 0x0243
+ 0x0008; // access
+ #20; // name_cpx
+ #13; // sig_cpx
+ [1] { // Attributes
+ Attr(#14, 37) { // Code at 0x024B
+ 3; // max_stack
+ 0; // max_locals
+ Bytes[13]{
+ 0xBB0005591206B700;
+ 0x07B30003B1;
+ };
+ [0] { // Traps
+ } // end Traps
+ [1] { // Attributes
+ Attr(#15, 6) { // LineNumberTable at 0x026A
+ [1] { // LineNumberTable
+ 0 3; // at 0x0276
+ }
+ } // end LineNumberTable
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ } // methods
+
+ [1] { // Attributes
+ Attr(#21, 2) { // SourceFile at 0x0278
+ #22;
+ } // end SourceFile
+ } // Attributes
+} // end class DupFldSigAttrs
+
+
+// Class containing a Signature attribute and a field and methods with Signature
+// attributes. Since neither the class nor any of its fields or methods have
+// duplicate Signature attributes, loading this class should not cause a
+// ClassFormatError exception.
+class OkaySigAttrs {
+ 0xCAFEBABE;
+ 0; // minor version
+ 53; // version
+ [42] { // Constant Pool
+ ; // first element is empty
+ Method #9 #23; // #1 at 0x0A
+ Field #24 #25; // #2 at 0x0F
+ Field #8 #26; // #3 at 0x14
+ Method #27 #28; // #4 at 0x19
+ class #29; // #5 at 0x1E
+ String #30; // #6 at 0x21
+ Method #5 #31; // #7 at 0x24
+ class #32; // #8 at 0x29
+ class #33; // #9 at 0x2C
+ Utf8 "str"; // #10 at 0x2F
+ Utf8 "Ljava/lang/String;"; // #11 at 0x35
+ Utf8 ""; // #12 at 0x4A
+ Utf8 "()V"; // #13 at 0x53
+ Utf8 "Code"; // #14 at 0x59
+ Utf8 "LineNumberTable"; // #15 at 0x60
+ Utf8 "main"; // #16 at 0x72
+ Utf8 "([Ljava/lang/String;)V"; // #17 at 0x79
+ Utf8 "Exceptions"; // #18 at 0x92
+ class #34; // #19 at 0x9F
+ Utf8 ""; // #20 at 0xA2
+ Utf8 "SourceFile"; // #21 at 0xAD
+ Utf8 "OkaySigAttrs.java"; // #22 at 0xBA
+ NameAndType #12 #13; // #23 at 0xCE
+ class #35; // #24 at 0xD3
+ NameAndType #36 #37; // #25 at 0xD6
+ NameAndType #10 #11; // #26 at 0xDB
+ class #38; // #27 at 0xE0
+ NameAndType #39 #40; // #28 at 0xE3
+ Utf8 "java/lang/String"; // #29 at 0xE8
+ Utf8 "Hi"; // #30 at 0xFB
+ NameAndType #12 #40; // #31 at 0x0100
+ Utf8 "OkaySigAttrs"; // #32 at 0x0105
+ Utf8 "java/lang/Object"; // #33 at 0x0114
+ Utf8 "java/lang/Throwable"; // #34 at 0x0127
+ Utf8 "java/lang/System"; // #35 at 0x013D
+ Utf8 "out"; // #36 at 0x0150
+ Utf8 "Ljava/io/PrintStream;"; // #37 at 0x0156
+ Utf8 "java/io/PrintStream"; // #38 at 0x016E
+ Utf8 "println"; // #39 at 0x0184
+ Utf8 "(Ljava/lang/String;)V"; // #40 at 0x018E
+ Utf8 "Signature"; // #41 at 0x01A6
+ } // Constant Pool
+
+ 0x0021; // access
+ #8;// this_cpx
+ #9;// super_cpx
+
+ [0] { // Interfaces
+ } // Interfaces
+
+ [1] { // fields
+ { // Member at 0x01BC
+ 0x0008; // access
+ #10; // name_cpx
+ #11; // sig_cpx
+ [1] { // Attributes
+ Attr(#41, 2) { // Signature at 0x01C4
+ #16;
+ } // end Signature
+ } // Attributes
+ } // Member
+ } // fields
+
+ [3] { // methods
+ { // Member at 0x01CE
+ 0x0001; // access
+ #12; // name_cpx
+ #13; // sig_cpx
+ [2] { // Attributes
+ Attr(#14, 29) { // Code at 0x01D6
+ 1; // max_stack
+ 1; // max_locals
+ Bytes[5]{
+ 0x2AB70001B1;
+ };
+ [0] { // Traps
+ } // end Traps
+ [1] { // Attributes
+ Attr(#15, 6) { // LineNumberTable at 0x01ED
+ [1] { // LineNumberTable
+ 0 1; // at 0x01F9
+ }
+ } // end LineNumberTable
+ } // Attributes
+ } // end Code
+ ;
+ Attr(#41, 2) { // Signature at 0x01F9
+ #16;
+ } // end Signature
+ } // Attributes
+ } // Member
+ ;
+ { // Member at 0x0201
+ 0x0009; // access
+ #16; // name_cpx
+ #17; // sig_cpx
+ [3] { // Attributes
+ Attr(#14, 38) { // Code at 0x0209
+ 2; // max_stack
+ 1; // max_locals
+ Bytes[10]{
+ 0xB20002B20003B600;
+ 0x04B1;
+ };
+ [0] { // Traps
+ } // end Traps
+ [1] { // Attributes
+ Attr(#15, 10) { // LineNumberTable at 0x0225
+ [2] { // LineNumberTable
+ 0 6; // at 0x0231
+ 9 7; // at 0x0235
+ }
+ } // end LineNumberTable
+ } // Attributes
+ } // end Code
+ ;
+ Attr(#41, 2) { // Signature at 0x0235
+ #16;
+ } // end Signature
+ ;
+ Attr(#18, 4) { // Exceptions at 0x023D
+ [1] { // Exceptions
+ #19; // at 0x0247
+ }
+ } // end Exceptions
+ } // Attributes
+ } // Member
+ ;
+ { // Member at 0x0247
+ 0x0008; // access
+ #20; // name_cpx
+ #13; // sig_cpx
+ [1] { // Attributes
+ Attr(#14, 37) { // Code at 0x024F
+ 3; // max_stack
+ 0; // max_locals
+ Bytes[13]{
+ 0xBB0005591206B700;
+ 0x07B30003B1;
+ };
+ [0] { // Traps
+ } // end Traps
+ [1] { // Attributes
+ Attr(#15, 6) { // LineNumberTable at 0x026E
+ [1] { // LineNumberTable
+ 0 3; // at 0x027A
+ }
+ } // end LineNumberTable
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ } // methods
+
+ [2] { // Attributes
+ Attr(#21, 2) { // SourceFile at 0x027C
+ #22;
+ } // end SourceFile
+ ;
+ Attr(#41, 2) { // Signature at 0x0284
+ #16;
+ } // end Signature
+ } // Attributes
+} // end class OkaySigAttrs
diff -r 18569c523d38 -r c61cc8a34456 hotspot/test/runtime/duplAttributes/TestDupSignatureAttr.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/duplAttributes/TestDupSignatureAttr.java Wed Jul 05 23:09:40 2017 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2017, 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 8176147
+ * @summary Throw ClassFormatError exception for multiple Signature attributes
+ * @compile DupSignatureAttrs.jcod
+ * @run main TestDupSignatureAttr
+ */
+
+public class TestDupSignatureAttr {
+ public static void main(String args[]) throws Throwable {
+
+ System.out.println("Regression test for bug 8176147");
+
+ String[] badClasses = new String[] {
+ "DupClassSigAttrs",
+ "DupMthSigAttrs",
+ "DupFldSigAttrs",
+ };
+ String[] messages = new String[] {
+ "Multiple Signature attributes in class file",
+ "Multiple Signature attributes for method",
+ "Multiple Signature attributes for field",
+ };
+
+ for (int x = 0; x < badClasses.length; x++) {
+ try {
+ Class newClass = Class.forName(badClasses[x]);
+ throw new RuntimeException("Expected ClassFormatError exception not thrown");
+ } catch (java.lang.ClassFormatError e) {
+ if (!e.getMessage().contains(messages[x])) {
+ throw new RuntimeException("Wrong ClassFormatError exception thrown: " +
+ e.getMessage());
+ }
+ }
+ }
+
+ // Multiple Signature attributes but no duplicates.
+ Class newClass = Class.forName("OkaySigAttrs");
+ }
+}
diff -r 18569c523d38 -r c61cc8a34456 hotspot/test/runtime/jni/CallWithJNIWeak/CallWithJNIWeak.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/jni/CallWithJNIWeak/CallWithJNIWeak.java Wed Jul 05 23:09:40 2017 +0200
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2017, 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 8166188
+ * @summary Test call of native function with JNI weak global ref.
+ * @modules java.base
+ * @run main/othervm/native CallWithJNIWeak
+ */
+
+public class CallWithJNIWeak {
+ static {
+ System.loadLibrary("CallWithJNIWeak");
+ }
+
+ private static native void testJNIFieldAccessors(CallWithJNIWeak o);
+
+ // The field initializations must be kept in sync with the JNI code
+ // which reads verifies the values of these fields.
+ private int i = 1;
+ private long j = 2;
+ private boolean z = true;
+ private char c = 'a';
+ private short s = 3;
+ private float f = 1.0f;
+ private double d = 2.0;
+ private Object l;
+
+ private CallWithJNIWeak() {
+ this.l = this;
+ }
+
+ private native void weakReceiverTest0();
+ private void weakReceiverTest() {
+ weakReceiverTest0();
+ }
+
+ private synchronized void synchonizedWeakReceiverTest() {
+ this.notifyAll();
+ }
+
+
+ private static native void runTests(CallWithJNIWeak o);
+
+ public static void main(String[] args) {
+ CallWithJNIWeak w = new CallWithJNIWeak();
+ for (int i = 0; i < 20000; i++) {
+ runTests(w);
+ }
+ }
+}
diff -r 18569c523d38 -r c61cc8a34456 hotspot/test/runtime/jni/CallWithJNIWeak/libCallWithJNIWeak.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/jni/CallWithJNIWeak/libCallWithJNIWeak.c Wed Jul 05 23:09:40 2017 +0200
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2017, 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
+
+/*
+ * Class: CallWithJNIWeak
+ * Method: testJNIFieldAccessors
+ * Signature: (LCallWithJNIWeak;)V
+ */
+JNIEXPORT void JNICALL
+Java_CallWithJNIWeak_testJNIFieldAccessors(JNIEnv *env, jclass clazz, jobject this) {
+ // Make sure that we have a weak reference to the receiver
+
+ jweak self = (*env)->NewWeakGlobalRef(env, this);
+
+ jclass this_class = (*env)->GetObjectClass(env, self);
+
+ jclass exception = (*env)->FindClass(env, "java/lang/RuntimeException");
+
+ jfieldID id_i = (*env)->GetFieldID(env, this_class, "i", "I");
+ jfieldID id_j = (*env)->GetFieldID(env, this_class, "j", "J");
+ jfieldID id_z = (*env)->GetFieldID(env, this_class, "z", "Z");
+ jfieldID id_c = (*env)->GetFieldID(env, this_class, "c", "C");
+ jfieldID id_s = (*env)->GetFieldID(env, this_class, "s", "S");
+ jfieldID id_f = (*env)->GetFieldID(env, this_class, "f", "F");
+ jfieldID id_d = (*env)->GetFieldID(env, this_class, "d", "D");
+ jfieldID id_l = (*env)->GetFieldID(env, this_class, "l", "Ljava/lang/Object;");
+ jvalue v;
+
+#define CHECK(variable, expected) \
+ do { \
+ if ((variable) != (expected)) { \
+ (*env)->ThrowNew(env, exception, #variable" != " #expected); \
+ return; \
+ } \
+ } while(0)
+
+ // The values checked below must be kept in sync with the Java source file.
+
+ v.i = (*env)->GetIntField(env, self, id_i);
+ CHECK(v.i, 1);
+
+ v.j = (*env)->GetLongField(env, self, id_j);
+ CHECK(v.j, 2);
+
+ v.z = (*env)->GetBooleanField(env, self, id_z);
+ CHECK(v.z, JNI_TRUE);
+
+ v.c = (*env)->GetCharField(env, self, id_c);
+ CHECK(v.c, 'a');
+
+ v.s = (*env)->GetShortField(env, self, id_s);
+ CHECK(v.s, 3);
+
+ v.f = (*env)->GetFloatField(env, self, id_f);
+ CHECK(v.f, 1.0f);
+
+ v.d = (*env)->GetDoubleField(env, self, id_d);
+ CHECK(v.d, 2.0);
+
+#undef CHECK
+
+ v.l = (*env)->GetObjectField(env, self, id_l);
+ if (v.l == NULL) {
+ (*env)->ThrowNew(env, exception, "Object field was null");
+ return;
+ }
+ {
+ jclass clz = (*env)->GetObjectClass(env, v.l);
+ if (!(*env)->IsSameObject(env, clazz, clz)) {
+ (*env)->ThrowNew(env, exception, "Bad object class");
+ }
+ }
+
+ (*env)->DeleteWeakGlobalRef(env, self);
+}
+
+/*
+ * Class: CallWithJNIWeak
+ * Method: runTests
+ * Signature: (LCallWithJNIWeak;)V
+ */
+JNIEXPORT void JNICALL
+Java_CallWithJNIWeak_runTests(JNIEnv *env, jclass clazz, jobject this) {
+ jweak that = (*env)->NewWeakGlobalRef(env, this);
+ {
+ jmethodID method = (*env)->GetStaticMethodID(env,
+ clazz, "testJNIFieldAccessors", "(LCallWithJNIWeak;)V");
+ (*env)->CallStaticVoidMethod(env, clazz, method, that);
+ if ((*env)->ExceptionCheck(env)) {
+ return;
+ }
+ }
+
+ {
+ jmethodID method = (*env)->GetMethodID(env, clazz, "weakReceiverTest", "()V");
+ (*env)->CallVoidMethod(env, that, method);
+ if ((*env)->ExceptionCheck(env)) {
+ return;
+ }
+ }
+
+ {
+ jmethodID method = (*env)->GetMethodID(env, clazz, "synchonizedWeakReceiverTest", "()V");
+ (*env)->CallVoidMethod(env, that, method);
+ if ((*env)->ExceptionCheck(env)) {
+ return;
+ }
+ }
+ (*env)->DeleteWeakGlobalRef(env, that);
+}
+
+/*
+ * Class: CallWithJNIWeak
+ * Method: weakReceiverTest0
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_CallWithJNIWeak_weakReceiverTest0(JNIEnv *env, jobject obj) {
+ (*env)->GetObjectClass(env, obj);
+}
diff -r 18569c523d38 -r c61cc8a34456 hotspot/test/runtime/jni/ReturnJNIWeak/ReturnJNIWeak.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/jni/ReturnJNIWeak/ReturnJNIWeak.java Wed Jul 05 23:09:40 2017 +0200
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2017, 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 8166188
+ * @requires vm.opt.ExplicitGCInvokesConcurrent != true
+ * @summary Test return of JNI weak global refs from native calls.
+ * @modules java.base
+ * @run main/othervm/native -Xint ReturnJNIWeak
+ * @run main/othervm/native -Xcomp ReturnJNIWeak
+ */
+
+public final class ReturnJNIWeak {
+
+ static {
+ System.loadLibrary("ReturnJNIWeak");
+ }
+
+ private static final class TestObject {
+ public final int value;
+
+ public TestObject(int value) {
+ this.value = value;
+ }
+ }
+
+ private static volatile TestObject testObject = null;
+
+ private static native void registerObject(Object o);
+ private static native void unregisterObject();
+ private static native Object getObject();
+
+ // Create the test object and record it both strongly and weakly.
+ private static void remember(int value) {
+ TestObject o = new TestObject(value);
+ registerObject(o);
+ testObject = o;
+ }
+
+ // Remove both strong and weak references to the current test object.
+ private static void forget() {
+ unregisterObject();
+ testObject = null;
+ }
+
+ // Verify the weakly recorded object
+ private static void checkValue(int value) throws Exception {
+ Object o = getObject();
+ if (o == null) {
+ throw new RuntimeException("Weak reference unexpectedly null");
+ }
+ TestObject t = (TestObject)o;
+ if (t.value != value) {
+ throw new RuntimeException("Incorrect value");
+ }
+ }
+
+ // Verify we can create a weak reference and get it back.
+ private static void testSanity() throws Exception {
+ System.out.println("running testSanity");
+ int value = 5;
+ try {
+ remember(value);
+ checkValue(value);
+ } finally {
+ forget();
+ }
+ }
+
+ // Verify weak ref value survives across collection if strong ref exists.
+ private static void testSurvival() throws Exception {
+ System.out.println("running testSurvival");
+ int value = 10;
+ try {
+ remember(value);
+ checkValue(value);
+ System.gc();
+ // Verify weak ref still has expected value.
+ checkValue(value);
+ } finally {
+ forget();
+ }
+ }
+
+ // Verify weak ref cleared if no strong ref exists.
+ private static void testClear() throws Exception {
+ System.out.println("running testClear");
+ int value = 15;
+ try {
+ remember(value);
+ checkValue(value);
+ // Verify still good.
+ checkValue(value);
+ // Drop reference.
+ testObject = null;
+ System.gc();
+ // Verify weak ref cleared as expected.
+ Object recorded = getObject();
+ if (recorded != null) {
+ throw new RuntimeException("expected clear");
+ }
+ } finally {
+ forget();
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ testSanity();
+ testSurvival();
+ testClear();
+ }
+}
diff -r 18569c523d38 -r c61cc8a34456 hotspot/test/runtime/jni/ReturnJNIWeak/libReturnJNIWeak.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/jni/ReturnJNIWeak/libReturnJNIWeak.c Wed Jul 05 23:09:40 2017 +0200
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/*
+ * Native support for ReturnJNIWeak test.
+ */
+
+#include "jni.h"
+
+static jweak registered = NULL;
+
+JNIEXPORT void JNICALL
+Java_ReturnJNIWeak_registerObject(JNIEnv* env,
+ jclass jclazz,
+ jobject value) {
+ // assert registered == NULL
+ registered = (*env)->NewWeakGlobalRef(env, value);
+}
+
+JNIEXPORT void JNICALL
+Java_ReturnJNIWeak_unregisterObject(JNIEnv* env, jclass jclazz) {
+ if (registered != NULL) {
+ (*env)->DeleteWeakGlobalRef(env, registered);
+ registered = NULL;
+ }
+}
+
+JNIEXPORT jobject JNICALL
+Java_ReturnJNIWeak_getObject(JNIEnv* env, jclass jclazz) {
+ // assert registered != NULL
+ return registered;
+}
diff -r 18569c523d38 -r c61cc8a34456 hotspot/test/runtime/modules/IgnoreModulePropertiesTest.java
--- a/hotspot/test/runtime/modules/IgnoreModulePropertiesTest.java Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/test/runtime/modules/IgnoreModulePropertiesTest.java Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, 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
@@ -44,7 +44,7 @@
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
"-D" + prop + "=" + value, "-version");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
- output.shouldContain("java version ");
+ output.shouldContain(" version ");
output.shouldHaveExitValue(0);
// Ensure that the property and its value aren't available.
diff -r 18569c523d38 -r c61cc8a34456 hotspot/test/serviceability/jvmti/GetNamedModule/libGetNamedModuleTest.c
--- a/hotspot/test/serviceability/jvmti/GetNamedModule/libGetNamedModuleTest.c Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/test/serviceability/jvmti/GetNamedModule/libGetNamedModuleTest.c Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, 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
@@ -183,7 +183,7 @@
err = (*jvmti)->GetNamedModule(jvmti, loader, pkg_name, module_ptr);
if (err != JVMTI_ERROR_NONE) {
printf(" Error in GetNamedModule for package \"%s\": %s (%d)\n",
- pkg_name, TranslateError(err), err);
+ name, TranslateError(err), err);
return err;
}
printf(" returned module: %p\n", *module_ptr);
diff -r 18569c523d38 -r c61cc8a34456 hotspot/test/test_env.sh
--- a/hotspot/test/test_env.sh Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/test/test_env.sh Wed Jul 05 23:09:40 2017 +0200
@@ -214,6 +214,11 @@
then
VM_CPU="aarch64"
fi
+grep "arm64" vm_version.out > ${NULL}
+if [ $? = 0 ]
+then
+ VM_CPU="aarch64"
+fi
export VM_TYPE VM_BITS VM_OS VM_CPU
echo "VM_TYPE=${VM_TYPE}"
echo "VM_BITS=${VM_BITS}"
diff -r 18569c523d38 -r c61cc8a34456 hotspot/test/testlibrary_tests/ctw/CtwTest.java
--- a/hotspot/test/testlibrary_tests/ctw/CtwTest.java Sat Apr 08 03:25:14 2017 +0000
+++ b/hotspot/test/testlibrary_tests/ctw/CtwTest.java Wed Jul 05 23:09:40 2017 +0200
@@ -37,6 +37,7 @@
import java.nio.file.StandardCopyOption;
import java.nio.charset.Charset;
+import jdk.test.lib.Platform;
import jdk.test.lib.JDKToolFinder;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.process.ProcessTools;
@@ -93,7 +94,12 @@
// concat CTW_COMMAND and args w/o 0th element
String[] cmd = Arrays.copyOf(CTW_COMMAND, CTW_COMMAND.length + args.length - 1);
System.arraycopy(args, 1, cmd, CTW_COMMAND.length, args.length - 1);
-
+ if (Platform.isWindows()) {
+ // '*' has to be escaped on windows
+ for (int i = 0; i < cmd.length; ++i) {
+ cmd[i] = cmd[i].replace("*", "\"*\"");
+ }
+ }
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, cmd);
OutputAnalyzer output = new OutputAnalyzer(pb.start());
dump(output, "compile");
diff -r 18569c523d38 -r c61cc8a34456 jaxp/.hgtags
--- a/jaxp/.hgtags Sat Apr 08 03:25:14 2017 +0000
+++ b/jaxp/.hgtags Wed Jul 05 23:09:40 2017 +0200
@@ -405,3 +405,6 @@
5695854e8831d0c088ab0ecf83b367ec16c9760a jdk-9+159
fb8f2c8e15295120ff0f281dc057cfffb309e90e jdk-9+160
51b63f1b8001a48a16805b43babc3af7b314d501 jdk-9+161
+d02b6fbcab06c59a5f5a4a6736bd4ec6d2567855 jdk-9+162
+92a38c75cd277d8b11f4382511a62087044659a1 jdk-9+163
+6dc790a4e8310c86712cfdf7561a9820818546e6 jdk-9+164
diff -r 18569c523d38 -r c61cc8a34456 jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesImpl.java
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesImpl.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesImpl.java Wed Jul 05 23:09:40 2017 +0200
@@ -486,7 +486,7 @@
ModuleDescriptor descriptor =
ModuleDescriptor.newModule(mn, Set.of(ModuleDescriptor.Modifier.SYNTHETIC))
.requires("java.xml")
- .exports(pn)
+ .exports(pn, Set.of("java.xml"))
.build();
Module m = createModule(descriptor, loader);
diff -r 18569c523d38 -r c61cc8a34456 jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogImpl.java
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogImpl.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogImpl.java Wed Jul 05 23:09:40 2017 +0200
@@ -88,6 +88,7 @@
/**
* Construct a Catalog with specified URI.
*
+ * @param f the features object
* @param uris the uri(s) to one or more catalogs
* @throws CatalogException If an error happens while parsing the specified
* catalog file.
@@ -100,6 +101,7 @@
* Construct a Catalog with specified URI.
*
* @param parent The parent catalog
+ * @param f the features object
* @param uris the uri(s) to one or more catalogs
* @throws CatalogException If an error happens while parsing the specified
* catalog file.
@@ -137,7 +139,7 @@
for (String temp : catalogFile) {
uri = URI.create(temp);
start++;
- if (verifyCatalogFile(uri)) {
+ if (verifyCatalogFile(null, uri)) {
systemId = temp;
try {
baseURI = new URL(systemId);
@@ -169,12 +171,14 @@
parse(systemId);
}
+ setCatalog(this);
+
//save this catalog before loading the next
loadedCatalogs.put(systemId, this);
//Load delegate and alternative catalogs if defer is false.
if (!isDeferred()) {
- loadDelegateCatalogs();
+ loadDelegateCatalogs(this);
loadNextCatalogs();
}
}
@@ -365,14 +369,16 @@
//Check those specified in nextCatalogs
if (nextCatalogs != null) {
while (c == null && nextCatalogIndex < nextCatalogs.size()) {
- c = getCatalog(nextCatalogs.get(nextCatalogIndex++).getCatalogURI());
+ c = getCatalog(catalog,
+ nextCatalogs.get(nextCatalogIndex++).getCatalogURI());
}
}
//Check the input list
if (c == null && inputFiles != null) {
while (c == null && inputFilesIndex < inputFiles.size()) {
- c = getCatalog(URI.create(inputFiles.get(inputFilesIndex++)));
+ c = getCatalog(null,
+ URI.create(inputFiles.get(inputFilesIndex++)));
}
}
@@ -408,14 +414,14 @@
//loads catalogs specified in nextCatalogs
if (nextCatalogs != null) {
nextCatalogs.stream().forEach((next) -> {
- getCatalog(next.getCatalogURI());
+ getCatalog(this, next.getCatalogURI());
});
}
//loads catalogs from the input list
if (inputFiles != null) {
inputFiles.stream().forEach((uri) -> {
- getCatalog(URI.create(uri));
+ getCatalog(null, URI.create(uri));
});
}
}
@@ -423,17 +429,19 @@
/**
* Returns a Catalog object by the specified path.
*
- * @param path the path to a catalog
+ * @param parent the parent catalog for the alternative catalogs to be loaded.
+ * It will be null if the ones to be loaded are from the input list.
+ * @param uri the path to a catalog
* @return a Catalog object
*/
- Catalog getCatalog(URI uri) {
+ Catalog getCatalog(CatalogImpl parent, URI uri) {
if (uri == null) {
return null;
}
CatalogImpl c = null;
- if (verifyCatalogFile(uri)) {
+ if (verifyCatalogFile(parent, uri)) {
c = getLoadedCatalog(uri.toASCIIString());
if (c == null) {
c = new CatalogImpl(this, features, uri);
@@ -459,6 +467,6 @@
* @return a count of all loaded catalogs
*/
int loadedCatalogCount() {
- return loadedCatalogs.size() + delegateCatalogs.size();
+ return loadedCatalogs.size();
}
}
diff -r 18569c523d38 -r c61cc8a34456 jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogMessages.properties
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogMessages.properties Sat Apr 08 03:25:14 2017 +0000
+++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogMessages.properties Wed Jul 05 23:09:40 2017 +0200
@@ -1,4 +1,4 @@
-# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2015, 2017, 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,25 +21,32 @@
# or visit www.oracle.com if you need additional information or have any
# questions.
-# Messages for message reporting
-BadMessageKey = The error message corresponding to the message key can not be found.
-FormatFailed = An internal error occurred while formatting the following message:\n
+# General errors
+BadMessageKey = JAXP09000001: The error message corresponding to the message key can not be found.
+FormatFailed = JAXP09000002: An internal error occurred while formatting the following message:\n
+OtherError = JAXP09000003: Unexpected error.
-#invalid catalog file
-InvalidCatalog = The document element of a catalog must be catalog.
-InvalidEntryType = The entry type ''{0}'' is not valid.
-CircularReference = Circular reference is not allowed: ''{0}''.
+# Implementation restriction
+CircularReference = JAXP09010001: Circular reference is not allowed: ''{0}''.
-#errors
-UriNotAbsolute = The specified URI ''{0}'' is not absolute.
-UriNotValidUrl = The specified URI ''{0}'' is not a valid URL.
-InvalidArgument = The specified argument ''{0}'' (case sensitive) for ''{1}'' is not valid.
-NullArgument = The argument ''{0}'' can not be null.
-InvalidPath = The path ''{0}'' is invalid.
-ParserConf = Unexpected error while configuring a SAX parser.
-ParsingFailed = Failed to parse the catalog file.
-NoCatalogFound = No Catalog is specified.
-NoMatchFound = No match found for publicId ''{0}'' and systemId ''{1}''.
-NoMatchURIFound = No match found for href ''{0}'' and base ''{1}''.
-FailedCreatingURI = Can not construct URI using href ''{0}'' and base ''{1}''.
-OtherError = Unexpected error.
\ No newline at end of file
+# Input or configuration errors
+InvalidCatalog = JAXP09020001: The document element of a catalog must be catalog.
+InvalidEntryType = JAXP09020002: The entry type ''{0}'' is not valid.
+UriNotAbsolute = JAXP09020003: The specified URI ''{0}'' is not absolute.
+UriNotValidUrl = JAXP09020004: The specified URI ''{0}'' is not a valid URL.
+InvalidArgument = JAXP09020005: The specified argument ''{0}'' (case sensitive) for ''{1}'' is not valid.
+NullArgument = JAXP09020006: The argument ''{0}'' can not be null.
+InvalidPath = JAXP09020007: The path ''{0}'' is invalid.
+
+
+# Parsing errors
+ParserConf = JAXP09030001: Unexpected error while configuring a SAX parser.
+ParsingFailed = JAXP09030002: Failed to parse the catalog file.
+NoCatalogFound = JAXP09030003: No Catalog is specified.
+
+
+# Resolving errors
+NoMatchFound = JAXP09040001: No match found for publicId ''{0}'' and systemId ''{1}''.
+NoMatchURIFound = JAXP09040002: No match found for href ''{0}'' and base ''{1}''.
+FailedCreatingURI = JAXP09040003: Can not construct URI using href ''{0}'' and base ''{1}''.
+
diff -r 18569c523d38 -r c61cc8a34456 jaxp/src/java.xml/share/classes/javax/xml/catalog/GroupEntry.java
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/GroupEntry.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/GroupEntry.java Wed Jul 05 23:09:40 2017 +0200
@@ -135,7 +135,8 @@
/**
* Constructs a GroupEntry
*
- * @param type The type of the entry
+ * @param type the type of the entry
+ * @param parent the parent Catalog
*/
public GroupEntry(CatalogEntryType type, CatalogImpl parent) {
super(type);
@@ -165,9 +166,9 @@
}
/**
* Constructs a group entry.
- * @param catalog The catalog this GroupEntry belongs
- * @param base The baseURI attribute
- * @param attributes The attributes
+ * @param catalog the catalog this GroupEntry belongs to
+ * @param base the baseURI attribute
+ * @param attributes the attributes
*/
public GroupEntry(CatalogImpl catalog, String base, String... attributes) {
super(CatalogEntryType.GROUP, base);
@@ -176,6 +177,15 @@
}
/**
+ * Sets the catalog for this GroupEntry.
+ *
+ * @param catalog the catalog this GroupEntry belongs to
+ */
+ void setCatalog(CatalogImpl catalog) {
+ this.catalog = catalog;
+ }
+
+ /**
* Adds an entry.
*
* @param entry The entry to be added.
@@ -382,10 +392,9 @@
/**
* Matches delegatePublic or delegateSystem against the specified id
*
- * @param isSystem The flag to indicate whether the delegate is system or
- * public
- * @param id The system or public id to be matched
- * @return The URI string if a mapping is found, or null otherwise.
+ * @param type the type of the Catalog entry
+ * @param id the system or public id to be matched
+ * @return the URI string if a mapping is found, or null otherwise.
*/
private String matchDelegate(CatalogEntryType type, String id) {
String match = null;
@@ -412,7 +421,7 @@
//Check delegate Catalogs
if (catalogId != null) {
- Catalog delegateCatalog = loadCatalog(catalogId);
+ Catalog delegateCatalog = loadDelegateCatalog(catalog, catalogId);
if (delegateCatalog != null) {
if (type == CatalogEntryType.DELEGATESYSTEM) {
@@ -430,30 +439,34 @@
/**
* Loads all delegate catalogs.
+ *
+ * @param parent the parent catalog of the delegate catalogs
*/
- void loadDelegateCatalogs() {
+ void loadDelegateCatalogs(CatalogImpl parent) {
entries.stream()
.filter((entry) -> (entry.type == CatalogEntryType.DELEGATESYSTEM ||
entry.type == CatalogEntryType.DELEGATEPUBLIC ||
entry.type == CatalogEntryType.DELEGATEURI))
.map((entry) -> (AltCatalog)entry)
.forEach((altCatalog) -> {
- loadCatalog(altCatalog.getCatalogURI());
+ loadDelegateCatalog(parent, altCatalog.getCatalogURI());
});
}
/**
* Loads a delegate catalog by the catalogId specified.
- * @param catalogId the catalog Id
+ *
+ * @param parent the parent catalog of the delegate catalog
+ * @param catalogURI the URI to the catalog
*/
- Catalog loadCatalog(URI catalogURI) {
+ Catalog loadDelegateCatalog(CatalogImpl parent, URI catalogURI) {
CatalogImpl delegateCatalog = null;
if (catalogURI != null) {
String catalogId = catalogURI.toASCIIString();
- delegateCatalog = getLoadedCatalog(catalogId);
- if (delegateCatalog == null) {
- if (verifyCatalogFile(catalogURI)) {
- delegateCatalog = new CatalogImpl(catalog, features, catalogURI);
+ if (verifyCatalogFile(parent, catalogURI)) {
+ delegateCatalog = getLoadedCatalog(catalogId);
+ if (delegateCatalog == null) {
+ delegateCatalog = new CatalogImpl(parent, features, catalogURI);
delegateCatalog.load();
delegateCatalogs.put(catalogId, delegateCatalog);
}
@@ -473,7 +486,7 @@
CatalogImpl getLoadedCatalog(String catalogId) {
CatalogImpl c = null;
- //checl delegate Catalogs
+ //check delegate Catalogs
c = delegateCatalogs.get(catalogId);
if (c == null) {
//check other loaded Catalogs
@@ -492,11 +505,12 @@
* Verifies that the catalog represented by the catalogId has not been
* searched or is not circularly referenced.
*
- * @param catalogId The URI to a catalog
+ * @param parent the parent of the catalog to be loaded
+ * @param catalogURI the URI to the catalog
* @throws CatalogException if circular reference is found.
* @return true if the catalogId passed verification, false otherwise
*/
- final boolean verifyCatalogFile(URI catalogURI) {
+ final boolean verifyCatalogFile(CatalogImpl parent, URI catalogURI) {
if (catalogURI == null) {
return false;
}
@@ -508,7 +522,7 @@
}
String catalogId = catalogURI.toASCIIString();
- if (catalogsSearched.contains(catalogId) || isCircular(catalogId)) {
+ if (catalogsSearched.contains(catalogId) || isCircular(parent, catalogId)) {
CatalogMessages.reportRunTimeError(CatalogMessages.ERR_CIRCULAR_REFERENCE,
new Object[]{CatalogMessages.sanitize(catalogId)});
}
@@ -518,10 +532,13 @@
/**
* Checks whether the catalog is circularly referenced
+ *
+ * @param parent the parent of the catalog to be loaded
* @param systemId the system identifier of the catalog to be loaded
* @return true if is circular, false otherwise
*/
- boolean isCircular(String systemId) {
+ boolean isCircular(CatalogImpl parent, String systemId) {
+ // first, check the parent of the catalog to be loaded
if (parent == null) {
return false;
}
@@ -530,6 +547,7 @@
return true;
}
- return parent.isCircular(systemId);
+ // next, check parent's parent
+ return parent.isCircular(parent.parent, systemId);
}
}
diff -r 18569c523d38 -r c61cc8a34456 jaxp/src/java.xml/share/classes/javax/xml/stream/FactoryFinder.java
--- a/jaxp/src/java.xml/share/classes/javax/xml/stream/FactoryFinder.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jaxp/src/java.xml/share/classes/javax/xml/stream/FactoryFinder.java Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -270,7 +270,7 @@
"Failed to read factoryId '" + factoryId + "'", se);
}
- // Try read $java.home/lib/stax.properties followed by
+ // Try read $java.home/conf/stax.properties followed by
// $java.home/conf/jaxp.properties if former not present
String configFile = null;
try {
@@ -278,7 +278,7 @@
synchronized (cacheProps) {
if (firstTime) {
configFile = ss.getSystemProperty("java.home") + File.separator +
- "lib" + File.separator + "stax.properties";
+ "conf" + File.separator + "stax.properties";
final File fStax = new File(configFile);
firstTime = false;
if (ss.doesFileExist(fStax)) {
diff -r 18569c523d38 -r c61cc8a34456 jaxp/src/java.xml/share/classes/javax/xml/stream/XMLEventFactory.java
--- a/jaxp/src/java.xml/share/classes/javax/xml/stream/XMLEventFactory.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jaxp/src/java.xml/share/classes/javax/xml/stream/XMLEventFactory.java Wed Jul 05 23:09:40 2017 +0200
@@ -155,7 +155,7 @@
* #newFactory(java.lang.String, java.lang.ClassLoader)}
* method defines no changes in behavior.
*/
- @Deprecated(since="7")
+ @Deprecated(since="1.7")
public static XMLEventFactory newInstance(String factoryId,
ClassLoader classLoader)
throws FactoryConfigurationError {
diff -r 18569c523d38 -r c61cc8a34456 jaxp/src/java.xml/share/classes/javax/xml/stream/XMLInputFactory.java
--- a/jaxp/src/java.xml/share/classes/javax/xml/stream/XMLInputFactory.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jaxp/src/java.xml/share/classes/javax/xml/stream/XMLInputFactory.java Wed Jul 05 23:09:40 2017 +0200
@@ -222,7 +222,7 @@
* java.util.ServiceConfigurationError service configuration error} or if
* the implementation is not available or cannot be instantiated.
*/
- @Deprecated(since="7")
+ @Deprecated(since="1.7")
public static XMLInputFactory newFactory()
throws FactoryConfigurationError
{
@@ -244,7 +244,7 @@
* #newFactory(java.lang.String, java.lang.ClassLoader)} method
* defines no changes in behavior.
*/
- @Deprecated(since="7")
+ @Deprecated(since="1.7")
public static XMLInputFactory newInstance(String factoryId,
ClassLoader classLoader)
throws FactoryConfigurationError {
diff -r 18569c523d38 -r c61cc8a34456 jaxp/src/java.xml/share/classes/javax/xml/stream/XMLOutputFactory.java
--- a/jaxp/src/java.xml/share/classes/javax/xml/stream/XMLOutputFactory.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jaxp/src/java.xml/share/classes/javax/xml/stream/XMLOutputFactory.java Wed Jul 05 23:09:40 2017 +0200
@@ -222,7 +222,7 @@
* Use the new method {@link #newFactory(java.lang.String,
* java.lang.ClassLoader)} instead.
*/
- @Deprecated(since="7")
+ @Deprecated(since="1.7")
public static XMLInputFactory newInstance(String factoryId,
ClassLoader classLoader)
throws FactoryConfigurationError {
diff -r 18569c523d38 -r c61cc8a34456 jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathFactoryFinder.java
--- a/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathFactoryFinder.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathFactoryFinder.java Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2017, 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,9 @@
String javah = ss.getSystemProperty( "java.home" );
String configFile = javah + File.separator +
- "lib" + File.separator + "jaxp.properties";
+ "conf" + File.separator + "jaxp.properties";
- // try to read from $java.home/lib/jaxp.properties
+ // try to read from $java.home/conf/jaxp.properties
try {
if(firstTime){
synchronized(cacheProps){
@@ -193,7 +193,7 @@
}
}
final String factoryClassName = cacheProps.getProperty(propertyName);
- debugPrintln(()->"found " + factoryClassName + " in $java.home/jaxp.properties");
+ debugPrintln(()->"found " + factoryClassName + " in $java.home/conf/jaxp.properties");
if (factoryClassName != null) {
xpathFactory = createInstance(factoryClassName, true);
diff -r 18569c523d38 -r c61cc8a34456 jaxp/src/java.xml/share/classes/module-info.java
--- a/jaxp/src/java.xml/share/classes/module-info.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jaxp/src/java.xml/share/classes/module-info.java Wed Jul 05 23:09:40 2017 +0200
@@ -27,6 +27,7 @@
* Defines the Java API for XML Processing (JAXP), the Streaming API for XML (StAX),
* the Simple API for XML (SAX), and the W3C Document Object Model (DOM) API.
*
+ * @moduleGraph
* @since 9
*/
module java.xml {
diff -r 18569c523d38 -r c61cc8a34456 jaxp/src/java.xml/share/classes/org/xml/sax/AttributeList.java
--- a/jaxp/src/java.xml/share/classes/org/xml/sax/AttributeList.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jaxp/src/java.xml/share/classes/org/xml/sax/AttributeList.java Wed Jul 05 23:09:40 2017 +0200
@@ -93,7 +93,7 @@
* @see org.xml.sax.DocumentHandler#startElement startElement
* @see org.xml.sax.helpers.AttributeListImpl AttributeListImpl
*/
-@Deprecated(since="5")
+@Deprecated(since="1.5")
public interface AttributeList {
diff -r 18569c523d38 -r c61cc8a34456 jaxp/src/java.xml/share/classes/org/xml/sax/DocumentHandler.java
--- a/jaxp/src/java.xml/share/classes/org/xml/sax/DocumentHandler.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jaxp/src/java.xml/share/classes/org/xml/sax/DocumentHandler.java Wed Jul 05 23:09:40 2017 +0200
@@ -68,7 +68,7 @@
* @see org.xml.sax.Locator
* @see org.xml.sax.HandlerBase
*/
-@Deprecated(since="5")
+@Deprecated(since="1.5")
public interface DocumentHandler {
diff -r 18569c523d38 -r c61cc8a34456 jaxp/src/java.xml/share/classes/org/xml/sax/Parser.java
--- a/jaxp/src/java.xml/share/classes/org/xml/sax/Parser.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jaxp/src/java.xml/share/classes/org/xml/sax/Parser.java Wed Jul 05 23:09:40 2017 +0200
@@ -73,7 +73,7 @@
* @see org.xml.sax.HandlerBase
* @see org.xml.sax.InputSource
*/
-@Deprecated(since="5")
+@Deprecated(since="1.5")
public interface Parser
{
diff -r 18569c523d38 -r c61cc8a34456 jaxp/src/java.xml/share/classes/org/xml/sax/helpers/ParserFactory.java
--- a/jaxp/src/java.xml/share/classes/org/xml/sax/helpers/ParserFactory.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jaxp/src/java.xml/share/classes/org/xml/sax/helpers/ParserFactory.java Wed Jul 05 23:09:40 2017 +0200
@@ -64,7 +64,7 @@
* @version 2.0.1 (sax2r2)
*/
@SuppressWarnings( "deprecation" )
-@Deprecated(since="5")
+@Deprecated(since="1.5")
public class ParserFactory {
private static SecuritySupport ss = new SecuritySupport();
diff -r 18569c523d38 -r c61cc8a34456 jaxp/src/java.xml/share/legal/bcel.md
--- a/jaxp/src/java.xml/share/legal/bcel.md Sat Apr 08 03:25:14 2017 +0000
+++ b/jaxp/src/java.xml/share/legal/bcel.md Wed Jul 05 23:09:40 2017 +0200
@@ -1,6 +1,6 @@
-## Apache Byte Code Engineering Library v5.2
+## Apache Byte Code Engineering Library (BCEL) v5.2
-### Notice
+### Apache BCEL Notice
=========================================================================
diff -r 18569c523d38 -r c61cc8a34456 jaxp/src/java.xml/share/legal/dom.md
--- a/jaxp/src/java.xml/share/legal/dom.md Sat Apr 08 03:25:14 2017 +0000
+++ b/jaxp/src/java.xml/share/legal/dom.md Wed Jul 05 23:09:40 2017 +0200
@@ -1,6 +1,6 @@
-## DOM Level 3 core specification, v1.0
+## DOM Level 3 Core Specification v1.0
-## W3C License
+### W3C License
W3C SOFTWARE NOTICE AND LICENSE
diff -r 18569c523d38 -r c61cc8a34456 jaxp/src/java.xml/share/legal/xalan.md
--- a/jaxp/src/java.xml/share/legal/xalan.md Sat Apr 08 03:25:14 2017 +0000
+++ b/jaxp/src/java.xml/share/legal/xalan.md Wed Jul 05 23:09:40 2017 +0200
@@ -1,6 +1,6 @@
## Apache Xalan v2.7.1
-### Notice
+### Apache Xalan Notice
======================================================================================
diff -r 18569c523d38 -r c61cc8a34456 jaxp/src/java.xml/share/legal/xerces.md
--- a/jaxp/src/java.xml/share/legal/xerces.md Sat Apr 08 03:25:14 2017 +0000
+++ b/jaxp/src/java.xml/share/legal/xerces.md Wed Jul 05 23:09:40 2017 +0200
@@ -1,7 +1,7 @@
## Apache Xerces v2.11.0
-### Notice
-
+### Apache Xerces Notice
+
=========================================================================
== NOTICE file corresponding to section 4(d) of the Apache License, ==
== Version 2.0, in this case for the Apache Xerces Java distribution. ==
@@ -17,6 +17,7 @@
- voluntary contributions made by Paul Eng on behalf of the
Apache Software Foundation that were originally developed at iClick, Inc.,
software copyright (c) 1999.
+
### Apache 2.0 License
diff -r 18569c523d38 -r c61cc8a34456 jaxp/src/java.xml/share/legal/xmlresolver.md
--- a/jaxp/src/java.xml/share/legal/xmlresolver.md Sat Apr 08 03:25:14 2017 +0000
+++ b/jaxp/src/java.xml/share/legal/xmlresolver.md Wed Jul 05 23:09:40 2017 +0200
@@ -1,6 +1,6 @@
## Apache XML Resolver Library v1.2
-### Notice
+### Apache XML Resolver Notice
Apache XML Commons Resolver
diff -r 18569c523d38 -r c61cc8a34456 jaxp/src/jdk.xml.dom/share/classes/module-info.java
--- a/jaxp/src/jdk.xml.dom/share/classes/module-info.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jaxp/src/jdk.xml.dom/share/classes/module-info.java Wed Jul 05 23:09:40 2017 +0200
@@ -27,6 +27,7 @@
* Defines the subset of the W3C Document Object Model (DOM) API that is not part
* of the Java SE API.
*
+ * @moduleGraph
* @since 9
*/
module jdk.xml.dom {
diff -r 18569c523d38 -r c61cc8a34456 jaxp/test/javax/xml/jaxp/functional/catalog/DeferFeatureTest.java
--- a/jaxp/test/javax/xml/jaxp/functional/catalog/DeferFeatureTest.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jaxp/test/javax/xml/jaxp/functional/catalog/DeferFeatureTest.java Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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,14 +27,16 @@
import static catalog.CatalogTestUtils.DEFER_TRUE;
import static catalog.CatalogTestUtils.getCatalogPath;
import static javax.xml.catalog.CatalogFeatures.Feature.DEFER;
-import static javax.xml.catalog.CatalogManager.catalog;
import static jaxp.library.JAXPTestUtilities.runWithAllPerm;
import static jaxp.library.JAXPTestUtilities.tryRunWithAllPerm;
import java.lang.reflect.Method;
import javax.xml.catalog.Catalog;
+import javax.xml.catalog.CatalogException;
import javax.xml.catalog.CatalogFeatures;
+import javax.xml.catalog.CatalogManager;
+import javax.xml.catalog.CatalogResolver;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
@@ -43,7 +45,7 @@
/*
* @test
- * @bug 8077931
+ * @bug 8077931 8176405
* @library /javax/xml/jaxp/libs
* @modules java.xml/javax.xml.catalog:open
* @run testng/othervm -DrunSecMngr=true catalog.DeferFeatureTest
@@ -61,6 +63,18 @@
Assert.assertEquals(loadedCatalogCount(catalog), catalogCount);
}
+ @Test(dataProvider = "testDeferFeatureByResolve")
+ public void testDeferFeatureByResolve(Catalog catalog, int catalogCount)
+ throws Exception {
+ CatalogResolver cr = createResolver(catalog);
+ // trigger loading alternative catalogs
+ try {
+ cr.resolveEntity("-//REMOTE//DTD ALICE DOCALICE", "http://remote/dtd/alice/");
+ } catch (CatalogException ce) {}
+
+ Assert.assertEquals(loadedCatalogCount(catalog), catalogCount);
+ }
+
@DataProvider(name = "catalog-countOfLoadedCatalogFile")
public Object[][] data() {
return new Object[][]{
@@ -73,12 +87,23 @@
{createCatalog(createDeferFeature(DEFER_FALSE)), 4}};
}
+ @DataProvider(name = "testDeferFeatureByResolve")
+ public Object[][] getData() {
+ return new Object[][]{
+ {createCatalog(createDeferFeature(DEFER_TRUE)), 4}
+ };
+ }
+
private CatalogFeatures createDeferFeature(String defer) {
return CatalogFeatures.builder().with(DEFER, defer).build();
}
private Catalog createCatalog(CatalogFeatures feature) {
- return catalog(feature, getCatalogPath("deferFeature.xml"));
+ return CatalogManager.catalog(feature, getCatalogPath("deferFeature.xml"));
+ }
+
+ private CatalogResolver createResolver(Catalog catalog) {
+ return CatalogManager.catalogResolver(catalog);
}
private int loadedCatalogCount(Catalog catalog) throws Exception {
diff -r 18569c523d38 -r c61cc8a34456 jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogTest.java
--- a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogTest.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogTest.java Wed Jul 05 23:09:40 2017 +0200
@@ -88,35 +88,6 @@
}
/*
- * @bug 8162431
- * Verifies that circular references are caught and
- * CatalogException is thrown.
- */
- @Test(dataProvider = "getFeatures", expectedExceptions = CatalogException.class)
- public void testCircularRef(CatalogFeatures cf, String xml) throws Exception {
- CatalogResolver catalogResolver = CatalogManager.catalogResolver(
- cf,
- getClass().getResource(xml).toURI());
- catalogResolver.resolve("anyuri", "");
- }
-
- /*
- DataProvider: used to verify circular reference
- Data columns: CatalogFeatures, catalog
- */
- @DataProvider(name = "getFeatures")
- public Object[][] getFeatures() {
- String self = "catalogReferCircle-itself.xml";
- String left = "catalogReferCircle-left.xml";
- return new Object[][]{
- {CatalogFeatures.builder().with(CatalogFeatures.Feature.DEFER, "false").build(), self},
- {CatalogFeatures.defaults(), self},
- {CatalogFeatures.builder().with(CatalogFeatures.Feature.DEFER, "false").build(), left},
- {CatalogFeatures.defaults(), left}
- };
- }
-
- /*
* @bug 8163232
* Verifies that the CatalogResolver supports the following XML Resolvers:
javax.xml.stream.XMLResolver
@@ -437,7 +408,10 @@
public void resolveWithPrefer(String prefer, String cfile, String publicId,
String systemId, String expected) throws Exception {
URI catalogFile = getClass().getResource(cfile).toURI();
- CatalogFeatures f = CatalogFeatures.builder().with(CatalogFeatures.Feature.PREFER, prefer).with(CatalogFeatures.Feature.RESOLVE, "ignore").build();
+ CatalogFeatures f = CatalogFeatures.builder()
+ .with(CatalogFeatures.Feature.PREFER, prefer)
+ .with(CatalogFeatures.Feature.RESOLVE, "ignore")
+ .build();
CatalogResolver catalogResolver = CatalogManager.catalogResolver(f, catalogFile);
String result = catalogResolver.resolveEntity(publicId, systemId).getSystemId();
Assert.assertEquals(expected, result);
@@ -452,7 +426,9 @@
@Test(dataProvider = "invalidAltCatalogs", expectedExceptions = CatalogException.class)
public void testDeferAltCatalogs(String file) throws Exception {
URI catalogFile = getClass().getResource(file).toURI();
- CatalogFeatures features = CatalogFeatures.builder().with(CatalogFeatures.Feature.DEFER, "true").build();
+ CatalogFeatures features = CatalogFeatures.builder().
+ with(CatalogFeatures.Feature.DEFER, "true")
+ .build();
/*
Since the defer attribute is set to false in the specified catalog file,
the parent catalog will try to load the alt catalog, which will fail
@@ -471,11 +447,17 @@
URI catalogFile = getClass().getResource("JDK8146237_catalog.xml").toURI();
try {
- CatalogFeatures features = CatalogFeatures.builder().with(CatalogFeatures.Feature.PREFER, "system").build();
+ CatalogFeatures features = CatalogFeatures.builder()
+ .with(CatalogFeatures.Feature.PREFER, "system")
+ .build();
Catalog catalog = CatalogManager.catalog(features, catalogFile);
CatalogResolver catalogResolver = CatalogManager.catalogResolver(catalog);
- String actualSystemId = catalogResolver.resolveEntity("-//FOO//DTD XML Dummy V0.0//EN", "http://www.oracle.com/alt1sys.dtd").getSystemId();
- Assert.assertTrue(actualSystemId.contains("dummy.dtd"), "Resulting id should contain dummy.dtd, indicating a match by publicId");
+ String actualSystemId = catalogResolver.resolveEntity(
+ "-//FOO//DTD XML Dummy V0.0//EN",
+ "http://www.oracle.com/alt1sys.dtd")
+ .getSystemId();
+ Assert.assertTrue(actualSystemId.contains("dummy.dtd"),
+ "Resulting id should contain dummy.dtd, indicating a match by publicId");
} catch (Exception e) {
Assert.fail(e.getMessage());
@@ -572,20 +554,21 @@
*/
@Test
public void testInvalidCatalog() throws Exception {
+ String expectedMsgId = "JAXP09040001";
URI catalog = getClass().getResource("catalog_invalid.xml").toURI();
- String test = "testInvalidCatalog";
try {
- CatalogResolver resolver = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalog);
- String actualSystemId = resolver.resolveEntity(null, "http://remote/xml/dtd/sys/alice/docAlice.dtd").getSystemId();
+ CatalogResolver resolver = CatalogManager.catalogResolver(
+ CatalogFeatures.defaults(), catalog);
+ String actualSystemId = resolver.resolveEntity(
+ null,
+ "http://remote/xml/dtd/sys/alice/docAlice.dtd")
+ .getSystemId();
} catch (Exception e) {
String msg = e.getMessage();
if (msg != null) {
- if (msg.contains("No match found for publicId")) {
- Assert.assertEquals(msg, "No match found for publicId 'null' and systemId 'http://remote/xml/dtd/sys/alice/docAlice.dtd'.");
- System.out.println(test + ": expected [No match found for publicId 'null' and systemId 'http://remote/xml/dtd/sys/alice/docAlice.dtd'.]");
- System.out.println("actual [" + msg + "]");
- }
+ Assert.assertTrue(msg.contains(expectedMsgId),
+ "Message shall contain the corrent message ID " + expectedMsgId);
}
}
}
@@ -607,7 +590,10 @@
String test = "testInvalidCatalog";
try {
CatalogResolver resolver = CatalogManager.catalogResolver(f);
- String actualSystemId = resolver.resolveEntity(null, "http://remote/xml/dtd/sys/alice/docAlice.dtd").getSystemId();
+ String actualSystemId = resolver.resolveEntity(
+ null,
+ "http://remote/xml/dtd/sys/alice/docAlice.dtd")
+ .getSystemId();
System.out.println("testIgnoreInvalidCatalog: expected [null]");
System.out.println("testIgnoreInvalidCatalog: expected [null]");
System.out.println("actual [" + actualSystemId + "]");
@@ -628,7 +614,11 @@
@DataProvider(name = "resolveUri")
public Object[][] getDataForUriResolver() {
return new Object[][]{
- {"uri.xml", "urn:publicid:-:Acme,+Inc.:DTD+Book+Version+1.0", null, "http://local/base/dtd/book.dtd", "Uri in publicId namespace is incorrectly unwrapped"},
+ {"uri.xml",
+ "urn:publicid:-:Acme,+Inc.:DTD+Book+Version+1.0",
+ null,
+ "http://local/base/dtd/book.dtd",
+ "Uri in publicId namespace is incorrectly unwrapped"},
};
}
@@ -654,7 +644,13 @@
public Object[][] getDataForMatchingBothIds() {
String expected = "http://www.groupxmlbase.com/dtds/rewrite.dtd";
return new Object[][]{
- {"rewriteSystem_id.xml", "system", "http://www.sys00test.com/rewrite.dtd", "PUB-404", expected, expected, "Relative rewriteSystem with xml:base at group level failed"},
+ {"rewriteSystem_id.xml",
+ "system",
+ "http://www.sys00test.com/rewrite.dtd",
+ "PUB-404",
+ expected,
+ expected,
+ "Relative rewriteSystem with xml:base at group level failed"},
};
}
diff -r 18569c523d38 -r c61cc8a34456 jaxp/test/javax/xml/jaxp/unittest/catalog/catalogReferCircle-itself.xml
--- a/jaxp/test/javax/xml/jaxp/unittest/catalog/catalogReferCircle-itself.xml Sat Apr 08 03:25:14 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-
-
-
-
-
-
diff -r 18569c523d38 -r c61cc8a34456 jaxp/test/javax/xml/jaxp/unittest/catalog/catalogReferCircle-left.xml
--- a/jaxp/test/javax/xml/jaxp/unittest/catalog/catalogReferCircle-left.xml Sat Apr 08 03:25:14 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-
-
-
-
-
-
diff -r 18569c523d38 -r c61cc8a34456 jaxp/test/javax/xml/jaxp/unittest/catalog/catalogReferCircle-right.xml
--- a/jaxp/test/javax/xml/jaxp/unittest/catalog/catalogReferCircle-right.xml Sat Apr 08 03:25:14 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-
-
-
-
-
-
diff -r 18569c523d38 -r c61cc8a34456 jaxws/.hgtags
--- a/jaxws/.hgtags Sat Apr 08 03:25:14 2017 +0000
+++ b/jaxws/.hgtags Wed Jul 05 23:09:40 2017 +0200
@@ -408,3 +408,6 @@
0ea34706c7fa5cd71accd493eb4f54262e4a5f4e jdk-9+159
6bff08fd5d217549aec10a20007378e52099be6c jdk-9+160
7d5352c54fc802b3301d8433b6b2b2a92b616630 jdk-9+161
+b8aebe5292f23689f97cb8e66a9f327834dd43e6 jdk-9+162
+3890f96e8995be8c84f330d1f65269b03ac36b24 jdk-9+163
+1a52de2da827459e866fd736f9e9c62eb2ecd6bb jdk-9+164
diff -r 18569c523d38 -r c61cc8a34456 jaxws/src/java.activation/share/classes/module-info.java
--- a/jaxws/src/java.activation/share/classes/module-info.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jaxws/src/java.activation/share/classes/module-info.java Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,8 +26,10 @@
/**
* Defines the JavaBeans Activation Framework (JAF) API.
*
+ * @moduleGraph
* @since 9
*/
+@Deprecated(since="9", forRemoval=true)
module java.activation {
requires transitive java.datatransfer;
requires java.logging;
diff -r 18569c523d38 -r c61cc8a34456 jaxws/src/java.xml.bind/share/classes/module-info.java
--- a/jaxws/src/java.xml.bind/share/classes/module-info.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jaxws/src/java.xml.bind/share/classes/module-info.java Wed Jul 05 23:09:40 2017 +0200
@@ -26,8 +26,10 @@
/**
* Defines the Java Architecture for XML Binding (JAXB) API.
*
+ * @moduleGraph
* @since 9
*/
+@Deprecated(since="9", forRemoval=true)
module java.xml.bind {
requires transitive java.activation;
requires transitive java.xml;
diff -r 18569c523d38 -r c61cc8a34456 jaxws/src/java.xml.ws.annotation/share/classes/module-info.java
--- a/jaxws/src/java.xml.ws.annotation/share/classes/module-info.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jaxws/src/java.xml.ws.annotation/share/classes/module-info.java Wed Jul 05 23:09:40 2017 +0200
@@ -27,8 +27,10 @@
* Defines a subset of the Common Annotations API to support programs running
* on the Java SE Platform.
*
+ * @moduleGraph
* @since 9
*/
+@Deprecated(since="9", forRemoval=true)
module java.xml.ws.annotation {
exports javax.annotation;
}
diff -r 18569c523d38 -r c61cc8a34456 jaxws/src/java.xml.ws/share/classes/module-info.java
--- a/jaxws/src/java.xml.ws/share/classes/module-info.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jaxws/src/java.xml.ws/share/classes/module-info.java Wed Jul 05 23:09:40 2017 +0200
@@ -27,8 +27,10 @@
* Defines the Java API for XML-Based Web Services (JAX-WS), and
* the Web Services Metadata API.
*
+ * @moduleGraph
* @since 9
*/
+@Deprecated(since="9", forRemoval=true)
module java.xml.ws {
requires transitive java.activation;
requires transitive java.xml;
diff -r 18569c523d38 -r c61cc8a34456 jaxws/src/jdk.xml.bind/share/legal/xmlresolver.md
--- a/jaxws/src/jdk.xml.bind/share/legal/xmlresolver.md Sat Apr 08 03:25:14 2017 +0000
+++ b/jaxws/src/jdk.xml.bind/share/legal/xmlresolver.md Wed Jul 05 23:09:40 2017 +0200
@@ -1,6 +1,6 @@
## Apache XML Resolver Library v1.2
-### Notice
+### Apache XML Resolver Notice
Apache XML Commons Resolver
diff -r 18569c523d38 -r c61cc8a34456 jdk/.hgtags
--- a/jdk/.hgtags Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/.hgtags Wed Jul 05 23:09:40 2017 +0200
@@ -405,3 +405,6 @@
49b54a4d9e84b7ba956b8c27fced5035465146ae jdk-9+159
cac788454598b95d8b0153c021a7fae3cd7e6fda jdk-9+160
09b92d3067a38ee07bc14efa336b14790c93f7e7 jdk-9+161
+f6bf027e88e9a4dd19f721001a7af00157af42c4 jdk-9+162
+50171f8c47961710cbf87aead6f03fa431d8d240 jdk-9+163
+6dea581453d7c0e767e3169cfec8b423a381e71d jdk-9+164
diff -r 18569c523d38 -r c61cc8a34456 jdk/make/GenerateModuleSummary.gmk
--- a/jdk/make/GenerateModuleSummary.gmk Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/make/GenerateModuleSummary.gmk Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2014, 2017, 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,7 +31,7 @@
include ModuleTools.gmk
GENGRAPHS_DIR := $(IMAGES_OUTPUTDIR)/gengraphs
-SPEC_DOTFILES_DIR := $(IMAGES_OUTPUTDIR)/spec-dotfiles
+SPEC_DOTFILES_DIR := $(GENGRAPHS_DIR)/spec-dotfiles
TOOLS_MODULE_SRCDIR := $(JDK_TOPDIR)/make/src/classes/build/tools/jigsaw
$(GENGRAPHS_DIR)/jdk.dot: $(BUILD_JIGSAW_TOOLS)
diff -r 18569c523d38 -r c61cc8a34456 jdk/make/ModuleTools.gmk
--- a/jdk/make/ModuleTools.gmk Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/make/ModuleTools.gmk Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2013, 2017, 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,8 +23,9 @@
# questions.
#
-include $(SPEC)
-include MakeBase.gmk
+ifndef _MODULE_TOOLS_GMK
+_MODULE_TOOLS_GMK := 1
+
include JavaCompilation.gmk
TOOLS_CLASSES_DIR := $(BUILDTOOLS_OUTPUTDIR)/tools_jigsaw_classes
@@ -32,7 +33,7 @@
# To avoid reevaluating the compilation setup for the tools each time this file
# is included, the actual compilation is handled by CompileModuleTools.gmk. The
# following trick is used to be able to declare a dependency on the built tools.
-BUILD_TOOLS_JDK := $(call SetupJavaCompilationCompileTarget, \
+BUILD_JIGSAW_TOOLS := $(call SetupJavaCompilationCompileTarget, \
BUILD_JIGSAW_TOOLS, $(TOOLS_CLASSES_DIR))
TOOL_GENGRAPHS := $(BUILD_JAVA) -esa -ea -cp $(TOOLS_CLASSES_DIR) \
@@ -47,3 +48,5 @@
-cp $(TOOLS_CLASSES_DIR) \
--add-exports java.base/jdk.internal.module=ALL-UNNAMED \
build.tools.jigsaw.AddPackagesAttribute
+
+endif # _MODULE_TOOLS_GMK
diff -r 18569c523d38 -r c61cc8a34456 jdk/make/copy/Copy-java.base.gmk
--- a/jdk/make/copy/Copy-java.base.gmk Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/make/copy/Copy-java.base.gmk Wed Jul 05 23:09:40 2017 +0200
@@ -235,8 +235,10 @@
# JDK license and assembly exception files to be packaged in JMOD
-JDK_LICENSE ?= $(TOPDIR)/LICENSE
-JDK_NOTICE ?= $(TOPDIR)/ASSEMBLY_EXCEPTION
+# The license files may not be present if the source has been obtained using a
+# different license.
+JDK_LICENSE ?= $(wildcard $(TOPDIR)/LICENSE)
+JDK_NOTICE ?= $(wildcard $(TOPDIR)/ASSEMBLY_EXCEPTION)
$(eval $(call SetupCopyFiles, COPY_JDK_NOTICES, \
FILES := $(JDK_LICENSE) $(JDK_NOTICE), \
@@ -245,4 +247,3 @@
))
TARGETS += $(COPY_JDK_NOTICES)
-
diff -r 18569c523d38 -r c61cc8a34456 jdk/make/mapfiles/libjava/mapfile-vers
--- a/jdk/make/mapfiles/libjava/mapfile-vers Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/make/mapfiles/libjava/mapfile-vers Wed Jul 05 23:09:40 2017 +0200
@@ -128,7 +128,6 @@
Java_java_lang_Class_isInstance;
Java_java_lang_Class_registerNatives;
Java_java_lang_ClassLoader_findBootstrapClass;
- Java_java_lang_ClassLoader_defineClass0;
Java_java_lang_ClassLoader_defineClass1;
Java_java_lang_ClassLoader_defineClass2;
Java_java_lang_ClassLoader_findBuiltinLib;
diff -r 18569c523d38 -r c61cc8a34456 jdk/make/src/classes/build/tools/jigsaw/GenGraphs.java
--- a/jdk/make/src/classes/build/tools/jigsaw/GenGraphs.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/make/src/classes/build/tools/jigsaw/GenGraphs.java Wed Jul 05 23:09:40 2017 +0200
@@ -26,7 +26,6 @@
package build.tools.jigsaw;
import com.sun.tools.jdeps.ModuleDotGraph;
-import com.sun.tools.jdeps.ModuleDotGraph.DotGraphBuilder;
import java.io.IOException;
import java.lang.module.Configuration;
@@ -36,10 +35,15 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
+import java.util.Properties;
import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collectors;
/**
* Generate the DOT file for a module graph for each module in the JDK
@@ -50,13 +54,19 @@
public static void main(String[] args) throws Exception {
Path dir = null;
boolean spec = false;
+ Properties props = null;
for (int i=0; i < args.length; i++) {
String arg = args[i];
if (arg.equals("--spec")) {
spec = true;
+ } else if (arg.equals("--dot-attributes")) {
+ if (i++ == args.length) {
+ throw new IllegalArgumentException("Missing argument: --dot-attributes option");
+ }
+ props = new Properties();
+ props.load(Files.newInputStream(Paths.get(args[i])));
} else if (arg.equals("--output")) {
- i++;
- dir = i < args.length ? Paths.get(args[i]) : null;
+ dir = ++i < args.length ? Paths.get(args[i]) : null;
} else if (arg.startsWith("-")) {
throw new IllegalArgumentException("Invalid option: " + arg);
}
@@ -67,11 +77,14 @@
System.exit(1);
}
- // setup and configure the dot graph attributes
- initDotGraphAttributes();
Files.createDirectories(dir);
-
- GenGraphs genGraphs = new GenGraphs(dir, spec);
+ ModuleGraphAttributes attributes;
+ if (props != null) {
+ attributes = new ModuleGraphAttributes(props);
+ } else {
+ attributes = new ModuleGraphAttributes();
+ }
+ GenGraphs genGraphs = new GenGraphs(dir, spec, attributes);
// print dot file for each module
Map configurations = new HashMap<>();
@@ -99,49 +112,149 @@
genGraphs.genDotFiles(configurations);
}
- static void initDotGraphAttributes() {
- int h = 1000;
- DotGraphBuilder.weight("java.se", "java.sql.rowset", h * 10);
- DotGraphBuilder.weight("java.sql.rowset", "java.sql", h * 10);
- DotGraphBuilder.weight("java.sql", "java.xml", h * 10);
- DotGraphBuilder.weight("java.xml", "java.base", h * 10);
+ /**
+ * Custom dot file attributes.
+ */
+ static class ModuleGraphAttributes implements ModuleDotGraph.Attributes {
+ static Map DEFAULT_ATTRIBUTES = Map.of(
+ "ranksep", "0.6",
+ "fontsize", "12",
+ "fontcolor", BLACK,
+ "fontname", "DejaVuSans",
+ "arrowsize", "1",
+ "arrowwidth", "2",
+ "arrowcolor", DARK_GRAY,
+ // custom
+ "requiresMandatedColor", LIGHT_GRAY,
+ "javaSubgraphColor", ORANGE,
+ "jdkSubgraphColor", BLUE
+ );
+
+ final Map weights = new HashMap<>();
+ final List> ranks = new ArrayList<>();
+ final Map attrs;
+ ModuleGraphAttributes(Map attrs) {
+ int h = 1000;
+ weight("java.se", "java.sql.rowset", h * 10);
+ weight("java.sql.rowset", "java.sql", h * 10);
+ weight("java.sql", "java.xml", h * 10);
+ weight("java.xml", "java.base", h * 10);
+
+ ranks.add(Set.of("java.logging", "java.scripting", "java.xml"));
+ ranks.add(Set.of("java.sql"));
+ ranks.add(Set.of("java.compiler", "java.instrument"));
+ ranks.add(Set.of("java.desktop", "java.management"));
+ ranks.add(Set.of("java.corba", "java.xml.ws"));
+ ranks.add(Set.of("java.xml.bind", "java.xml.ws.annotation"));
+
+ this.attrs = attrs;
+ }
+
+ ModuleGraphAttributes() {
+ this(DEFAULT_ATTRIBUTES);
+ }
+ ModuleGraphAttributes(Properties props) {
+ this(toAttributes(props));
+ }
+
+ @Override
+ public double rankSep() {
+ return Double.valueOf(attrs.get("ranksep"));
+ }
+
+ @Override
+ public int fontSize() {
+ return Integer.valueOf(attrs.get("fontsize"));
+ }
+
+ @Override
+ public String fontName() {
+ return attrs.get("fontname");
+ }
- DotGraphBuilder.sameRankNodes(Set.of("java.logging", "java.scripting", "java.xml"));
- DotGraphBuilder.sameRankNodes(Set.of("java.sql"));
- DotGraphBuilder.sameRankNodes(Set.of("java.compiler", "java.instrument"));
- DotGraphBuilder.sameRankNodes(Set.of("java.desktop", "java.management"));
- DotGraphBuilder.sameRankNodes(Set.of("java.corba", "java.xml.ws"));
- DotGraphBuilder.sameRankNodes(Set.of("java.xml.bind", "java.xml.ws.annotation"));
- DotGraphBuilder.setRankSep(0.7);
- DotGraphBuilder.setFontSize(12);
- DotGraphBuilder.setArrowSize(1);
- DotGraphBuilder.setArrowWidth(2);
+ @Override
+ public String fontColor() {
+ return attrs.get("fontcolor");
+ }
+
+ @Override
+ public int arrowSize() {
+ return Integer.valueOf(attrs.get("arrowsize"));
+ }
+
+ @Override
+ public int arrowWidth() {
+ return Integer.valueOf(attrs.get("arrowwidth"));
+ }
+
+ @Override
+ public String arrowColor() {
+ return attrs.get("arrowcolor");
+ }
+
+ @Override
+ public List> ranks() {
+ return ranks;
+ }
+
+ @Override
+ public String requiresMandatedColor() {
+ return attrs.get("requiresMandatedColor");
+ }
+
+ @Override
+ public String javaSubgraphColor() {
+ return attrs.get("javaSubgraphColor");
+ }
+
+ @Override
+ public String jdkSubgraphColor() {
+ return attrs.get("jdkSubgraphColor");
+ }
+
+ @Override
+ public int weightOf(String s, String t) {
+ int w = weights.getOrDefault(s + ":" + t, 1);
+ if (w != 1)
+ return w;
+ if (s.startsWith("java.") && t.startsWith("java."))
+ return 10;
+ return 1;
+ }
+
+ public void weight(String s, String t, int w) {
+ weights.put(s + ":" + t, w);
+ }
+
+ static Map toAttributes(Properties props) {
+ return DEFAULT_ATTRIBUTES.keySet().stream()
+ .collect(Collectors.toMap(Function.identity(),
+ k -> props.getProperty(k, DEFAULT_ATTRIBUTES.get(k))));
+ }
}
private final Path dir;
private final boolean spec;
- GenGraphs(Path dir, boolean spec) {
+ private final ModuleGraphAttributes attributes;
+ GenGraphs(Path dir, boolean spec, ModuleGraphAttributes attributes) {
this.dir = dir;
this.spec = spec;
+ this.attributes = attributes;
}
void genDotFiles(Map configurations) throws IOException {
ModuleDotGraph dotGraph = new ModuleDotGraph(configurations, spec);
- dotGraph.genDotFiles(dir);
+ dotGraph.genDotFiles(dir, attributes);
}
+ /**
+ * Returns true for any name if generating graph for non-spec;
+ * otherwise, returns true except "jdk" and name with "jdk.internal." prefix
+ */
boolean accept(String name, ModuleDescriptor descriptor) {
- if (!spec) return true;
-
- if (name.equals("jdk"))
- return false;
-
- if (name.equals("java.se") || name.equals("java.se.ee"))
+ if (!spec)
return true;
- // only the module that has exported API
- return descriptor.exports().stream()
- .filter(e -> !e.isQualified())
- .findAny().isPresent();
+ return !name.equals("jdk") && !name.startsWith("jdk.internal.");
}
-}
\ No newline at end of file
+}
diff -r 18569c523d38 -r c61cc8a34456 jdk/make/src/classes/build/tools/jigsaw/javadoc-graphs.properties
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/src/classes/build/tools/jigsaw/javadoc-graphs.properties Wed Jul 05 23:09:40 2017 +0200
@@ -0,0 +1,2 @@
+arrowcolor=#999999
+requiresMandatedColor=#999999
diff -r 18569c523d38 -r c61cc8a34456 jdk/make/src/classes/build/tools/taglet/Incubating.java
--- a/jdk/make/src/classes/build/tools/taglet/Incubating.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/make/src/classes/build/tools/taglet/Incubating.java Wed Jul 05 23:09:40 2017 +0200
@@ -28,6 +28,7 @@
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
+import javax.lang.model.element.Element;
import com.sun.source.doctree.DocTree;
import jdk.javadoc.doclet.Taglet;
import static jdk.javadoc.doclet.Taglet.Location.*;
@@ -59,7 +60,7 @@
+ " Will be removed in a future release.";
@Override
- public String toString(List extends DocTree> tags) {
+ public String toString(List extends DocTree> tags, Element elem) {
return MESSAGE;
}
}
diff -r 18569c523d38 -r c61cc8a34456 jdk/make/src/classes/build/tools/taglet/ModuleGraph.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/src/classes/build/tools/taglet/ModuleGraph.java Wed Jul 05 23:09:40 2017 +0200
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2017, 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 build.tools.taglet;
+
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Set;
+import javax.lang.model.element.Element;
+import com.sun.source.doctree.DocTree;
+import jdk.javadoc.doclet.Taglet;
+import static jdk.javadoc.doclet.Taglet.Location.*;
+
+/**
+ * A block tag to optionally insert a reference to a module graph.
+ */
+public class ModuleGraph implements Taglet {
+ private static final boolean enableModuleGraph =
+ Boolean.getBoolean("enableModuleGraph");
+
+ /** Returns the set of locations in which a taglet may be used. */
+ @Override
+ public Set getAllowedLocations() {
+ return EnumSet.of(MODULE);
+ }
+
+ @Override
+ public boolean isInlineTag() {
+ return false;
+ }
+
+ @Override
+ public String getName() {
+ return "moduleGraph";
+ }
+
+ @Override
+ public String toString(List extends DocTree> tags, Element element) {
+ if (!enableModuleGraph) {
+ return "";
+ }
+
+ String moduleName = element.getSimpleName().toString();
+ String imageFile = moduleName + "-graph.png";
+ int thumbnailHeight = -1;
+ String hoverImage = "";
+ if (!moduleName.equals("java.base")) {
+ thumbnailHeight = 100; // also appears in the stylesheet
+ hoverImage = ""
+ + getImage(moduleName, imageFile, -1, true)
+ + "";
+ }
+ return ""
+ + "Module Graph:\n"
+ + ""
+ + ""
+ + ""
+ + getImage(moduleName, imageFile, thumbnailHeight, false)
+ + hoverImage
+ + ""
+ + "";
+ }
+
+ private static final String VERTICAL_ALIGN = "vertical-align:top";
+ private static final String BORDER = "border: solid lightgray 1px;";
+
+ private String getImage(String moduleName, String file, int height, boolean useBorder) {
+ return String.format("",
+ useBorder ? BORDER + " " + VERTICAL_ALIGN : VERTICAL_ALIGN,
+ moduleName,
+ file,
+ (height <= 0 ? "" : " height=\"" + height + "\""));
+ }
+}
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/io/ObjectInputFilter.java
--- a/jdk/src/java.base/share/classes/java/io/ObjectInputFilter.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/io/ObjectInputFilter.java Wed Jul 05 23:09:40 2017 +0200
@@ -104,7 +104,6 @@
* @return {@link Status#ALLOWED Status.ALLOWED} if accepted,
* {@link Status#REJECTED Status.REJECTED} if rejected,
* {@link Status#UNDECIDED Status.UNDECIDED} if undecided.
- * @since 9
*/
Status checkInput(FilterInfo filterInfo);
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/io/ObjectInputStream.java
--- a/jdk/src/java.base/share/classes/java/io/ObjectInputStream.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/io/ObjectInputStream.java Wed Jul 05 23:09:40 2017 +0200
@@ -812,23 +812,24 @@
}
/**
- * Enable the stream to allow objects read from the stream to be replaced.
- * When enabled, the resolveObject method is called for every object being
+ * Enables the stream to do replacement of objects read from the stream. When
+ * enabled, the {@link #resolveObject} method is called for every object being
* deserialized.
*
- * If enable is true, and there is a security manager installed,
+ *
If object replacement is currently not enabled, and
+ * {@code enable} is true, and there is a security manager installed,
* this method first calls the security manager's
- * checkPermission
method with the
- * SerializablePermission("enableSubstitution")
permission to
- * ensure it's ok to enable the stream to allow objects read from the
- * stream to be replaced.
+ * {@code checkPermission} method with the
+ * {@code SerializablePermission("enableSubstitution")} permission to
+ * ensure that the caller is permitted to enable the stream to do replacement
+ * of objects read from the stream.
*
- * @param enable true for enabling use of resolveObject
for
+ * @param enable true for enabling use of {@code resolveObject} for
* every object being deserialized
* @return the previous setting before this method was invoked
* @throws SecurityException if a security manager exists and its
- * checkPermission
method denies enabling the stream
- * to allow objects read from the stream to be replaced.
+ * {@code checkPermission} method denies enabling the stream
+ * to do replacement of objects read from the stream.
* @see SecurityManager#checkPermission
* @see java.io.SerializablePermission
*/
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/io/ObjectOutputStream.java
--- a/jdk/src/java.base/share/classes/java/io/ObjectOutputStream.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/io/ObjectOutputStream.java Wed Jul 05 23:09:40 2017 +0200
@@ -589,22 +589,24 @@
}
/**
- * Enable the stream to do replacement of objects in the stream. When
- * enabled, the replaceObject method is called for every object being
+ * Enables the stream to do replacement of objects written to the stream. When
+ * enabled, the {@link #replaceObject} method is called for every object being
* serialized.
*
- *
If enable
is true, and there is a security manager
- * installed, this method first calls the security manager's
- * checkPermission
method with a
- * SerializablePermission("enableSubstitution")
permission to
- * ensure it's ok to enable the stream to do replacement of objects in the
- * stream.
+ *
If object replacement is currently not enabled, and
+ * {@code enable} is true, and there is a security manager installed,
+ * this method first calls the security manager's
+ * {@code checkPermission} method with the
+ * {@code SerializablePermission("enableSubstitution")} permission to
+ * ensure that the caller is permitted to enable the stream to do replacement
+ * of objects written to the stream.
*
- * @param enable boolean parameter to enable replacement of objects
+ * @param enable true for enabling use of {@code replaceObject} for
+ * every object being serialized
* @return the previous setting before this method was invoked
* @throws SecurityException if a security manager exists and its
- * checkPermission
method denies enabling the stream
- * to do replacement of objects in the stream.
+ * {@code checkPermission} method denies enabling the stream
+ * to do replacement of objects written to the stream.
* @see SecurityManager#checkPermission
* @see java.io.SerializablePermission
*/
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/lang/Class.java
--- a/jdk/src/java.base/share/classes/java/lang/Class.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/Class.java Wed Jul 05 23:09:40 2017 +0200
@@ -64,9 +64,9 @@
import jdk.internal.HotSpotIntrinsicCandidate;
import jdk.internal.loader.BootLoader;
import jdk.internal.loader.BuiltinClassLoader;
-import jdk.internal.loader.ResourceHelper;
import jdk.internal.misc.Unsafe;
import jdk.internal.misc.VM;
+import jdk.internal.module.Resources;
import jdk.internal.reflect.CallerSensitive;
import jdk.internal.reflect.ConstantPool;
import jdk.internal.reflect.Reflection;
@@ -2563,11 +2563,11 @@
Module module = getModule();
if (module.isNamed()) {
- if (!ResourceHelper.isSimpleResource(name)) {
+ if (Resources.canEncapsulate(name)) {
Module caller = Reflection.getCallerClass().getModule();
if (caller != module) {
Set packages = module.getDescriptor().packages();
- String pn = ResourceHelper.getPackageName(name);
+ String pn = Resources.toPackageName(name);
if (packages.contains(pn) && !module.isOpen(pn, caller)) {
// resource is in package not open to caller
return null;
@@ -2665,11 +2665,11 @@
Module module = getModule();
if (module.isNamed()) {
- if (!ResourceHelper.isSimpleResource(name)) {
+ if (Resources.canEncapsulate(name)) {
Module caller = Reflection.getCallerClass().getModule();
if (caller != module) {
Set packages = module.getDescriptor().packages();
- String pn = ResourceHelper.getPackageName(name);
+ String pn = Resources.toPackageName(name);
if (packages.contains(pn) && !module.isOpen(pn, caller)) {
// resource is in package not open to caller
return null;
@@ -2771,7 +2771,7 @@
* In all other cases, it requires RuntimePermission("accessDeclaredMembers")
* permission.
*/
- final ClassLoader ccl = caller.getClassLoader0();
+ final ClassLoader ccl = ClassLoader.getClassLoader(caller);
if (which != Member.PUBLIC) {
final ClassLoader cl = getClassLoader0();
if (ccl != cl) {
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/lang/ClassLoader.java
--- a/jdk/src/java.base/share/classes/java/lang/ClassLoader.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java Wed Jul 05 23:09:40 2017 +0200
@@ -983,7 +983,7 @@
{
protectionDomain = preDefineClass(name, protectionDomain);
String source = defineClassSourceLocation(protectionDomain);
- Class> c = defineClass1(name, b, off, len, protectionDomain, source);
+ Class> c = defineClass1(this, name, b, off, len, protectionDomain, source);
postDefineClass(c, protectionDomain);
return c;
}
@@ -1075,17 +1075,17 @@
protectionDomain = preDefineClass(name, protectionDomain);
String source = defineClassSourceLocation(protectionDomain);
- Class> c = defineClass2(name, b, b.position(), len, protectionDomain, source);
+ Class> c = defineClass2(this, name, b, b.position(), len, protectionDomain, source);
postDefineClass(c, protectionDomain);
return c;
}
- private native Class> defineClass1(String name, byte[] b, int off, int len,
- ProtectionDomain pd, String source);
+ static native Class> defineClass1(ClassLoader loader, String name, byte[] b, int off, int len,
+ ProtectionDomain pd, String source);
- private native Class> defineClass2(String name, java.nio.ByteBuffer b,
- int off, int len, ProtectionDomain pd,
- String source);
+ static native Class> defineClass2(ClassLoader loader, String name, java.nio.ByteBuffer b,
+ int off, int len, ProtectionDomain pd,
+ String source);
// true if the name is null or has the potential to be a valid binary name
private boolean checkName(String name) {
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/lang/LiveStackFrame.java
--- a/jdk/src/java.base/share/classes/java/lang/LiveStackFrame.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/LiveStackFrame.java Wed Jul 05 23:09:40 2017 +0200
@@ -169,7 +169,7 @@
* it denies access to {@code RuntimePermission("liveStackFrames")}; or
* or if the given {@code options} contains
* {@link StackWalker.Option#RETAIN_CLASS_REFERENCE Option.RETAIN_CLASS_REFERENCE}
- * and it denies access to {@code StackFramePermission("retainClassReference")}.
+ * and it denies access to {@code RuntimePermission("getStackWalkerWithClassReference")}.
*/
public static StackWalker getStackWalker(Set options) {
SecurityManager sm = System.getSecurityManager();
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/lang/Math.java
--- a/jdk/src/java.base/share/classes/java/lang/Math.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/Math.java Wed Jul 05 23:09:40 2017 +0200
@@ -1079,6 +1079,7 @@
* @param x the first value
* @param y the second value
* @return the result
+ * @since 9
*/
public static long multiplyFull(int x, int y) {
return (long)x * (long)y;
@@ -1091,6 +1092,7 @@
* @param x the first value
* @param y the second value
* @return the result
+ * @since 9
*/
public static long multiplyHigh(long x, long y) {
if (x < 0 || y < 0) {
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/lang/ProcessBuilder.java
--- a/jdk/src/java.base/share/classes/java/lang/ProcessBuilder.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/ProcessBuilder.java Wed Jul 05 23:09:40 2017 +0200
@@ -1251,6 +1251,7 @@
* If the operating system does not support the creation of processes
*
* @throws IOException if an I/O error occurs
+ * @since 9
*/
public static List startPipeline(List builders) throws IOException {
// Accumulate and check the builders
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/lang/ProcessHandleImpl.java
--- a/jdk/src/java.base/share/classes/java/lang/ProcessHandleImpl.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/ProcessHandleImpl.java Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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 @@
*/
package java.lang;
+import java.lang.annotation.Native;
import java.security.PrivilegedAction;
import java.time.Duration;
import java.time.Instant;
@@ -57,6 +58,12 @@
private static long REAPER_DEFAULT_STACKSIZE = 128 * 1024;
/**
+ * Return value from waitForProcessExit0 indicating the process is not a child.
+ */
+ @Native
+ private static final int NOT_A_CHILD = -2;
+
+ /**
* Cache the ProcessHandle of this process.
*/
private static final ProcessHandleImpl current;
@@ -131,6 +138,29 @@
// spawn a thread to wait for and deliver the exit value
processReaperExecutor.execute(() -> {
int exitValue = waitForProcessExit0(pid, shouldReap);
+ if (exitValue == NOT_A_CHILD) {
+ // pid not alive or not a child of this process
+ // If it is alive wait for it to terminate
+ long sleep = 300; // initial milliseconds to sleep
+ int incr = 30; // increment to the sleep time
+
+ long startTime = isAlive0(pid);
+ long origStart = startTime;
+ while (startTime >= 0) {
+ try {
+ Thread.sleep(Math.min(sleep, 5000L)); // no more than 5 sec
+ sleep += incr;
+ } catch (InterruptedException ie) {
+ // ignore and retry
+ }
+ startTime = isAlive0(pid); // recheck if is alive
+ if (origStart > 0 && startTime != origStart) {
+ // start time changed, pid is not the same process
+ break;
+ }
+ }
+ exitValue = 0;
+ }
newCompletion.complete(exitValue);
// remove from cache afterwards
completions.remove(pid, newCompletion);
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/lang/Runtime.java
--- a/jdk/src/java.base/share/classes/java/lang/Runtime.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/Runtime.java Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2017, 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
@@ -955,7 +955,7 @@
*
* A version number, {@code $VNUM}, is a non-empty sequence
* of elements separated by period characters (U+002E). An element is
- * either zero, or a unsigned integer numeral without leading zeros. The
+ * either zero, or an unsigned integer numeral without leading zeros. The
* final element in a version number must not be zero. The format is:
*
*
@@ -1053,8 +1053,8 @@
*
*
*
- * A version number {@code 10-ea} matches {@code $VNUM = "10"} and
- * {@code $PRE = "ea"}. The version number {@code 10+-ea} matches
+ *
A version string {@code 10-ea} matches {@code $VNUM = "10"} and
+ * {@code $PRE = "ea"}. The version string {@code 10+-ea} matches
* {@code $VNUM = "10"} and {@code $OPT = "ea"}.
*
* When comparing two version strings, the value of {@code $OPT}, if
@@ -1247,7 +1247,7 @@
* Compares this version to another.
*
*
Each of the components in the version is
- * compared in the follow order of precedence: version numbers,
+ * compared in the following order of precedence: version numbers,
* pre-release identifiers, build numbers, optional build information.
*
*
@@ -1337,14 +1337,12 @@
int oSize = ob.version().size();
int min = Math.min(size, oSize);
for (int i = 0; i < min; i++) {
- Integer val = version.get(i);
- Integer oVal = ob.version().get(i);
+ int val = version.get(i);
+ int oVal = ob.version().get(i);
if (val != oVal)
return val - oVal;
}
- if (size != oSize)
- return size - oSize;
- return 0;
+ return size - oSize;
}
private int comparePre(Version ob) {
@@ -1375,9 +1373,9 @@
if (oBuild.isPresent()) {
return (build.isPresent()
? build.get().compareTo(oBuild.get())
- : 1);
+ : -1);
} else if (build.isPresent()) {
- return -1;
+ return 1;
}
return 0;
}
@@ -1461,7 +1459,7 @@
*
* @return {@code true} if, and only if, the given object is a {@code
* Version} that is identical to this {@code Version}
- * ignoring the optinal build information
+ * ignoring the optional build information
*
*/
public boolean equalsIgnoreOptional(Object ob) {
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/lang/RuntimePermission.java
--- a/jdk/src/java.base/share/classes/java/lang/RuntimePermission.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/RuntimePermission.java Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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,9 +26,7 @@
package java.lang;
import java.security.*;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.StringTokenizer;
+import java.lang.module.ModuleFinder;
/**
* This class is for runtime permissions. A {@code RuntimePermission}
@@ -265,6 +263,16 @@
*
*
*
+ * defineClass |
+ * Define a class with
+ * {@link java.lang.invoke.MethodHandles.Lookup#defineClass(byte[])
+ * Lookup.defineClass}. |
+ * This grants code with a suitably privileged {@code Lookup} object
+ * permission to define classes in the same package as the {@code Lookup}'s
+ * lookup class. |
+ *
+ *
+ *
* accessDeclaredMembers |
* Access to the declared members of a class |
* This grants code permission to query a class for its public,
@@ -298,6 +306,14 @@
* |
*
*
+ * getStackWalkerWithClassReference |
+ * Get a stack walker that can retrieve stack frames with class reference. |
+ * This allows retrieval of Class objects from stack walking.
+ * This might allow malicious code to access Class objects on the stack
+ * outside its own context. |
+ *
+ *
+ *
* setDefaultUncaughtExceptionHandler |
* Setting the default handler to be used when a thread
* terminates abruptly due to an uncaught exception |
@@ -359,6 +375,14 @@
* See {@link java.lang.System.LoggerFinder java.lang.System.LoggerFinder}
* for more information. |
*
+ *
+ *
+ * accessSystemModules |
+ * Access system modules in the runtime image. |
+ * This grants the permission to access resources in the
+ * {@linkplain ModuleFinder#ofSystem system modules} in the runtime image. |
+ *
+ *
*
*
* @implNote
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/lang/StackFramePermission.java
--- a/jdk/src/java.base/share/classes/java/lang/StackFramePermission.java Sat Apr 08 03:25:14 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +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 java.lang;
-
-/**
- * Permission to access {@link StackWalker.StackFrame}.
- *
- * @see java.lang.StackWalker.Option#RETAIN_CLASS_REFERENCE
- * @see StackWalker.StackFrame#getDeclaringClass()
- */
-public class StackFramePermission extends java.security.BasicPermission {
- private static final long serialVersionUID = 2841894854386706014L;
-
- /**
- * Creates a new {@code StackFramePermission} object.
- *
- * @param name Permission name. Must be "retainClassReference".
- *
- * @throws IllegalArgumentException if {@code name} is invalid.
- * @throws NullPointerException if {@code name} is {@code null}.
- */
- public StackFramePermission(String name) {
- super(name);
- if (!name.equals("retainClassReference")) {
- throw new IllegalArgumentException("name: " + name);
- }
- }
-}
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/lang/StackStreamFactory.java
--- a/jdk/src/java.base/share/classes/java/lang/StackStreamFactory.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/StackStreamFactory.java Wed Jul 05 23:09:40 2017 +0200
@@ -982,13 +982,6 @@
}
private static boolean isReflectionFrame(Class> c) {
- if (c.getName().startsWith("jdk.internal.reflect") &&
- !MethodAccessor.class.isAssignableFrom(c) &&
- !ConstructorAccessor.class.isAssignableFrom(c)) {
- throw new InternalError("Not jdk.internal.reflect.MethodAccessor"
- + " or jdk.internal.reflect.ConstructorAccessor: "
- + c.toString());
- }
// ## should filter all @Hidden frames?
return c == Method.class ||
c == Constructor.class ||
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/lang/StackWalker.java
--- a/jdk/src/java.base/share/classes/java/lang/StackWalker.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/StackWalker.java Wed Jul 05 23:09:40 2017 +0200
@@ -279,7 +279,7 @@
* If a security manager is present and the given {@code option} is
* {@link Option#RETAIN_CLASS_REFERENCE Option.RETAIN_CLASS_REFERENCE},
* it calls its {@link SecurityManager#checkPermission checkPermission}
- * method for {@code StackFramePermission("retainClassReference")}.
+ * method for {@code RuntimePermission("getStackWalkerWithClassReference")}.
*
* @param option {@link Option stack walking option}
*
@@ -303,7 +303,7 @@
* If a security manager is present and the given {@code options} contains
* {@link Option#RETAIN_CLASS_REFERENCE Option.RETAIN_CLASS_REFERENCE},
* it calls its {@link SecurityManager#checkPermission checkPermission}
- * method for {@code StackFramePermission("retainClassReference")}.
+ * method for {@code RuntimePermission("getStackWalkerWithClassReference")}.
*
* @param options {@link Option stack walking option}
*
@@ -333,7 +333,7 @@
* If a security manager is present and the given {@code options} contains
* {@link Option#RETAIN_CLASS_REFERENCE Option.RETAIN_CLASS_REFERENCE},
* it calls its {@link SecurityManager#checkPermission checkPermission}
- * method for {@code StackFramePermission("retainClassReference")}.
+ * method for {@code RuntimePermission("getStackWalkerWithClassReference")}.
*
*
* The {@code estimateDepth} specifies the estimate number of stack frames
@@ -376,7 +376,7 @@
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
if (options.contains(Option.RETAIN_CLASS_REFERENCE)) {
- sm.checkPermission(new StackFramePermission("retainClassReference"));
+ sm.checkPermission(new RuntimePermission("getStackWalkerWithClassReference"));
}
}
}
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/lang/String.java
--- a/jdk/src/java.base/share/classes/java/lang/String.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/String.java Wed Jul 05 23:09:40 2017 +0200
@@ -2672,7 +2672,6 @@
* point is passed through uninterpreted.
*
* @return an IntStream of char values from this sequence
- * @since 9
*/
@Override
public IntStream chars() {
@@ -2692,7 +2691,6 @@
* {@code int} values which are then passed to the stream.
*
* @return an IntStream of Unicode code points from this sequence
- * @since 9
*/
@Override
public IntStream codePoints() {
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/lang/StringCoding.java
--- a/jdk/src/java.base/share/classes/java/lang/StringCoding.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/StringCoding.java Wed Jul 05 23:09:40 2017 +0200
@@ -272,8 +272,7 @@
// (2)The defensive copy of the input byte/char[] has a big performance
// impact, as well as the outgoing result byte/char[]. Need to do the
// optimization check of (sm==null && classLoader0==null) for both.
- // (3)getClass().getClassLoader0() is expensive
- // (4)There might be a timing gap in isTrusted setting. getClassLoader0()
+ // (3)There might be a timing gap in isTrusted setting. getClassLoader0()
// is only checked (and then isTrusted gets set) when (SM==null). It is
// possible that the SM==null for now but then SM is NOT null later
// when safeTrim() is invoked...the "safe" way to do is to redundant
@@ -299,8 +298,8 @@
if (len == 0) {
return new Result().with();
}
- if (System.getSecurityManager() != null &&
- cs.getClass().getClassLoader0() != null) {
+ if (cs.getClass().getClassLoader0() != null &&
+ System.getSecurityManager() != null) {
ba = Arrays.copyOfRange(ba, off, off + len);
off = 0;
}
@@ -609,8 +608,8 @@
if (len == 0) {
return ba;
}
- boolean isTrusted = System.getSecurityManager() == null ||
- cs.getClass().getClassLoader0() == null;
+ boolean isTrusted = cs.getClass().getClassLoader0() == null ||
+ System.getSecurityManager() == null;
ce.onMalformedInput(CodingErrorAction.REPLACE)
.onUnmappableCharacter(CodingErrorAction.REPLACE)
.reset();
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/lang/System.java
--- a/jdk/src/java.base/share/classes/java/lang/System.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/System.java Wed Jul 05 23:09:40 2017 +0200
@@ -43,6 +43,7 @@
import java.lang.reflect.Module;
import java.net.URL;
import java.security.AccessControlContext;
+import java.security.ProtectionDomain;
import java.util.Properties;
import java.util.PropertyPermission;
import java.util.Map;
@@ -1569,6 +1570,14 @@
* obtained by calling {@link LoggerFinder#getLogger(java.lang.String,
* java.lang.reflect.Module) LoggerFinder.getLogger(name, module)}, where
* {@code module} is the caller's module.
+ * In cases where {@code System.getLogger} is called from a context where
+ * there is no caller frame on the stack (e.g when called directly
+ * from a JNI attached thread), {@code IllegalCallerException} is thrown.
+ * To obtain a logger in such a context, use an auxiliary class that will
+ * implicitly be identified as the caller, or use the system {@link
+ * LoggerFinder#getLoggerFinder() LoggerFinder} to obtain a logger instead.
+ * Note that doing the latter may eagerly initialize the underlying
+ * logging system.
*
* @apiNote
* This method may defer calling the {@link
@@ -1581,6 +1590,8 @@
* @return an instance of {@link Logger} that can be used by the calling
* class.
* @throws NullPointerException if {@code name} is {@code null}.
+ * @throws IllegalCallerException if there is no Java caller frame on the
+ * stack.
*
* @since 9
*/
@@ -1588,6 +1599,9 @@
public static Logger getLogger(String name) {
Objects.requireNonNull(name);
final Class> caller = Reflection.getCallerClass();
+ if (caller == null) {
+ throw new IllegalCallerException("no caller frame");
+ }
return LazyLoggers.getLogger(name, caller.getModule());
}
@@ -1601,8 +1615,16 @@
* The returned logger will perform message localization as specified
* by {@link LoggerFinder#getLocalizedLogger(java.lang.String,
* java.util.ResourceBundle, java.lang.reflect.Module)
- * LoggerFinder.getLocalizedLogger(name, bundle, module}, where
+ * LoggerFinder.getLocalizedLogger(name, bundle, module)}, where
* {@code module} is the caller's module.
+ * In cases where {@code System.getLogger} is called from a context where
+ * there is no caller frame on the stack (e.g when called directly
+ * from a JNI attached thread), {@code IllegalCallerException} is thrown.
+ * To obtain a logger in such a context, use an auxiliary class that
+ * will implicitly be identified as the caller, or use the system {@link
+ * LoggerFinder#getLoggerFinder() LoggerFinder} to obtain a logger instead.
+ * Note that doing the latter may eagerly initialize the underlying
+ * logging system.
*
* @apiNote
* This method is intended to be used after the system is fully initialized.
@@ -1621,6 +1643,8 @@
* resource bundle for message localization.
* @throws NullPointerException if {@code name} is {@code null} or
* {@code bundle} is {@code null}.
+ * @throws IllegalCallerException if there is no Java caller frame on the
+ * stack.
*
* @since 9
*/
@@ -1629,6 +1653,9 @@
final ResourceBundle rb = Objects.requireNonNull(bundle);
Objects.requireNonNull(name);
final Class> caller = Reflection.getCallerClass();
+ if (caller == null) {
+ throw new IllegalCallerException("no caller frame");
+ }
final SecurityManager sm = System.getSecurityManager();
// We don't use LazyLoggers if a resource bundle is specified.
// Bootstrap sensitive classes in the JDK do not use resource bundles
@@ -1847,6 +1874,39 @@
}
/**
+ * Logs an exception/error at initialization time to stdout or stderr.
+ *
+ * @param printToStderr to print to stderr rather than stdout
+ * @param printStackTrace to print the stack trace
+ * @param msg the message to print before the exception, can be {@code null}
+ * @param e the exception or error
+ */
+ private static void logInitException(boolean printToStderr,
+ boolean printStackTrace,
+ String msg,
+ Throwable e) {
+ if (VM.initLevel() < 1) {
+ throw new InternalError("system classes not initialized");
+ }
+ PrintStream log = (printToStderr) ? err : out;
+ if (msg != null) {
+ log.println(msg);
+ }
+ if (printStackTrace) {
+ e.printStackTrace(log);
+ } else {
+ log.println(e);
+ for (Throwable suppressed : e.getSuppressed()) {
+ log.println("Suppressed: " + suppressed);
+ }
+ Throwable cause = e.getCause();
+ if (cause != null) {
+ log.println("Caused by: " + cause);
+ }
+ }
+ }
+
+ /**
* Initialize the system class. Called after thread initialization.
*/
private static void initPhase1() {
@@ -1924,13 +1984,25 @@
/*
* Invoked by VM. Phase 2 module system initialization.
* Only classes in java.base can be loaded in this phase.
+ *
+ * @param printToStderr print exceptions to stderr rather than stdout
+ * @param printStackTrace print stack trace when exception occurs
+ *
+ * @return JNI_OK for success, JNI_ERR for failure
*/
- private static void initPhase2() {
- // initialize the module system
- System.bootLayer = ModuleBootstrap.boot();
+ private static int initPhase2(boolean printToStderr, boolean printStackTrace) {
+ try {
+ bootLayer = ModuleBootstrap.boot();
+ } catch (Exception | Error e) {
+ logInitException(printToStderr, printStackTrace,
+ "Error occurred during initialization of boot layer", e);
+ return -1; // JNI_ERR
+ }
// module system initialized
VM.initLevel(2);
+
+ return 0; // JNI_OK
}
/*
@@ -2036,6 +2108,9 @@
public ConcurrentHashMap, ?> createOrGetClassLoaderValueMap(ClassLoader cl) {
return cl.createOrGetClassLoaderValueMap();
}
+ public Class> defineClass(ClassLoader loader, String name, byte[] b, ProtectionDomain pd, String source) {
+ return ClassLoader.defineClass1(loader, name, b, 0, b.length, pd, source);
+ }
public Class> findBootstrapClassOrNull(ClassLoader cl, String name) {
return cl.findBootstrapClassOrNull(name);
}
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/lang/invoke/CallSite.java
--- a/jdk/src/java.base/share/classes/java/lang/invoke/CallSite.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/CallSite.java Wed Jul 05 23:09:40 2017 +0200
@@ -82,6 +82,7 @@
}
}
* @author John Rose, JSR 292 EG
+ * @since 1.7
*/
abstract
public class CallSite {
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/lang/invoke/ConstantCallSite.java
--- a/jdk/src/java.base/share/classes/java/lang/invoke/ConstantCallSite.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/ConstantCallSite.java Wed Jul 05 23:09:40 2017 +0200
@@ -30,6 +30,7 @@
* An {@code invokedynamic} instruction linked to a {@code ConstantCallSite} is permanently
* bound to the call site's target.
* @author John Rose, JSR 292 EG
+ * @since 1.7
*/
public class ConstantCallSite extends CallSite {
private final boolean isFrozen;
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/lang/invoke/LambdaConversionException.java
--- a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaConversionException.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaConversionException.java Wed Jul 05 23:09:40 2017 +0200
@@ -27,6 +27,8 @@
/**
* LambdaConversionException
+ *
+ * @since 1.8
*/
public class LambdaConversionException extends Exception {
private static final long serialVersionUID = 292L + 8L;
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/lang/invoke/LambdaMetafactory.java
--- a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaMetafactory.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaMetafactory.java Wed Jul 05 23:09:40 2017 +0200
@@ -211,6 +211,7 @@
* theory, any method handle could be used. Currently supported are direct method
* handles representing invocation of virtual, interface, constructor and static
* methods.
+ * @since 1.8
*/
public class LambdaMetafactory {
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java Wed Jul 05 23:09:40 2017 +0200
@@ -423,6 +423,7 @@
* @see MethodType
* @see MethodHandles
* @author John Rose, JSR 292 EG
+ * @since 1.7
*/
public abstract class MethodHandle {
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleProxies.java
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleProxies.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleProxies.java Wed Jul 05 23:09:40 2017 +0200
@@ -38,6 +38,8 @@
/**
* This class consists exclusively of static methods that help adapt
* method handles to other JVM types, such as interfaces.
+ *
+ * @since 1.7
*/
public class MethodHandleProxies {
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Wed Jul 05 23:09:40 2017 +0200
@@ -25,6 +25,9 @@
package java.lang.invoke;
+import jdk.internal.misc.SharedSecrets;
+import jdk.internal.module.IllegalAccessLogger;
+import jdk.internal.org.objectweb.asm.ClassReader;
import jdk.internal.reflect.CallerSensitive;
import jdk.internal.reflect.Reflection;
import jdk.internal.vm.annotation.ForceInline;
@@ -43,6 +46,9 @@
import java.lang.reflect.Module;
import java.lang.reflect.ReflectPermission;
import java.nio.ByteOrder;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
@@ -191,6 +197,12 @@
}
if ((lookup.lookupModes() & Lookup.MODULE) == 0)
throw new IllegalAccessException("lookup does not have MODULE lookup mode");
+ if (!callerModule.isNamed() && targetModule.isNamed()) {
+ IllegalAccessLogger logger = IllegalAccessLogger.illegalAccessLogger();
+ if (logger != null) {
+ logger.logIfOpenedByBackdoor(lookup, targetClass);
+ }
+ }
return new Lookup(targetClass);
}
@@ -855,6 +867,112 @@
return new Lookup(lookupClass(), newModes);
}
+ /**
+ * Defines a class to the same class loader and in the same runtime package and
+ * {@linkplain java.security.ProtectionDomain protection domain} as this lookup's
+ * {@linkplain #lookupClass() lookup class}.
+ *
+ * The {@linkplain #lookupModes() lookup modes} for this lookup must include
+ * {@link #PACKAGE PACKAGE} access as default (package) members will be
+ * accessible to the class. The {@code PACKAGE} lookup mode serves to authenticate
+ * that the lookup object was created by a caller in the runtime package (or derived
+ * from a lookup originally created by suitably privileged code to a target class in
+ * the runtime package). The lookup modes cannot include {@link #PRIVATE PRIVATE}
+ * access. A lookup with {@code PRIVATE} access can be downgraded to drop this lookup
+ * mode with the {@linkplain #dropLookupMode(int) dropLookupMode} method.
+ *
+ * The {@code bytes} parameter is the class bytes of a valid class file (as defined
+ * by the The Java Virtual Machine Specification) with a class name in the
+ * same package as the lookup class.
+ *
+ * This method does not run the class initializer. The class initializer may
+ * run at a later time, as detailed in section 12.4 of the The Java Language
+ * Specification.
+ *
+ * If there is a security manager, its {@code checkPermission} method is first called
+ * to check {@code RuntimePermission("defineClass")}.
+ *
+ * @param bytes the class bytes
+ * @return the {@code Class} object for the class
+ * @throws IllegalArgumentException the bytes are for a class in a different package
+ * to the lookup class
+ * @throws IllegalAccessException if this lookup does not have {@code PACKAGE} access
+ * @throws UnsupportedOperationException if the lookup class has {@code PRIVATE} access
+ * @throws LinkageError if the class is malformed ({@code ClassFormatError}), cannot be
+ * verified ({@code VerifyError}), is already defined, or another linkage error occurs
+ * @throws SecurityException if denied by the security manager
+ * @throws NullPointerException if {@code bytes} is {@code null}
+ * @since 9
+ * @spec JPMS
+ * @see Lookup#privateLookupIn
+ * @see Lookup#dropLookupMode
+ * @see ClassLoader#defineClass(String,byte[],int,int,ProtectionDomain)
+ */
+ public Class> defineClass(byte[] bytes) throws IllegalAccessException {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkPermission(new RuntimePermission("defineClass"));
+ if (hasPrivateAccess())
+ throw new UnsupportedOperationException("PRIVATE access not supported");
+ if ((lookupModes() & PACKAGE) == 0)
+ throw new IllegalAccessException("Lookup does not have PACKAGE access");
+ assert (lookupModes() & (MODULE|PUBLIC)) != 0;
+
+ // parse class bytes to get class name (in internal form)
+ bytes = bytes.clone();
+ String name;
+ try {
+ ClassReader reader = new ClassReader(bytes);
+ name = reader.getClassName();
+ } catch (RuntimeException e) {
+ // ASM exceptions are poorly specified
+ ClassFormatError cfe = new ClassFormatError();
+ cfe.initCause(e);
+ throw cfe;
+ }
+
+ // get package and class name in binary form
+ String cn, pn;
+ int index = name.lastIndexOf('/');
+ if (index == -1) {
+ cn = name;
+ pn = "";
+ } else {
+ cn = name.replace('/', '.');
+ pn = cn.substring(0, index);
+ }
+ if (!pn.equals(lookupClass.getPackageName())) {
+ throw new IllegalArgumentException("Class not in same package as lookup class");
+ }
+
+ // invoke the class loader's defineClass method
+ ClassLoader loader = lookupClass.getClassLoader();
+ ProtectionDomain pd = (loader != null) ? lookupClassProtectionDomain() : null;
+ String source = "__Lookup_defineClass__";
+ Class> clazz = SharedSecrets.getJavaLangAccess().defineClass(loader, cn, bytes, pd, source);
+ assert clazz.getClassLoader() == lookupClass.getClassLoader()
+ && clazz.getPackageName().equals(lookupClass.getPackageName())
+ && protectionDomain(clazz) == lookupClassProtectionDomain();
+ return clazz;
+ }
+
+ private ProtectionDomain lookupClassProtectionDomain() {
+ ProtectionDomain pd = cachedProtectionDomain;
+ if (pd == null) {
+ cachedProtectionDomain = pd = protectionDomain(lookupClass);
+ }
+ return pd;
+ }
+
+ private ProtectionDomain protectionDomain(Class> clazz) {
+ PrivilegedAction pa = clazz::getProtectionDomain;
+ return AccessController.doPrivileged(pa);
+ }
+
+ // cached protection domain
+ private volatile ProtectionDomain cachedProtectionDomain;
+
+
// Make sure outer class is initialized first.
static { IMPL_NAMES.getClass(); }
@@ -1948,7 +2066,7 @@
/**
* Returns {@code true} if this lookup has {@code PRIVATE} access.
- * @return {@code true} if this lookup has {@code PRIVATE} acesss.
+ * @return {@code true} if this lookup has {@code PRIVATE} access.
* @since 9
*/
public boolean hasPrivateAccess() {
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java Wed Jul 05 23:09:40 2017 +0200
@@ -88,6 +88,7 @@
* (But the classes need not be initialized, as is the case with a {@code CONSTANT_Class}.)
* This loading may occur at any time before the {@code MethodType} object is first derived.
* @author John Rose, JSR 292 EG
+ * @since 1.7
*/
public final
class MethodType implements java.io.Serializable {
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/lang/invoke/MutableCallSite.java
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MutableCallSite.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MutableCallSite.java Wed Jul 05 23:09:40 2017 +0200
@@ -81,6 +81,7 @@
* For target values which will be frequently updated, consider using
* a {@linkplain VolatileCallSite volatile call site} instead.
* @author John Rose, JSR 292 EG
+ * @since 1.7
*/
public class MutableCallSite extends CallSite {
/**
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/lang/invoke/SerializedLambda.java
--- a/jdk/src/java.base/share/classes/java/lang/invoke/SerializedLambda.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/SerializedLambda.java Wed Jul 05 23:09:40 2017 +0200
@@ -54,6 +54,7 @@
* lambda actually captured by that class.
*
* @see LambdaMetafactory
+ * @since 1.8
*/
public final class SerializedLambda implements Serializable {
private static final long serialVersionUID = 8025925345765570181L;
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/lang/invoke/SwitchPoint.java
--- a/jdk/src/java.base/share/classes/java/lang/invoke/SwitchPoint.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/SwitchPoint.java Wed Jul 05 23:09:40 2017 +0200
@@ -108,6 +108,7 @@
* }
* }
* @author Remi Forax, JSR 292 EG
+ * @since 1.7
*/
public class SwitchPoint {
private static final MethodHandle
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/lang/invoke/VolatileCallSite.java
--- a/jdk/src/java.base/share/classes/java/lang/invoke/VolatileCallSite.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/VolatileCallSite.java Wed Jul 05 23:09:40 2017 +0200
@@ -40,6 +40,7 @@
* with {@code MutableCallSite}.
* @see MutableCallSite
* @author John Rose, JSR 292 EG
+ * @since 1.7
*/
public class VolatileCallSite extends CallSite {
/**
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/lang/module/Configuration.java
--- a/jdk/src/java.base/share/classes/java/lang/module/Configuration.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/module/Configuration.java Wed Jul 05 23:09:40 2017 +0200
@@ -112,11 +112,9 @@
// module constraints on target
private final String osName;
private final String osArch;
- private final String osVersion;
String osName() { return osName; }
String osArch() { return osArch; }
- String osVersion() { return osVersion; }
private Configuration() {
this.parents = Collections.emptyList();
@@ -125,7 +123,6 @@
this.nameToModule = Collections.emptyMap();
this.osName = null;
this.osArch = null;
- this.osVersion = null;
}
private Configuration(List parents,
@@ -152,7 +149,6 @@
this.osName = resolver.osName();
this.osArch = resolver.osArch();
- this.osVersion = resolver.osVersion();
}
/**
@@ -281,6 +277,7 @@
* observability-related reasons:
*
*
+ *
* A root module, or a direct or transitive dependency, is not
* found.
*
@@ -289,13 +286,6 @@
* descriptor ({@code module-info.class}) or two versions of the same
* module are found in the same directory.
*
- * A module with the required name is found but the module
- * requires a different {@link ModuleDescriptor#osName() operating
- * system}, {@link ModuleDescriptor#osArch() architecture}, or {@link
- * ModuleDescriptor#osVersion() version} to other modules that have
- * been resolved for the new configuration or modules in the parent
- * configurations.
- *
*
*
* Post-resolution consistency checks may fail with {@code
@@ -306,6 +296,10 @@
*
A cycle is detected, say where module {@code m1} requires
* module {@code m2} and {@code m2} requires {@code m1}.
*
+ * A module reads two or more modules with the same name. This
+ * includes the case where a module reads another with the same name as
+ * itself.
+ *
* Two or more modules in the configuration export the same
* package to a module that reads both. This includes the case where a
* module {@code M} containing package {@code p} reads another module
@@ -319,8 +313,9 @@
*
*
* @implNote In the implementation then observability of modules may depend
- * on referential integrity checks that ensure different builds of tightly
- * coupled modules are not combined in the same configuration.
+ * on referential integrity or other checks that ensure different builds of
+ * tightly coupled modules or modules for specific operating systems or
+ * architectures are not combined in the same configuration.
*
* @param before
* The before module finder to find modules
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java
--- a/jdk/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java Wed Jul 05 23:09:40 2017 +0200
@@ -179,8 +179,10 @@
private final Set mods;
private final String name;
private final Version compiledVersion;
+ private final String rawCompiledVersion;
- private Requires(Set ms, String mn, Version v) {
+ private Requires(Set ms, String mn, Version v, String vs) {
+ assert v == null || vs == null;
if (ms.isEmpty()) {
ms = Collections.emptySet();
} else {
@@ -189,12 +191,14 @@
this.mods = ms;
this.name = mn;
this.compiledVersion = v;
+ this.rawCompiledVersion = vs;
}
private Requires(Set ms, String mn, Version v, boolean unused) {
this.mods = ms;
this.name = mn;
this.compiledVersion = v;
+ this.rawCompiledVersion = null;
}
/**
@@ -218,13 +222,34 @@
/**
* Returns the version of the module if recorded at compile-time.
*
- * @return The version of the module if recorded at compile-time
+ * @return The version of the module if recorded at compile-time,
+ * or an empty {@code Optional} if no version was recorded or
+ * the version string recorded is {@linkplain Version#parse(String)
+ * unparseable}
*/
public Optional compiledVersion() {
return Optional.ofNullable(compiledVersion);
}
/**
+ * Returns the string with the possibly-unparseable version of the module
+ * if recorded at compile-time.
+ *
+ * @return The string containing the version of the module if recorded
+ * at compile-time, or an empty {@code Optional} if no version
+ * was recorded
+ *
+ * @see #compiledVersion()
+ */
+ public Optional rawCompiledVersion() {
+ if (compiledVersion != null) {
+ return Optional.of(compiledVersion.toString());
+ } else {
+ return Optional.ofNullable(rawCompiledVersion);
+ }
+ }
+
+ /**
* Compares this module dependence to another.
*
* Two {@code Requires} objects are compared by comparing their
@@ -236,7 +261,10 @@
* recorded at compile-time are compared. When comparing the versions
* recorded at compile-time then a dependence that has a recorded
* version is considered to succeed a dependence that does not have a
- * recorded version.
+ * recorded version. If both recorded versions are {@linkplain
+ * Version#parse(String) unparseable} then the {@linkplain
+ * #rawCompiledVersion() raw version strings} are compared
+ * lexicographically.
*
* @param that
* The module dependence to compare
@@ -262,6 +290,10 @@
c = compare(this.compiledVersion, that.compiledVersion);
if (c != 0) return c;
+ // rawCompiledVersion
+ c = compare(this.rawCompiledVersion, that.rawCompiledVersion);
+ if (c != 0) return c;
+
return 0;
}
@@ -289,7 +321,8 @@
return false;
Requires that = (Requires)ob;
return name.equals(that.name) && mods.equals(that.mods)
- && Objects.equals(compiledVersion, that.compiledVersion);
+ && Objects.equals(compiledVersion, that.compiledVersion)
+ && Objects.equals(rawCompiledVersion, that.rawCompiledVersion);
}
/**
@@ -306,6 +339,8 @@
int hash = name.hashCode() * 43 + mods.hashCode();
if (compiledVersion != null)
hash = hash * 43 + compiledVersion.hashCode();
+ if (rawCompiledVersion != null)
+ hash = hash * 43 + rawCompiledVersion.hashCode();
return hash;
}
@@ -774,7 +809,7 @@
/**
* Returns the fully qualified class name of the service type.
*
- * @return The fully qualified class name of the service type.
+ * @return The fully qualified class name of the service type
*/
public String service() { return service; }
@@ -1199,6 +1234,7 @@
private final String name;
private final Version version;
+ private final String rawVersionString;
private final Set modifiers;
private final boolean open; // true if modifiers contains OPEN
private final boolean automatic; // true if modifiers contains AUTOMATIC
@@ -1209,12 +1245,10 @@
private final Set provides;
private final Set packages;
private final String mainClass;
- private final String osName;
- private final String osArch;
- private final String osVersion;
private ModuleDescriptor(String name,
Version version,
+ String rawVersionString,
Set modifiers,
Set requires,
Set exports,
@@ -1222,13 +1256,12 @@
Set uses,
Set provides,
Set packages,
- String mainClass,
- String osName,
- String osArch,
- String osVersion)
+ String mainClass)
{
+ assert version == null || rawVersionString == null;
this.name = name;
this.version = version;
+ this.rawVersionString = rawVersionString;
this.modifiers = emptyOrUnmodifiableSet(modifiers);
this.open = modifiers.contains(Modifier.OPEN);
this.automatic = modifiers.contains(Modifier.AUTOMATIC);
@@ -1242,9 +1275,6 @@
this.packages = emptyOrUnmodifiableSet(packages);
this.mainClass = mainClass;
- this.osName = osName;
- this.osArch = osArch;
- this.osVersion = osVersion;
}
/**
@@ -1261,13 +1291,11 @@
Set provides,
Set packages,
String mainClass,
- String osName,
- String osArch,
- String osVersion,
int hashCode,
boolean unused) {
this.name = name;
this.version = version;
+ this.rawVersionString = null;
this.modifiers = modifiers;
this.open = modifiers.contains(Modifier.OPEN);
this.automatic = modifiers.contains(Modifier.AUTOMATIC);
@@ -1278,9 +1306,6 @@
this.provides = provides;
this.packages = packages;
this.mainClass = mainClass;
- this.osName = osName;
- this.osArch = osArch;
- this.osVersion = osVersion;
this.hash = hashCode;
}
@@ -1394,18 +1419,37 @@
/**
* Returns the module version.
*
- * @return This module's version
+ * @return This module's version, or an empty {@code Optional} if the
+ * module does not have a version or the version is
+ * {@linkplain Version#parse(String) unparseable}
*/
public Optional version() {
return Optional.ofNullable(version);
}
/**
+ * Returns the string with the possibly-unparseable version of the
+ * module
+ *
+ * @return The string containing the version of the module or an empty
+ * {@code Optional} if the module does not have a version
+ *
+ * @see #version()
+ */
+ public Optional rawVersion() {
+ if (version != null) {
+ return Optional.of(version.toString());
+ } else {
+ return Optional.ofNullable(rawVersionString);
+ }
+ }
+
+ /**
* Returns a string containing the module name and, if present, its
* version.
*
* @return A string containing the module name and, if present, its
- * version.
+ * version
*/
public String toNameAndVersion() {
if (version != null) {
@@ -1425,40 +1469,11 @@
}
/**
- * Returns the operating system name if the module is operating system
- * specific.
- *
- * @return The operating system name or an empty {@code Optional}
- * if the module is not operating system specific
- */
- public Optional osName() {
- return Optional.ofNullable(osName);
- }
-
- /**
- * Returns the operating system architecture if the module is operating
- * system architecture specific.
+ * Returns the set of packages in the module.
*
- * @return The operating system architecture or an empty {@code Optional}
- * if the module is not operating system architecture specific
- */
- public Optional osArch() {
- return Optional.ofNullable(osArch);
- }
-
- /**
- * Returns the operating system version if the module is operating
- * system version specific.
- *
- * @return The operating system version or an empty {@code Optional}
- * if the module is not operating system version specific
- */
- public Optional osVersion() {
- return Optional.ofNullable(osVersion);
- }
-
- /**
- * Returns the set of packages in the module.
+ * The set of packages includes all exported and open packages, as well
+ * as the packages of any service providers, and the package for the main
+ * class.
*
* @return A possibly-empty unmodifiable set of the packages in the module
*/
@@ -1518,9 +1533,7 @@
final Set uses = new HashSet<>();
final Map provides = new HashMap<>();
Version version;
- String osName;
- String osArch;
- String osVersion;
+ String rawVersionString;
String mainClass;
/**
@@ -1604,24 +1617,21 @@
Objects.requireNonNull(compiledVersion);
if (strict)
mn = requireModuleName(mn);
- return requires(new Requires(ms, mn, compiledVersion));
+ return requires(new Requires(ms, mn, compiledVersion, null));
}
/* package */Builder requires(Set ms,
String mn,
- String compiledVersion) {
- Version v = null;
+ String rawCompiledVersion) {
+ Requires r;
try {
- v = Version.parse(compiledVersion);
+ Version v = Version.parse(rawCompiledVersion);
+ r = new Requires(ms, mn, v, null);
} catch (IllegalArgumentException e) {
- // for now, drop un-parsable version when non-strict
if (strict) throw e;
+ r = new Requires(ms, mn, null, rawCompiledVersion);
}
- if (v == null) {
- return requires(ms, mn);
- } else {
- return requires(ms, mn, v);
- }
+ return requires(r);
}
/**
@@ -1646,7 +1656,7 @@
public Builder requires(Set ms, String mn) {
if (strict)
mn = requireModuleName(mn);
- return requires(new Requires(ms, mn, null));
+ return requires(new Requires(ms, mn, null, null));
}
/**
@@ -1952,7 +1962,7 @@
* a class in a named package
* @throws IllegalStateException
* If a dependency on the service type has already been declared
- * or this is a builder for an an automatic module
+ * or this is a builder for an automatic module
*/
public Builder uses(String service) {
if (automatic)
@@ -2068,6 +2078,7 @@
*/
public Builder version(Version v) {
version = requireNonNull(v);
+ rawVersionString = null;
return this;
}
@@ -2086,18 +2097,15 @@
* @see Version#parse(String)
*/
public Builder version(String vs) {
- Version v;
- if (strict) {
- v = Version.parse(vs);
- } else {
- try {
- v = Version.parse(vs);
- } catch (IllegalArgumentException ignore) {
- // for now, ignore when non-strict
- return this;
- }
+ try {
+ version = Version.parse(vs);
+ rawVersionString = null;
+ } catch (IllegalArgumentException e) {
+ if (strict) throw e;
+ version = null;
+ rawVersionString = vs;
}
- return version(v);
+ return this;
}
/**
@@ -2132,60 +2140,6 @@
}
/**
- * Sets the operating system name.
- *
- * @param name
- * The operating system name
- *
- * @return This builder
- *
- * @throws IllegalArgumentException
- * If {@code name} is {@code null} or the empty String
- */
- public Builder osName(String name) {
- if (name == null || name.isEmpty())
- throw new IllegalArgumentException("OS name is null or empty");
- osName = name;
- return this;
- }
-
- /**
- * Sets the operating system architecture.
- *
- * @param arch
- * The operating system architecture
- *
- * @return This builder
- *
- * @throws IllegalArgumentException
- * If {@code name} is {@code null} or the empty String
- */
- public Builder osArch(String arch) {
- if (arch == null || arch.isEmpty())
- throw new IllegalArgumentException("OS arch is null or empty");
- osArch = arch;
- return this;
- }
-
- /**
- * Sets the operating system version.
- *
- * @param version
- * The operating system version
- *
- * @return This builder
- *
- * @throws IllegalArgumentException
- * If {@code name} is {@code null} or the empty String
- */
- public Builder osVersion(String version) {
- if (version == null || version.isEmpty())
- throw new IllegalArgumentException("OS version is null or empty");
- osVersion = version;
- return this;
- }
-
- /**
* Builds and returns a {@code ModuleDescriptor} from its components.
*
* The module will require "{@code java.base}" even if the dependence
@@ -2208,6 +2162,7 @@
&& !this.requires.containsKey("java.base")) {
requires.add(new Requires(Set.of(Requires.Modifier.MANDATED),
"java.base",
+ null,
null));
}
@@ -2215,6 +2170,7 @@
return new ModuleDescriptor(name,
version,
+ rawVersionString,
modifiers,
requires,
exports,
@@ -2222,10 +2178,7 @@
uses,
provides,
packages,
- mainClass,
- osName,
- osArch,
- osVersion);
+ mainClass);
}
}
@@ -2237,9 +2190,11 @@
* module names lexicographically. Where the module names are equal then the
* module versions are compared. When comparing the module versions then a
* module descriptor with a version is considered to succeed a module
- * descriptor that does not have a version. Where the module names are equal
- * and the versions are equal (or not present in both), then the set of
- * modifiers are compared. Sets of modifiers are compared by comparing
+ * descriptor that does not have a version. If both versions are {@linkplain
+ * Version#parse(String) unparseable} then the {@linkplain #rawVersion()
+ * raw version strings} are compared lexicographically. Where the module names
+ * are equal and the versions are equal (or not present in both), then the
+ * set of modifiers are compared. Sets of modifiers are compared by comparing
* a binary value computed for each set. If a modifier is present
* in the set then the bit at the position of its ordinal is {@code 1}
* in the binary value, otherwise {@code 0}. If the two set of modifiers
@@ -2263,6 +2218,9 @@
c = compare(this.version, that.version);
if (c != 0) return c;
+ c = compare(this.rawVersionString, that.rawVersionString);
+ if (c != 0) return c;
+
long v1 = modsValue(this.modifiers());
long v2 = modsValue(that.modifiers());
c = Long.compare(v1, v2);
@@ -2289,15 +2247,6 @@
c = compare(this.mainClass, that.mainClass);
if (c != 0) return c;
- c = compare(this.osName, that.osName);
- if (c != 0) return c;
-
- c = compare(this.osArch, that.osArch);
- if (c != 0) return c;
-
- c = compare(this.osVersion, that.osVersion);
- if (c != 0) return c;
-
return 0;
}
@@ -2333,10 +2282,8 @@
&& uses.equals(that.uses)
&& provides.equals(that.provides)
&& Objects.equals(version, that.version)
- && Objects.equals(mainClass, that.mainClass)
- && Objects.equals(osName, that.osName)
- && Objects.equals(osArch, that.osArch)
- && Objects.equals(osVersion, that.osVersion));
+ && Objects.equals(rawVersionString, that.rawVersionString)
+ && Objects.equals(mainClass, that.mainClass));
}
/**
@@ -2361,10 +2308,8 @@
hc = hc * 43 + uses.hashCode();
hc = hc * 43 + provides.hashCode();
hc = hc * 43 + Objects.hashCode(version);
+ hc = hc * 43 + Objects.hashCode(rawVersionString);
hc = hc * 43 + Objects.hashCode(mainClass);
- hc = hc * 43 + Objects.hashCode(osName);
- hc = hc * 43 + Objects.hashCode(osArch);
- hc = hc * 43 + Objects.hashCode(osVersion);
if (hc == 0)
hc = -1;
hash = hc;
@@ -2713,8 +2658,8 @@
public void requires(ModuleDescriptor.Builder builder,
Set ms,
String mn,
- String compiledVersion) {
- builder.requires(ms, mn, compiledVersion);
+ String rawCompiledVersion) {
+ builder.requires(ms, mn, rawCompiledVersion);
}
@Override
@@ -2762,9 +2707,6 @@
Set provides,
Set packages,
String mainClass,
- String osName,
- String osArch,
- String osVersion,
int hashCode) {
return new ModuleDescriptor(name,
version,
@@ -2776,9 +2718,6 @@
provides,
packages,
mainClass,
- osName,
- osArch,
- osVersion,
hashCode,
false);
}
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/lang/module/ModuleFinder.java
--- a/jdk/src/java.base/share/classes/java/lang/module/ModuleFinder.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/module/ModuleFinder.java Wed Jul 05 23:09:40 2017 +0200
@@ -25,8 +25,6 @@
package java.lang.module;
-import java.io.File;
-import java.io.FilePermission;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -43,9 +41,9 @@
import java.util.Set;
import jdk.internal.module.ModuleBootstrap;
+import jdk.internal.module.ModulePatcher;
import jdk.internal.module.ModulePath;
import jdk.internal.module.SystemModuleFinder;
-import sun.security.action.GetPropertyAction;
/**
* A finder of modules. A {@code ModuleFinder} is used to find modules during
@@ -146,9 +144,9 @@
*
* If there is a security manager set then its {@link
* SecurityManager#checkPermission(Permission) checkPermission} method is
- * invoked to check that the caller has been granted {@link FilePermission}
- * to recursively read the directory that is the value of the system
- * property {@code java.home}.
+ * invoked to check that the caller has been granted
+ * {@link RuntimePermission RuntimePermission("accessSystemModules")}
+ * to access the system modules.
*
* @return A {@code ModuleFinder} that locates the system modules
*
@@ -156,26 +154,29 @@
* If denied by the security manager
*/
static ModuleFinder ofSystem() {
- String home;
-
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- PrivilegedAction pa = new GetPropertyAction("java.home");
- home = AccessController.doPrivileged(pa);
- Permission p = new FilePermission(home + File.separator + "-", "read");
- sm.checkPermission(p);
+ sm.checkPermission(new RuntimePermission("accessSystemModules"));
+ PrivilegedAction pa = ModuleFinder::privilegedOfSystem;
+ return AccessController.doPrivileged(pa);
} else {
- home = System.getProperty("java.home");
+ return privilegedOfSystem();
}
+ }
+ /**
+ * Returns a module finder that locates the system modules. This method
+ * assumes it has permissions to access the runtime image.
+ */
+ private static ModuleFinder privilegedOfSystem() {
+ String home = System.getProperty("java.home");
Path modules = Paths.get(home, "lib", "modules");
if (Files.isRegularFile(modules)) {
return SystemModuleFinder.getInstance();
} else {
- Path mlib = Paths.get(home, "modules");
- if (Files.isDirectory(mlib)) {
- // exploded build may be patched
- return ModulePath.of(ModuleBootstrap.patcher(), mlib);
+ Path dir = Paths.get(home, "modules");
+ if (Files.isDirectory(dir)) {
+ return privilegedOf(ModuleBootstrap.patcher(), dir);
} else {
throw new InternalError("Unable to detect the run-time image");
}
@@ -183,6 +184,26 @@
}
/**
+ * Returns a module finder that locates the system modules in an exploded
+ * image. The image may be patched.
+ */
+ private static ModuleFinder privilegedOf(ModulePatcher patcher, Path dir) {
+ ModuleFinder finder = ModulePath.of(patcher, dir);
+ return new ModuleFinder() {
+ @Override
+ public Optional find(String name) {
+ PrivilegedAction> pa = () -> finder.find(name);
+ return AccessController.doPrivileged(pa);
+ }
+ @Override
+ public Set findAll() {
+ PrivilegedAction> pa = finder::findAll;
+ return AccessController.doPrivileged(pa);
+ }
+ };
+ }
+
+ /**
* Returns a module finder that locates modules on the file system by
* searching a sequence of directories and/or packaged modules.
*
@@ -201,7 +222,7 @@
*
* If an element is a path to a directory of modules then each entry in
* the directory is a packaged module or the top-level directory of an
- * exploded module. It it an error if a directory contains more than one
+ * exploded module. It is an error if a directory contains more than one
* module with the same name. If an element is a path to a directory, and
* that directory contains a file named {@code module-info.class}, then the
* directory is treated as an exploded module rather than a directory of
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/lang/module/ModuleReader.java
--- a/jdk/src/java.base/share/classes/java/lang/module/ModuleReader.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/module/ModuleReader.java Wed Jul 05 23:09:40 2017 +0200
@@ -48,7 +48,11 @@
*
A resource in a module is identified by an abstract name that is a
* '{@code /}'-separated path string. For example, module {@code java.base} may
* have a resource "{@code java/lang/Object.class}" that, by convention, is the
- * class file for {@code java.lang.Object}.
+ * class file for {@code java.lang.Object}. A module reader may treat
+ * directories in the module content as resources (whether it does or not is
+ * module reader specific). Where the module content contains a directory
+ * that can be located as a resource then its name ends with a slash ('/'). The
+ * directory can also be located with a name that drops the trailing slash.
*
* A {@code ModuleReader} is {@linkplain ModuleReference#open open} upon
* creation and is closed by invoking the {@link #close close} method. Failure
@@ -80,6 +84,9 @@
/**
* Finds a resource, returning a URI to the resource in the module.
*
+ *
If the module reader can determine that the name locates a directory
+ * then the resulting URI will end with a slash ('/').
+ *
* @param name
* The name of the resource to open for reading
*
@@ -140,7 +147,7 @@
*
* @apiNote This method is intended for high-performance class loading. It
* is not capable (or intended) to read arbitrary large resources that
- * could potentially be 2GB or larger. The rational for using this method
+ * could potentially be 2GB or larger. The rationale for using this method
* in conjunction with the {@code release} method is to allow module reader
* implementations manage buffers in an efficient manner.
*
@@ -195,7 +202,9 @@
/**
* Lists the contents of the module, returning a stream of elements that
- * are the names of all resources in the module.
+ * are the names of all resources in the module. Whether the stream of
+ * elements includes names corresponding to directories in the module is
+ * module reader specific.
*
* In lazy implementations then an {@code IOException} may be thrown
* when using the stream to list the module contents. If this occurs then
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/lang/module/Resolver.java
--- a/jdk/src/java.base/share/classes/java/lang/module/Resolver.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/module/Resolver.java Wed Jul 05 23:09:40 2017 +0200
@@ -47,6 +47,7 @@
import jdk.internal.module.ModuleHashes;
import jdk.internal.module.ModuleReferenceImpl;
+import jdk.internal.module.ModuleTarget;
/**
* The resolver used by {@link Configuration#resolve} and {@link
@@ -69,11 +70,9 @@
// module constraints on target platform
private String osName;
private String osArch;
- private String osVersion;
String osName() { return osName; }
String osArch() { return osArch; }
- String osVersion() { return osVersion; }
/**
* @throws IllegalArgumentException if there are more than one parent and
@@ -110,16 +109,6 @@
}
}
}
- value = parent.osVersion();
- if (value != null) {
- if (osVersion == null) {
- osVersion = value;
- } else {
- if (!value.equals(osVersion)) {
- failParentConflict("OS version", osVersion, value);
- }
- }
- }
}
}
@@ -318,13 +307,15 @@
* the target platform with the constraints of other modules.
*/
private void addFoundModule(ModuleReference mref) {
- ModuleDescriptor descriptor = mref.descriptor();
- nameToReference.put(descriptor.name(), mref);
+ String mn = mref.descriptor().name();
- if (descriptor.osName().isPresent()
- || descriptor.osArch().isPresent()
- || descriptor.osVersion().isPresent())
- checkTargetConstraints(descriptor);
+ if (mref instanceof ModuleReferenceImpl) {
+ ModuleTarget target = ((ModuleReferenceImpl)mref).moduleTarget();
+ if (target != null)
+ checkTargetConstraints(mn, target);
+ }
+
+ nameToReference.put(mn, mref);
}
/**
@@ -332,58 +323,44 @@
* conflict with the constraints of other modules resolved so far or
* modules in parent configurations.
*/
- private void checkTargetConstraints(ModuleDescriptor descriptor) {
- String value = descriptor.osName().orElse(null);
+ private void checkTargetConstraints(String mn, ModuleTarget target) {
+ String value = target.osName();
if (value != null) {
if (osName == null) {
osName = value;
} else {
if (!value.equals(osName)) {
- failTargetConstraint(descriptor);
+ failTargetConstraint(mn, target);
}
}
}
- value = descriptor.osArch().orElse(null);
+ value = target.osArch();
if (value != null) {
if (osArch == null) {
osArch = value;
} else {
if (!value.equals(osArch)) {
- failTargetConstraint(descriptor);
- }
- }
- }
- value = descriptor.osVersion().orElse(null);
- if (value != null) {
- if (osVersion == null) {
- osVersion = value;
- } else {
- if (!value.equals(osVersion)) {
- failTargetConstraint(descriptor);
+ failTargetConstraint(mn, target);
}
}
}
}
- private void failTargetConstraint(ModuleDescriptor md) {
- String s1 = targetAsString(osName, osArch, osVersion);
- String s2 = targetAsString(md);
- findFail("Module %s has constraints on target platform that conflict" +
- " with other modules: %s, %s", md.name(), s1, s2);
+ private void failTargetConstraint(String mn, ModuleTarget target) {
+ String s1 = targetAsString(osName, osArch);
+ String s2 = targetAsString(target.osName(), target.osArch());
+ findFail("Module %s has constraints on target platform (%s) that"
+ + " conflict with other modules: %s", mn, s1, s2);
}
- private String targetAsString(ModuleDescriptor descriptor) {
- String osName = descriptor.osName().orElse(null);
- String osArch = descriptor.osArch().orElse(null);
- String osVersion = descriptor.osVersion().orElse(null);
- return targetAsString(osName, osArch, osVersion);
+ private String targetAsString(ModuleTarget target) {
+ return targetAsString(target.osName(), target.osArch());
}
- private String targetAsString(String osName, String osArch, String osVersion) {
+ private String targetAsString(String osName, String osArch) {
return new StringJoiner("-")
.add(Objects.toString(osName, "*"))
.add(Objects.toString(osArch, "*"))
- .add(Objects.toString(osVersion, "*"))
.toString();
}
@@ -712,16 +689,30 @@
/**
- * Checks the readability graph to ensure that no two modules export the
- * same package to a module. This includes the case where module M has
- * a local package P and M reads another module that exports P to M.
- * Also checks the uses/provides of module M to ensure that it reads a
- * module that exports the package of the service type to M.
+ * Checks the readability graph to ensure that
+ *
+ * A module does not read two or more modules with the same name.
+ * This includes the case where a module reads another another with the
+ * same name as itself.
+ * Two or more modules in the configuration don't export the same
+ * package to a module that reads both. This includes the case where a
+ * module {@code M} containing package {@code p} reads another module
+ * that exports {@code p} to {@code M}.
+ * A module {@code M} doesn't declare that it "{@code uses p.S}"
+ * or "{@code provides p.S with ...}" but package {@code p} is neither
+ * in module {@code M} nor exported to {@code M} by any module that
+ * {@code M} reads.
+ *
*/
private void checkExportSuppliers(Map> graph) {
for (Map.Entry> e : graph.entrySet()) {
ModuleDescriptor descriptor1 = e.getKey().descriptor();
+ String name1 = descriptor1.name();
+
+ // the names of the modules that are read (including self)
+ Set names = new HashSet<>();
+ names.add(name1);
// the map of packages that are local or exported to descriptor1
Map packageToExporter = new HashMap<>();
@@ -737,9 +728,20 @@
for (ResolvedModule endpoint : reads) {
ModuleDescriptor descriptor2 = endpoint.descriptor();
+ String name2 = descriptor2.name();
+ if (descriptor2 != descriptor1 && !names.add(name2)) {
+ if (name2.equals(name1)) {
+ resolveFail("Module %s reads another module named %s",
+ name1, name1);
+ } else{
+ resolveFail("Module %s reads more than one module named %s",
+ name1, name2);
+ }
+ }
+
if (descriptor2.isAutomatic()) {
// automatic modules read self and export all packages
- if (descriptor2 != descriptor1){
+ if (descriptor2 != descriptor1) {
for (String source : descriptor2.packages()) {
ModuleDescriptor supplier
= packageToExporter.putIfAbsent(source, descriptor2);
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java
--- a/jdk/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java Wed Jul 05 23:09:40 2017 +0200
@@ -28,9 +28,12 @@
import java.lang.annotation.Annotation;
import java.security.AccessController;
+import jdk.internal.misc.VM;
+import jdk.internal.module.IllegalAccessLogger;
import jdk.internal.reflect.CallerSensitive;
import jdk.internal.reflect.Reflection;
import jdk.internal.reflect.ReflectionFactory;
+import sun.security.action.GetPropertyAction;
/**
* The {@code AccessibleObject} class is the base class for {@code Field},
@@ -288,27 +291,20 @@
if (callerModule == Object.class.getModule()) return true;
if (!declaringModule.isNamed()) return true;
- // package is open to caller
- String pn = packageName(declaringClass);
- if (declaringModule.isOpen(pn, callerModule)) {
- dumpStackIfOpenedReflectively(declaringModule, pn, callerModule);
- return true;
- }
-
- // package is exported to caller
- boolean isExported = declaringModule.isExported(pn, callerModule);
- boolean isClassPublic = Modifier.isPublic(declaringClass.getModifiers());
+ String pn = declaringClass.getPackageName();
int modifiers;
if (this instanceof Executable) {
modifiers = ((Executable) this).getModifiers();
} else {
modifiers = ((Field) this).getModifiers();
}
- if (isExported && isClassPublic) {
+ // class is public and package is exported to caller
+ boolean isClassPublic = Modifier.isPublic(declaringClass.getModifiers());
+ if (isClassPublic && declaringModule.isExported(pn, callerModule)) {
// member is public
if (Modifier.isPublic(modifiers)) {
- dumpStackIfExportedReflectively(declaringModule, pn, callerModule);
+ logIfExportedByBackdoor(caller, declaringClass);
return true;
}
@@ -316,11 +312,17 @@
if (Modifier.isProtected(modifiers)
&& Modifier.isStatic(modifiers)
&& isSubclassOf(caller, declaringClass)) {
- dumpStackIfExportedReflectively(declaringModule, pn, callerModule);
+ logIfExportedByBackdoor(caller, declaringClass);
return true;
}
}
+ // package is open to caller
+ if (declaringModule.isOpen(pn, callerModule)) {
+ logIfOpenedByBackdoor(caller, declaringClass);
+ return true;
+ }
+
if (throwExceptionIfDenied) {
// not accessible
String msg = "Unable to make ";
@@ -333,7 +335,7 @@
msg += "opens";
msg += " " + pn + "\" to " + callerModule;
InaccessibleObjectException e = new InaccessibleObjectException(msg);
- if (Reflection.printStackTraceWhenAccessFails()) {
+ if (printStackTraceWhenAccessFails()) {
e.printStackTrace(System.err);
}
throw e;
@@ -351,48 +353,35 @@
return false;
}
- private void dumpStackIfOpenedReflectively(Module module,
- String pn,
- Module other) {
- dumpStackIfExposedReflectively(module, pn, other, true);
- }
-
- private void dumpStackIfExportedReflectively(Module module,
- String pn,
- Module other) {
- dumpStackIfExposedReflectively(module, pn, other, false);
+ private void logIfOpenedByBackdoor(Class> caller, Class> declaringClass) {
+ Module callerModule = caller.getModule();
+ Module targetModule = declaringClass.getModule();
+ // callerModule is null during early startup
+ if (callerModule != null && !callerModule.isNamed() && targetModule.isNamed()) {
+ IllegalAccessLogger logger = IllegalAccessLogger.illegalAccessLogger();
+ if (logger != null) {
+ logger.logIfOpenedByBackdoor(caller, declaringClass, this::toShortString);
+ }
+ }
}
- private void dumpStackIfExposedReflectively(Module module,
- String pn,
- Module other,
- boolean open)
- {
- if (Reflection.printStackTraceWhenAccessSucceeds()
- && !module.isStaticallyExportedOrOpen(pn, other, open))
- {
- String msg = other + " allowed to invoke setAccessible on ";
- if (this instanceof Field)
- msg += "field ";
- msg += this;
- new Exception(msg) {
- private static final long serialVersionUID = 42L;
- public String toString() {
- return "WARNING: " + getMessage();
- }
- }.printStackTrace(System.err);
+ private void logIfExportedByBackdoor(Class> caller, Class> declaringClass) {
+ Module callerModule = caller.getModule();
+ Module targetModule = declaringClass.getModule();
+ // callerModule is null during early startup
+ if (callerModule != null && !callerModule.isNamed() && targetModule.isNamed()) {
+ IllegalAccessLogger logger = IllegalAccessLogger.illegalAccessLogger();
+ if (logger != null) {
+ logger.logIfExportedByBackdoor(caller, declaringClass, this::toShortString);
+ }
}
}
/**
- * Returns the package name of the given class.
+ * Returns a short descriptive string to describe this object in log messages.
*/
- private static String packageName(Class> c) {
- while (c.isArray()) {
- c = c.getComponentType();
- }
- String pn = c.getPackageName();
- return (pn != null) ? pn : "";
+ String toShortString() {
+ return toString();
}
/**
@@ -409,6 +398,7 @@
* it should use {@link #canAccess(Object)}.
*
* @revised 9
+ * @spec JPMS
*/
@Deprecated(since="9")
public boolean isAccessible() {
@@ -483,10 +473,7 @@
} else {
targetClass = Modifier.isStatic(modifiers) ? null : obj.getClass();
}
- return Reflection.verifyMemberAccess(caller,
- declaringClass,
- targetClass,
- modifiers);
+ return verifyAccess(caller, declaringClass, targetClass, modifiers);
}
/**
@@ -527,7 +514,7 @@
return AnnotatedElement.super.isAnnotationPresent(annotationClass);
}
- /**
+ /**
* @throws NullPointerException {@inheritDoc}
* @since 1.8
*/
@@ -598,8 +585,21 @@
Class> targetClass, int modifiers)
throws IllegalAccessException
{
+ if (!verifyAccess(caller, memberClass, targetClass, modifiers)) {
+ IllegalAccessException e = Reflection.newIllegalAccessException(
+ caller, memberClass, targetClass, modifiers);
+ if (printStackTraceWhenAccessFails()) {
+ e.printStackTrace(System.err);
+ }
+ throw e;
+ }
+ }
+
+ final boolean verifyAccess(Class> caller, Class> memberClass,
+ Class> targetClass, int modifiers)
+ {
if (caller == memberClass) { // quick check
- return; // ACCESS IS OK
+ return true; // ACCESS IS OK
}
Object cache = securityCheckCache; // read volatile
if (targetClass != null // instance member or constructor
@@ -610,26 +610,31 @@
Class>[] cache2 = (Class>[]) cache;
if (cache2[1] == targetClass &&
cache2[0] == caller) {
- return; // ACCESS IS OK
+ return true; // ACCESS IS OK
}
// (Test cache[1] first since range check for [1]
// subsumes range check for [0].)
}
} else if (cache == caller) {
// Non-protected case (or targetClass == memberClass or static member).
- return; // ACCESS IS OK
+ return true; // ACCESS IS OK
}
// If no return, fall through to the slow path.
- slowCheckMemberAccess(caller, memberClass, targetClass, modifiers);
+ return slowVerifyAccess(caller, memberClass, targetClass, modifiers);
}
// Keep all this slow stuff out of line:
- void slowCheckMemberAccess(Class> caller, Class> memberClass,
- Class> targetClass, int modifiers)
- throws IllegalAccessException
+ private boolean slowVerifyAccess(Class> caller, Class> memberClass,
+ Class> targetClass, int modifiers)
{
- Reflection.ensureMemberAccess(caller, memberClass, targetClass, modifiers);
+ if (!Reflection.verifyMemberAccess(caller, memberClass, targetClass, modifiers)) {
+ // access denied
+ return false;
+ }
+
+ // access okay
+ logIfExportedByBackdoor(caller, memberClass);
// Success: Update the cache.
Object cache = (targetClass != null
@@ -643,5 +648,27 @@
// guarantees that the initializing stores for the cache
// elements will occur before the volatile write.
securityCheckCache = cache; // write volatile
+ return true;
+ }
+
+ // true to print a stack trace when access fails
+ private static volatile boolean printStackWhenAccessFails;
+
+ // true if printStack* values are initialized
+ private static volatile boolean printStackPropertiesSet;
+
+ /**
+ * Returns true if a stack trace should be printed when access fails.
+ */
+ private static boolean printStackTraceWhenAccessFails() {
+ if (!printStackPropertiesSet && VM.initLevel() >= 1) {
+ String s = GetPropertyAction.privilegedGetProperty(
+ "sun.reflect.debugModuleAccessChecks");
+ if (s != null) {
+ printStackWhenAccessFails = !s.equalsIgnoreCase("false");
+ }
+ printStackPropertiesSet = true;
+ }
+ return printStackWhenAccessFails;
}
}
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/lang/reflect/Constructor.java
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Constructor.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Constructor.java Wed Jul 05 23:09:40 2017 +0200
@@ -38,6 +38,7 @@
import sun.reflect.generics.scope.ConstructorScope;
import java.lang.annotation.Annotation;
import java.lang.annotation.AnnotationFormatError;
+import java.util.StringJoiner;
/**
* {@code Constructor} provides information about, and access to, a single
@@ -173,7 +174,6 @@
* @throws SecurityException if the request is denied by the security manager
* or this is a constructor for {@code java.lang.Class}
*
- * @since 9
* @spec JPMS
*/
@Override
@@ -360,6 +360,20 @@
sb.append(getDeclaringClass().getTypeName());
}
+ @Override
+ String toShortString() {
+ StringBuilder sb = new StringBuilder("constructor ");
+ sb.append(getDeclaringClass().getTypeName());
+ sb.append('(');
+ StringJoiner sj = new StringJoiner(",");
+ for (Class> parameterType : getParameterTypes()) {
+ sj.add(parameterType.getTypeName());
+ }
+ sb.append(sj);
+ sb.append(')');
+ return sb.toString();
+ }
+
/**
* Returns a string describing this {@code Constructor},
* including type parameters. The string is formatted as the
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/lang/reflect/Field.java
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Field.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Field.java Wed Jul 05 23:09:40 2017 +0200
@@ -324,6 +324,11 @@
+ getName());
}
+ @Override
+ String toShortString() {
+ return "field " + getDeclaringClass().getTypeName() + "." + getName();
+ }
+
/**
* Returns a string describing this {@code Field}, including
* its generic type. The format is the access modifiers for the
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/lang/reflect/Layer.java
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Layer.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Layer.java Wed Jul 05 23:09:40 2017 +0200
@@ -66,9 +66,7 @@
* ResolvedModule} in the configuration. For each resolved module that is
* {@link ResolvedModule#reads() read}, the {@code Module} {@link
* Module#canRead reads} the corresponding run-time {@code Module}, which may
- * be in the same layer or a {@link #parents() parent} layer. The {@code Module}
- * {@link Module#isExported(String) exports} and {@link Module#isOpen(String)
- * opens} the packages described by its {@link ModuleDescriptor}.
+ * be in the same layer or a {@link #parents() parent} layer.
*
* The {@link #defineModulesWithOneLoader defineModulesWithOneLoader} and
* {@link #defineModulesWithManyLoaders defineModulesWithManyLoaders} methods
@@ -91,6 +89,28 @@
* built-in into the Java virtual machine. The boot layer will often be
* the {@link #parents() parent} when creating additional layers.
*
+ * Each {@code Module} in a layer is created so that it {@link
+ * Module#isExported(String) exports} and {@link Module#isOpen(String) opens}
+ * the packages described by its {@link ModuleDescriptor}. Qualified exports
+ * (where a package is exported to a set of target modules rather than all
+ * modules) are reified when creating the layer as follows:
+ *
+ * - If module {@code X} exports a package to {@code Y}, and if the
+ * runtime {@code Module} {@code X} reads {@code Module} {@code Y}, then
+ * the package is exported to {@code Module} {@code Y} (which may be in
+ * the same layer as {@code X} or a parent layer).
+ *
+ * - If module {@code X} exports a package to {@code Y}, and if the
+ * runtime {@code Module} {@code X} does not read {@code Y} then target
+ * {@code Y} is located as if by invoking {@link #findModule(String)
+ * findModule} to find the module in the layer or its parent layers. If
+ * {@code Y} is found then the package is exported to the instance of
+ * {@code Y} that was found. If {@code Y} is not found then the qualified
+ * export is ignored.
+ *
+ *
+ * Qualified opens are handled in same way as qualified exports.
+ *
* As when creating a {@code Configuration},
* {@link ModuleDescriptor#isAutomatic() automatic} modules receive special
* treatment when creating a layer. An automatic module is created in the
@@ -193,7 +213,7 @@
}
private void ensureInLayer(Module source) {
- if (!layer.modules().contains(source))
+ if (source.getLayer() != layer)
throw new IllegalArgumentException(source + " not in layer");
}
@@ -220,9 +240,8 @@
* @see Module#addReads
*/
public Controller addReads(Module source, Module target) {
- Objects.requireNonNull(source);
+ ensureInLayer(source);
Objects.requireNonNull(target);
- ensureInLayer(source);
Modules.addReads(source, target);
return this;
}
@@ -248,9 +267,9 @@
* @see Module#addOpens
*/
public Controller addOpens(Module source, String pn, Module target) {
- Objects.requireNonNull(source);
+ ensureInLayer(source);
+ Objects.requireNonNull(pn);
Objects.requireNonNull(target);
- ensureInLayer(source);
Modules.addOpens(source, pn, target);
return this;
}
@@ -408,8 +427,8 @@
*
*
*
In addition, a layer cannot be created if the configuration contains
- * a module named "{@code java.base}" or a module with a package name
- * starting with "{@code java.}".
+ * a module named "{@code java.base}", or a module contains a package named
+ * "{@code java}" or a package with a name starting with "{@code java.}".
*
* If there is a security manager then the class loader created by
* this method will load classes and resources with privileges that are
@@ -418,7 +437,7 @@
* @param cf
* The configuration for the layer
* @param parentLayers
- * The list parent layers in search order
+ * The list of parent layers in search order
* @param parentLoader
* The parent class loader for the class loader created by this
* method; may be {@code null} for the bootstrap class loader
@@ -485,7 +504,7 @@
* @param cf
* The configuration for the layer
* @param parentLayers
- * The list parent layers in search order
+ * The list of parent layers in search order
* @param parentLoader
* The parent class loader for each of the class loaders created by
* this method; may be {@code null} for the bootstrap class loader
@@ -497,8 +516,10 @@
* the parent layers, including order
* @throws LayerInstantiationException
* If the layer cannot be created because the configuration contains
- * a module named "{@code java.base}" or a module with a package
- * name starting with "{@code java.}"
+ * a module named "{@code java.base}" or a module contains a package
+ * named "{@code java}" or a package with a name starting with
+ * "{@code java.}"
+ *
* @throws SecurityException
* If {@code RuntimePermission("createClassLoader")} or
* {@code RuntimePermission("getClassLoader")} is denied by
@@ -558,10 +579,11 @@
*
*
In addition, a layer cannot be created if the configuration contains
* a module named "{@code java.base}", a configuration contains a module
- * with a package name starting with "{@code java.}" is mapped to a class
- * loader other than the {@link ClassLoader#getPlatformClassLoader()
- * platform class loader}, or the function to map a module name to a class
- * loader returns {@code null}.
+ * with a package named "{@code java}" or a package name starting with
+ * "{@code java.}" and the module is mapped to a class loader other than
+ * the {@link ClassLoader#getPlatformClassLoader() platform class loader},
+ * or the function to map a module name to a class loader returns
+ * {@code null}.
*
* If the function to map a module name to class loader throws an error
* or runtime exception then it is propagated to the caller of this method.
@@ -575,7 +597,7 @@
* @param cf
* The configuration for the layer
* @param parentLayers
- * The list parent layers in search order
+ * The list of parent layers in search order
* @param clf
* The function to map a module name to a class loader
*
@@ -754,10 +776,16 @@
* @return A possibly-empty unmodifiable set of the modules in this layer
*/
public Set modules() {
- return Collections.unmodifiableSet(
- nameToModule.values().stream().collect(Collectors.toSet()));
+ Set modules = this.modules;
+ if (modules == null) {
+ this.modules = modules =
+ Collections.unmodifiableSet(new HashSet<>(nameToModule.values()));
+ }
+ return modules;
}
+ private volatile Set modules;
+
/**
* Returns the module with the given name in this layer, or if not in this
@@ -776,6 +804,8 @@
*/
public Optional findModule(String name) {
Objects.requireNonNull(name);
+ if (this == EMPTY_LAYER)
+ return Optional.empty();
Module m = nameToModule.get(name);
if (m != null)
return Optional.of(m);
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/lang/reflect/Method.java
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Method.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Method.java Wed Jul 05 23:09:40 2017 +0200
@@ -42,6 +42,7 @@
import java.lang.annotation.Annotation;
import java.lang.annotation.AnnotationFormatError;
import java.nio.ByteBuffer;
+import java.util.StringJoiner;
/**
* A {@code Method} provides information about, and access to, a single method
@@ -416,6 +417,21 @@
sb.append(getName());
}
+ @Override
+ String toShortString() {
+ StringBuilder sb = new StringBuilder("method ");
+ sb.append(getDeclaringClass().getTypeName()).append('.');
+ sb.append(getName());
+ sb.append('(');
+ StringJoiner sj = new StringJoiner(",");
+ for (Class> parameterType : getParameterTypes()) {
+ sj.add(parameterType.getTypeName());
+ }
+ sb.append(sj);
+ sb.append(')');
+ return sb.toString();
+ }
+
/**
* Returns a string describing this {@code Method}, including
* type parameters. The string is formatted as the method access
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/lang/reflect/Module.java
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Module.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Module.java Wed Jul 05 23:09:40 2017 +0200
@@ -39,8 +39,10 @@
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
@@ -51,11 +53,11 @@
import jdk.internal.loader.BuiltinClassLoader;
import jdk.internal.loader.BootLoader;
-import jdk.internal.loader.ResourceHelper;
import jdk.internal.misc.JavaLangAccess;
import jdk.internal.misc.JavaLangReflectModuleAccess;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.module.ServicesCatalog;
+import jdk.internal.module.Resources;
import jdk.internal.org.objectweb.asm.AnnotationVisitor;
import jdk.internal.org.objectweb.asm.Attribute;
import jdk.internal.org.objectweb.asm.ClassReader;
@@ -369,28 +371,19 @@
* If {@code syncVM} is {@code true} then the VM is notified.
*/
private void implAddReads(Module other, boolean syncVM) {
- Objects.requireNonNull(other);
-
- // nothing to do
- if (other == this || !this.isNamed())
- return;
-
- // check if we already read this module
- Set reads = this.reads;
- if (reads != null && reads.contains(other))
- return;
+ if (!canRead(other)) {
+ // update VM first, just in case it fails
+ if (syncVM) {
+ if (other == ALL_UNNAMED_MODULE) {
+ addReads0(this, null);
+ } else {
+ addReads0(this, other);
+ }
+ }
- // update VM first, just in case it fails
- if (syncVM) {
- if (other == ALL_UNNAMED_MODULE) {
- addReads0(this, null);
- } else {
- addReads0(this, other);
- }
+ // add reflective read
+ reflectivelyReads.putIfAbsent(this, other, Boolean.TRUE);
}
-
- // add reflective read
- reflectivelyReads.putIfAbsent(this, other, Boolean.TRUE);
}
@@ -553,7 +546,7 @@
* Returns {@code true} if this module exports or opens a package to
* the given module via its module declaration.
*/
- boolean isStaticallyExportedOrOpen(String pn, Module other, boolean open) {
+ private boolean isStaticallyExportedOrOpen(String pn, Module other, boolean open) {
// package is open to everyone or
Map> openPackages = this.openPackages;
if (openPackages != null) {
@@ -909,9 +902,7 @@
* Returns an array of the package names of the packages in this module.
*
* For named modules, the returned array contains an element for each
- * package in the module. It may contain elements corresponding to packages
- * added to the module, dynamic modules
- * for example, after it was loaded.
+ * package in the module.
*
* For unnamed modules, this method is the equivalent to invoking the
* {@link ClassLoader#getDefinedPackages() getDefinedPackages} method of
@@ -950,15 +941,6 @@
}
/**
- * Add a package to this module.
- *
- * @apiNote This method is for Proxy use.
- */
- void addPackage(String pn) {
- implAddPackage(pn, true);
- }
-
- /**
* Add a package to this module without notifying the VM.
*
* @apiNote This method is VM white-box testing.
@@ -1080,20 +1062,28 @@
// reads
Set reads = new HashSet<>();
+
+ // name -> source Module when in parent layer
+ Map nameToSource = Collections.emptyMap();
+
for (ResolvedModule other : resolvedModule.reads()) {
Module m2 = null;
if (other.configuration() == cf) {
- String dn = other.reference().descriptor().name();
- m2 = nameToModule.get(dn);
+ // this configuration
+ m2 = nameToModule.get(other.name());
+ assert m2 != null;
} else {
+ // parent layer
for (Layer parent: layer.parents()) {
m2 = findModule(parent, other);
if (m2 != null)
break;
}
+ assert m2 != null;
+ if (nameToSource.isEmpty())
+ nameToSource = new HashMap<>();
+ nameToSource.put(other.name(), m2);
}
- assert m2 != null;
-
reads.add(m2);
// update VM view
@@ -1107,7 +1097,7 @@
}
// exports and opens
- initExportsAndOpens(descriptor, nameToModule, m);
+ initExportsAndOpens(m, nameToSource, nameToModule, layer.parents());
}
// register the modules in the boot layer
@@ -1159,15 +1149,17 @@
.orElse(null);
}
+
/**
* Initialize the maps of exported and open packages for module m.
*/
- private static void initExportsAndOpens(ModuleDescriptor descriptor,
+ private static void initExportsAndOpens(Module m,
+ Map nameToSource,
Map nameToModule,
- Module m)
- {
+ List parents) {
// The VM doesn't special case open or automatic modules so need to
// export all packages
+ ModuleDescriptor descriptor = m.getDescriptor();
if (descriptor.isOpen() || descriptor.isAutomatic()) {
assert descriptor.opens().isEmpty();
for (String source : descriptor.packages()) {
@@ -1187,8 +1179,7 @@
// qualified opens
Set targets = new HashSet<>();
for (String target : opens.targets()) {
- // only open to modules that are in this configuration
- Module m2 = nameToModule.get(target);
+ Module m2 = findModule(target, nameToSource, nameToModule, parents);
if (m2 != null) {
addExports0(m, source, m2);
targets.add(m2);
@@ -1217,8 +1208,7 @@
// qualified exports
Set targets = new HashSet<>();
for (String target : exports.targets()) {
- // only export to modules that are in this configuration
- Module m2 = nameToModule.get(target);
+ Module m2 = findModule(target, nameToSource, nameToModule, parents);
if (m2 != null) {
// skip qualified export if already open to m2
if (openToTargets == null || !openToTargets.contains(m2)) {
@@ -1244,6 +1234,32 @@
m.exportedPackages = exportedPackages;
}
+ /**
+ * Find the runtime Module with the given name. The module name is the
+ * name of a target module in a qualified exports or opens directive.
+ *
+ * @param target The target module to find
+ * @param nameToSource The modules in parent layers that are read
+ * @param nameToModule The modules in the layer under construction
+ * @param parents The parent layers
+ */
+ private static Module findModule(String target,
+ Map nameToSource,
+ Map nameToModule,
+ List parents) {
+ Module m = nameToSource.get(target);
+ if (m == null) {
+ m = nameToModule.get(target);
+ if (m == null) {
+ for (Layer parent : parents) {
+ m = parent.findModule(target).orElse(null);
+ if (m != null) break;
+ }
+ }
+ }
+ return m;
+ }
+
// -- annotations --
@@ -1428,12 +1444,12 @@
name = name.substring(1);
}
- if (isNamed() && !ResourceHelper.isSimpleResource(name)) {
+ if (isNamed() && Resources.canEncapsulate(name)) {
Module caller = Reflection.getCallerClass().getModule();
if (caller != this && caller != Object.class.getModule()) {
// ignore packages added for proxies via addPackage
Set packages = getDescriptor().packages();
- String pn = ResourceHelper.getPackageName(name);
+ String pn = Resources.toPackageName(name);
if (packages.contains(pn) && !isOpen(pn, caller)) {
// resource is in package not open to caller
return null;
@@ -1531,26 +1547,26 @@
m.implAddReads(Module.ALL_UNNAMED_MODULE);
}
@Override
+ public void addExports(Module m, String pn) {
+ m.implAddExportsOrOpens(pn, Module.EVERYONE_MODULE, false, true);
+ }
+ @Override
public void addExports(Module m, String pn, Module other) {
m.implAddExportsOrOpens(pn, other, false, true);
}
@Override
+ public void addExportsToAllUnnamed(Module m, String pn) {
+ m.implAddExportsOrOpens(pn, Module.ALL_UNNAMED_MODULE, false, true);
+ }
+ @Override
+ public void addOpens(Module m, String pn) {
+ m.implAddExportsOrOpens(pn, Module.EVERYONE_MODULE, true, true);
+ }
+ @Override
public void addOpens(Module m, String pn, Module other) {
m.implAddExportsOrOpens(pn, other, true, true);
}
@Override
- public void addExportsToAll(Module m, String pn) {
- m.implAddExportsOrOpens(pn, Module.EVERYONE_MODULE, false, true);
- }
- @Override
- public void addOpensToAll(Module m, String pn) {
- m.implAddExportsOrOpens(pn, Module.EVERYONE_MODULE, true, true);
- }
- @Override
- public void addExportsToAllUnnamed(Module m, String pn) {
- m.implAddExportsOrOpens(pn, Module.ALL_UNNAMED_MODULE, false, true);
- }
- @Override
public void addOpensToAllUnnamed(Module m, String pn) {
m.implAddExportsOrOpens(pn, Module.ALL_UNNAMED_MODULE, true, true);
}
@@ -1559,10 +1575,6 @@
m.implAddUses(service);
}
@Override
- public void addPackage(Module m, String pn) {
- m.implAddPackage(pn, true);
- }
- @Override
public ServicesCatalog getServicesCatalog(Layer layer) {
return layer.getServicesCatalog();
}
@@ -1574,10 +1586,6 @@
public Stream layers(ClassLoader loader) {
return Layer.layers(loader);
}
- @Override
- public boolean isStaticallyExported(Module module, String pn, Module other) {
- return module.isStaticallyExportedOrOpen(pn, other, false);
- }
});
}
}
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/lang/reflect/Proxy.java
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Proxy.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Proxy.java Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, 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
@@ -359,10 +359,11 @@
* @throws NullPointerException if the {@code interfaces} array
* argument or any of its elements are {@code null}
*
- * @deprecated Proxy classes generated in a named module are encapsulated and not
- * accessible to code outside its module.
- * {@link Constructor#newInstance(Object...) Constructor.newInstance} will throw
- * {@code IllegalAccessException} when it is called on an inaccessible proxy class.
+ * @deprecated Proxy classes generated in a named module are encapsulated
+ * and not accessible to code outside its module.
+ * {@link Constructor#newInstance(Object...) Constructor.newInstance}
+ * will throw {@code IllegalAccessException} when it is called on
+ * an inaccessible proxy class.
* Use {@link #newProxyInstance(ClassLoader, Class[], InvocationHandler)}
* to create a proxy instance instead.
*
@@ -511,17 +512,19 @@
"Unnamed package cannot be added to " + m);
}
- // add the package to the runtime module if not exists
if (m.isNamed()) {
- m.addPackage(proxyPkg);
+ if (!m.getDescriptor().packages().contains(proxyPkg)) {
+ throw new InternalError(proxyPkg + " not exist in " + m.getName());
+ }
}
/*
* Choose a name for the proxy class to generate.
*/
long num = nextUniqueNumber.getAndIncrement();
- String proxyName = proxyPkg.isEmpty() ? proxyClassNamePrefix + num
- : proxyPkg + "." + proxyClassNamePrefix + num;
+ String proxyName = proxyPkg.isEmpty()
+ ? proxyClassNamePrefix + num
+ : proxyPkg + "." + proxyClassNamePrefix + num;
ClassLoader loader = getLoader(m);
trace(proxyName, m, loader, interfaces);
@@ -581,9 +584,13 @@
c.getModule().getName(), c.getName(), access, ld);
}
- static void trace(String cn, Module module, ClassLoader loader, List> interfaces) {
+ static void trace(String cn,
+ Module module,
+ ClassLoader loader,
+ List> interfaces) {
if (isDebug()) {
- System.out.format("PROXY: %s/%s defined by %s%n", module.getName(), cn, loader);
+ System.err.format("PROXY: %s/%s defined by %s%n",
+ module.getName(), cn, loader);
}
if (isDebug("debug")) {
interfaces.stream()
@@ -592,7 +599,7 @@
}
private static final String DEBUG =
- GetPropertyAction.privilegedGetProperty("jdk.proxy.debug", "");
+ GetPropertyAction.privilegedGetProperty("jdk.proxy.debug", "");
private static boolean isDebug() {
return !DEBUG.isEmpty();
@@ -603,15 +610,16 @@
// ProxyBuilder instance members start here....
- private final ClassLoader loader;
private final List> interfaces;
private final Module module;
ProxyBuilder(ClassLoader loader, List> interfaces) {
if (!VM.isModuleSystemInited()) {
- throw new InternalError("Proxy is not supported until module system is fully initialized");
+ throw new InternalError("Proxy is not supported until "
+ + "module system is fully initialized");
}
if (interfaces.size() > 65535) {
- throw new IllegalArgumentException("interface limit exceeded: " + interfaces.size());
+ throw new IllegalArgumentException("interface limit exceeded: "
+ + interfaces.size());
}
Set> refTypes = referencedTypes(loader, interfaces);
@@ -619,7 +627,6 @@
// IAE if violates any restrictions specified in newProxyInstance
validateProxyInterfaces(loader, interfaces, refTypes);
- this.loader = loader;
this.interfaces = interfaces;
this.module = mapToModule(loader, interfaces, refTypes);
assert getLoader(module) == loader;
@@ -659,8 +666,8 @@
* Validate the given proxy interfaces and the given referenced types
* are visible to the defining loader.
*
- * @throws IllegalArgumentException if it violates the restrictions specified
- * in {@link Proxy#newProxyInstance}
+ * @throws IllegalArgumentException if it violates the restrictions
+ * specified in {@link Proxy#newProxyInstance}
*/
private static void validateProxyInterfaces(ClassLoader loader,
List> interfaces,
@@ -731,9 +738,9 @@
* is in the same module of the package-private interface.
*
* If all proxy interfaces are public and at least one in a non-exported
- * package, then the proxy class is in a dynamic module in a non-exported
- * package. Reads edge and qualified exports are added for
- * dynamic module to access.
+ * package, then the proxy class is in a dynamic module in a
+ * non-exported package. Reads edge and qualified exports are added
+ * for dynamic module to access.
*/
private static Module mapToModule(ClassLoader loader,
List> interfaces,
@@ -752,11 +759,12 @@
}
}
- // all proxy interfaces are public and exported, the proxy class is in unnamed module
- // Such proxy class is accessible to any unnamed module and named module that
- // can read unnamed module
+ // all proxy interfaces are public and exported, the proxy class
+ // is in unnamed module. Such proxy class is accessible to
+ // any unnamed module and named module that can read unnamed module
if (packagePrivateTypes.isEmpty() && modulePrivateTypes.isEmpty()) {
- return loader != null ? loader.getUnnamedModule() : BootLoader.getUnnamedModule();
+ return loader != null ? loader.getUnnamedModule()
+ : BootLoader.getUnnamedModule();
}
if (packagePrivateTypes.size() > 0) {
@@ -778,7 +786,8 @@
Module target = null;
for (Module m : packagePrivateTypes.values()) {
if (getLoader(m) != loader) {
- // the specified loader is not the same class loader of the non-public interface
+ // the specified loader is not the same class loader
+ // of the non-public interface
throw new IllegalArgumentException(
"non-public interface is not defined by the given loader");
}
@@ -799,8 +808,9 @@
return target;
}
- // all proxy interfaces are public and at least one in a non-exported package
- // map to dynamic proxy module and add reads edge and qualified exports, if necessary
+ // All proxy interfaces are public and at least one in a non-exported
+ // package. So maps to a dynamic proxy module and add reads edge
+ // and qualified exports, if necessary
Module target = getDynamicModule(loader);
// set up proxy class access to proxy interfaces and types
@@ -856,8 +866,8 @@
private static final AtomicInteger counter = new AtomicInteger();
/*
- * Define a dynamic module for the generated proxy classes in a non-exported package
- * named com.sun.proxy.$MODULE.
+ * Define a dynamic module for the generated proxy classes in
+ * a non-exported package named com.sun.proxy.$MODULE.
*
* Each class loader will have one dynamic module.
*/
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/nio/MappedByteBuffer.java
--- a/jdk/src/java.base/share/classes/java/nio/MappedByteBuffer.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/nio/MappedByteBuffer.java Wed Jul 05 23:09:40 2017 +0200
@@ -213,7 +213,6 @@
/**
* {@inheritDoc}
- * @since 9
*/
@Override
public final MappedByteBuffer position(int newPosition) {
@@ -223,7 +222,6 @@
/**
* {@inheritDoc}
- * @since 9
*/
@Override
public final MappedByteBuffer limit(int newLimit) {
@@ -233,7 +231,6 @@
/**
* {@inheritDoc}
- * @since 9
*/
@Override
public final MappedByteBuffer mark() {
@@ -243,7 +240,6 @@
/**
* {@inheritDoc}
- * @since 9
*/
@Override
public final MappedByteBuffer reset() {
@@ -253,7 +249,6 @@
/**
* {@inheritDoc}
- * @since 9
*/
@Override
public final MappedByteBuffer clear() {
@@ -263,7 +258,6 @@
/**
* {@inheritDoc}
- * @since 9
*/
@Override
public final MappedByteBuffer flip() {
@@ -273,7 +267,6 @@
/**
* {@inheritDoc}
- * @since 9
*/
@Override
public final MappedByteBuffer rewind() {
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/nio/X-Buffer.java.template
--- a/jdk/src/java.base/share/classes/java/nio/X-Buffer.java.template Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/nio/X-Buffer.java.template Wed Jul 05 23:09:40 2017 +0200
@@ -1069,7 +1069,6 @@
/**
* {@inheritDoc}
- * @since 9
*/
@Override
public
@@ -1083,7 +1082,6 @@
/**
* {@inheritDoc}
- * @since 9
*/
@Override
public
@@ -1097,7 +1095,6 @@
/**
* {@inheritDoc}
- * @since 9
*/
@Override
public
@@ -1111,7 +1108,6 @@
/**
* {@inheritDoc}
- * @since 9
*/
@Override
public
@@ -1125,7 +1121,6 @@
/**
* {@inheritDoc}
- * @since 9
*/
@Override
public
@@ -1139,7 +1134,6 @@
/**
* {@inheritDoc}
- * @since 9
*/
@Override
public
@@ -1153,7 +1147,6 @@
/**
* {@inheritDoc}
- * @since 9
*/
@Override
public
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/nio/file/ClosedFileSystemException.java
--- a/jdk/src/java.base/share/classes/java/nio/file/ClosedFileSystemException.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/nio/file/ClosedFileSystemException.java Wed Jul 05 23:09:40 2017 +0200
@@ -28,6 +28,8 @@
/**
* Unchecked exception thrown when an attempt is made to invoke an operation on
* a file and the file system is closed.
+ *
+ * @since 1.7
*/
public class ClosedFileSystemException
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/nio/file/ClosedWatchServiceException.java
--- a/jdk/src/java.base/share/classes/java/nio/file/ClosedWatchServiceException.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/nio/file/ClosedWatchServiceException.java Wed Jul 05 23:09:40 2017 +0200
@@ -28,6 +28,8 @@
/**
* Unchecked exception thrown when an attempt is made to invoke an operation on
* a watch service that is closed.
+ *
+ * @since 1.7
*/
public class ClosedWatchServiceException
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/nio/file/FileSystemAlreadyExistsException.java
--- a/jdk/src/java.base/share/classes/java/nio/file/FileSystemAlreadyExistsException.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/nio/file/FileSystemAlreadyExistsException.java Wed Jul 05 23:09:40 2017 +0200
@@ -28,6 +28,8 @@
/**
* Runtime exception thrown when an attempt is made to create a file system that
* already exists.
+ *
+ * @since 1.7
*/
public class FileSystemAlreadyExistsException
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/nio/file/FileSystemNotFoundException.java
--- a/jdk/src/java.base/share/classes/java/nio/file/FileSystemNotFoundException.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/nio/file/FileSystemNotFoundException.java Wed Jul 05 23:09:40 2017 +0200
@@ -27,6 +27,8 @@
/**
* Runtime exception thrown when a file system cannot be found.
+ *
+ * @since 1.7
*/
public class FileSystemNotFoundException
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/nio/file/InvalidPathException.java
--- a/jdk/src/java.base/share/classes/java/nio/file/InvalidPathException.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/nio/file/InvalidPathException.java Wed Jul 05 23:09:40 2017 +0200
@@ -29,6 +29,8 @@
* Unchecked exception thrown when path string cannot be converted into a
* {@link Path} because the path string contains invalid characters, or
* the path string is invalid for other file system specific reasons.
+ *
+ * @since 1.7
*/
public class InvalidPathException
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/nio/file/ProviderMismatchException.java
--- a/jdk/src/java.base/share/classes/java/nio/file/ProviderMismatchException.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/nio/file/ProviderMismatchException.java Wed Jul 05 23:09:40 2017 +0200
@@ -29,6 +29,8 @@
* Unchecked exception thrown when an attempt is made to invoke a method on an
* object created by one file system provider with a parameter created by a
* different file system provider.
+ *
+ * @since 1.7
*/
public class ProviderMismatchException
extends java.lang.IllegalArgumentException
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/nio/file/ProviderNotFoundException.java
--- a/jdk/src/java.base/share/classes/java/nio/file/ProviderNotFoundException.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/nio/file/ProviderNotFoundException.java Wed Jul 05 23:09:40 2017 +0200
@@ -27,6 +27,8 @@
/**
* Runtime exception thrown when a provider of the required type cannot be found.
+ *
+ * @since 1.7
*/
public class ProviderNotFoundException
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/nio/file/ReadOnlyFileSystemException.java
--- a/jdk/src/java.base/share/classes/java/nio/file/ReadOnlyFileSystemException.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/nio/file/ReadOnlyFileSystemException.java Wed Jul 05 23:09:40 2017 +0200
@@ -28,6 +28,8 @@
/**
* Unchecked exception thrown when an attempt is made to update an object
* associated with a {@link FileSystem#isReadOnly() read-only} {@code FileSystem}.
+ *
+ * @since 1.7
*/
public class ReadOnlyFileSystemException
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/security/SecureRandom.java
--- a/jdk/src/java.base/share/classes/java/security/SecureRandom.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/security/SecureRandom.java Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, 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,7 +40,7 @@
*
* A cryptographically strong random number minimally complies with the
* statistical random number generator tests specified in
- *
+ *
* FIPS 140-2, Security Requirements for Cryptographic Modules,
* section 4.9.1.
* Additionally, {@code SecureRandom} must produce non-deterministic output.
@@ -651,8 +651,6 @@
* {@code SecureRandom}.
*
* @return the string representation
- *
- * @since 9
*/
@Override
public String toString() {
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/security/SecureRandomSpi.java
--- a/jdk/src/java.base/share/classes/java/security/SecureRandomSpi.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/security/SecureRandomSpi.java Wed Jul 05 23:09:40 2017 +0200
@@ -211,8 +211,6 @@
* {@code SecureRandom}.
*
* @return the string representation
- *
- * @since 9
*/
@Override
public String toString() {
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/security/cert/X509CRL.java
--- a/jdk/src/java.base/share/classes/java/security/cert/X509CRL.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/security/cert/X509CRL.java Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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,6 +32,7 @@
import java.security.Principal;
import java.security.Provider;
import java.security.PublicKey;
+import java.security.Signature;
import javax.security.auth.x500.X500Principal;
import java.math.BigInteger;
@@ -241,7 +242,17 @@
public void verify(PublicKey key, Provider sigProvider)
throws CRLException, NoSuchAlgorithmException,
InvalidKeyException, SignatureException {
- X509CRLImpl.verify(this, key, sigProvider);
+ Signature sig = (sigProvider == null)
+ ? Signature.getInstance(getSigAlgName())
+ : Signature.getInstance(getSigAlgName(), sigProvider);
+ sig.initVerify(key);
+
+ byte[] tbsCRL = getTBSCertList();
+ sig.update(tbsCRL, 0, tbsCRL.length);
+
+ if (sig.verify(getSignature()) == false) {
+ throw new SignatureException("Signature does not match.");
+ }
}
/**
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/security/cert/X509Certificate.java
--- a/jdk/src/java.base/share/classes/java/security/cert/X509Certificate.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/security/cert/X509Certificate.java Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -647,7 +647,7 @@
return X509CertImpl.getIssuerAlternativeNames(this);
}
- /**
+ /**
* Verifies that this certificate was signed using the
* private key that corresponds to the specified public key.
* This method uses the signature verification engine
@@ -673,6 +673,16 @@
public void verify(PublicKey key, Provider sigProvider)
throws CertificateException, NoSuchAlgorithmException,
InvalidKeyException, SignatureException {
- X509CertImpl.verify(this, key, sigProvider);
+ Signature sig = (sigProvider == null)
+ ? Signature.getInstance(getSigAlgName())
+ : Signature.getInstance(getSigAlgName(), sigProvider);
+ sig.initVerify(key);
+
+ byte[] tbsCert = getTBSCertificate();
+ sig.update(tbsCert, 0, tbsCert.length);
+
+ if (sig.verify(getSignature()) == false) {
+ throw new SignatureException("Signature does not match.");
+ }
}
}
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/time/Duration.java
--- a/jdk/src/java.base/share/classes/java/time/Duration.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/time/Duration.java Wed Jul 05 23:09:40 2017 +0200
@@ -1370,6 +1370,7 @@
* @return a {@code Duration} based on this duration with the time truncated, not null
* @throws DateTimeException if the unit is invalid for truncation
* @throws UnsupportedTemporalTypeException if the unit is not supported
+ * @since 9
*/
public Duration truncatedTo(TemporalUnit unit) {
Objects.requireNonNull(unit, "unit");
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/time/chrono/Era.java
--- a/jdk/src/java.base/share/classes/java/time/chrono/Era.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/time/chrono/Era.java Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, 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
@@ -310,8 +310,8 @@
* The parameters control the style of the returned text and the locale.
*
* If no textual mapping is found then the {@link #getValue() numeric value} is returned.
- *
- * This default implementation is suitable for all implementations.
+ *
+ * @apiNote This default implementation is suitable for most implementations.
*
* @param style the style of the text required, not null
* @param locale the locale to use, not null
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/time/chrono/JapaneseEra.java
--- a/jdk/src/java.base/share/classes/java/time/chrono/JapaneseEra.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/time/chrono/JapaneseEra.java Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, 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
@@ -240,19 +240,10 @@
}
/**
- * Gets the textual representation of this era.
- *
- * This returns the textual name used to identify the era,
- * suitable for presentation to the user.
- * The parameters control the style of the returned text and the locale.
- *
- * If no textual mapping is found then the {@link #getValue() numeric value}
- * is returned.
+ * {@inheritDoc}
*
- * @param style the style of the text required, not null
- * @param locale the locale to use, not null
- * @return the text value of the era, not null
- * @since 9
+ * @param style {@inheritDoc}
+ * @param locale {@inheritDoc}
*/
@Override
public String getDisplayName(TextStyle style, Locale locale) {
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java
--- a/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java Wed Jul 05 23:09:40 2017 +0200
@@ -1278,6 +1278,7 @@
*
* @param textStyle the text style to use, not null
* @return this, for chaining, not null
+ * @since 9
*/
public DateTimeFormatterBuilder appendGenericZoneText(TextStyle textStyle) {
appendInternal(new ZoneTextPrinterParser(textStyle, null, true));
@@ -1303,6 +1304,7 @@
* @param textStyle the text style to use, not null
* @param preferredZones the set of preferred zone ids, not null
* @return this, for chaining, not null
+ * @since 9
*/
public DateTimeFormatterBuilder appendGenericZoneText(TextStyle textStyle,
Set preferredZones) {
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/util/Date.java
--- a/jdk/src/java.base/share/classes/java/util/Date.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/util/Date.java Wed Jul 05 23:09:40 2017 +0200
@@ -728,7 +728,6 @@
* @see java.util.Calendar
* @deprecated As of JDK version 1.1,
* replaced by {@code Calendar.get(Calendar.DAY_OF_MONTH)}.
- * @deprecated
*/
@Deprecated
public int getDate() {
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/util/Iterator.java
--- a/jdk/src/java.base/share/classes/java/util/Iterator.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/util/Iterator.java Wed Jul 05 23:09:40 2017 +0200
@@ -109,7 +109,8 @@
* Exceptions thrown by the action are relayed to the caller.
*
* The behavior of an iterator is unspecified if the action modifies the
- * collection in any way (even by calling the {@link #remove remove} method),
+ * collection in any way (even by calling the {@link #remove remove} method
+ * or other mutator methods of {@code Iterator} subtypes),
* unless an overriding class has specified a concurrent modification policy.
*
* Subsequent behavior of an iterator is unspecified if the action throws an
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/util/Observable.java
--- a/jdk/src/java.base/share/classes/java/util/Observable.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/util/Observable.java Wed Jul 05 23:09:40 2017 +0200
@@ -69,6 +69,8 @@
* {@link java.beans} package. For reliable and ordered
* messaging among threads, consider using one of the concurrent data
* structures in the {@link java.util.concurrent} package.
+ * For reactive streams style programming, see the
+ * {@link java.util.concurrent.Flow} API.
*/
@Deprecated(since="9")
public class Observable {
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/util/ServiceLoader.java
--- a/jdk/src/java.base/share/classes/java/util/ServiceLoader.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/util/ServiceLoader.java Wed Jul 05 23:09:40 2017 +0200
@@ -1007,6 +1007,7 @@
{
static final String PREFIX = "META-INF/services/";
+ Set providerNames = new HashSet<>(); // to avoid duplicates
Enumeration configs;
Iterator pending;
Class> nextClass;
@@ -1016,7 +1017,7 @@
/**
* Parse a single line from the given configuration file, adding the
- * name on the line to the names list.
+ * name on the line to set of names if not already seen.
*/
private int parseLine(URL u, BufferedReader r, int lc, Set names)
throws IOException
@@ -1041,7 +1042,9 @@
if (!Character.isJavaIdentifierPart(cp) && (cp != '.'))
fail(service, u, lc, "Illegal provider-class name: " + ln);
}
- names.add(ln);
+ if (providerNames.add(ln)) {
+ names.add(ln);
+ }
}
return lc + 1;
}
@@ -1072,7 +1075,7 @@
return true;
}
- Class> clazz = null;
+ Class> clazz;
do {
if (configs == null) {
try {
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/util/jar/Pack200.java
--- a/jdk/src/java.base/share/classes/java/util/jar/Pack200.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/util/jar/Pack200.java Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -452,13 +452,13 @@
String CODE_ATTRIBUTE_PFX = "pack.code.attribute.";
/**
- * The unpacker's progress as a percentage, as periodically
- * updated by the unpacker.
+ * The packer's progress as a percentage, as periodically
+ * updated by the packer.
* Values of 0 - 100 are normal, and -1 indicates a stall.
* Progress can be monitored by polling the value of this
* property.
*
- * At a minimum, the unpacker must set progress to 0
+ * At a minimum, the packer must set progress to 0
* at the beginning of a packing operation, and to 100
* at the end.
*/
@@ -623,7 +623,7 @@
* property.
*
* At a minimum, the unpacker must set progress to 0
- * at the beginning of a packing operation, and to 100
+ * at the beginning of an unpacking operation, and to 100
* at the end.
*/
String PROGRESS = "unpack.progress";
@@ -631,7 +631,7 @@
/**
* Get the set of this engine's properties. This set is
* a "live view", so that changing its
- * contents immediately affects the Packer engine, and
+ * contents immediately affects the Unpacker engine, and
* changes from the engine (such as progress indications)
* are immediately visible in the map.
*
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/java/util/zip/ZipException.java
--- a/jdk/src/java.base/share/classes/java/util/zip/ZipException.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/util/zip/ZipException.java Wed Jul 05 23:09:40 2017 +0200
@@ -32,7 +32,7 @@
*
* @author unascribed
* @see java.io.IOException
- * @since 1.0
+ * @since 1.1
*/
public
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/jdk/internal/jmod/JmodFile.java
--- a/jdk/src/java.base/share/classes/jdk/internal/jmod/JmodFile.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/jmod/JmodFile.java Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, 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
@@ -59,7 +59,7 @@
bis.read(magic);
if (magic[0] != JMOD_MAGIC_NUMBER[0] ||
magic[1] != JMOD_MAGIC_NUMBER[1]) {
- throw new IOException("Invalid jmod file: " + file.toString());
+ throw new IOException("Invalid JMOD file: " + file.toString());
}
if (magic[2] > JMOD_MAJOR_VERSION ||
(magic[2] == JMOD_MAJOR_VERSION && magic[3] > JMOD_MINOR_VERSION)) {
@@ -131,6 +131,13 @@
}
/**
+ * Returns true if the entry is a directory in the JMOD file.
+ */
+ public boolean isDirectory() {
+ return zipEntry.isDirectory();
+ }
+
+ /**
* Returns the size of this entry.
*/
public long size() {
@@ -186,12 +193,12 @@
public Entry getEntry(Section section, String name) {
String entry = section.jmodDir() + "/" + name;
ZipEntry ze = zipfile.getEntry(entry);
- return (ze == null || ze.isDirectory()) ? null : new Entry(ze);
+ return (ze != null) ? new Entry(ze) : null;
}
/**
* Opens an {@code InputStream} for reading the named entry of the given
- * section in this jmod file.
+ * section in this JMOD file.
*
* @throws IOException if the named entry is not found, or I/O error
* occurs when reading it
@@ -201,7 +208,7 @@
{
String entry = section.jmodDir() + "/" + name;
ZipEntry e = zipfile.getEntry(entry);
- if (e == null || e.isDirectory()) {
+ if (e == null) {
throw new IOException(name + " not found: " + file);
}
return zipfile.getInputStream(e);
@@ -217,11 +224,10 @@
}
/**
- * Returns a stream of non-directory entries in this jmod file.
+ * Returns a stream of entries in this JMOD file.
*/
public Stream stream() {
return zipfile.stream()
- .filter(e -> !e.isDirectory())
.map(Entry::new);
}
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystemProvider.java
--- a/jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystemProvider.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystemProvider.java Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, 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
@@ -65,14 +65,12 @@
}
/**
- * Need FilePermission ${java.home}/-", "read" to create or get jrt:/
+ * Need RuntimePermission "accessSystemModules" to create or get jrt:/
*/
private void checkPermission() {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- String home = SystemImage.RUNTIME_HOME;
- FilePermission perm
- = new FilePermission(home + File.separator + "-", "read");
+ RuntimePermission perm = new RuntimePermission("accessSystemModules");
sm.checkPermission(perm);
}
}
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/jdk/internal/loader/BootLoader.java
--- a/jdk/src/java.base/share/classes/jdk/internal/loader/BootLoader.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/loader/BootLoader.java Wed Jul 05 23:09:40 2017 +0200
@@ -96,6 +96,14 @@
}
/**
+ * Returns {@code true} if there is a class path associated with the
+ * BootLoader.
+ */
+ public static boolean hasClassPath() {
+ return ClassLoaders.bootLoader().hasClassPath();
+ }
+
+ /**
* Register a module with this class loader so that its classes (and
* resources) become visible via this class loader.
*/
@@ -188,14 +196,6 @@
}
/**
- * Returns {@code true} if there is a class path associated with the
- * BootLoader.
- */
- public static boolean hasClassPath() {
- return ClassLoaders.bootLoader().hasClassPath();
- }
-
- /**
* Helper class to define {@code Package} objects for packages in modules
* defined to the boot loader.
*/
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java
--- a/jdk/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java Wed Jul 05 23:09:40 2017 +0200
@@ -60,6 +60,7 @@
import jdk.internal.misc.VM;
import jdk.internal.module.ModulePatcher.PatchedModuleReader;
import jdk.internal.module.SystemModules;
+import jdk.internal.module.Resources;
/**
@@ -163,6 +164,14 @@
}
/**
+ * Returns {@code true} if there is a class path associated with this
+ * class loader.
+ */
+ boolean hasClassPath() {
+ return ucp != null;
+ }
+
+ /**
* Register a module this this class loader. This has the effect of making
* the types in the module visible.
*/
@@ -248,18 +257,24 @@
*/
@Override
public URL findResource(String name) {
- String pn = ResourceHelper.getPackageName(name);
+ String pn = Resources.toPackageName(name);
LoadedModule module = packageToModule.get(pn);
if (module != null) {
// resource is in a package of a module defined to this loader
- if (module.loader() == this
- && (name.endsWith(".class") || isOpen(module.mref(), pn))) {
+ if (module.loader() == this) {
+ URL url;
try {
- return findResource(module.name(), name); // checks URL
+ url = findResource(module.name(), name); // checks URL
} catch (IOException ioe) {
return null;
}
+ if (url != null
+ && (name.endsWith(".class")
+ || url.toString().endsWith("/")
+ || isOpen(module.mref(), pn))) {
+ return url;
+ }
}
} else {
@@ -293,15 +308,17 @@
public Enumeration findResources(String name) throws IOException {
List checked = new ArrayList<>(); // list of checked URLs
- String pn = ResourceHelper.getPackageName(name);
+ String pn = Resources.toPackageName(name);
LoadedModule module = packageToModule.get(pn);
if (module != null) {
// resource is in a package of a module defined to this loader
- if (module.loader() == this
- && (name.endsWith(".class") || isOpen(module.mref(), pn))) {
- URL url = findResource(module.name(), name); // checks URL
- if (url != null) {
+ if (module.loader() == this) {
+ URL url = findResource(module.name(), name); // checks URL
+ if (url != null
+ && (name.endsWith(".class")
+ || url.toString().endsWith("/")
+ || isOpen(module.mref(), pn))) {
checked.add(url);
}
}
@@ -351,11 +368,13 @@
new PrivilegedExceptionAction<>() {
@Override
public List run() throws IOException {
- List result = new ArrayList<>();
+ List result = null;
for (ModuleReference mref : nameToModule.values()) {
URI u = moduleReaderFor(mref).find(name).orElse(null);
if (u != null) {
try {
+ if (result == null)
+ result = new ArrayList<>();
result.add(u.toURL());
} catch (MalformedURLException |
IllegalArgumentException e) {
@@ -375,7 +394,7 @@
map = new ConcurrentHashMap<>();
this.resourceCache = new SoftReference<>(map);
}
- if (urls.isEmpty())
+ if (urls == null)
urls = Collections.emptyList();
map.putIfAbsent(name, urls);
}
@@ -870,14 +889,6 @@
}
/**
- * Returns {@code true} if there is a class path associated with this
- * class loader.
- */
- boolean hasClassPath() {
- return ucp != null;
- }
-
- /**
* Returns {@code true} if the specified package name is sealed according to
* the given manifest.
*/
@@ -975,7 +986,7 @@
*/
private boolean isOpen(ModuleReference mref, String pn) {
ModuleDescriptor descriptor = mref.descriptor();
- if (descriptor.isOpen())
+ if (descriptor.isOpen() || descriptor.isAutomatic())
return true;
for (ModuleDescriptor.Opens opens : descriptor.opens()) {
String source = opens.source();
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/jdk/internal/loader/Loader.java
--- a/jdk/src/java.base/share/classes/jdk/internal/loader/Loader.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/loader/Loader.java Wed Jul 05 23:09:40 2017 +0200
@@ -60,6 +60,7 @@
import java.util.stream.Stream;
import jdk.internal.misc.SharedSecrets;
+import jdk.internal.module.Resources;
/**
@@ -356,45 +357,52 @@
@Override
public URL findResource(String name) {
- URL url = null;
- String pn = ResourceHelper.getPackageName(name);
+ String pn = Resources.toPackageName(name);
LoadedModule module = localPackageToModule.get(pn);
+
if (module != null) {
- if (name.endsWith(".class") || isOpen(module.mref(), pn)) {
- try {
- url = findResource(module.name(), name);
- } catch (IOException ioe) {
- // ignore
+ try {
+ URL url = findResource(module.name(), name);
+ if (url != null
+ && (name.endsWith(".class")
+ || url.toString().endsWith("/")
+ || isOpen(module.mref(), pn))) {
+ return url;
}
+ } catch (IOException ioe) {
+ // ignore
}
+
} else {
for (ModuleReference mref : nameToModule.values()) {
try {
- url = findResource(mref.descriptor().name(), name);
- if (url != null)
- break;
+ URL url = findResource(mref.descriptor().name(), name);
+ if (url != null) return url;
} catch (IOException ioe) {
// ignore
}
}
}
- return url;
+
+ return null;
}
@Override
public Enumeration findResources(String name) throws IOException {
List urls = new ArrayList<>();
- String pn = ResourceHelper.getPackageName(name);
+ String pn = Resources.toPackageName(name);
LoadedModule module = localPackageToModule.get(pn);
if (module != null) {
- if (name.endsWith(".class") || isOpen(module.mref(), pn)) {
- try {
- URL url = findResource(module.name(), name);
- if (url != null)
- urls.add(url);
- } catch (IOException ioe) {
- // ignore
+ try {
+ URL url = findResource(module.name(), name);
+ if (url != null
+ && (name.endsWith(".class")
+ || url.toString().endsWith("/")
+ || isOpen(module.mref(), pn))) {
+ urls.add(url);
}
+ } catch (IOException ioe) {
+ // ignore
}
} else {
for (ModuleReference mref : nameToModule.values()) {
@@ -643,7 +651,7 @@
*/
private boolean isOpen(ModuleReference mref, String pn) {
ModuleDescriptor descriptor = mref.descriptor();
- if (descriptor.isOpen())
+ if (descriptor.isOpen() || descriptor.isAutomatic())
return true;
for (ModuleDescriptor.Opens opens : descriptor.opens()) {
String source = opens.source();
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/jdk/internal/loader/ResourceHelper.java
--- a/jdk/src/java.base/share/classes/jdk/internal/loader/ResourceHelper.java Sat Apr 08 03:25:14 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,125 +0,0 @@
-/*
- * Copyright (c) 2016, 2017, 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.loader;
-
-import java.io.File;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-
-import jdk.internal.module.Checks;
-
-/**
- * Helper class for Class#getResource, Module#getResourceAsStream, and other
- * methods that locate a resource in a module.
- */
-public final class ResourceHelper {
- private ResourceHelper() { }
-
- /**
- * Returns the package name for a resource or the empty package if
- * the resource name does not contain a slash.
- */
- public static String getPackageName(String name) {
- int index = name.lastIndexOf('/');
- if (index != -1) {
- return name.substring(0, index).replace("/", ".");
- } else {
- return "";
- }
- }
-
- /**
- * Returns true if the resource is a simple resource. Simple
- * resources can never be encapsulated. Resources ending in "{@code .class}"
- * or where the package name is not a legal package name can not be
- * encapsulated.
- */
- public static boolean isSimpleResource(String name) {
- int len = name.length();
- if (len > 6 && name.endsWith(".class")) {
- return true;
- }
- if (!Checks.isPackageName(getPackageName(name))) {
- return true;
- }
- return false;
- }
-
- /**
- * Converts a resource name to a file path. Returns {@code null} if the
- * resource name cannot be converted into a file path. Resource names
- * with empty elements, or elements that are "." or ".." are rejected,
- * as is a resource name that translates to a file path with a root
- * component.
- */
- public static Path toFilePath(String name) {
- // scan the resource name to eagerly reject obviously invalid names
- int next;
- int off = 0;
- while ((next = name.indexOf('/', off)) != -1) {
- int len = next - off;
- if (!mayTranslate(name, off, len)) {
- return null;
- }
- off = next + 1;
- }
- int rem = name.length() - off;
- if (!mayTranslate(name, off, rem)) {
- return null;
- }
-
- // convert to file path
- Path path;
- if (File.separatorChar == '/') {
- path = Paths.get(name);
- } else {
- // not allowed to embed file separators
- if (name.contains(File.separator))
- return null;
- path = Paths.get(name.replace('/', File.separatorChar));
- }
-
- // file path not allowed to have root component
- return (path.getRoot() == null) ? path : null;
- }
-
- /**
- * Returns {@code true} if the element in a resource name is a candidate
- * to translate to the element of a file path.
- */
- private static boolean mayTranslate(String name, int off, int len) {
- if (len <= 2) {
- if (len == 0)
- return false;
- boolean starsWithDot = (name.charAt(off) == '.');
- if (len == 1 && starsWithDot)
- return false;
- if (len == 2 && starsWithDot && (name.charAt(off+1) == '.'))
- return false;
- }
- return true;
- }
-
-}
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/jdk/internal/logger/DefaultLoggerFinder.java
--- a/jdk/src/java.base/share/classes/jdk/internal/logger/DefaultLoggerFinder.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/logger/DefaultLoggerFinder.java Wed Jul 05 23:09:40 2017 +0200
@@ -30,6 +30,7 @@
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
+import java.util.Objects;
import java.lang.System.LoggerFinder;
import java.lang.System.Logger;
import java.lang.ref.ReferenceQueue;
@@ -155,6 +156,8 @@
@Override
public final Logger getLogger(String name, Module module) {
+ Objects.requireNonNull(name, "name");
+ Objects.requireNonNull(module, "module");
checkPermission();
return demandLoggerFor(name, module);
}
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangAccess.java
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangAccess.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangAccess.java Wed Jul 05 23:09:40 2017 +0200
@@ -33,6 +33,7 @@
import java.lang.reflect.Module;
import java.net.URL;
import java.security.AccessControlContext;
+import java.security.ProtectionDomain;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Stream;
@@ -150,6 +151,11 @@
ConcurrentHashMap, ?> createOrGetClassLoaderValueMap(ClassLoader cl);
/**
+ * Defines a class with the given name to a class loader.
+ */
+ Class> defineClass(ClassLoader cl, String name, byte[] b, ProtectionDomain pd, String source);
+
+ /**
* Returns a class loaded by the bootstrap class loader.
*/
Class> findBootstrapClassOrNull(ClassLoader cl, String name);
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangModuleAccess.java
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangModuleAccess.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangModuleAccess.java Wed Jul 05 23:09:40 2017 +0200
@@ -73,7 +73,7 @@
void requires(ModuleDescriptor.Builder builder,
Set ms,
String mn,
- String compiledVersion);
+ String rawCompiledVersion);
/**
* Returns a {@code ModuleDescriptor.Requires} of the given modifiers
@@ -127,9 +127,6 @@
Set provides,
Set packages,
String mainClass,
- String osName,
- String osArch,
- String osVersion,
int hashCode);
/**
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangReflectModuleAccess.java
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangReflectModuleAccess.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangReflectModuleAccess.java Wed Jul 05 23:09:40 2017 +0200
@@ -66,33 +66,33 @@
void addReadsAllUnnamed(Module m);
/**
+ * Update module m to export a package to all modules.
+ */
+ void addExports(Module m, String pn);
+
+ /**
* Updates module m1 to export a package to module m2. The export does
* not result in a strong reference to m2 (m2 can be GC'ed).
*/
void addExports(Module m1, String pkg, Module m2);
/**
+ * Updates a module m to export a package to all unnamed modules.
+ */
+ void addExportsToAllUnnamed(Module m, String pkg);
+
+ /**
+ * Updates a module m to open a package to all modules.
+ */
+ void addOpens(Module m, String pkg);
+
+ /**
* Updates module m1 to open a package to module m2. Opening the
* package does not result in a strong reference to m2 (m2 can be GC'ed).
*/
void addOpens(Module m1, String pkg, Module m2);
/**
- * Updates a module m to export a package to all modules.
- */
- void addExportsToAll(Module m, String pkg);
-
- /**
- * Updates a module m to open a package to all modules.
- */
- void addOpensToAll(Module m, String pkg);
-
- /**
- * Updates a module m to export a package to all unnamed modules.
- */
- void addExportsToAllUnnamed(Module m, String pkg);
-
- /**
* Updates a module m to open a package to all unnamed modules.
*/
void addOpensToAllUnnamed(Module m, String pkg);
@@ -103,11 +103,6 @@
void addUses(Module m, Class> service);
/**
- * Add a package to the given module.
- */
- void addPackage(Module m, String pkg);
-
- /**
* Returns the ServicesCatalog for the given Layer.
*/
ServicesCatalog getServicesCatalog(Layer layer);
@@ -123,12 +118,4 @@
* given class loader.
*/
Stream layers(ClassLoader loader);
-
- /**
- * Tests if a module exports a package at least {@code other} via its
- * module declaration.
- *
- * @apiNote This is a temporary method for debugging features.
- */
- boolean isStaticallyExported(Module module, String pn, Module other);
}
\ No newline at end of file
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/jdk/internal/module/Builder.java
--- a/jdk/src/java.base/share/classes/jdk/internal/module/Builder.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/Builder.java Wed Jul 05 23:09:40 2017 +0200
@@ -145,9 +145,6 @@
Set provides;
Version version;
String mainClass;
- String osName;
- String osArch;
- String osVersion;
Builder(String name) {
this.name = name;
@@ -248,30 +245,6 @@
}
/**
- * Sets the OS name.
- */
- public Builder osName(String name) {
- this.osName = name;
- return this;
- }
-
- /**
- * Sets the OS arch.
- */
- public Builder osArch(String arch) {
- this.osArch = arch;
- return this;
- }
-
- /**
- * Sets the OS version.
- */
- public Builder osVersion(String version) {
- this.osVersion = version;
- return this;
- }
-
- /**
* Returns an immutable set of the module modifiers derived from the flags.
*/
private Set modifiers() {
@@ -305,9 +278,6 @@
provides,
packages,
mainClass,
- osName,
- osArch,
- osVersion,
hashCode);
}
}
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/jdk/internal/module/Checks.java
--- a/jdk/src/java.base/share/classes/jdk/internal/module/Checks.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/Checks.java Wed Jul 05 23:09:40 2017 +0200
@@ -180,41 +180,38 @@
}
/**
- * Returns {@code true} if the last character of the given name is legal
- * as the last character of a module name.
- *
- * @throws IllegalArgumentException if name is empty
+ * Returns {@code true} if a given legal module name contains an identifier
+ * that doesn't end with a Java letter.
*/
- public static boolean hasLegalModuleNameLastCharacter(String name) {
- if (name.isEmpty())
- throw new IllegalArgumentException("name is empty");
- int len = name.length();
- if (isASCIIString(name)) {
- char c = name.charAt(len-1);
- return Character.isJavaIdentifierStart(c);
- } else {
- int i = 0;
- int cp = -1;
- while (i < len) {
- cp = name.codePointAt(i);
- i += Character.charCount(cp);
+ public static boolean hasJavaIdentifierWithTrailingDigit(String name) {
+ // quick scan to allow names that are just ASCII without digits
+ boolean needToParse = false;
+ int i = 0;
+ while (i < name.length()) {
+ int c = name.charAt(i);
+ if (c > 0x7F || (c >= '0' && c <= '9')) {
+ needToParse = true;
+ break;
}
- return Character.isJavaIdentifierStart(cp);
- }
- }
-
- /**
- * Returns true if the given string only contains ASCII characters.
- */
- private static boolean isASCIIString(String s) {
- int i = 0;
- while (i < s.length()) {
- int c = s.charAt(i);
- if (c > 0x7F)
- return false;
i++;
}
- return true;
+ if (!needToParse)
+ return false;
+
+ // slow path
+ int next;
+ int off = 0;
+ while ((next = name.indexOf('.', off)) != -1) {
+ int last = isJavaIdentifier(name, off, (next - off));
+ if (!Character.isJavaIdentifierStart(last))
+ return true;
+ off = next+1;
+ }
+ int last = isJavaIdentifier(name, off, name.length() - off);
+ if (!Character.isJavaIdentifierStart(last))
+ return true;
+ return false;
+
}
/**
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/jdk/internal/module/ClassFileAttributes.java
--- a/jdk/src/java.base/share/classes/jdk/internal/module/ClassFileAttributes.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ClassFileAttributes.java Wed Jul 05 23:09:40 2017 +0200
@@ -292,11 +292,11 @@
attr.putShort(module_flags);
// module_version
- Version v = descriptor.version().orElse(null);
- if (v == null) {
+ String vs = descriptor.rawVersion().orElse(null);
+ if (vs == null) {
attr.putShort(0);
} else {
- int module_version_index = cw.newUTF8(v.toString());
+ int module_version_index = cw.newUTF8(vs);
attr.putShort(module_version_index);
}
@@ -320,11 +320,11 @@
attr.putShort(requires_flags);
int requires_version_index;
- v = r.compiledVersion().orElse(null);
- if (v == null) {
+ vs = r.rawCompiledVersion().orElse(null);
+ if (vs == null) {
requires_version_index = 0;
} else {
- requires_version_index = cw.newUTF8(v.toString());
+ requires_version_index = cw.newUTF8(vs);
}
attr.putShort(requires_version_index);
}
@@ -553,8 +553,6 @@
* u2 os_name_index;
* // index to CONSTANT_utf8_info structure with the OS arch
* u2 os_arch_index
- * // index to CONSTANT_utf8_info structure with the OS version
- * u2 os_version_index;
* }
*
* }
@@ -562,17 +560,23 @@
public static class ModuleTargetAttribute extends Attribute {
private final String osName;
private final String osArch;
- private final String osVersion;
- public ModuleTargetAttribute(String osName, String osArch, String osVersion) {
+ public ModuleTargetAttribute(String osName, String osArch) {
super(MODULE_TARGET);
this.osName = osName;
this.osArch = osArch;
- this.osVersion = osVersion;
}
public ModuleTargetAttribute() {
- this(null, null, null);
+ this(null, null);
+ }
+
+ public String osName() {
+ return osName;
+ }
+
+ public String osArch() {
+ return osArch;
}
@Override
@@ -586,7 +590,6 @@
String osName = null;
String osArch = null;
- String osVersion = null;
int name_index = cr.readUnsignedShort(off);
if (name_index != 0)
@@ -598,12 +601,7 @@
osArch = cr.readUTF8(off, buf);
off += 2;
- int version_index = cr.readUnsignedShort(off);
- if (version_index != 0)
- osVersion = cr.readUTF8(off, buf);
- off += 2;
-
- return new ModuleTargetAttribute(osName, osArch, osVersion);
+ return new ModuleTargetAttribute(osName, osArch);
}
@Override
@@ -625,11 +623,6 @@
arch_index = cw.newUTF8(osArch);
attr.putShort(arch_index);
- int version_index = 0;
- if (osVersion != null && osVersion.length() > 0)
- version_index = cw.newUTF8(osVersion);
- attr.putShort(version_index);
-
return attr;
}
}
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/jdk/internal/module/IllegalAccessLogger.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/IllegalAccessLogger.java Wed Jul 05 23:09:40 2017 +0200
@@ -0,0 +1,345 @@
+/*
+ * Copyright (c) 2017, 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.module;
+
+import java.io.PrintStream;
+import java.lang.invoke.MethodHandles;
+import java.lang.reflect.Module;
+import java.net.URL;
+import java.security.AccessController;
+import java.security.CodeSource;
+import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.WeakHashMap;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
+
+import jdk.internal.loader.BootLoader;
+import sun.security.action.GetPropertyAction;
+
+/**
+ * Supports logging of access to members of API packages that are exported or
+ * opened via backdoor mechanisms to code in unnamed modules.
+ */
+
+public final class IllegalAccessLogger {
+
+ /**
+ * Holder class to lazily create the StackWalker object and determine
+ * if the stack trace should be printed
+ */
+ static class Holder {
+ static final StackWalker STACK_WALKER;
+ static final boolean PRINT_STACK_TRACE;
+
+ static {
+ PrivilegedAction pa = () ->
+ StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
+ STACK_WALKER = AccessController.doPrivileged(pa);
+
+ String name = "sun.reflect.debugModuleAccessChecks";
+ String value = GetPropertyAction.privilegedGetProperty(name, null);
+ PRINT_STACK_TRACE = "access" .equals(value);
+ }
+ }
+
+ // the maximum number of frames to capture
+ private static final int MAX_STACK_FRAMES = 32;
+
+ // lock to avoid interference when printing stack traces
+ private static final Object OUTPUT_LOCK = new Object();
+
+ // caller -> usages
+ private final Map, Set> callerToUsages = new WeakHashMap<>();
+
+ // module -> (package name -> CLI option)
+ private final Map> exported;
+ private final Map> opened;
+
+ // the print stream to send the warnings
+ private final PrintStream warningStream;
+
+ private IllegalAccessLogger(Map> exported,
+ Map> opened,
+ PrintStream warningStream) {
+ this.exported = deepCopy(exported);
+ this.opened = deepCopy(opened);
+ this.warningStream = warningStream;
+ }
+
+ /**
+ * Returns that a Builder that is seeded with the packages known to this logger.
+ */
+ public Builder toBuilder() {
+ return new Builder(exported, opened);
+ }
+
+ /**
+ * Logs access to the member of a target class by a caller class if the class
+ * is in a package that is exported via a backdoor mechanism.
+ *
+ * The {@code whatSupplier} supplies the message that describes the member.
+ */
+ public void logIfExportedByBackdoor(Class> caller,
+ Class> target,
+ Supplier whatSupplier) {
+ Map packages = exported.get(target.getModule());
+ if (packages != null) {
+ String how = packages.get(target.getPackageName());
+ if (how != null) {
+ log(caller, whatSupplier.get(), how);
+ }
+ }
+ }
+
+ /**
+ * Logs access to the member of a target class by a caller class if the class
+ * is in a package that is opened via a backdoor mechanism.
+ *
+ * The {@code what} parameter supplies the message that describes the member.
+ */
+ public void logIfOpenedByBackdoor(Class> caller,
+ Class> target,
+ Supplier whatSupplier) {
+ Map packages = opened.get(target.getModule());
+ if (packages != null) {
+ String how = packages.get(target.getPackageName());
+ if (how != null) {
+ log(caller, whatSupplier.get(), how);
+ }
+ }
+ }
+
+ /**
+ * Logs access by a caller class. The {@code what} parameter describes
+ * the member is accessed, the {@code how} parameter is the means by which
+ * access is allocated (CLI option for example).
+ */
+ private void log(Class> caller, String what, String how) {
+ log(caller, what, () -> {
+ PrivilegedAction pa = caller::getProtectionDomain;
+ CodeSource cs = AccessController.doPrivileged(pa).getCodeSource();
+ URL url = (cs != null) ? cs.getLocation() : null;
+ String source = caller.getName();
+ if (url != null)
+ source += " (" + url + ")";
+ return "WARNING: Illegal access by " + source + " to " + what
+ + " (permitted by " + how + ")";
+ });
+ }
+
+
+ /**
+ * Logs access to caller class if the class is in a package that is opened via
+ * a backdoor mechanism.
+ */
+ public void logIfOpenedByBackdoor(MethodHandles.Lookup caller, Class> target) {
+ Map packages = opened.get(target.getModule());
+ if (packages != null) {
+ String how = packages.get(target.getPackageName());
+ if (how != null) {
+ log(caller.lookupClass(), target.getName(), () ->
+ "WARNING: Illegal access using Lookup on " + caller.lookupClass()
+ + " to " + target + " (permitted by " + how + ")");
+ }
+ }
+ }
+
+ /**
+ * Log access by a caller. The {@code what} parameter describes the class or
+ * member that is being accessed. The {@code msgSupplier} supplies the log
+ * message.
+ *
+ * To reduce output, this method only logs the access if it hasn't been seen
+ * previously. "Seen previously" is implemented as a map of caller class -> Usage,
+ * where a Usage is the "what" and a hash of the stack trace. The map has weak
+ * keys so it can be expunged when the caller is GC'ed/unloaded.
+ */
+ private void log(Class> caller, String what, Supplier msgSupplier) {
+ // stack trace without the top-most frames in java.base
+ List stack = Holder.STACK_WALKER.walk(s ->
+ s.dropWhile(this::isJavaBase)
+ .limit(MAX_STACK_FRAMES)
+ .collect(Collectors.toList())
+ );
+
+ // check if the access has already been recorded
+ Usage u = new Usage(what, hash(stack));
+ boolean firstUsage;
+ synchronized (this) {
+ firstUsage = callerToUsages.computeIfAbsent(caller, k -> new HashSet<>()).add(u);
+ }
+
+ // log message if first usage
+ if (firstUsage) {
+ String msg = msgSupplier.get();
+ if (Holder.PRINT_STACK_TRACE) {
+ synchronized (OUTPUT_LOCK) {
+ warningStream.println(msg);
+ stack.forEach(f -> warningStream.println("\tat " + f));
+ }
+ } else {
+ warningStream.println(msg);
+ }
+ }
+ }
+
+ private static class Usage {
+ private final String what;
+ private final int stack;
+ Usage(String what, int stack) {
+ this.what = what;
+ this.stack = stack;
+ }
+ @Override
+ public int hashCode() {
+ return what.hashCode() ^ stack;
+ }
+ @Override
+ public boolean equals(Object ob) {
+ if (ob instanceof Usage) {
+ Usage that = (Usage)ob;
+ return what.equals(that.what) && stack == (that.stack);
+ } else {
+ return false;
+ }
+ }
+ }
+
+ /**
+ * Returns true if the stack frame is for a class in java.base.
+ */
+ private boolean isJavaBase(StackWalker.StackFrame frame) {
+ Module caller = frame.getDeclaringClass().getModule();
+ return "java.base".equals(caller.getName());
+ }
+
+ /**
+ * Computes a hash code for the give stack frames. The hash code is based
+ * on the class, method name, and BCI.
+ */
+ private int hash(List stack) {
+ int hash = 0;
+ for (StackWalker.StackFrame frame : stack) {
+ hash = (31 * hash) + Objects.hash(frame.getDeclaringClass(),
+ frame.getMethodName(),
+ frame.getByteCodeIndex());
+ }
+ return hash;
+ }
+
+ // system-wide IllegalAccessLogger
+ private static volatile IllegalAccessLogger logger;
+
+ /**
+ * Sets the system-wide IllegalAccessLogger
+ */
+ public static void setIllegalAccessLogger(IllegalAccessLogger l) {
+ if (l.exported.isEmpty() && l.opened.isEmpty()) {
+ logger = null;
+ } else {
+ logger = l;
+ }
+ }
+
+ /**
+ * Returns the system-wide IllegalAccessLogger or {@code null} if there is
+ * no logger.
+ */
+ public static IllegalAccessLogger illegalAccessLogger() {
+ return logger;
+ }
+
+ /**
+ * A builder for IllegalAccessLogger objects.
+ */
+ public static class Builder {
+ private final Module UNNAMED = BootLoader.getUnnamedModule();
+ private Map> exported;
+ private Map> opened;
+ private PrintStream warningStream = System.err;
+
+ public Builder() { }
+
+ public Builder(Map> exported,
+ Map> opened) {
+ this.exported = deepCopy(exported);
+ this.opened = deepCopy(opened);
+ }
+
+ public Builder logAccessToExportedPackage(Module m, String pn, String how) {
+ if (!m.isExported(pn, UNNAMED)) {
+ if (exported == null)
+ exported = new HashMap<>();
+ exported.computeIfAbsent(m, k -> new HashMap<>()).putIfAbsent(pn, how);
+ }
+ return this;
+ }
+
+ public Builder logAccessToOpenPackage(Module m, String pn, String how) {
+ // opens implies exported at run-time.
+ logAccessToExportedPackage(m, pn, how);
+
+ if (!m.isOpen(pn, UNNAMED)) {
+ if (opened == null)
+ opened = new HashMap<>();
+ opened.computeIfAbsent(m, k -> new HashMap<>()).putIfAbsent(pn, how);
+ }
+ return this;
+ }
+
+ public Builder warningStream(PrintStream warningStream) {
+ this.warningStream = Objects.requireNonNull(warningStream);
+ return this;
+ }
+
+ /**
+ * Builds the logger.
+ */
+ public IllegalAccessLogger build() {
+ return new IllegalAccessLogger(exported, opened, warningStream);
+ }
+ }
+
+
+ static Map> deepCopy(Map> map) {
+ if (map == null || map.isEmpty()) {
+ return new HashMap<>();
+ } else {
+ Map> newMap = new HashMap<>();
+ for (Map.Entry> e : map.entrySet()) {
+ newMap.put(e.getKey(), new HashMap<>(e.getValue()));
+ }
+ return newMap;
+ }
+ }
+}
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java
--- a/jdk/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java Wed Jul 05 23:09:40 2017 +0200
@@ -33,6 +33,7 @@
import java.lang.module.ModuleReference;
import java.lang.module.ResolvedModule;
import java.lang.reflect.Layer;
+import java.lang.reflect.LayerInstantiationException;
import java.lang.reflect.Module;
import java.net.URI;
import java.nio.file.Path;
@@ -46,7 +47,6 @@
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
-import java.util.stream.Stream;
import jdk.internal.loader.BootLoader;
import jdk.internal.loader.BuiltinClassLoader;
@@ -327,8 +327,9 @@
for (String p : descriptor.packages()) {
String other = packageToModule.putIfAbsent(p, name);
if (other != null) {
- fail("Package " + p + " in both module "
- + name + " and module " + other);
+ String msg = "Package " + p + " in both module "
+ + name + " and module " + other;
+ throw new LayerInstantiationException(msg);
}
}
}
@@ -359,7 +360,7 @@
PerfCounters.loadModulesTime.addElapsedTimeFrom(t5);
- // --add-reads, -add-exports/-add-opens
+ // --add-reads, --add-exports/--add-opens
addExtraReads(bootLayer);
addExtraExportsAndOpens(bootLayer);
@@ -514,7 +515,6 @@
* additional packages specified on the command-line.
*/
private static void addExtraExportsAndOpens(Layer bootLayer) {
-
// --add-exports
String prefix = "jdk.module.addexports.";
Map> extraExports = decode(prefix);
@@ -529,6 +529,23 @@
addExtraExportsOrOpens(bootLayer, extraOpens, true);
}
+ // --permit-illegal-access
+ if (getAndRemoveProperty("jdk.module.permitIllegalAccess") != null) {
+ warn("--permit-illegal-access will be removed in the next major release");
+ IllegalAccessLogger.Builder builder = new IllegalAccessLogger.Builder();
+ Module unnamed = BootLoader.getUnnamedModule();
+ bootLayer.modules().stream().forEach(m -> {
+ m.getDescriptor()
+ .packages()
+ .stream()
+ .filter(pn -> !m.isOpen(pn, unnamed)) // skip if opened by --add-opens
+ .forEach(pn -> {
+ builder.logAccessToOpenPackage(m, pn, "--permit-illegal-access");
+ Modules.addOpensToAllUnnamed(m, pn);
+ });
+ });
+ IllegalAccessLogger.setIllegalAccessLogger(builder.build());
+ }
}
private static void addExtraExportsOrOpens(Layer bootLayer,
@@ -542,12 +559,12 @@
String key = e.getKey();
String[] s = key.split("/");
if (s.length != 2)
- fail(unableToParse(option, "/", key));
+ fail(unableToParse(option, "/", key));
String mn = s[0];
String pn = s[1];
if (mn.isEmpty() || pn.isEmpty())
- fail(unableToParse(option, "/", key));
+ fail(unableToParse(option, "/", key));
// The exporting module is in the boot layer
Module m;
@@ -632,7 +649,7 @@
// value is (,)* or ()*
if (!allowDuplicates && map.containsKey(key))
- fail(key + " specified more than once in " + option(prefix));
+ fail(key + " specified more than once to " + option(prefix));
List values = map.computeIfAbsent(key, k -> new ArrayList<>());
int ntargets = 0;
for (String s : rhs.split(regex)) {
@@ -676,10 +693,6 @@
ModuleReference mref = rm.reference();
String mn = mref.descriptor().name();
- // emit warning if module name ends with a non-Java letter
- if (!Checks.hasLegalModuleNameLastCharacter(mn))
- warn("Module name \"" + mn + "\" may soon be illegal");
-
// emit warning if the WARN_INCUBATING module resolution bit set
if (ModuleResolution.hasIncubatingWarning(mref)) {
if (incubating == null) {
@@ -705,7 +718,7 @@
}
static void warnUnknownModule(String option, String mn) {
- warn("Unknown module: " + mn + " specified in " + option);
+ warn("Unknown module: " + mn + " specified to " + option);
}
static String unableToParse(String option, String text, String value) {
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/jdk/internal/module/ModuleInfo.java
--- a/jdk/src/java.base/share/classes/jdk/internal/module/ModuleInfo.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModuleInfo.java Wed Jul 05 23:09:40 2017 +0200
@@ -89,18 +89,24 @@
*/
public static final class Attributes {
private final ModuleDescriptor descriptor;
+ private final ModuleTarget target;
private final ModuleHashes recordedHashes;
private final ModuleResolution moduleResolution;
Attributes(ModuleDescriptor descriptor,
+ ModuleTarget target,
ModuleHashes recordedHashes,
ModuleResolution moduleResolution) {
this.descriptor = descriptor;
+ this.target = target;
this.recordedHashes = recordedHashes;
this.moduleResolution = moduleResolution;
}
public ModuleDescriptor descriptor() {
return descriptor;
}
+ public ModuleTarget target() {
+ return target;
+ }
public ModuleHashes recordedHashes() {
return recordedHashes;
}
@@ -221,8 +227,8 @@
Builder builder = null;
Set allPackages = null;
String mainClass = null;
- String[] osValues = null;
- ModuleHashes hashes = null;
+ ModuleTarget moduleTarget = null;
+ ModuleHashes moduelHashes = null;
ModuleResolution moduleResolution = null;
for (int i = 0; i < attributes_count ; i++) {
@@ -251,12 +257,12 @@
break;
case MODULE_TARGET :
- osValues = readModuleTargetAttribute(in, cpool);
+ moduleTarget = readModuleTargetAttribute(in, cpool);
break;
case MODULE_HASHES :
if (parseHashes) {
- hashes = readModuleHashesAttribute(in, cpool);
+ moduelHashes = readModuleHashesAttribute(in, cpool);
} else {
in.skipBytes(length);
}
@@ -282,15 +288,10 @@
throw invalidModuleDescriptor(MODULE + " attribute not found");
}
- // ModuleMainClass and ModuleTarget attributes
+ // ModuleMainClass attribute
if (mainClass != null) {
builder.mainClass(mainClass);
}
- if (osValues != null) {
- if (osValues[0] != null) builder.osName(osValues[0]);
- if (osValues[1] != null) builder.osArch(osValues[1]);
- if (osValues[2] != null) builder.osVersion(osValues[2]);
- }
// If the ModulePackages attribute is not present then the packageFinder
// is used to find the set of packages
@@ -323,7 +324,10 @@
}
ModuleDescriptor descriptor = builder.build();
- return new Attributes(descriptor, hashes, moduleResolution);
+ return new Attributes(descriptor,
+ moduleTarget,
+ moduelHashes,
+ moduleResolution);
}
/**
@@ -422,7 +426,11 @@
Set targets = new HashSet<>(exports_to_count);
for (int j=0; j targets = new HashSet<>(open_to_count);
for (int j=0; j cw.visitAttribute(new ModuleMainClassAttribute(mc)));
- // write ModuleTarget attribute if have any of OS name/arch/version
- String osName = md.osName().orElse(null);
- String osArch = md.osArch().orElse(null);
- String osVersion = md.osVersion().orElse(null);
- if (osName != null || osArch != null || osVersion != null) {
- cw.visitAttribute(new ModuleTargetAttribute(osName, osArch, osVersion));
+ // write ModuleTarget if there is a platform OS/arch
+ if (target != null) {
+ cw.visitAttribute(new ModuleTargetAttribute(target.osName(),
+ target.osArch()));
}
cw.visitEnd();
@@ -82,11 +80,23 @@
* Writes a module descriptor to the given output stream as a
* module-info.class.
*/
+ public static void write(ModuleDescriptor descriptor,
+ ModuleTarget target,
+ OutputStream out)
+ throws IOException
+ {
+ byte[] bytes = toModuleInfo(descriptor, target);
+ out.write(bytes);
+ }
+
+ /**
+ * Writes a module descriptor to the given output stream as a
+ * module-info.class.
+ */
public static void write(ModuleDescriptor descriptor, OutputStream out)
throws IOException
{
- byte[] bytes = toModuleInfo(descriptor);
- out.write(bytes);
+ write(descriptor, null, out);
}
/**
@@ -94,8 +104,7 @@
* in module-info.class format.
*/
public static ByteBuffer toByteBuffer(ModuleDescriptor descriptor) {
- byte[] bytes = toModuleInfo(descriptor);
+ byte[] bytes = toModuleInfo(descriptor, null);
return ByteBuffer.wrap(bytes);
}
-
}
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/jdk/internal/module/ModulePatcher.java
--- a/jdk/src/java.base/share/classes/jdk/internal/module/ModulePatcher.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModulePatcher.java Wed Jul 05 23:09:40 2017 +0200
@@ -55,7 +55,6 @@
import java.util.stream.Stream;
import jdk.internal.loader.Resource;
-import jdk.internal.loader.ResourceHelper;
import jdk.internal.misc.JavaLangModuleAccess;
import jdk.internal.misc.SharedSecrets;
import sun.net.www.ParseUtil;
@@ -165,9 +164,6 @@
descriptor.version().ifPresent(builder::version);
descriptor.mainClass().ifPresent(builder::mainClass);
- descriptor.osName().ifPresent(builder::osName);
- descriptor.osArch().ifPresent(builder::osArch);
- descriptor.osVersion().ifPresent(builder::osVersion);
// original + new packages
builder.packages(descriptor.packages());
@@ -179,10 +175,12 @@
// return a module reference to the patched module
URI location = mref.location().orElse(null);
+ ModuleTarget target = null;
ModuleHashes recordedHashes = null;
ModuleResolution mres = null;
if (mref instanceof ModuleReferenceImpl) {
ModuleReferenceImpl impl = (ModuleReferenceImpl)mref;
+ target = impl.moduleTarget();
recordedHashes = impl.recordedHashes();
mres = impl.moduleResolution();
}
@@ -191,6 +189,7 @@
location,
() -> new PatchedModuleReader(paths, mref),
this,
+ target,
recordedHashes,
null,
mres);
@@ -226,7 +225,7 @@
private volatile ModuleReader delegate;
/**
- * Creates the ModuleReader to reads resources a patched module.
+ * Creates the ModuleReader to reads resources in a patched module.
*/
PatchedModuleReader(List patches, ModuleReference mref) {
List finders = new ArrayList<>();
@@ -291,13 +290,16 @@
}
/**
- * Finds a resources in the patch locations. Returns null if not found.
+ * Finds a resources in the patch locations. Returns null if not found
+ * or the name is "module-info.class" as that cannot be overridden.
*/
private Resource findResourceInPatch(String name) throws IOException {
- for (ResourceFinder finder : finders) {
- Resource r = finder.find(name);
- if (r != null)
- return r;
+ if (!name.equals("module-info.class")) {
+ for (ResourceFinder finder : finders) {
+ Resource r = finder.find(name);
+ if (r != null)
+ return r;
+ }
}
return null;
}
@@ -478,9 +480,7 @@
@Override
public Stream list() throws IOException {
- return jf.stream()
- .filter(e -> !e.isDirectory())
- .map(JarEntry::getName);
+ return jf.stream().map(JarEntry::getName);
}
}
@@ -500,14 +500,12 @@
@Override
public Resource find(String name) throws IOException {
- Path path = ResourceHelper.toFilePath(name);
- if (path != null) {
- Path file = dir.resolve(path);
- if (Files.isRegularFile(file)) {
- return newResource(name, dir, file);
- }
+ Path file = Resources.toFilePath(dir, name);
+ if (file != null) {
+ return newResource(name, dir, file);
+ } else {
+ return null;
}
- return null;
}
private Resource newResource(String name, Path top, Path file) {
@@ -550,11 +548,9 @@
@Override
public Stream list() throws IOException {
- return Files.find(dir, Integer.MAX_VALUE,
- (path, attrs) -> attrs.isRegularFile())
- .map(f -> dir.relativize(f)
- .toString()
- .replace(File.separatorChar, '/'));
+ return Files.walk(dir, Integer.MAX_VALUE)
+ .map(f -> Resources.toResourceName(dir, f))
+ .filter(s -> s.length() > 0);
}
}
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/jdk/internal/module/ModulePath.java
--- a/jdk/src/java.base/share/classes/jdk/internal/module/ModulePath.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModulePath.java Wed Jul 05 23:09:40 2017 +0200
@@ -513,7 +513,7 @@
String pn = packageName(cn);
if (!packages.contains(pn)) {
String msg = "Provider class " + cn + " not in module";
- throw new IOException(msg);
+ throw new InvalidModuleDescriptorException(msg);
}
providerClasses.add(cn);
}
@@ -533,7 +533,7 @@
String pn = packageName(mainClass);
if (!packages.contains(pn)) {
String msg = "Main-Class " + mainClass + " not in module";
- throw new IOException(msg);
+ throw new InvalidModuleDescriptorException(msg);
}
builder.mainClass(mainClass);
}
@@ -609,11 +609,10 @@
// no module-info.class so treat it as automatic module
try {
ModuleDescriptor md = deriveModuleDescriptor(jf);
- attrs = new ModuleInfo.Attributes(md, null, null);
- } catch (IllegalArgumentException e) {
- throw new FindException(
- "Unable to derive module descriptor for: "
- + jf.getName(), e);
+ attrs = new ModuleInfo.Attributes(md, null, null, null);
+ } catch (RuntimeException e) {
+ throw new FindException("Unable to derive module descriptor for "
+ + jf.getName(), e);
}
} else {
@@ -672,18 +671,18 @@
/**
* Maps the name of an entry in a JAR or ZIP file to a package name.
*
- * @throws IllegalArgumentException if the name is a class file in
- * the top-level directory of the JAR/ZIP file (and it's
- * not module-info.class)
+ * @throws InvalidModuleDescriptorException if the name is a class file in
+ * the top-level directory of the JAR/ZIP file (and it's not
+ * module-info.class)
*/
private Optional toPackageName(String name) {
assert !name.endsWith("/");
int index = name.lastIndexOf("/");
if (index == -1) {
if (name.endsWith(".class") && !name.equals(MODULE_INFO)) {
- throw new IllegalArgumentException(name
- + " found in top-level directory"
- + " (unnamed package not allowed in module)");
+ String msg = name + " found in top-level directory"
+ + " (unnamed package not allowed in module)";
+ throw new InvalidModuleDescriptorException(msg);
}
return Optional.empty();
}
@@ -701,8 +700,8 @@
* Maps the relative path of an entry in an exploded module to a package
* name.
*
- * @throws IllegalArgumentException if the name is a class file in
- * the top-level directory (and it's not module-info.class)
+ * @throws InvalidModuleDescriptorException if the name is a class file in
+ * the top-level directory (and it's not module-info.class)
*/
private Optional toPackageName(Path file) {
assert file.getRoot() == null;
@@ -711,9 +710,9 @@
if (parent == null) {
String name = file.toString();
if (name.endsWith(".class") && !name.equals(MODULE_INFO)) {
- throw new IllegalArgumentException(name
- + " found in top-level directory"
- + " (unnamed package not allowed in module)");
+ String msg = name + " found in top-level directory"
+ + " (unnamed package not allowed in module)";
+ throw new InvalidModuleDescriptorException(msg);
}
return Optional.empty();
}
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/jdk/internal/module/ModuleReferenceImpl.java
--- a/jdk/src/java.base/share/classes/jdk/internal/module/ModuleReferenceImpl.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModuleReferenceImpl.java Wed Jul 05 23:09:40 2017 +0200
@@ -46,6 +46,9 @@
// non-null if the module is patched
private final ModulePatcher patcher;
+ // ModuleTarget if the module is OS/architecture specific
+ private final ModuleTarget target;
+
// the hashes of other modules recorded in this module
private final ModuleHashes recordedHashes;
@@ -65,6 +68,7 @@
URI location,
Supplier readerSupplier,
ModulePatcher patcher,
+ ModuleTarget target,
ModuleHashes recordedHashes,
ModuleHashes.HashSupplier hasher,
ModuleResolution moduleResolution)
@@ -72,6 +76,7 @@
super(descriptor, Objects.requireNonNull(location));
this.readerSupplier = readerSupplier;
this.patcher = patcher;
+ this.target = target;
this.recordedHashes = recordedHashes;
this.hasher = hasher;
this.moduleResolution = moduleResolution;
@@ -94,6 +99,13 @@
}
/**
+ * Returns the ModuleTarget or {@code null} if the no target platform.
+ */
+ public ModuleTarget moduleTarget() {
+ return target;
+ }
+
+ /**
* Returns the hashes recorded in this module or {@code null} if there
* are no hashes recorded.
*/
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/jdk/internal/module/ModuleReferences.java
--- a/jdk/src/java.base/share/classes/jdk/internal/module/ModuleReferences.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModuleReferences.java Wed Jul 05 23:09:40 2017 +0200
@@ -25,7 +25,6 @@
package jdk.internal.module;
-import java.io.File;
import java.io.IOError;
import java.io.IOException;
import java.io.InputStream;
@@ -50,7 +49,6 @@
import java.util.zip.ZipFile;
import jdk.internal.jmod.JmodFile;
-import jdk.internal.loader.ResourceHelper;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.module.ModuleHashes.HashSupplier;
import jdk.internal.util.jar.VersionedStream;
@@ -78,6 +76,7 @@
uri,
supplier,
null,
+ attrs.target(),
attrs.recordedHashes(),
hasher,
attrs.moduleResolution());
@@ -242,8 +241,7 @@
}
private JarEntry getEntry(String name) {
- JarEntry entry = jf.getJarEntry(Objects.requireNonNull(name));
- return (entry == null || entry.isDirectory()) ? null : entry;
+ return jf.getJarEntry(Objects.requireNonNull(name));
}
@Override
@@ -252,6 +250,8 @@
if (je != null) {
if (jf.isMultiRelease())
name = SharedSecrets.javaUtilJarAccess().getRealName(jf, je);
+ if (je.isDirectory() && !name.endsWith("/"))
+ name += "/";
String encodedPath = ParseUtil.encodePath(name, false);
String uris = "jar:" + uri + "!/" + encodedPath;
return Optional.of(URI.create(uris));
@@ -274,7 +274,6 @@
Stream implList() throws IOException {
// take snapshot to avoid async close
List names = VersionedStream.stream(jf)
- .filter(e -> !e.isDirectory())
.map(JarEntry::getName)
.collect(Collectors.toList());
return names.stream();
@@ -316,6 +315,8 @@
Optional implFind(String name) {
JmodFile.Entry je = getEntry(name);
if (je != null) {
+ if (je.isDirectory() && !name.endsWith("/"))
+ name += "/";
String encodedPath = ParseUtil.encodePath(name, false);
String uris = "jmod:" + uri + "!/" + encodedPath;
return Optional.of(URI.create(uris));
@@ -376,26 +377,10 @@
if (closed) throw new IOException("ModuleReader is closed");
}
- /**
- * Returns a Path to access the given resource. Returns null if the
- * resource name does not convert to a file path that locates a regular
- * file in the module.
- */
- private Path toFilePath(String name) {
- Path path = ResourceHelper.toFilePath(name);
- if (path != null) {
- Path file = dir.resolve(path);
- if (Files.isRegularFile(file)) {
- return file;
- }
- }
- return null;
- }
-
@Override
public Optional find(String name) throws IOException {
ensureOpen();
- Path path = toFilePath(name);
+ Path path = Resources.toFilePath(dir, name);
if (path != null) {
try {
return Optional.of(path.toUri());
@@ -410,7 +395,7 @@
@Override
public Optional open(String name) throws IOException {
ensureOpen();
- Path path = toFilePath(name);
+ Path path = Resources.toFilePath(dir, name);
if (path != null) {
return Optional.of(Files.newInputStream(path));
} else {
@@ -421,7 +406,7 @@
@Override
public Optional read(String name) throws IOException {
ensureOpen();
- Path path = toFilePath(name);
+ Path path = Resources.toFilePath(dir, name);
if (path != null) {
return Optional.of(ByteBuffer.wrap(Files.readAllBytes(path)));
} else {
@@ -432,12 +417,9 @@
@Override
public Stream list() throws IOException {
ensureOpen();
- // sym links not followed
- return Files.find(dir, Integer.MAX_VALUE,
- (path, attrs) -> attrs.isRegularFile())
- .map(f -> dir.relativize(f)
- .toString()
- .replace(File.separatorChar, '/'));
+ return Files.walk(dir, Integer.MAX_VALUE)
+ .map(f -> Resources.toResourceName(dir, f))
+ .filter(s -> s.length() > 0);
}
@Override
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/jdk/internal/module/ModuleTarget.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModuleTarget.java Wed Jul 05 23:09:40 2017 +0200
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2017, 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.module;
+
+public final class ModuleTarget {
+
+ private final String osName;
+ private final String osArch;
+
+ public ModuleTarget(String osName, String osArch) {
+ this.osName = osName;
+ this.osArch = osArch;
+ }
+
+ public String osName() {
+ return osName;
+ }
+
+ public String osArch() {
+ return osArch;
+ }
+
+}
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/jdk/internal/module/Modules.java
--- a/jdk/src/java.base/share/classes/jdk/internal/module/Modules.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/Modules.java Wed Jul 05 23:09:40 2017 +0200
@@ -31,7 +31,6 @@
import java.net.URI;
import java.security.AccessController;
import java.security.PrivilegedAction;
-import java.util.Set;
import jdk.internal.loader.BootLoader;
import jdk.internal.loader.ClassLoaders;
@@ -39,10 +38,10 @@
import jdk.internal.misc.SharedSecrets;
/**
- * A helper class to allow JDK classes create dynamic modules and to update
- * modules, exports and the readability graph. It is also invoked by the VM
- * to add read edges when agents are instrumenting code that need to link
- * to supporting classes.
+ * A helper class for creating and updating modules. This class is intended to
+ * support command-line options, tests, and the instrumentation API. It is also
+ * used by the VM to add read edges when agents are instrumenting code that
+ * need to link to supporting classes.
*
* The parameters that are package names in this API are the fully-qualified
* names of the packages as defined in section 6.5.3 of The Java™
@@ -72,25 +71,7 @@
}
/**
- * Define a new module to the VM. The module has the given set of
- * packages and is defined to the given class loader.
- *
- * The resulting Module is in a larval state in that it does not not read
- * any other module and does not have any exports.
- */
- public static Module defineModule(ClassLoader loader,
- String name,
- Set packages)
- {
- ModuleDescriptor descriptor = ModuleDescriptor.newModule(name)
- .packages(packages)
- .build();
-
- return JLRMA.defineModule(loader, descriptor, null);
- }
-
- /**
- * Adds a read-edge so that module {@code m1} reads module {@code m1}.
+ * Updates m1 to read m2.
* Same as m1.addReads(m2) but without a caller check.
*/
public static void addReads(Module m1, Module m2) {
@@ -98,21 +79,46 @@
}
/**
- * Update module {@code m} to read all unnamed modules.
+ * Update module m to read all unnamed modules.
*/
public static void addReadsAllUnnamed(Module m) {
JLRMA.addReadsAllUnnamed(m);
}
/**
+ * Update module m to export a package to all modules.
+ *
+ * This method is for intended for use by tests only.
+ */
+ public static void addExports(Module m, String pn) {
+ JLRMA.addExports(m, pn);
+ }
+
+ /**
* Updates module m1 to export a package to module m2.
- * Same as m1.addExports(pn, m2) but without a caller check.
+ * Same as m1.addExports(pn, m2) but without a caller check
*/
public static void addExports(Module m1, String pn, Module m2) {
JLRMA.addExports(m1, pn, m2);
}
/**
+ * Updates module m to export a package to all unnamed modules.
+ */
+ public static void addExportsToAllUnnamed(Module m, String pn) {
+ JLRMA.addExportsToAllUnnamed(m, pn);
+ }
+
+ /**
+ * Update module m to open a package to all modules.
+ *
+ * This method is for intended for use by tests only.
+ */
+ public static void addOpens(Module m, String pn) {
+ JLRMA.addOpens(m, pn);
+ }
+
+ /**
* Updates module m1 to open a package to module m2.
* Same as m1.addOpens(pn, m2) but without a caller check.
*/
@@ -121,27 +127,6 @@
}
/**
- * Updates a module m to export a package to all modules.
- */
- public static void addExportsToAll(Module m, String pn) {
- JLRMA.addExportsToAll(m, pn);
- }
-
- /**
- * Updates a module m to open a package to all modules.
- */
- public static void addOpensToAll(Module m, String pn) {
- JLRMA.addOpensToAll(m, pn);
- }
-
- /**
- * Updates module m to export a package to all unnamed modules.
- */
- public static void addExportsToAllUnnamed(Module m, String pn) {
- JLRMA.addExportsToAllUnnamed(m, pn);
- }
-
- /**
* Updates module m to open a package to all unnamed modules.
*/
public static void addOpensToAllUnnamed(Module m, String pn) {
@@ -149,7 +134,8 @@
}
/**
- * Updates module m to use a service
+ * Updates module m to use a service.
+ * Same as m2.addUses(service) but without a caller check.
*/
public static void addUses(Module m, Class> service) {
JLRMA.addUses(m, service);
@@ -183,16 +169,6 @@
}
/**
- * Adds a package to a module's content.
- *
- * This method is a no-op if the module already contains the package or the
- * module is an unnamed module.
- */
- public static void addPackage(Module m, String pn) {
- JLRMA.addPackage(m, pn);
- }
-
- /**
* Called by the VM when code in the given Module has been transformed by
* an agent and so may have been instrumented to call into supporting
* classes on the boot class path or application class path.
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/jdk/internal/module/Resources.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/Resources.java Wed Jul 05 23:09:40 2017 +0200
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2016, 2017, 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.module;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.NoSuchFileException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.attribute.BasicFileAttributes;
+
+/**
+ * A helper class to support working with resources in modules. Also provides
+ * support for translating resource names to file paths.
+ */
+public final class Resources {
+ private Resources() { }
+
+ /**
+ * Return true if a resource can be encapsulated. Resource with names
+ * ending in ".class" or "/" cannot be encapsulated. Resource names
+ * that map to a legal package name can be encapsulated.
+ */
+ public static boolean canEncapsulate(String name) {
+ int len = name.length();
+ if (len > 6 && name.endsWith(".class")) {
+ return false;
+ } else {
+ return Checks.isPackageName(toPackageName(name));
+ }
+ }
+
+ /**
+ * Derive a package name for a resource. The package name
+ * returned by this method may not be a legal package name. This method
+ * returns null if the the resource name ends with a "/" (a directory)
+ * or the resource name does not contain a "/".
+ */
+ public static String toPackageName(String name) {
+ int index = name.lastIndexOf('/');
+ if (index == -1 || index == name.length()-1) {
+ return "";
+ } else {
+ return name.substring(0, index).replace("/", ".");
+ }
+ }
+
+ /**
+ * Returns a resource name corresponding to the relative file path
+ * between {@code dir} and {@code file}. If the file is a directory
+ * then the name will end with a "/", except the top-level directory
+ * where the empty string is returned.
+ */
+ public static String toResourceName(Path dir, Path file) {
+ String s = dir.relativize(file)
+ .toString()
+ .replace(File.separatorChar, '/');
+ if (s.length() > 0 && Files.isDirectory(file))
+ s += "/";
+ return s;
+ }
+
+ /**
+ * Returns a file path to a resource in a file tree. If the resource
+ * name has a trailing "/" then the file path will locate a directory.
+ * Returns {@code null} if the resource does not map to a file in the
+ * tree file.
+ */
+ public static Path toFilePath(Path dir, String name) throws IOException {
+ boolean expectDirectory = name.endsWith("/");
+ if (expectDirectory) {
+ name = name.substring(0, name.length() - 1); // drop trailing "/"
+ }
+ Path path = toSafeFilePath(name);
+ if (path != null) {
+ Path file = dir.resolve(path);
+ try {
+ BasicFileAttributes attrs;
+ attrs = Files.readAttributes(file, BasicFileAttributes.class);
+ if (attrs.isDirectory()
+ || (!attrs.isDirectory() && !expectDirectory))
+ return file;
+ } catch (NoSuchFileException ignore) { }
+ }
+ return null;
+ }
+
+ /**
+ * Map a resource name to a "safe" file path. Returns {@code null} if
+ * the resource name cannot be converted into a "safe" file path.
+ *
+ * Resource names with empty elements, or elements that are "." or ".."
+ * are rejected, as are resource names that translates to a file path
+ * with a root component.
+ */
+ private static Path toSafeFilePath(String name) {
+ // scan elements of resource name
+ int next;
+ int off = 0;
+ while ((next = name.indexOf('/', off)) != -1) {
+ int len = next - off;
+ if (!mayTranslate(name, off, len)) {
+ return null;
+ }
+ off = next + 1;
+ }
+ int rem = name.length() - off;
+ if (!mayTranslate(name, off, rem)) {
+ return null;
+ }
+
+ // convert to file path
+ Path path;
+ if (File.separatorChar == '/') {
+ path = Paths.get(name);
+ } else {
+ // not allowed to embed file separators
+ if (name.contains(File.separator))
+ return null;
+ path = Paths.get(name.replace('/', File.separatorChar));
+ }
+
+ // file path not allowed to have root component
+ return (path.getRoot() == null) ? path : null;
+ }
+
+ /**
+ * Returns {@code true} if the element in a resource name is a candidate
+ * to translate to the element of a file path.
+ */
+ private static boolean mayTranslate(String name, int off, int len) {
+ if (len <= 2) {
+ if (len == 0)
+ return false;
+ boolean starsWithDot = (name.charAt(off) == '.');
+ if (len == 1 && starsWithDot)
+ return false;
+ if (len == 2 && starsWithDot && (name.charAt(off+1) == '.'))
+ return false;
+ }
+ return true;
+ }
+
+}
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/jdk/internal/module/SystemModuleFinder.java
--- a/jdk/src/java.base/share/classes/jdk/internal/module/SystemModuleFinder.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/SystemModuleFinder.java Wed Jul 05 23:09:40 2017 +0200
@@ -150,18 +150,21 @@
System.getProperty("jdk.system.module.finder.disabledFastPath") != null;
ModuleDescriptor[] descriptors;
+ ModuleTarget[] targets;
ModuleHashes[] recordedHashes;
ModuleResolution[] moduleResolutions;
// fast loading of ModuleDescriptor of system modules
if (isFastPathSupported() && !disabled) {
descriptors = SystemModules.descriptors();
+ targets = SystemModules.targets();
recordedHashes = SystemModules.hashes();
moduleResolutions = SystemModules.moduleResolutions();
} else {
// if fast loading of ModuleDescriptors is disabled
// fallback to read module-info.class
descriptors = new ModuleDescriptor[n];
+ targets = new ModuleTarget[n];
recordedHashes = new ModuleHashes[n];
moduleResolutions = new ModuleResolution[n];
ImageReader imageReader = SystemImage.reader();
@@ -171,6 +174,7 @@
ModuleInfo.Attributes attrs =
ModuleInfo.read(imageReader.getResourceBuffer(loc), null);
descriptors[i] = attrs.descriptor();
+ targets[i] = attrs.target();
recordedHashes[i] = attrs.recordedHashes();
moduleResolutions[i] = attrs.moduleResolution();
}
@@ -206,6 +210,7 @@
// create the ModuleReference
ModuleReference mref = toModuleReference(md,
+ targets[i],
recordedHashes[i],
hashSupplier(names[i]),
moduleResolutions[i]);
@@ -233,6 +238,7 @@
}
private ModuleReference toModuleReference(ModuleDescriptor md,
+ ModuleTarget target,
ModuleHashes recordedHashes,
HashSupplier hasher,
ModuleResolution mres) {
@@ -246,9 +252,14 @@
}
};
- ModuleReference mref =
- new ModuleReferenceImpl(md, uri, readerSupplier, null,
- recordedHashes, hasher, mres);
+ ModuleReference mref = new ModuleReferenceImpl(md,
+ uri,
+ readerSupplier,
+ null,
+ target,
+ recordedHashes,
+ hasher,
+ mres);
// may need a reference to a patched module if --patch-module specified
mref = ModuleBootstrap.patcher().patchIfNeeded(mref);
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/jdk/internal/module/SystemModules.java
--- a/jdk/src/java.base/share/classes/jdk/internal/module/SystemModules.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/SystemModules.java Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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,7 +27,7 @@
import java.lang.module.ModuleDescriptor;
-/*
+/**
* SystemModules class will be generated at link time to create
* ModuleDescriptor for the system modules directly to improve
* the module descriptor reconstitution time.
@@ -65,7 +65,7 @@
}
/**
- * Returns a non-empty array of ModuleDescriptors in the run-time image.
+ * Returns a non-empty array of ModuleDescriptor objects in the run-time image.
*
* When running an exploded image it returns an empty array.
*/
@@ -74,6 +74,15 @@
}
/**
+ * Returns a non-empty array of ModuleTarget objects in the run-time image.
+ *
+ * When running an exploded image it returns an empty array.
+ */
+ public static ModuleTarget[] targets() {
+ throw new InternalError("expected to be overridden at link time");
+ }
+
+ /**
* Returns a non-empty array of ModuleHashes recorded in each module
* in the run-time image.
*
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassReader.java
--- a/jdk/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassReader.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassReader.java Wed Jul 05 23:09:40 2017 +0200
@@ -2508,7 +2508,7 @@
}
/**
- * Reads a CONSTANT_Pakcage_info item in {@code b}. This method is
+ * Reads a CONSTANT_Package_info item in {@code b}. This method is
* intended for {@link Attribute} sub slasses, and is normally not needed
* by class generators or adapters.
*
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/jdk/internal/reflect/Reflection.java
--- a/jdk/src/java.base/share/classes/jdk/internal/reflect/Reflection.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/reflect/Reflection.java Wed Jul 05 23:09:40 2017 +0200
@@ -31,9 +31,7 @@
import java.util.Map;
import java.util.Objects;
import jdk.internal.HotSpotIntrinsicCandidate;
-import jdk.internal.misc.SharedSecrets;
import jdk.internal.misc.VM;
-import sun.security.action.GetPropertyAction;
/** Common utility routines used by both java.lang and
java.lang.reflect */
@@ -104,39 +102,40 @@
int modifiers)
throws IllegalAccessException
{
- if (currentClass == null || memberClass == null) {
- throw new InternalError();
- }
-
if (!verifyMemberAccess(currentClass, memberClass, targetClass, modifiers)) {
- throwIllegalAccessException(currentClass, memberClass, targetClass, modifiers);
+ throw newIllegalAccessException(currentClass, memberClass, targetClass, modifiers);
}
}
/**
- * Verify access to a member, returning {@code false} if no access
+ * Verify access to a member and return {@code true} if it is granted.
+ *
+ * @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
+ * @return {@code true} if access to member is granted
*/
public 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
- // "modifiers".
-
- boolean gotIsSameClassPackage = false;
- boolean isSameClassPackage = false;
-
if (currentClass == memberClass) {
// Always succeeds
return true;
}
- if (!verifyModuleAccess(currentClass, memberClass)) {
+ if (!verifyModuleAccess(currentClass.getModule(), memberClass)) {
return false;
}
+ boolean gotIsSameClassPackage = false;
+ boolean isSameClassPackage = false;
+
if (!Modifier.isPublic(getClassAccessFlags(memberClass))) {
isSameClassPackage = isSameClassPackage(currentClass, memberClass);
gotIsSameClassPackage = true;
@@ -196,31 +195,20 @@
}
/**
- * Returns {@code true} if memberClass's's module exports memberClass's
- * package to currentClass's module.
+ * Returns {@code true} if memberClass's module exports memberClass's
+ * package to currentModule.
*/
- public static boolean verifyModuleAccess(Class> currentClass,
- Class> memberClass) {
- return verifyModuleAccess(currentClass.getModule(), memberClass);
- }
-
public static boolean verifyModuleAccess(Module currentModule, Class> memberClass) {
Module memberModule = memberClass.getModule();
-
- // module may be null during startup (initLevel 0)
- if (currentModule == memberModule)
- return true; // same module (named or unnamed)
-
- String pkg = memberClass.getPackageName();
- boolean allowed = memberModule.isExported(pkg, currentModule);
- if (allowed && memberModule.isNamed() && printStackTraceWhenAccessSucceeds()) {
- if (!SharedSecrets.getJavaLangReflectModuleAccess()
- .isStaticallyExported(memberModule, pkg, currentModule)) {
- String msg = currentModule + " allowed access to member of " + memberClass;
- new Exception(msg).printStackTrace(System.err);
- }
+ if (currentModule == memberModule) {
+ // same module (named or unnamed) or both null if called
+ // before module system is initialized, which means we are
+ // dealing with java.base only.
+ return true;
+ } else {
+ String pkg = memberClass.getPackageName();
+ return memberModule.isExported(pkg, currentModule);
}
- return allowed;
}
/**
@@ -344,46 +332,14 @@
return false;
}
-
- // true to print a stack trace when access fails
- private static volatile boolean printStackWhenAccessFails;
-
- // true to print a stack trace when access succeeds
- private static volatile boolean printStackWhenAccessSucceeds;
-
- // true if printStack* values are initialized
- private static volatile boolean printStackPropertiesSet;
-
- private static void ensurePrintStackPropertiesSet() {
- if (!printStackPropertiesSet && VM.initLevel() >= 1) {
- String s = GetPropertyAction.privilegedGetProperty(
- "sun.reflect.debugModuleAccessChecks");
- if (s != null) {
- printStackWhenAccessFails = !s.equalsIgnoreCase("false");
- printStackWhenAccessSucceeds = s.equalsIgnoreCase("access");
- }
- printStackPropertiesSet = true;
- }
- }
-
- public static boolean printStackTraceWhenAccessFails() {
- ensurePrintStackPropertiesSet();
- return printStackWhenAccessFails;
- }
-
- public static boolean printStackTraceWhenAccessSucceeds() {
- ensurePrintStackPropertiesSet();
- return printStackWhenAccessSucceeds;
- }
-
/**
- * Throws IllegalAccessException with the an exception message based on
+ * Returns an IllegalAccessException with an exception message based on
* the access that is denied.
*/
- private static void throwIllegalAccessException(Class> currentClass,
- Class> memberClass,
- Object target,
- int modifiers)
+ public static IllegalAccessException newIllegalAccessException(Class> currentClass,
+ Class> memberClass,
+ Class> targetClass,
+ int modifiers)
throws IllegalAccessException
{
String currentSuffix = "";
@@ -411,20 +367,6 @@
if (m2.isNamed()) msg += " to " + m1;
}
- throwIllegalAccessException(msg);
- }
-
- /**
- * Throws IllegalAccessException with the given exception message.
- */
- public static void throwIllegalAccessException(String msg)
- throws IllegalAccessException
- {
- IllegalAccessException e = new IllegalAccessException(msg);
- ensurePrintStackPropertiesSet();
- if (printStackWhenAccessFails) {
- e.printStackTrace(System.err);
- }
- throw e;
+ return new IllegalAccessException(msg);
}
}
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java
--- a/jdk/src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2017, 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
@@ -44,6 +44,7 @@
import java.util.Objects;
import java.util.Properties;
+import jdk.internal.misc.VM;
import sun.reflect.misc.ReflectUtil;
import sun.security.action.GetPropertyAction;
@@ -585,17 +586,10 @@
private static void checkInitted() {
if (initted) return;
- // Tests to ensure the system properties table is fully
- // initialized. This is needed because reflection code is
- // called very early in the initialization process (before
- // command-line arguments have been parsed and therefore
- // these user-settable properties installed.) We assume that
- // if System.out is non-null then the System class has been
- // fully initialized and that the bulk of the startup code
- // has been run.
-
- if (System.out == null) {
- // java.lang.System not yet fully initialized
+ // Defer initialization until module system is initialized so as
+ // to avoid inflation and spinning bytecode in unnamed modules
+ // during early startup.
+ if (!VM.isModuleSystemInited()) {
return;
}
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/module-info.java
--- a/jdk/src/java.base/share/classes/module-info.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/module-info.java Wed Jul 05 23:09:40 2017 +0200
@@ -26,6 +26,7 @@
/**
* Defines the foundational APIs of the Java SE Platform.
*
+ * @moduleGraph
* @since 9
*/
module java.base {
@@ -125,10 +126,9 @@
jdk.jlink;
exports jdk.internal.loader to
java.instrument,
- java.logging,
- jdk.jlink;
+ java.logging;
exports jdk.internal.jmod to
- jdk.compiler,
+ jdk.compiler, // reflective dependency
jdk.jlink;
exports jdk.internal.logger to
java.logging;
@@ -140,10 +140,7 @@
exports jdk.internal.org.objectweb.asm.tree to
jdk.jlink;
exports jdk.internal.org.objectweb.asm.util to
- jdk.jlink,
jdk.scripting.nashorn;
- exports jdk.internal.org.objectweb.asm.tree.analysis to
- jdk.jlink;
exports jdk.internal.org.objectweb.asm.commons to
jdk.scripting.nashorn;
exports jdk.internal.org.objectweb.asm.signature to
@@ -157,7 +154,6 @@
jdk.jlink;
exports jdk.internal.misc to
java.desktop,
- jdk.incubator.httpclient,
java.logging,
java.management,
java.naming,
@@ -166,8 +162,8 @@
java.sql,
java.xml,
jdk.charsets,
- jdk.compiler,
- jdk.jartool,
+ jdk.compiler, // reflective dependency
+ jdk.incubator.httpclient,
jdk.jdeps,
jdk.jlink,
jdk.jshell,
@@ -210,11 +206,10 @@
jdk.naming.dns;
exports sun.net.util to
java.desktop,
- jdk.jconsole,
- jdk.naming.dns;
+ jdk.jconsole;
exports sun.net.www to
+ java.desktop,
jdk.incubator.httpclient,
- java.desktop,
jdk.jartool;
exports sun.net.www.protocol.http to
java.security.jgss;
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/sun/launcher/LauncherHelper.java
--- a/jdk/src/java.base/share/classes/sun/launcher/LauncherHelper.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/sun/launcher/LauncherHelper.java Wed Jul 05 23:09:40 2017 +0200
@@ -428,7 +428,7 @@
abort(null, "java.launcher.jar.error3", jarname);
}
- // Add-Exports and Add-Opens to break encapsulation
+ // Add-Exports and Add-Opens
String exports = mainAttrs.getValue(ADD_EXPORTS);
if (exports != null) {
addExportsOrOpens(exports, false);
@@ -466,6 +466,7 @@
if (s.length == 2) {
String mn = s[0];
String pn = s[1];
+
Layer.boot().findModule(mn).ifPresent(m -> {
if (m.getDescriptor().packages().contains(pn)) {
if (open) {
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/sun/launcher/resources/launcher.properties
--- a/jdk/src/java.base/share/classes/sun/launcher/resources/launcher.properties Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/sun/launcher/resources/launcher.properties Wed Jul 05 23:09:40 2017 +0200
@@ -24,12 +24,15 @@
#
# Translators please note do not translate the options themselves
-java.launcher.opt.header = Usage: {0} [options] class [args...]\n\
-\ (to execute a class)\n or {0} [options] -jar jarfile [args...]\n\
+java.launcher.opt.header = Usage: {0} [options] [args...]\n\
+\ (to execute a class)\n or {0} [options] -jar [args...]\n\
\ (to execute a jar file)\n\
-\ or {0} [options] -p -m [/] [args...]\n\
+\ or {0} [options] -m [/] [args...]\n\
+\ {0} [options] --module [/] [args...]\n\
\ (to execute the main class in a module)\n\n\
-where options include:\n\n
+\ Arguments following the main class, -jar , -m or --module\n\
+\ / are passed as the arguments to main class.\n\n\
+\ where options include:\n\n
java.launcher.opt.datamodel =\ -d{0}\t Deprecated, will be removed in a future release\n
java.launcher.opt.vmselect =\ {0}\t to select the "{1}" VM\n
@@ -49,10 +52,6 @@
\ A {0} separated list of directories, each directory\n\
\ is a directory of modules that replace upgradeable\n\
\ modules in the runtime image\n\
-\ -m [/]\n\
-\ --module [/]\n\
-\ the initial module to resolve, and the name of the main class\n\
-\ to execute if not specified by the module\n\
\ --add-modules [,...]\n\
\ root modules to resolve in addition to the initial module.\n\
\ can also be ALL-DEFAULT, ALL-SYSTEM,\n\
@@ -129,7 +128,7 @@
\ -Xms set initial Java heap size\n\
\ -Xmx set maximum Java heap size\n\
\ -Xnoclassgc disable class garbage collection\n\
-\ -Xprof output cpu profiling data\n\
+\ -Xprof output cpu profiling data (deprecated)\n\
\ -Xrs reduce use of OS signals by Java/VM (see documentation)\n\
\ -Xshare:auto use shared class data if possible (default)\n\
\ -Xshare:off do not attempt to use shared class data\n\
@@ -157,6 +156,10 @@
\ --add-opens /=(,)*\n\
\ updates to open to\n\
\ , regardless of module declaration.\n\
+\ --permit-illegal-access\n\
+\ permit illegal access to members of types in named modules\n\
+\ by code in unnamed modules. This compatibility option will\n\
+\ be removed in the next release.\n\
\ --disable-@files disable further argument file expansion\n\
\ --patch-module =({0})*\n\
\ Override or augment a module with classes and resources\n\
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/sun/net/www/protocol/jrt/JavaRuntimeURLConnection.java
--- a/jdk/src/java.base/share/classes/sun/net/www/protocol/jrt/JavaRuntimeURLConnection.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/jrt/JavaRuntimeURLConnection.java Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,8 +26,6 @@
package sun.net.www.protocol.jrt;
import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FilePermission;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
@@ -44,7 +42,6 @@
import jdk.internal.loader.Resource;
import sun.net.www.ParseUtil;
import sun.net.www.URLConnection;
-import sun.security.action.GetPropertyAction;
/**
* URLConnection implementation that can be used to connect to resources
@@ -66,9 +63,6 @@
// the Resource when connected
private volatile Resource resource;
- // the permission to access resources in the runtime image, created lazily
- private static volatile Permission permission;
-
JavaRuntimeURLConnection(URL url) throws IOException {
super(url);
String path = url.getPath();
@@ -164,14 +158,8 @@
}
@Override
- public Permission getPermission() throws IOException {
- Permission p = permission;
- if (p == null) {
- String home = GetPropertyAction.privilegedGetProperty("java.home");
- p = new FilePermission(home + File.separator + "-", "read");
- permission = p;
- }
- return p;
+ public Permission getPermission() {
+ return new RuntimePermission("accessSystemModules");
}
/**
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/sun/security/provider/certpath/RevocationChecker.java
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/RevocationChecker.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/RevocationChecker.java Wed Jul 05 23:09:40 2017 +0200
@@ -986,9 +986,7 @@
// any way to convey them back to the application.
// That's the default, so no need to write code.
builderParams.setDate(params.date());
- // CertPathCheckers need to be cloned to start from fresh state
- builderParams.setCertPathCheckers(
- params.getPKIXParameters().getCertPathCheckers());
+ builderParams.setCertPathCheckers(params.certPathCheckers());
builderParams.setSigProvider(params.sigProvider());
// Skip revocation during this build to detect circular
@@ -1116,15 +1114,6 @@
}
}
- @Override
- public RevocationChecker clone() {
- RevocationChecker copy = (RevocationChecker)super.clone();
- // we don't deep-copy the exceptions, but that is ok because they
- // are never modified after they are instantiated
- copy.softFailExceptions = new LinkedList<>(softFailExceptions);
- return copy;
- }
-
/*
* This inner class extends the X509CertSelector to add an additional
* check to make sure the subject public key isn't on a particular list.
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/sun/security/rsa/RSAPrivateCrtKeyImpl.java
--- a/jdk/src/java.base/share/classes/sun/security/rsa/RSAPrivateCrtKeyImpl.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/rsa/RSAPrivateCrtKeyImpl.java Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -191,14 +191,22 @@
if (version != 0) {
throw new IOException("Version must be 0");
}
- n = getBigInteger(data);
- e = getBigInteger(data);
- d = getBigInteger(data);
- p = getBigInteger(data);
- q = getBigInteger(data);
- pe = getBigInteger(data);
- qe = getBigInteger(data);
- coeff = getBigInteger(data);
+
+ /*
+ * Some implementations do not correctly encode ASN.1 INTEGER values
+ * in 2's complement format, resulting in a negative integer when
+ * decoded. Correct the error by converting it to a positive integer.
+ *
+ * See CR 6255949
+ */
+ n = data.getPositiveBigInteger();
+ e = data.getPositiveBigInteger();
+ d = data.getPositiveBigInteger();
+ p = data.getPositiveBigInteger();
+ q = data.getPositiveBigInteger();
+ pe = data.getPositiveBigInteger();
+ qe = data.getPositiveBigInteger();
+ coeff = data.getPositiveBigInteger();
if (derValue.data.available() != 0) {
throw new IOException("Extra data available");
}
@@ -206,23 +214,4 @@
throw new InvalidKeyException("Invalid RSA private key", e);
}
}
-
- /**
- * Read a BigInteger from the DerInputStream.
- */
- static BigInteger getBigInteger(DerInputStream data) throws IOException {
- BigInteger b = data.getBigInteger();
-
- /*
- * Some implementations do not correctly encode ASN.1 INTEGER values
- * in 2's complement format, resulting in a negative integer when
- * decoded. Correct the error by converting it to a positive integer.
- *
- * See CR 6255949
- */
- if (b.signum() < 0) {
- b = new BigInteger(1, b.toByteArray());
- }
- return b;
- }
}
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/sun/security/rsa/RSAPublicKeyImpl.java
--- a/jdk/src/java.base/share/classes/sun/security/rsa/RSAPublicKeyImpl.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/rsa/RSAPublicKeyImpl.java Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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,8 +111,8 @@
throw new IOException("Not a SEQUENCE");
}
DerInputStream data = derValue.data;
- n = RSAPrivateCrtKeyImpl.getBigInteger(data);
- e = RSAPrivateCrtKeyImpl.getBigInteger(data);
+ n = data.getPositiveBigInteger();
+ e = data.getPositiveBigInteger();
if (derValue.data.available() != 0) {
throw new IOException("Extra data available");
}
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java
--- a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java Wed Jul 05 23:09:40 2017 +0200
@@ -1025,6 +1025,13 @@
cf = CertificateFactory.getInstance("X509");
}
+ // -trustcacerts can only be specified on -importcert.
+ // Reset it so that warnings on CA cert will remain for
+ // -printcert, etc.
+ if (command != IMPORTCERT) {
+ trustcacerts = false;
+ }
+
if (trustcacerts) {
caks = KeyStoreUtil.getCacertsKeyStore();
}
@@ -1758,9 +1765,8 @@
if (keyPass == null) {
keyPass = promptForKeyPass(alias, null, storePass);
}
+ checkWeak(rb.getString("the.generated.certificate"), chain[0]);
keyStore.setKeyEntry(alias, privKey, keyPass, chain);
-
- checkWeak(rb.getString("the.generated.certificate"), chain[0]);
}
/**
@@ -2118,6 +2124,10 @@
}
try {
+ Certificate c = srckeystore.getCertificate(alias);
+ if (c != null) {
+ checkWeak("<" + newAlias + ">", c);
+ }
keyStore.setEntry(newAlias, entry, pp);
// Place the check so that only successful imports are blocked.
// For example, we don't block a failed SecretEntry import.
@@ -2127,10 +2137,6 @@
"The.destination.pkcs12.keystore.has.different.storepass.and.keypass.Please.retry.with.destkeypass.specified."));
}
}
- Certificate c = srckeystore.getCertificate(alias);
- if (c != null) {
- checkWeak("<" + newAlias + ">", c);
- }
return 1;
} catch (KeyStoreException kse) {
Object[] source2 = {alias, kse.toString()};
@@ -2814,8 +2820,8 @@
}
if (noprompt) {
+ checkWeak(rb.getString("the.input"), cert);
keyStore.setCertificateEntry(alias, cert);
- checkWeak(rb.getString("the.input"), cert);
return true;
}
@@ -3049,6 +3055,11 @@
MessageFormat form = new MessageFormat
(rb.getString(".PATTERN.printX509Cert.with.weak"));
PublicKey pkey = cert.getPublicKey();
+ String sigName = cert.getSigAlgName();
+ // No need to warn about sigalg of a trust anchor
+ if (!isTrustedCert(cert)) {
+ sigName = withWeak(sigName);
+ }
Object[] source = {cert.getSubjectDN().toString(),
cert.getIssuerDN().toString(),
cert.getSerialNumber().toString(16),
@@ -3056,7 +3067,7 @@
cert.getNotAfter().toString(),
getCertFingerPrint("SHA-1", cert),
getCertFingerPrint("SHA-256", cert),
- withWeak(cert.getSigAlgName()),
+ sigName,
withWeak(pkey),
cert.getVersion()
};
@@ -3111,7 +3122,7 @@
* or null otherwise. A label is added.
*/
private static Pair
- getTrustedSigner(Certificate cert, KeyStore ks) throws Exception {
+ getSigner(Certificate cert, KeyStore ks) throws Exception {
if (ks.getCertificateAlias(cert) != null) {
return new Pair<>("", cert);
}
@@ -3467,9 +3478,9 @@
// do we trust the cert at the top?
Certificate topCert = replyCerts[replyCerts.length-1];
boolean fromKeyStore = true;
- Pair root = getTrustedSigner(topCert, keyStore);
+ Pair root = getSigner(topCert, keyStore);
if (root == null && trustcacerts && caks != null) {
- root = getTrustedSigner(topCert, caks);
+ root = getSigner(topCert, caks);
fromKeyStore = false;
}
if (root == null) {
@@ -4301,9 +4312,19 @@
return result;
}
+ private boolean isTrustedCert(Certificate cert) throws KeyStoreException {
+ if (caks != null && caks.getCertificateAlias(cert) != null) {
+ return true;
+ } else {
+ String inKS = keyStore.getCertificateAlias(cert);
+ return inKS != null && keyStore.isCertificateEntry(inKS);
+ }
+ }
+
private void checkWeak(String label, String sigAlg, Key key) {
- if (!DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, sigAlg, null)) {
+ if (sigAlg != null && !DISABLED_CHECK.permits(
+ SIG_PRIMITIVE_SET, sigAlg, null)) {
weakWarnings.add(String.format(
rb.getString("whose.sigalg.risk"), label, sigAlg));
}
@@ -4316,7 +4337,8 @@
}
}
- private void checkWeak(String label, Certificate[] certs) {
+ private void checkWeak(String label, Certificate[] certs)
+ throws KeyStoreException {
for (int i = 0; i < certs.length; i++) {
Certificate cert = certs[i];
if (cert instanceof X509Certificate) {
@@ -4325,15 +4347,18 @@
if (certs.length > 1) {
fullLabel = oneInMany(label, i, certs.length);
}
- checkWeak(fullLabel, xc.getSigAlgName(), xc.getPublicKey());
+ checkWeak(fullLabel, xc);
}
}
}
- private void checkWeak(String label, Certificate cert) {
+ private void checkWeak(String label, Certificate cert)
+ throws KeyStoreException {
if (cert instanceof X509Certificate) {
X509Certificate xc = (X509Certificate)cert;
- checkWeak(label, xc.getSigAlgName(), xc.getPublicKey());
+ // No need to check the sigalg of a trust anchor
+ String sigAlg = isTrustedCert(cert) ? null : xc.getSigAlgName();
+ checkWeak(label, sigAlg, xc.getPublicKey());
}
}
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/sun/security/util/DerInputBuffer.java
--- a/jdk/src/java.base/share/classes/sun/security/util/DerInputBuffer.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/util/DerInputBuffer.java Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, 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
@@ -44,16 +44,26 @@
*/
class DerInputBuffer extends ByteArrayInputStream implements Cloneable {
- DerInputBuffer(byte[] buf) { super(buf); }
+ boolean allowBER = true;
+
+ // used by sun/security/util/DerInputBuffer/DerInputBufferEqualsHashCode.java
+ DerInputBuffer(byte[] buf) {
+ this(buf, true);
+ }
- DerInputBuffer(byte[] buf, int offset, int len) {
+ DerInputBuffer(byte[] buf, boolean allowBER) {
+ super(buf);
+ this.allowBER = allowBER;
+ }
+
+ DerInputBuffer(byte[] buf, int offset, int len, boolean allowBER) {
super(buf, offset, len);
+ this.allowBER = allowBER;
}
DerInputBuffer dup() {
try {
DerInputBuffer retval = (DerInputBuffer)clone();
-
retval.mark(Integer.MAX_VALUE);
return retval;
} catch (CloneNotSupportedException e) {
@@ -147,8 +157,8 @@
System.arraycopy(buf, pos, bytes, 0, len);
skip(len);
- // check to make sure no extra leading 0s for DER
- if (len >= 2 && (bytes[0] == 0) && (bytes[1] >= 0)) {
+ // BER allows leading 0s but DER does not
+ if (!allowBER && (len >= 2 && (bytes[0] == 0) && (bytes[1] >= 0))) {
throw new IOException("Invalid encoding: redundant leading 0s");
}
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/sun/security/util/DerInputStream.java
--- a/jdk/src/java.base/share/classes/sun/security/util/DerInputStream.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/util/DerInputStream.java Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, 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
@@ -81,6 +81,25 @@
}
/**
+ * Create a DER input stream from part of a data buffer with
+ * additional arg to control whether DER checks are enforced.
+ * The buffer is not copied, it is shared. Accordingly, the
+ * buffer should be treated as read-only.
+ *
+ * @param data the buffer from which to create the string (CONSUMED)
+ * @param offset the first index of data which will
+ * be read as DER input in the new stream
+ * @param len how long a chunk of the buffer to use,
+ * starting at "offset"
+ * @param allowBER whether to allow constructed indefinite-length
+ * encoding as well as tolerate leading 0s
+ */
+ public DerInputStream(byte[] data, int offset, int len,
+ boolean allowBER) throws IOException {
+ init(data, offset, len, allowBER);
+ }
+
+ /**
* Create a DER input stream from part of a data buffer.
* The buffer is not copied, it is shared. Accordingly, the
* buffer should be treated as read-only.
@@ -95,47 +114,27 @@
init(data, offset, len, true);
}
- /**
- * Create a DER input stream from part of a data buffer with
- * additional arg to indicate whether to allow constructed
- * indefinite-length encoding.
- * The buffer is not copied, it is shared. Accordingly, the
- * buffer should be treated as read-only.
- *
- * @param data the buffer from which to create the string (CONSUMED)
- * @param offset the first index of data which will
- * be read as DER input in the new stream
- * @param len how long a chunk of the buffer to use,
- * starting at "offset"
- * @param allowIndefiniteLength whether to allow constructed
- * indefinite-length encoding
- */
- public DerInputStream(byte[] data, int offset, int len,
- boolean allowIndefiniteLength) throws IOException {
- init(data, offset, len, allowIndefiniteLength);
- }
-
/*
* private helper routine
*/
- private void init(byte[] data, int offset, int len,
- boolean allowIndefiniteLength) throws IOException {
+ private void init(byte[] data, int offset, int len, boolean allowBER) throws IOException {
if ((offset+2 > data.length) || (offset+len > data.length)) {
throw new IOException("Encoding bytes too short");
}
// check for indefinite length encoding
if (DerIndefLenConverter.isIndefinite(data[offset+1])) {
- if (!allowIndefiniteLength) {
+ if (!allowBER) {
throw new IOException("Indefinite length BER encoding found");
} else {
byte[] inData = new byte[len];
System.arraycopy(data, offset, inData, 0, len);
DerIndefLenConverter derIn = new DerIndefLenConverter();
- buffer = new DerInputBuffer(derIn.convert(inData));
+ buffer = new DerInputBuffer(derIn.convert(inData), allowBER);
}
- } else
- buffer = new DerInputBuffer(data, offset, len);
+ } else {
+ buffer = new DerInputBuffer(data, offset, len, allowBER);
+ }
buffer.mark(Integer.MAX_VALUE);
}
@@ -156,7 +155,7 @@
*/
public DerInputStream subStream(int len, boolean do_skip)
throws IOException {
- DerInputBuffer newbuf = buffer.dup();
+ DerInputBuffer newbuf = buffer.dup();
newbuf.truncate(len);
if (do_skip) {
@@ -399,7 +398,8 @@
dis.readFully(indefData, offset, readLen);
dis.close();
DerIndefLenConverter derIn = new DerIndefLenConverter();
- buffer = new DerInputBuffer(derIn.convert(indefData));
+ buffer = new DerInputBuffer(derIn.convert(indefData), buffer.allowBER);
+
if (tag != buffer.read())
throw new IOException("Indefinite length encoding" +
" not supported");
@@ -427,7 +427,7 @@
DerValue value;
do {
- value = new DerValue(newstr.buffer);
+ value = new DerValue(newstr.buffer, buffer.allowBER);
vec.addElement(value);
} while (newstr.available() > 0);
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/sun/security/util/DerValue.java
--- a/jdk/src/java.base/share/classes/sun/security/util/DerValue.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/util/DerValue.java Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
-/*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+/**
+ * Copyright (c) 1996, 2017, 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
@@ -225,6 +225,16 @@
data = init(stringTag, value);
}
+ // Creates a DerValue from a tag and some DER-encoded data w/ additional
+ // arg to control whether DER checks are enforced.
+ DerValue(byte tag, byte[] data, boolean allowBER) {
+ this.tag = tag;
+ buffer = new DerInputBuffer(data.clone(), allowBER);
+ length = data.length;
+ this.data = new DerInputStream(buffer);
+ this.data.mark(Integer.MAX_VALUE);
+ }
+
/**
* Creates a DerValue from a tag and some DER-encoded data.
*
@@ -232,20 +242,16 @@
* @param data the DER-encoded data
*/
public DerValue(byte tag, byte[] data) {
- this.tag = tag;
- buffer = new DerInputBuffer(data.clone());
- length = data.length;
- this.data = new DerInputStream(buffer);
- this.data.mark(Integer.MAX_VALUE);
+ this(tag, data, true);
}
/*
* package private
*/
DerValue(DerInputBuffer in) throws IOException {
+
// XXX must also parse BER-encoded constructed
// values such as sequences, sets...
-
tag = (byte)in.read();
byte lenByte = (byte)in.read();
length = DerInputStream.getLength(lenByte, in);
@@ -260,7 +266,7 @@
dis.readFully(indefData, offset, readLen);
dis.close();
DerIndefLenConverter derIn = new DerIndefLenConverter();
- inbuf = new DerInputBuffer(derIn.convert(indefData));
+ inbuf = new DerInputBuffer(derIn.convert(indefData), in.allowBER);
if (tag != inbuf.read())
throw new IOException
("Indefinite length encoding not supported");
@@ -282,6 +288,12 @@
}
}
+ // Get an ASN.1/DER encoded datum from a buffer w/ additional
+ // arg to control whether DER checks are enforced.
+ DerValue(byte[] buf, boolean allowBER) throws IOException {
+ data = init(true, new ByteArrayInputStream(buf), allowBER);
+ }
+
/**
* Get an ASN.1/DER encoded datum from a buffer. The
* entire buffer must hold exactly one datum, including
@@ -290,7 +302,14 @@
* @param buf buffer holding a single DER-encoded datum.
*/
public DerValue(byte[] buf) throws IOException {
- data = init(true, new ByteArrayInputStream(buf));
+ this(buf, true);
+ }
+
+ // Get an ASN.1/DER encoded datum from part of a buffer w/ additional
+ // arg to control whether DER checks are enforced.
+ DerValue(byte[] buf, int offset, int len, boolean allowBER)
+ throws IOException {
+ data = init(true, new ByteArrayInputStream(buf, offset, len), allowBER);
}
/**
@@ -303,7 +322,13 @@
* @param len how many bytes are in the encoded datum
*/
public DerValue(byte[] buf, int offset, int len) throws IOException {
- data = init(true, new ByteArrayInputStream(buf, offset, len));
+ this(buf, offset, len, true);
+ }
+
+ // Get an ASN1/DER encoded datum from an input stream w/ additional
+ // arg to control whether DER checks are enforced.
+ DerValue(InputStream in, boolean allowBER) throws IOException {
+ data = init(false, in, allowBER);
}
/**
@@ -316,10 +341,11 @@
* which may be followed by additional data
*/
public DerValue(InputStream in) throws IOException {
- data = init(false, in);
+ this(in, true);
}
- private DerInputStream init(byte stringTag, String value) throws IOException {
+ private DerInputStream init(byte stringTag, String value)
+ throws IOException {
String enc = null;
tag = stringTag;
@@ -347,7 +373,7 @@
byte[] buf = value.getBytes(enc);
length = buf.length;
- buffer = new DerInputBuffer(buf);
+ buffer = new DerInputBuffer(buf, true);
DerInputStream result = new DerInputStream(buffer);
result.mark(Integer.MAX_VALUE);
return result;
@@ -356,8 +382,8 @@
/*
* helper routine
*/
- private DerInputStream init(boolean fullyBuffered, InputStream in)
- throws IOException {
+ private DerInputStream init(boolean fullyBuffered, InputStream in,
+ boolean allowBER) throws IOException {
tag = (byte)in.read();
byte lenByte = (byte)in.read();
@@ -384,7 +410,7 @@
byte[] bytes = IOUtils.readFully(in, length, true);
- buffer = new DerInputBuffer(bytes);
+ buffer = new DerInputBuffer(bytes, allowBER);
return new DerInputStream(buffer);
}
@@ -479,7 +505,8 @@
if (buffer.read(bytes) != length)
throw new IOException("short read on DerValue buffer");
if (isConstructed()) {
- DerInputStream in = new DerInputStream(bytes);
+ DerInputStream in = new DerInputStream(bytes, 0, bytes.length,
+ buffer.allowBER);
bytes = null;
while (in.available() != 0) {
bytes = append(bytes, in.getOctetString());
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/sun/security/x509/X509CRLImpl.java
--- a/jdk/src/java.base/share/classes/sun/security/x509/X509CRLImpl.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/x509/X509CRLImpl.java Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -443,18 +443,6 @@
}
/**
- * This static method is the default implementation of the
- * verify(PublicKey key, Provider sigProvider) method in X509CRL.
- * Called from java.security.cert.X509CRL.verify(PublicKey key,
- * Provider sigProvider)
- */
- public static void verify(X509CRL crl, PublicKey key,
- Provider sigProvider) throws CRLException,
- NoSuchAlgorithmException, InvalidKeyException, SignatureException {
- crl.verify(key, sigProvider);
- }
-
- /**
* Encodes an X.509 CRL, and signs it using the given key.
*
* @param key the private key used for signing.
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/classes/sun/security/x509/X509CertImpl.java
--- a/jdk/src/java.base/share/classes/sun/security/x509/X509CertImpl.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/x509/X509CertImpl.java Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, 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
@@ -494,18 +494,6 @@
}
}
- /**
- * This static method is the default implementation of the
- * verify(PublicKey key, Provider sigProvider) method in X509Certificate.
- * Called from java.security.cert.X509Certificate.verify(PublicKey key,
- * Provider sigProvider)
- */
- public static void verify(X509Certificate cert, PublicKey key,
- Provider sigProvider) throws CertificateException,
- NoSuchAlgorithmException, InvalidKeyException, SignatureException {
- cert.verify(key, sigProvider);
- }
-
/**
* Creates an X.509 certificate, and signs it using the given key
* (associating a signature algorithm and an X.500 name).
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/conf/security/java.security
--- a/jdk/src/java.base/share/conf/security/java.security Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/conf/security/java.security Wed Jul 05 23:09:40 2017 +0200
@@ -598,8 +598,8 @@
# jdk.certpath.disabledAlgorithms=MD2, DSA, RSA keySize < 2048
#
#
-jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \
- DSA keySize < 1024, EC keySize < 224
+jdk.certpath.disabledAlgorithms=MD2, MD5, SHA1 jdkCA & usage TLSServer, \
+ RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224
#
# Algorithm restrictions for signed JAR files
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/legal/zlib.md
--- a/jdk/src/java.base/share/legal/zlib.md Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/legal/zlib.md Wed Jul 05 23:09:40 2017 +0200
@@ -1,9 +1,9 @@
-## zlib v1.2.8
+## zlib v1.2.11
### zlib License
-Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
+Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/native/libjava/ClassLoader.c
--- a/jdk/src/java.base/share/native/libjava/ClassLoader.c Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/native/libjava/ClassLoader.c Wed Jul 05 23:09:40 2017 +0200
@@ -72,23 +72,9 @@
return utfStr;
}
-// The existence or signature of this method is not guaranteed since it
-// supports a private method. This method will be changed in 1.7.
-JNIEXPORT jclass JNICALL
-Java_java_lang_ClassLoader_defineClass0(JNIEnv *env,
- jobject loader,
- jstring name,
- jbyteArray data,
- jint offset,
- jint length,
- jobject pd)
-{
- return Java_java_lang_ClassLoader_defineClass1(env, loader, name, data, offset,
- length, pd, NULL);
-}
-
JNIEXPORT jclass JNICALL
Java_java_lang_ClassLoader_defineClass1(JNIEnv *env,
+ jclass cls,
jobject loader,
jstring name,
jbyteArray data,
@@ -163,6 +149,7 @@
JNIEXPORT jclass JNICALL
Java_java_lang_ClassLoader_defineClass2(JNIEnv *env,
+ jclass cls,
jobject loader,
jstring name,
jobject data,
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/share/native/libjava/Module.c
--- a/jdk/src/java.base/share/native/libjava/Module.c Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/share/native/libjava/Module.c Wed Jul 05 23:09:40 2017 +0200
@@ -73,30 +73,32 @@
jstring location, jobjectArray packages)
{
char** pkgs = NULL;
- jsize idx;
jsize num_packages = (*env)->GetArrayLength(env, packages);
if (num_packages != 0 && (pkgs = calloc(num_packages, sizeof(char*))) == NULL) {
JNU_ThrowOutOfMemoryError(env, NULL);
return;
- } else {
- int valid = 1;
+ } else if ((*env)->EnsureLocalCapacity(env, (jint)num_packages) == 0) {
+ jboolean failed = JNI_FALSE;
+ int idx;
for (idx = 0; idx < num_packages; idx++) {
jstring pkg = (*env)->GetObjectArrayElement(env, packages, idx);
- pkgs[idx] = GetInternalPackageName(env, pkg, NULL, 0);
- if (pkgs[idx] == NULL) {
- valid = 0;
+ char* name = GetInternalPackageName(env, pkg, NULL, 0);
+ if (name != NULL) {
+ pkgs[idx] = name;
+ } else {
+ failed = JNI_TRUE;
break;
}
}
-
- if (valid != 0) {
+ if (!failed) {
JVM_DefineModule(env, module, is_open, version, location,
- (const char* const*)pkgs, num_packages);
+ (const char* const*)pkgs, num_packages);
}
}
if (num_packages > 0) {
+ int idx;
for (idx = 0; idx < num_packages; idx++) {
if (pkgs[idx] != NULL) {
free(pkgs[idx]);
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.base/unix/native/libjava/ProcessHandleImpl_unix.c
--- a/jdk/src/java.base/unix/native/libjava/ProcessHandleImpl_unix.c Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.base/unix/native/libjava/ProcessHandleImpl_unix.c Wed Jul 05 23:09:40 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -244,7 +244,8 @@
int status;
while (waitpid(pid, &status, 0) < 0) {
switch (errno) {
- case ECHILD: return 0;
+ case ECHILD:
+ return java_lang_ProcessHandleImpl_NOT_A_CHILD; // No child
case EINTR: break;
default: return -1;
}
@@ -269,9 +270,10 @@
memset(&siginfo, 0, sizeof siginfo);
while (waitid(P_PID, pid, &siginfo, options) < 0) {
switch (errno) {
- case ECHILD: return 0;
- case EINTR: break;
- default: return -1;
+ case ECHILD:
+ return java_lang_ProcessHandleImpl_NOT_A_CHILD; // No child
+ case EINTR: break;
+ default: return -1;
}
}
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.datatransfer/share/classes/module-info.java
--- a/jdk/src/java.datatransfer/share/classes/module-info.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.datatransfer/share/classes/module-info.java Wed Jul 05 23:09:40 2017 +0200
@@ -24,8 +24,9 @@
*/
/**
- * Defines an API for transferring data between and within applications.
+ * Defines the API for transferring data between and within applications.
*
+ * @moduleGraph
* @since 9
*/
module java.datatransfer {
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaButtonBorder.java
--- a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaButtonBorder.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaButtonBorder.java Wed Jul 05 23:09:40 2017 +0200
@@ -37,7 +37,7 @@
import com.apple.laf.AquaUtils.*;
public abstract class AquaButtonBorder extends AquaBorder implements Border, UIResource {
- public static final RecyclableSingleton fDynamic = new RecyclableSingletonFromDefaultConstructor(Dynamic.class);
+ private static final RecyclableSingleton fDynamic = new RecyclableSingletonFromDefaultConstructor(Dynamic.class);
public static AquaButtonBorder getDynamicButtonBorder() {
return fDynamic.get();
}
@@ -47,12 +47,12 @@
return fToggle.get();
}
- public static final RecyclableSingleton fToolBar = new RecyclableSingletonFromDefaultConstructor(Toolbar.class);
+ private static final RecyclableSingleton fToolBar = new RecyclableSingletonFromDefaultConstructor(Toolbar.class);
public static Border getToolBarButtonBorder() {
return fToolBar.get();
}
- public static final RecyclableSingleton fBevel = new RecyclableSingleton() {
+ private static final RecyclableSingleton fBevel = new RecyclableSingleton() {
protected Named getInstance() {
return new Named(Widget.BUTTON_BEVEL, new SizeDescriptor(new SizeVariant().alterMargins(2, 4, 2, 4)));
}
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaButtonCheckBoxUI.java
--- a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaButtonCheckBoxUI.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaButtonCheckBoxUI.java Wed Jul 05 23:09:40 2017 +0200
@@ -34,8 +34,8 @@
import com.apple.laf.AquaUtils.*;
public class AquaButtonCheckBoxUI extends AquaButtonLabeledUI {
- protected static final RecyclableSingleton instance = new RecyclableSingletonFromDefaultConstructor(AquaButtonCheckBoxUI.class);
- protected static final RecyclableSingleton sizingIcon = new RecyclableSingleton() {
+ private static final RecyclableSingleton instance = new RecyclableSingletonFromDefaultConstructor(AquaButtonCheckBoxUI.class);
+ private static final RecyclableSingleton sizingIcon = new RecyclableSingleton() {
protected ImageIcon getInstance() {
return new ImageIcon(AquaNativeResources.getRadioButtonSizerImage());
}
diff -r 18569c523d38 -r c61cc8a34456 jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaButtonExtendedTypes.java
--- a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaButtonExtendedTypes.java Sat Apr 08 03:25:14 2017 +0000
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaButtonExtendedTypes.java Wed Jul 05 23:09:40 2017 +0200
@@ -138,7 +138,7 @@
return typeDefinitions.get().get(name);
}
- protected static final RecyclableSingleton